From 4a37da35939b3c1bfc5b79b6ed92042af1371ebe Mon Sep 17 00:00:00 2001 From: amammad Date: Sun, 25 Jun 2023 20:04:50 +1000 Subject: [PATCH 001/404] V1 --- .../CWE/CWE-409-DecompressionBomb/Bombs.ql | 69 +++++++++ .../DecompressionBomb.qhelp | 35 +++++ .../CWE-409-DecompressionBomb/example_bad.cpp | 30 ++++ .../example_good.cpp | 38 +++++ .../DecompressionBomb.ql | 121 +++++++++++++++ .../DecompressionBombs.qhelp | 26 ++++ .../RemoteFlowSource.qll | 62 ++++++++ .../DecompressionBombs.cs | 140 ++++++++++++++++++ .../DecompressionBombs.qlref | 1 + 9 files changed, 522 insertions(+) create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bombs.ql create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp create mode 100644 csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql create mode 100644 csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qhelp create mode 100644 csharp/ql/src/experimental/CWE-502-DecompressionBombs/RemoteFlowSource.qll create mode 100644 csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.cs create mode 100644 csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qlref diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bombs.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bombs.ql new file mode 100644 index 00000000000..2e595bb11b8 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bombs.ql @@ -0,0 +1,69 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision medium + * @id cpp/user-controlled-file-decompression + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * The `gzopen` function, which can perform command substitution. + */ +private class GzopenFunction extends Function { + GzopenFunction() { hasGlobalName("gzopen") } +} + +/** + * The `gzread` function, which can perform command substitution. + */ +private class GzreadFunction extends Function { + GzreadFunction() { hasGlobalName("gzread") } +} + +module ZlibTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | + fc.getArgument(0) = source.asExpr() + ) + } + + predicate isSink(DataFlow::Node sink) { + exists(FunctionCall fc | fc.getTarget() instanceof GzreadFunction | + fc.getArgument(0) = sink.asExpr() and + not sanitizer(fc) + ) + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc + ) + } +} + +predicate sanitizer(FunctionCall fc) { + exists(Expr e | fc.getTarget() instanceof GzreadFunction | + // a RelationalOperation which isn't compared with a Literal that using for end of read + TaintTracking::localExprTaint(fc, e.(RelationalOperation).getAChild*()) and + not e.getAChild*().(Literal).getValue() = ["0", "1", "-1"] + ) +} + +module ZlibTaint = TaintTracking::Global; + +import ZlibTaint::PathGraph + +from ZlibTaint::PathNode source, ZlibTaint::PathNode sink +where ZlibTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp new file mode 100644 index 00000000000..44256d36ea9 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp @@ -0,0 +1,35 @@ + + + +

Extracting Compressed files with any compression algorithm like gzip can cause to denial of service attacks.

+

Attackers can compress a huge file which created by repeated similiar byte and convert it to a small compressed file.

+ +
+ + +

When you want to decompress a user-provided compressed file you must be careful about the decompression ratio or read these files within a loop byte by byte to be able to manage the decompressed size in each cycle of the loop.

+ +
+ + +

+Reading uncompressed Gzip file within a loop and check for a threshold size in each cycle. +

+ + +

+An Unsafe Approach can be this example which we don't check for uncompressed size. +

+ + +
+ + +
  • +A great research to gain more impact by this kind of attacks +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp new file mode 100644 index 00000000000..843b200231a --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp @@ -0,0 +1,30 @@ +#include +#include +#include "zlib.h" +int UnsafeRead() { + std::cout << "enter compressed file name!\n" << std::endl; + char fileName[100]; + std::cin >> fileName; + gzFile inFileZ = gzopen(fileName, "rb"); + if (inFileZ == nullptr) { + printf("Error: Failed to gzopen %s\n", fileName); + exit(0); + } + unsigned char unzipBuffer[8192]; + unsigned int unzippedBytes; + std::vector unzippedData; + while (true) { + unzippedBytes = gzread(inFileZ, unzipBuffer, 8192); + if (unzippedBytes > 0) { + unzippedData.insert(unzippedData.end(), unzipBuffer, unzipBuffer + unzippedBytes); + } else { + break; + } + } + + for ( auto &&i: unzippedData) + std::cout << i; + gzclose(inFileZ); + + return 0; +} \ No newline at end of file diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp new file mode 100644 index 00000000000..3d26569bdb4 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp @@ -0,0 +1,38 @@ +#include +#include +#include "zlib.h" +int SafeRead() { + std::cout << "enter compressed file name!\n" << std::endl; + char fileName[100]; + std::cin >> fileName; + gzFile inFileZ = gzopen(fileName, "rb"); + if (inFileZ == nullptr) { + printf("Error: Failed to gzopen %s\n", fileName); + exit(0); + } + unsigned char unzipBuffer[8192]; + unsigned int unzippedBytes; + uint totalRead = 0; + std::vector unzippedData; + while (true) { + unzippedBytes = gzread(inFileZ, unzipBuffer, 8192); + totalRead += unzippedBytes; + if (unzippedBytes > 0) { + unzippedData.insert(unzippedData.end(), unzipBuffer, unzipBuffer + unzippedBytes); + if (totalRead > 1024 * 1024 * 4) { + std::cout << "Bombs!" << totalRead; + exit(1); + } else { + std::cout << "not Bomb yet!!" << totalRead << std::endl; + } + } else { + break; + } + } + + for (auto &&i: unzippedData) + std::cout << i; + gzclose(inFileZ); + + return 0; +} \ No newline at end of file diff --git a/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql b/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql new file mode 100644 index 00000000000..72f81731800 --- /dev/null +++ b/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql @@ -0,0 +1,121 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision medium + * @id cs/user-controlled-file-decompression + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import csharp +import semmle.code.csharp.security.dataflow.flowsources.Remote + +/** + * A data flow source for unsafe Decompression extraction. + */ +abstract class DecompressionSource extends DataFlow::Node { } + +class ZipOpenReadSource extends DecompressionSource { + ZipOpenReadSource() { + exists(MethodCall mc | + mc.getTarget().hasQualifiedName("System.IO.Compression", "ZipFile", ["OpenRead", "Open"]) and + this.asExpr() = mc.getArgument(0) and + not mc.getArgument(0).getType().isConst() + ) + } +} + +/** A path argument to a call to the `ZipArchive` constructor call. */ +class ZipArchiveArgSource extends DecompressionSource { + ZipArchiveArgSource() { + exists(ObjectCreation oc | + oc.getTarget().getDeclaringType().hasQualifiedName("System.IO.Compression", "ZipArchive") + | + this.asExpr() = oc.getArgument(0) + ) + } +} + +/** + * A data flow sink for unsafe zip extraction. + */ +abstract class DecompressionSink extends DataFlow::Node { } + +/** A Caller of the `ExtractToFile` method. */ +class ExtractToFileCallSink extends DecompressionSink { + ExtractToFileCallSink() { + exists(MethodCall mc | + mc.getTarget().hasQualifiedName("System.IO.Compression", "ZipFileExtensions", "ExtractToFile") and + this.asExpr() = mc.getArgumentForName("source") + ) + } +} + +/** A Qualifier of the `Open()` method. */ +class OpenCallSink extends DecompressionSink { + OpenCallSink() { + exists(MethodCall mc | + mc.getTarget().hasQualifiedName("System.IO.Compression", "ZipArchiveEntry", "Open") and + this.asExpr() = mc.getQualifier() + ) + } +} + +/** A Call to the `GZipStreamSink` first arugument of Constructor Call . */ +class GZipStreamSink extends DecompressionSink, DecompressionSource { + GZipStreamSink() { + exists(Constructor mc | + mc.getDeclaringType().hasQualifiedName("System.IO.Compression", "GZipStream") and + this.asExpr() = mc.getACall().getArgument(0) + ) + } +} + +/** + * A taint tracking configuration for Decompression Bomb. + */ +private module DecompressionBombConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + source instanceof DecompressionSource + or + source instanceof RemoteFlowSource + } + + predicate isSink(DataFlow::Node sink) { sink instanceof DecompressionSink } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + // var node2 = new ZipArchive(node1, ZipArchiveMode.Read); + exists(ObjectCreation oc | + oc.getTarget().getDeclaringType().hasQualifiedName("System.IO.Compression", "ZipArchive") and + node2.asExpr() = oc and + node1.asExpr() = oc.getArgumentForName("stream") + ) + or + // var node2 = node1.ExtractToFile("./output.txt", true) + exists(MethodCall mc | + mc.getTarget().hasQualifiedName("System.IO.Compression", "ZipFileExtensions", "ExtractToFile") and + node2.asExpr() = mc and + node1.asExpr() = mc.getArgumentForName("source") + ) + or + // var node2 = node1.OpenReadStream() + exists(MethodCall mc | + mc.getTarget().hasQualifiedName("Microsoft.AspNetCore.Http", "IFormFile", "OpenReadStream") and + node2.asExpr() = mc and + node1.asExpr() = mc.getQualifier() + ) + } +} + +module DecompressionBomb = TaintTracking::Global; + +import DecompressionBomb::PathGraph + +from DecompressionBomb::PathNode source, DecompressionBomb::PathNode sink +where DecompressionBomb::flowPath(source, sink) +select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qhelp b/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qhelp new file mode 100644 index 00000000000..c3c874cddf7 --- /dev/null +++ b/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qhelp @@ -0,0 +1,26 @@ + + + +

    Extracting Compressed files with any compression algorithm like gzip can cause to denial of service attacks.

    +

    Attackers can compress a huge file which created by repeated similiar byte and convert it to a small compressed file.

    + +
    + + +

    When you want to decompress a user-provided compressed file you must be careful about the decompression ratio or read these files within a loop byte by byte to be able to manage the decompressed size in each cycle of the loop.

    + +
    + + +

    A good Blog Post about decompression bombs and recommended method is already written by Gérald Barré in this blog post

    + + + +
  • +A great research to gain more impact by this kind of attack +
  • + +
    +
    diff --git a/csharp/ql/src/experimental/CWE-502-DecompressionBombs/RemoteFlowSource.qll b/csharp/ql/src/experimental/CWE-502-DecompressionBombs/RemoteFlowSource.qll new file mode 100644 index 00000000000..f849ab3f4a1 --- /dev/null +++ b/csharp/ql/src/experimental/CWE-502-DecompressionBombs/RemoteFlowSource.qll @@ -0,0 +1,62 @@ +import csharp +import semmle.code.csharp.security.dataflow.flowsources.Remote + +/** A data flow source of remote user input by Form File (ASP.NET unvalidated request data). */ +class FormFile extends AspNetRemoteFlowSource { + FormFile() { + exists(MethodCall mc | + mc.getTarget() + .hasQualifiedName(["Microsoft.AspNetCore.Http", "Microsoft.AspNetCore.Http.Features"], + "IFormFile", ["OpenReadStream", "ContentType", "ContentDisposition", "Name", "FileName"]) and + this.asExpr() = mc + ) + or + exists(MethodCall mc | + mc.getTarget() + .hasQualifiedName(["Microsoft.AspNetCore.Http", "Microsoft.AspNetCore.Http.Features"], + "IFormFile", "CopyTo") and + this.asParameter() = mc.getTarget().getParameter(0) + ) + or + exists(Property fa | + fa.getDeclaringType() + .hasQualifiedName(["Microsoft.AspNetCore.Http", "Microsoft.AspNetCore.Http.Features"], + "IFormFile") and + fa.hasName(["ContentType", "ContentDisposition", "Name", "FileName"]) and + this.asExpr() = fa.getAnAccess() + ) + } + + override string getSourceType() { + result = "ASP.NET unvalidated request data from multipart request" + } +} + +/** A data flow source of remote user input by Form (ASP.NET unvalidated request data). */ +class FormCollection extends AspNetRemoteFlowSource { + FormCollection() { + exists(Property fa | + fa.getDeclaringType().hasQualifiedName("Microsoft.AspNetCore.Http", "IFormCollection") and + fa.hasName("Keys") and + this.asExpr() = fa.getAnAccess() + ) + } + + override string getSourceType() { + result = "ASP.NET unvalidated request data from multipart request Form Keys" + } +} + +/** A data flow source of remote user input by Headers (ASP.NET unvalidated request data). */ +class HeaderDictionary extends AspNetRemoteFlowSource { + HeaderDictionary() { + exists(Property fa | + fa.getDeclaringType().hasQualifiedName("Microsoft.AspNetCore.Http", "IHeaderDictionary") and + this.asExpr() = fa.getAnAccess() + ) + } + + override string getSourceType() { + result = "ASP.NET unvalidated request data from Headers of request" + } +} diff --git a/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.cs b/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.cs new file mode 100644 index 00000000000..b73eac9bade --- /dev/null +++ b/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.cs @@ -0,0 +1,140 @@ +using System.IO.Compression; +using Microsoft.AspNetCore.Mvc; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 + +namespace MultipartFormWebAPITest.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class ZipFile1Controller : ControllerBase + { + // POST api/ + [HttpPost] + public string Post(List files) + { + if (!Request.ContentType!.StartsWith("multipart/form-data")) + return "400"; + if (files.Count == 0) + return "400"; + foreach (var formFile in files) + { + using var readStream = formFile.OpenReadStream(); + if (readStream.Length == 0) return "400"; + ZipHelpers.Bomb3(readStream); + ZipHelpers.Bomb2(formFile.FileName); + ZipHelpers.Bomb1(formFile.FileName); + } + var tmp = Request.Form["aa"]; + var tmp2 = Request.Form.Keys; + // when we don't have only one file as body + ZipHelpers.Bomb3(Request.Body); + ZipHelpers.Bomb2(Request.Query["param1"].ToString()); + var headers = Request.Headers; + ZipHelpers.Bomb1(headers.ETag); + return "200"; + } + } +} + +internal static class ZipHelpers +{ + public static void Bomb3(Stream compressedFileStream) + { + // using FileStream compressedFileStream = File.Open(CompressedFileName, FileMode.Open); + // using FileStream outputFileStream = File.Create(DecompressedFileName); + using var decompressor = new GZipStream(compressedFileStream, CompressionMode.Decompress); + using var ms = new MemoryStream(); + decompressor.CopyTo(ms); + } + + public static void Bomb2(string filename) + { + using var zipToOpen = new FileStream(filename, FileMode.Open); + using var archive = new ZipArchive(zipToOpen, ZipArchiveMode.Read); + foreach (var entry in archive.Entries) entry.ExtractToFile("./output.txt", true); // Sensitive + } + + public static void Bomb1(string filename) + { + const long maxLength = 10 * 1024 * 1024; // 10MB + // var filename = "/home/am/0_WorkDir/Payloads/Bombs/bombs-bones-codes-BH-2016/archives/evil-headers/10GB.zip"; + using var zipFile = ZipFile.OpenRead(filename); + // Quickly check the value from the zip header + var declaredSize = zipFile.Entries.Sum(entry => entry.Length); + if (declaredSize > maxLength) + throw new Exception("Archive is too big"); + foreach (var entry in zipFile.Entries) + { + using var entryStream = entry.Open(); + // Use MaxLengthStream to ensure we don't read more than the declared length + using var maxLengthStream = new MaxLengthStream(entryStream, entry.Length); + // Be sure to use the maxLengthSteam variable to read the content of the entry, not entryStream + using var ms = new MemoryStream(); + maxLengthStream.CopyTo(ms); + } + } +} + +internal sealed class MaxLengthStream : Stream +{ + private readonly Stream _stream; + private long _length; + + public MaxLengthStream(Stream stream, long maxLength) + { + _stream = stream ?? throw new ArgumentNullException(nameof(stream)); + MaxLength = maxLength; + } + + private long MaxLength { get; } + + public override bool CanRead => _stream.CanRead; + public override bool CanSeek => false; + public override bool CanWrite => false; + public override long Length => _stream.Length; + + public override long Position + { + get => _stream.Position; + set => throw new NotSupportedException(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + var result = _stream.Read(buffer, offset, count); + _length += result; + if (_length > MaxLength) + throw new Exception("Stream is larger than the maximum allowed size"); + + return result; + } + + // TODO ReadAsync + + public override void Flush() + { + throw new NotSupportedException(); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotSupportedException(); + } + + protected override void Dispose(bool disposing) + { + _stream.Dispose(); + base.Dispose(disposing); + } +} \ No newline at end of file diff --git a/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qlref b/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qlref new file mode 100644 index 00000000000..19b7ebbb843 --- /dev/null +++ b/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qlref @@ -0,0 +1 @@ +experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql \ No newline at end of file From 430375e2f01859e481de54860b3eadd11c614e00 Mon Sep 17 00:00:00 2001 From: amammad Date: Sun, 25 Jun 2023 20:28:45 +1000 Subject: [PATCH 002/404] fix a commit mistake --- .../DecompressionBomb.ql | 121 --------------- .../DecompressionBombs.qhelp | 26 ---- .../RemoteFlowSource.qll | 62 -------- .../DecompressionBombs.cs | 140 ------------------ .../DecompressionBombs.qlref | 1 - 5 files changed, 350 deletions(-) delete mode 100644 csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql delete mode 100644 csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qhelp delete mode 100644 csharp/ql/src/experimental/CWE-502-DecompressionBombs/RemoteFlowSource.qll delete mode 100644 csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.cs delete mode 100644 csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qlref diff --git a/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql b/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql deleted file mode 100644 index 72f81731800..00000000000 --- a/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision medium - * @id cs/user-controlled-file-decompression - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -import csharp -import semmle.code.csharp.security.dataflow.flowsources.Remote - -/** - * A data flow source for unsafe Decompression extraction. - */ -abstract class DecompressionSource extends DataFlow::Node { } - -class ZipOpenReadSource extends DecompressionSource { - ZipOpenReadSource() { - exists(MethodCall mc | - mc.getTarget().hasQualifiedName("System.IO.Compression", "ZipFile", ["OpenRead", "Open"]) and - this.asExpr() = mc.getArgument(0) and - not mc.getArgument(0).getType().isConst() - ) - } -} - -/** A path argument to a call to the `ZipArchive` constructor call. */ -class ZipArchiveArgSource extends DecompressionSource { - ZipArchiveArgSource() { - exists(ObjectCreation oc | - oc.getTarget().getDeclaringType().hasQualifiedName("System.IO.Compression", "ZipArchive") - | - this.asExpr() = oc.getArgument(0) - ) - } -} - -/** - * A data flow sink for unsafe zip extraction. - */ -abstract class DecompressionSink extends DataFlow::Node { } - -/** A Caller of the `ExtractToFile` method. */ -class ExtractToFileCallSink extends DecompressionSink { - ExtractToFileCallSink() { - exists(MethodCall mc | - mc.getTarget().hasQualifiedName("System.IO.Compression", "ZipFileExtensions", "ExtractToFile") and - this.asExpr() = mc.getArgumentForName("source") - ) - } -} - -/** A Qualifier of the `Open()` method. */ -class OpenCallSink extends DecompressionSink { - OpenCallSink() { - exists(MethodCall mc | - mc.getTarget().hasQualifiedName("System.IO.Compression", "ZipArchiveEntry", "Open") and - this.asExpr() = mc.getQualifier() - ) - } -} - -/** A Call to the `GZipStreamSink` first arugument of Constructor Call . */ -class GZipStreamSink extends DecompressionSink, DecompressionSource { - GZipStreamSink() { - exists(Constructor mc | - mc.getDeclaringType().hasQualifiedName("System.IO.Compression", "GZipStream") and - this.asExpr() = mc.getACall().getArgument(0) - ) - } -} - -/** - * A taint tracking configuration for Decompression Bomb. - */ -private module DecompressionBombConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - source instanceof DecompressionSource - or - source instanceof RemoteFlowSource - } - - predicate isSink(DataFlow::Node sink) { sink instanceof DecompressionSink } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - // var node2 = new ZipArchive(node1, ZipArchiveMode.Read); - exists(ObjectCreation oc | - oc.getTarget().getDeclaringType().hasQualifiedName("System.IO.Compression", "ZipArchive") and - node2.asExpr() = oc and - node1.asExpr() = oc.getArgumentForName("stream") - ) - or - // var node2 = node1.ExtractToFile("./output.txt", true) - exists(MethodCall mc | - mc.getTarget().hasQualifiedName("System.IO.Compression", "ZipFileExtensions", "ExtractToFile") and - node2.asExpr() = mc and - node1.asExpr() = mc.getArgumentForName("source") - ) - or - // var node2 = node1.OpenReadStream() - exists(MethodCall mc | - mc.getTarget().hasQualifiedName("Microsoft.AspNetCore.Http", "IFormFile", "OpenReadStream") and - node2.asExpr() = mc and - node1.asExpr() = mc.getQualifier() - ) - } -} - -module DecompressionBomb = TaintTracking::Global; - -import DecompressionBomb::PathGraph - -from DecompressionBomb::PathNode source, DecompressionBomb::PathNode sink -where DecompressionBomb::flowPath(source, sink) -select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qhelp b/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qhelp deleted file mode 100644 index c3c874cddf7..00000000000 --- a/csharp/ql/src/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qhelp +++ /dev/null @@ -1,26 +0,0 @@ - - - -

    Extracting Compressed files with any compression algorithm like gzip can cause to denial of service attacks.

    -

    Attackers can compress a huge file which created by repeated similiar byte and convert it to a small compressed file.

    - -
    - - -

    When you want to decompress a user-provided compressed file you must be careful about the decompression ratio or read these files within a loop byte by byte to be able to manage the decompressed size in each cycle of the loop.

    - -
    - - -

    A good Blog Post about decompression bombs and recommended method is already written by Gérald Barré in this blog post

    - - - -
  • -A great research to gain more impact by this kind of attack -
  • - -
    -
    diff --git a/csharp/ql/src/experimental/CWE-502-DecompressionBombs/RemoteFlowSource.qll b/csharp/ql/src/experimental/CWE-502-DecompressionBombs/RemoteFlowSource.qll deleted file mode 100644 index f849ab3f4a1..00000000000 --- a/csharp/ql/src/experimental/CWE-502-DecompressionBombs/RemoteFlowSource.qll +++ /dev/null @@ -1,62 +0,0 @@ -import csharp -import semmle.code.csharp.security.dataflow.flowsources.Remote - -/** A data flow source of remote user input by Form File (ASP.NET unvalidated request data). */ -class FormFile extends AspNetRemoteFlowSource { - FormFile() { - exists(MethodCall mc | - mc.getTarget() - .hasQualifiedName(["Microsoft.AspNetCore.Http", "Microsoft.AspNetCore.Http.Features"], - "IFormFile", ["OpenReadStream", "ContentType", "ContentDisposition", "Name", "FileName"]) and - this.asExpr() = mc - ) - or - exists(MethodCall mc | - mc.getTarget() - .hasQualifiedName(["Microsoft.AspNetCore.Http", "Microsoft.AspNetCore.Http.Features"], - "IFormFile", "CopyTo") and - this.asParameter() = mc.getTarget().getParameter(0) - ) - or - exists(Property fa | - fa.getDeclaringType() - .hasQualifiedName(["Microsoft.AspNetCore.Http", "Microsoft.AspNetCore.Http.Features"], - "IFormFile") and - fa.hasName(["ContentType", "ContentDisposition", "Name", "FileName"]) and - this.asExpr() = fa.getAnAccess() - ) - } - - override string getSourceType() { - result = "ASP.NET unvalidated request data from multipart request" - } -} - -/** A data flow source of remote user input by Form (ASP.NET unvalidated request data). */ -class FormCollection extends AspNetRemoteFlowSource { - FormCollection() { - exists(Property fa | - fa.getDeclaringType().hasQualifiedName("Microsoft.AspNetCore.Http", "IFormCollection") and - fa.hasName("Keys") and - this.asExpr() = fa.getAnAccess() - ) - } - - override string getSourceType() { - result = "ASP.NET unvalidated request data from multipart request Form Keys" - } -} - -/** A data flow source of remote user input by Headers (ASP.NET unvalidated request data). */ -class HeaderDictionary extends AspNetRemoteFlowSource { - HeaderDictionary() { - exists(Property fa | - fa.getDeclaringType().hasQualifiedName("Microsoft.AspNetCore.Http", "IHeaderDictionary") and - this.asExpr() = fa.getAnAccess() - ) - } - - override string getSourceType() { - result = "ASP.NET unvalidated request data from Headers of request" - } -} diff --git a/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.cs b/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.cs deleted file mode 100644 index b73eac9bade..00000000000 --- a/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System.IO.Compression; -using Microsoft.AspNetCore.Mvc; - -// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 - -namespace MultipartFormWebAPITest.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class ZipFile1Controller : ControllerBase - { - // POST api/ - [HttpPost] - public string Post(List files) - { - if (!Request.ContentType!.StartsWith("multipart/form-data")) - return "400"; - if (files.Count == 0) - return "400"; - foreach (var formFile in files) - { - using var readStream = formFile.OpenReadStream(); - if (readStream.Length == 0) return "400"; - ZipHelpers.Bomb3(readStream); - ZipHelpers.Bomb2(formFile.FileName); - ZipHelpers.Bomb1(formFile.FileName); - } - var tmp = Request.Form["aa"]; - var tmp2 = Request.Form.Keys; - // when we don't have only one file as body - ZipHelpers.Bomb3(Request.Body); - ZipHelpers.Bomb2(Request.Query["param1"].ToString()); - var headers = Request.Headers; - ZipHelpers.Bomb1(headers.ETag); - return "200"; - } - } -} - -internal static class ZipHelpers -{ - public static void Bomb3(Stream compressedFileStream) - { - // using FileStream compressedFileStream = File.Open(CompressedFileName, FileMode.Open); - // using FileStream outputFileStream = File.Create(DecompressedFileName); - using var decompressor = new GZipStream(compressedFileStream, CompressionMode.Decompress); - using var ms = new MemoryStream(); - decompressor.CopyTo(ms); - } - - public static void Bomb2(string filename) - { - using var zipToOpen = new FileStream(filename, FileMode.Open); - using var archive = new ZipArchive(zipToOpen, ZipArchiveMode.Read); - foreach (var entry in archive.Entries) entry.ExtractToFile("./output.txt", true); // Sensitive - } - - public static void Bomb1(string filename) - { - const long maxLength = 10 * 1024 * 1024; // 10MB - // var filename = "/home/am/0_WorkDir/Payloads/Bombs/bombs-bones-codes-BH-2016/archives/evil-headers/10GB.zip"; - using var zipFile = ZipFile.OpenRead(filename); - // Quickly check the value from the zip header - var declaredSize = zipFile.Entries.Sum(entry => entry.Length); - if (declaredSize > maxLength) - throw new Exception("Archive is too big"); - foreach (var entry in zipFile.Entries) - { - using var entryStream = entry.Open(); - // Use MaxLengthStream to ensure we don't read more than the declared length - using var maxLengthStream = new MaxLengthStream(entryStream, entry.Length); - // Be sure to use the maxLengthSteam variable to read the content of the entry, not entryStream - using var ms = new MemoryStream(); - maxLengthStream.CopyTo(ms); - } - } -} - -internal sealed class MaxLengthStream : Stream -{ - private readonly Stream _stream; - private long _length; - - public MaxLengthStream(Stream stream, long maxLength) - { - _stream = stream ?? throw new ArgumentNullException(nameof(stream)); - MaxLength = maxLength; - } - - private long MaxLength { get; } - - public override bool CanRead => _stream.CanRead; - public override bool CanSeek => false; - public override bool CanWrite => false; - public override long Length => _stream.Length; - - public override long Position - { - get => _stream.Position; - set => throw new NotSupportedException(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - var result = _stream.Read(buffer, offset, count); - _length += result; - if (_length > MaxLength) - throw new Exception("Stream is larger than the maximum allowed size"); - - return result; - } - - // TODO ReadAsync - - public override void Flush() - { - throw new NotSupportedException(); - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - - protected override void Dispose(bool disposing) - { - _stream.Dispose(); - base.Dispose(disposing); - } -} \ No newline at end of file diff --git a/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qlref b/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qlref deleted file mode 100644 index 19b7ebbb843..00000000000 --- a/csharp/ql/test/experimental/CWE-502-DecompressionBombs/DecompressionBombs.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/CWE-502-DecompressionBombs/DecompressionBomb.ql \ No newline at end of file From ae98510f77671bb55e1a56f3a28b7acba4fb8205 Mon Sep 17 00:00:00 2001 From: amammad Date: Mon, 26 Jun 2023 00:21:55 +1000 Subject: [PATCH 003/404] add more source and sinks and sanitizers --- .../CWE/CWE-409-DecompressionBomb/Bombs.ql | 69 --------- .../DecompressionBombsGzopen.ql | 139 ++++++++++++++++++ .../DecompressionBombsInflator.ql | 56 +++++++ .../DecompressionBombsUncompress.ql | 56 +++++++ 4 files changed, 251 insertions(+), 69 deletions(-) delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bombs.ql create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsUncompress.ql diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bombs.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bombs.ql deleted file mode 100644 index 2e595bb11b8..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bombs.ql +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision medium - * @id cpp/user-controlled-file-decompression - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources - -/** - * The `gzopen` function, which can perform command substitution. - */ -private class GzopenFunction extends Function { - GzopenFunction() { hasGlobalName("gzopen") } -} - -/** - * The `gzread` function, which can perform command substitution. - */ -private class GzreadFunction extends Function { - GzreadFunction() { hasGlobalName("gzread") } -} - -module ZlibTaintConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | - fc.getArgument(0) = source.asExpr() - ) - } - - predicate isSink(DataFlow::Node sink) { - exists(FunctionCall fc | fc.getTarget() instanceof GzreadFunction | - fc.getArgument(0) = sink.asExpr() and - not sanitizer(fc) - ) - } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc - ) - } -} - -predicate sanitizer(FunctionCall fc) { - exists(Expr e | fc.getTarget() instanceof GzreadFunction | - // a RelationalOperation which isn't compared with a Literal that using for end of read - TaintTracking::localExprTaint(fc, e.(RelationalOperation).getAChild*()) and - not e.getAChild*().(Literal).getValue() = ["0", "1", "-1"] - ) -} - -module ZlibTaint = TaintTracking::Global; - -import ZlibTaint::PathGraph - -from ZlibTaint::PathNode source, ZlibTaint::PathNode sink -where ZlibTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This file extraction depends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql new file mode 100644 index 00000000000..644841af23e --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql @@ -0,0 +1,139 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression1 + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A gzFile Variable as a Flow source + */ +private class GzFileVar extends VariableAccess { + GzFileVar() { this.getType().hasName("gzFile") } +} + +/** + * The `gzopen` function as a Flow source + */ +private class GzopenFunction extends Function { + GzopenFunction() { hasGlobalName("gzopen") } +} + +/** + * The `gzdopen` function as a Flow source + */ +private class GzdopenFunction extends Function { + GzdopenFunction() { hasGlobalName("gzdopen") } +} + +/** + * The `gzfread` function is used in Flow sink + */ +private class GzfreadFunction extends Function { + GzfreadFunction() { hasGlobalName("gzfread") } +} + +/** + * The `gzread` function is used in Flow sink + */ +private class GzreadFunction extends Function { + GzreadFunction() { hasGlobalName("gzread") } +} + +module ZlibTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + // gzopen(const char *path, const char *mode); + exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | + fc.getArgument(0) = source.asExpr() and + // arg 0 can be a path string whichwe must do following check + not fc.getArgument(0).isConstant() + ) + or + //gzdopen(int fd, const char *mode); + // IDK whether it is good to use all file decriptors function returns as source or not + // because we can do more sanitization from fd function sources + exists(FunctionCall fc | fc.getTarget() instanceof GzdopenFunction | + fc.getArgument(0) = source.asExpr() + ) + or + source.asExpr() instanceof GzFileVar + } + + predicate isSink(DataFlow::Node sink) { + // gzread(gzFile file, voidp buf, unsigned len)); + exists(FunctionCall fc | fc.getTarget() instanceof GzreadFunction | + fc.getArgument(0) = sink.asExpr() and + not sanitizer(fc) + // TODO: and not sanitizer2(fc.getArgument(2)) + ) + or + // gzfread((voidp buf, z_size_t size, z_size_t nitems, gzFile file)); + exists(FunctionCall fc | fc.getTarget() instanceof GzfreadFunction | + sink.asExpr() = fc.getArgument(3) + ) + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + // gzopen(const char *path, const char *mode); + // gzdopen(int fd, const char *mode); + exists(FunctionCall fc | + fc.getTarget() instanceof GzopenFunction or fc.getTarget() instanceof GzdopenFunction + | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc + ) + or + // gzread(gzFile file, voidp buf, unsigned len); + exists(FunctionCall fc | fc.getTarget() instanceof GzreadFunction | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) + ) + or + // gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file); + exists(FunctionCall fc | fc.getTarget() instanceof GzfreadFunction | + node1.asExpr() = fc.getArgument(3) and + node2.asExpr() = fc.getArgument(0) + ) + } +} + +predicate sanitizer(FunctionCall fc) { + exists(Expr e | + // a RelationalOperation which isn't compared with a Literal that using for end of read + TaintTracking::localExprTaint(fc, e.(RelationalOperation).getAChild*()) and + not e.getAChild*().(Literal).getValue() = ["0", "1", "-1"] + ) +} + +// TODO: +// predicate sanitizer2(Expr arg) { +// exists(Expr e | +// // a RelationalOperation which isn't compared with a Literal that using for end of read +// TaintTracking::localExprTaint(arg, e.(RelationalOperation).getAChild*()) +// ) +// } +// predicate test(FunctionCall fc, Expr sink) { +// exists( | fc.getTarget() instanceof GzreadFunction | +// // a RelationalOperation which isn't compared with a Literal that using for end of read +// TaintTracking::localExprTaint(fc.getArgument(2).(VariableAccess), sink) +// ) and +// sink.getFile().getLocation().toString().matches("%main.cpp%") +// } +module ZlibTaint = TaintTracking::Global; + +import ZlibTaint::PathGraph + +from ZlibTaint::PathNode source, ZlibTaint::PathNode sink +where ZlibTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql new file mode 100644 index 00000000000..541c23c58ec --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql @@ -0,0 +1,56 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression2 + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A z_stream Variable as a Flow source + */ +private class ZStreamVar extends VariableAccess { + ZStreamVar() { this.getType().hasName("z_stream") } +} + +/** + * The `inflate`/`inflateSync` function is used in Flow sink + */ +private class DeflateFunction extends Function { + DeflateFunction() { hasGlobalName(["inflate", "inflateSync"]) } +} + +module ZlibTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr() instanceof ZStreamVar } + + predicate isSink(DataFlow::Node sink) { + exists(FunctionCall fc | fc.getTarget() instanceof DeflateFunction | + fc.getArgument(0) = sink.asExpr() + ) + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall fc | fc.getTarget() instanceof DeflateFunction | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc + ) + } +} + +module ZlibTaint = TaintTracking::Global; + +import ZlibTaint::PathGraph + +from ZlibTaint::PathNode source, ZlibTaint::PathNode sink +where ZlibTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompression depends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsUncompress.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsUncompress.ql new file mode 100644 index 00000000000..09327616fd9 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsUncompress.ql @@ -0,0 +1,56 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression3 + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A Bytef Variable as a Flow source + */ +private class BytefVar extends VariableAccess { + BytefVar() { this.getType().hasName("Bytef") } +} + +/** + * The `uncompress`/`uncompress2` function is used in Flow sink + */ +private class UncompressFunction extends Function { + UncompressFunction() { hasGlobalName(["uncompress", "uncompress2"]) } +} + +module ZlibTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source.asExpr() instanceof BytefVar } + + predicate isSink(DataFlow::Node sink) { + exists(FunctionCall fc | fc.getTarget() instanceof UncompressFunction | + fc.getArgument(0) = sink.asExpr() + ) + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall fc | fc.getTarget() instanceof UncompressFunction | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc + ) + } +} + +module ZlibTaint = TaintTracking::Global; + +import ZlibTaint::PathGraph + +from ZlibTaint::PathNode source, ZlibTaint::PathNode sink +where ZlibTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompression depends on a $@.", source.getNode(), + "potentially untrusted source" From 3ddc9a8b31612ad0fb264928ab20f73411cc81a7 Mon Sep 17 00:00:00 2001 From: amammad Date: Mon, 26 Jun 2023 05:26:30 +1000 Subject: [PATCH 004/404] fix warnings, more sinks,sources,comments --- .../DecompressionBombsGzopen.ql | 55 +++++++++++-------- .../DecompressionBombsInflator.ql | 16 ++++-- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql index 644841af23e..6c0804404cd 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql @@ -16,7 +16,7 @@ import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources /** - * A gzFile Variable as a Flow source + * A `gzFile` Variable as a Flow source */ private class GzFileVar extends VariableAccess { GzFileVar() { this.getType().hasName("gzFile") } @@ -24,42 +24,57 @@ private class GzFileVar extends VariableAccess { /** * The `gzopen` function as a Flow source + * + * `gzopen(const char *path, const char *mode)` */ private class GzopenFunction extends Function { - GzopenFunction() { hasGlobalName("gzopen") } + GzopenFunction() { this.hasGlobalName("gzopen") } } /** * The `gzdopen` function as a Flow source + * + * `gzdopen(int fd, const char *mode)` */ private class GzdopenFunction extends Function { - GzdopenFunction() { hasGlobalName("gzdopen") } + GzdopenFunction() { this.hasGlobalName("gzdopen") } } /** * The `gzfread` function is used in Flow sink + * + * `gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file)` */ private class GzfreadFunction extends Function { - GzfreadFunction() { hasGlobalName("gzfread") } + GzfreadFunction() { this.hasGlobalName("gzfread") } +} + +/** + * The `gzgets` function is used in Flow sink. + * + * `gzgets(gzFile file, char *buf, int len)` + */ +private class GzgetsFunction extends Function { + GzgetsFunction() { this.hasGlobalName("gzgets") } } /** * The `gzread` function is used in Flow sink + * + * `gzread(gzFile file, voidp buf, unsigned len)` */ private class GzreadFunction extends Function { - GzreadFunction() { hasGlobalName("gzread") } + GzreadFunction() { this.hasGlobalName("gzread") } } module ZlibTaintConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { - // gzopen(const char *path, const char *mode); exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | fc.getArgument(0) = source.asExpr() and // arg 0 can be a path string whichwe must do following check not fc.getArgument(0).isConstant() ) or - //gzdopen(int fd, const char *mode); // IDK whether it is good to use all file decriptors function returns as source or not // because we can do more sanitization from fd function sources exists(FunctionCall fc | fc.getTarget() instanceof GzdopenFunction | @@ -70,22 +85,22 @@ module ZlibTaintConfig implements DataFlow::ConfigSig { } predicate isSink(DataFlow::Node sink) { - // gzread(gzFile file, voidp buf, unsigned len)); exists(FunctionCall fc | fc.getTarget() instanceof GzreadFunction | fc.getArgument(0) = sink.asExpr() and not sanitizer(fc) // TODO: and not sanitizer2(fc.getArgument(2)) ) or - // gzfread((voidp buf, z_size_t size, z_size_t nitems, gzFile file)); exists(FunctionCall fc | fc.getTarget() instanceof GzfreadFunction | sink.asExpr() = fc.getArgument(3) ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzgetsFunction | + sink.asExpr() = fc.getArgument(0) + ) } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - // gzopen(const char *path, const char *mode); - // gzdopen(int fd, const char *mode); exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction or fc.getTarget() instanceof GzdopenFunction | @@ -93,17 +108,20 @@ module ZlibTaintConfig implements DataFlow::ConfigSig { node2.asExpr() = fc ) or - // gzread(gzFile file, voidp buf, unsigned len); exists(FunctionCall fc | fc.getTarget() instanceof GzreadFunction | node1.asExpr() = fc.getArgument(0) and node2.asExpr() = fc.getArgument(1) ) or - // gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file); exists(FunctionCall fc | fc.getTarget() instanceof GzfreadFunction | node1.asExpr() = fc.getArgument(3) and node2.asExpr() = fc.getArgument(0) ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzgetsFunction | + node1.asExpr() = fc.getArgument(0) and + node1.asExpr() = fc.getArgument(1) + ) } } @@ -116,19 +134,12 @@ predicate sanitizer(FunctionCall fc) { } // TODO: -// predicate sanitizer2(Expr arg) { +// predicate sanitizer2(FunctionCall fc) { // exists(Expr e | // // a RelationalOperation which isn't compared with a Literal that using for end of read -// TaintTracking::localExprTaint(arg, e.(RelationalOperation).getAChild*()) +// TaintTracking::localExprTaint(fc.getArgument(2), e) // ) // } -// predicate test(FunctionCall fc, Expr sink) { -// exists( | fc.getTarget() instanceof GzreadFunction | -// // a RelationalOperation which isn't compared with a Literal that using for end of read -// TaintTracking::localExprTaint(fc.getArgument(2).(VariableAccess), sink) -// ) and -// sink.getFile().getLocation().toString().matches("%main.cpp%") -// } module ZlibTaint = TaintTracking::Global; import ZlibTaint::PathGraph diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql index 541c23c58ec..fdd11e1fc16 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql @@ -16,30 +16,34 @@ import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources /** - * A z_stream Variable as a Flow source + * A `z_stream` Variable as a Flow source */ private class ZStreamVar extends VariableAccess { ZStreamVar() { this.getType().hasName("z_stream") } } /** - * The `inflate`/`inflateSync` function is used in Flow sink + * The `inflate`/`inflateSync` functions are used in Flow sink + * + * `inflate(z_streamp strm, int flush)` + * + * `inflateSync(z_streamp strm)` */ -private class DeflateFunction extends Function { - DeflateFunction() { hasGlobalName(["inflate", "inflateSync"]) } +private class InflateFunction extends Function { + InflateFunction() { this.hasGlobalName(["inflate", "inflateSync"]) } } module ZlibTaintConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr() instanceof ZStreamVar } predicate isSink(DataFlow::Node sink) { - exists(FunctionCall fc | fc.getTarget() instanceof DeflateFunction | + exists(FunctionCall fc | fc.getTarget() instanceof InflateFunction | fc.getArgument(0) = sink.asExpr() ) } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(FunctionCall fc | fc.getTarget() instanceof DeflateFunction | + exists(FunctionCall fc | fc.getTarget() instanceof InflateFunction | node1.asExpr() = fc.getArgument(0) and node2.asExpr() = fc ) From f715a3437b1793dfca1941111aae1af5b420544b Mon Sep 17 00:00:00 2001 From: amammad Date: Mon, 26 Jun 2023 05:29:16 +1000 Subject: [PATCH 005/404] better examples --- .../CWE-409-DecompressionBomb/example_bad.cpp | 112 ++++++++++++++++-- .../example_good.cpp | 45 ++++++- 2 files changed, 143 insertions(+), 14 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp index 843b200231a..94e3e969a51 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp @@ -1,7 +1,64 @@ -#include -#include -#include "zlib.h" -int UnsafeRead() { + +int UnsafeInflate(int argc, char *argv[]) { + // original string len = 36 + char a[50] = "Hello Hello Hello Hello Hello Hello!"; + // placeholder for the compressed (deflated) version of "a" + char b[50]; + // placeholder for the Uncompressed (inflated) version of "b" + char c[50]; + printf("Uncompressed size is: %lu\n", strlen(a)); + printf("Uncompressed string is: %s\n", a); + printf("\n----------\n\n"); + + // STEP 1. + // zlib struct + z_stream defstream; + defstream.zalloc = Z_NULL; + defstream.zfree = Z_NULL; + defstream.opaque = Z_NULL; + // setup "a" as the input and "b" as the compressed output + defstream.avail_in = (uInt) strlen(a) + 1; // size of input, string + terminator + defstream.next_in = (Bytef *) a; // input char array + defstream.avail_out = (uInt) sizeof(b); // size of output + defstream.next_out = (Bytef *) b; // output char array + + // the actual compression work. + deflateInit(&defstream, Z_BEST_COMPRESSION); + deflate(&defstream, Z_FINISH); + deflateEnd(&defstream); + + // This is one way of getting the size of the output + printf("Compressed size is: %lu\n", strlen(b)); + printf("Compressed string is: %s\n", b); + printf("\n----------\n\n"); + // STEP 2. + // inflate b into c + // zlib struct + z_stream infstream; + infstream.zalloc = Z_NULL; + infstream.zfree = Z_NULL; + infstream.opaque = Z_NULL; + // setup "b" as the input and "c" as the compressed output + // TOTHINK: Here we can add additional step from Right operand to z_stream variable access + infstream.avail_in = (uInt) ((char *) defstream.next_out - b); // size of input + infstream.next_in = (Bytef *) b; // input char array + infstream.avail_out = (uInt) sizeof(c); // size of output + infstream.next_out = (Bytef *) c; // output char array + + // uLong total_out; /* total number of bytes output so far */ + // the actual DE-compression work. + inflateInit(&infstream); + std::cout << infstream.total_out << std::endl; + inflate(&infstream, Z_NO_FLUSH); + std::cout << infstream.total_out << std::endl; + inflateEnd(&infstream); + + printf("Uncompressed size is: %lu\n", strlen(c)); + printf("Uncompressed string is: %s\n", c); + return 0; +} + +int UnsafeGzread() { std::cout << "enter compressed file name!\n" << std::endl; char fileName[100]; std::cin >> fileName; @@ -21,10 +78,47 @@ int UnsafeRead() { break; } } - - for ( auto &&i: unzippedData) - std::cout << i; + for (auto &&i: unzippedData) + std::cout << i; gzclose(inFileZ); - return 0; -} \ No newline at end of file +} + +int UnsafeGzfread() { + std::cout << "enter compressed file name!\n" << std::endl; + char fileName[100]; + std::cin >> fileName; + gzFile inFileZ = gzopen(fileName, "rb"); + if (inFileZ == nullptr) { + printf("Error: Failed to gzopen %s\n", fileName); + exit(0); + } + while (true) { + char buffer[1000]; + if (!gzfread(buffer, 999, 1, inFileZ)) { + break; + } + } + gzclose(inFileZ); + return 0; +} + +int UnsafeGzgets() { + std::cout << "enter compressed file name!\n" << std::endl; + char fileName[100]; + std::cin >> fileName; + gzFile inFileZ = gzopen(fileName, "rb"); + if (inFileZ == nullptr) { + printf("Error: Failed to gzopen %s\n", fileName); + exit(0); + } + char *buffer = new char[4000000000]; + char *result = gzgets(inFileZ, buffer, 1000000000); + while (true) { + result = gzgets(inFileZ, buffer, 1000000000); + if (result == nullptr) { + break; + } + } + return 0; +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp index 3d26569bdb4..e3a2d4b2e50 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp @@ -1,7 +1,5 @@ -#include -#include -#include "zlib.h" -int SafeRead() { + +int SafeGzread() { std::cout << "enter compressed file name!\n" << std::endl; char fileName[100]; std::cin >> fileName; @@ -35,4 +33,41 @@ int SafeRead() { gzclose(inFileZ); return 0; -} \ No newline at end of file +} + +int SafeGzread2() { + std::cout << "enter compressed file name!\n" << std::endl; + char fileName[100]; + std::cin >> fileName; + gzFile inFileZ = gzopen(fileName, "rb"); + if (inFileZ == nullptr) { + printf("Error: Failed to gzopen %s\n", fileName); + exit(0); + } + const int BUFFER_SIZE = 8192; + unsigned char unzipBuffer[BUFFER_SIZE]; + unsigned int unzippedBytes; + uint totalRead = 0; + std::vector unzippedData; + while (true) { + unzippedBytes = gzread(inFileZ, unzipBuffer, BUFFER_SIZE); + totalRead += BUFFER_SIZE; + if (unzippedBytes > 0) { + unzippedData.insert(unzippedData.end(), unzipBuffer, unzipBuffer + unzippedBytes); + if (totalRead > 1024 * 1024 * 4) { + std::cout << "Bombs!" << totalRead; + exit(1); + } else { + std::cout << "not Bomb yet!!" << totalRead << std::endl; + } + } else { + break; + } + } + + for (auto &&i: unzippedData) + std::cout << i; + gzclose(inFileZ); + + return 0; +} From 042133a9912072040f8a67ad870d69d881a8a2e2 Mon Sep 17 00:00:00 2001 From: amammad Date: Mon, 3 Jul 2023 09:12:37 +1000 Subject: [PATCH 006/404] add queries for more popular libs --- .../DecompressionBomb.qhelp | 6 +- .../DecompressionBombsBrotli.ql | 107 +++++++++++++ .../DecompressionBombsBzip2.ql | 126 ++++++++++++++++ .../DecompressionBombsMiniZip.ql | 102 +++++++++++++ .../DecompressionBombsXZ.ql | 100 +++++++++++++ .../DecompressionBombsZSTD.ql | 140 ++++++++++++++++++ ...pen.ql => DecompressionBombsZlibGzopen.ql} | 2 +- ...r.ql => DecompressionBombsZlibInflator.ql} | 9 +- ...ql => DecompressionBombsZlibUncompress.ql} | 9 +- .../CWE-409-DecompressionBomb/example_bad.cpp | 5 + .../example_good.cpp | 5 + 11 files changed, 593 insertions(+), 18 deletions(-) create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBrotli.ql create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBzip2.ql create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsXZ.ql create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZSTD.ql rename cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/{DecompressionBombsGzopen.ql => DecompressionBombsZlibGzopen.ql} (98%) rename cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/{DecompressionBombsInflator.ql => DecompressionBombsZlibInflator.ql} (84%) rename cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/{DecompressionBombsUncompress.ql => DecompressionBombsZlibUncompress.ql} (83%) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp index 44256d36ea9..cdadabbf207 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp @@ -5,7 +5,6 @@

    Extracting Compressed files with any compression algorithm like gzip can cause to denial of service attacks.

    Attackers can compress a huge file which created by repeated similiar byte and convert it to a small compressed file.

    -
    @@ -25,8 +24,13 @@ An Unsafe Approach can be this example which we don't check for uncompressed siz + +
  • +Zlib Documentation +
  • +
  • A great research to gain more impact by this kind of attacks
  • diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBrotli.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBrotli.ql new file mode 100644 index 00000000000..b09858d6471 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBrotli.ql @@ -0,0 +1,107 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression-brotli + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +// https://github.com/google/brotli +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.commons.File + +/** + * A Pointer Variable is used in Flow source + */ +private class PointerVar extends VariableAccess { + PointerVar() { this.getType() instanceof PointerType } +} + +/** + * A Pointer Variable is used in Flow source + */ +private class Uint8Var extends VariableAccess { + Uint8Var() { this.getType() instanceof UInt8_t } +} + +/** + * A ZSTD_inBuffer Variable is used in Flow source + */ +private class ZSTDinBufferVar extends VariableAccess { + ZSTDinBufferVar() { this.getType().hasName("ZSTD_inBuffer") } +} + +/** + * The `ZSTD_decompress_usingDDict` function is used in Flow sink + * Ref: https://www.brotli.org/decode.html#af68 + */ +private class BrotliDecoderDecompressFunction extends Function { + BrotliDecoderDecompressFunction() { this.hasGlobalName(["BrotliDecoderDecompress"]) } +} + +/** + * The `BrotliDecoderDecompressStream` function is used in Flow sink + * Ref: https://www.brotli.org/decode.html#a234 + */ +private class BrotliDecoderDecompressStreamFunction extends Function { + BrotliDecoderDecompressStreamFunction() { this.hasGlobalName(["BrotliDecoderDecompressStream"]) } +} + +module BrotliTaintConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof AllocationFunction | + fc = source.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fopenCall(fc) | + fc = source.asExpr() and + state = "" + ) + or + source.asExpr() instanceof PointerVar and + state = "" + or + source.asExpr() instanceof Uint8Var and + state = "" + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressStreamFunction | + fc.getArgument(2) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressFunction | + fc.getArgument(1) = sink.asExpr() and + state = "" + ) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } +} + +module BrotliTaint = TaintTracking::GlobalWithState; + +import BrotliTaint::PathGraph + +from BrotliTaint::PathNode source, BrotliTaint::PathNode sink +where BrotliTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompression depends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBzip2.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBzip2.ql new file mode 100644 index 00000000000..e9b7d60715d --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBzip2.ql @@ -0,0 +1,126 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression-bzip2 + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.commons.File + +/** + * A `bz_stream` Variable as a Flow source + */ +private class BzStreamVar extends VariableAccess { + BzStreamVar() { this.getType().hasName("bz_stream") } +} + +/** + * A `BZFILE` Variable as a Flow source + */ +private class BZFILEVar extends VariableAccess { + BZFILEVar() { this.getType().hasName("BZFILE") } +} + +/** + * The `BZ2_bzopen`,`BZ2_bzdopen` functions as a Flow source + */ +private class BZ2BzopenFunction extends Function { + BZ2BzopenFunction() { this.hasGlobalName(["BZ2_bzopen", "BZ2_bzdopen"]) } +} + +/** + * The `BZ2_bzDecompress` function as a Flow source + */ +private class BZ2BzDecompressFunction extends Function { + BZ2BzDecompressFunction() { this.hasGlobalName(["BZ2_bzDecompress"]) } +} + +/** + * The `BZ2_bzReadOpen` function + */ +private class BZ2BzReadOpenFunction extends Function { + BZ2BzReadOpenFunction() { this.hasGlobalName(["BZ2_bzReadOpen"]) } +} + +/** + * The `BZ2_bzRead` function is used in Flow sink + */ +private class BZ2BzReadFunction extends Function { + BZ2BzReadFunction() { this.hasGlobalName("BZ2_bzRead") } +} + +/** + * The `BZ2_bzRead` function is used in Flow sink + */ +private class BZ2BzBuffToBuffDecompressFunction extends Function { + BZ2BzBuffToBuffDecompressFunction() { this.hasGlobalName("BZ2_bzBuffToBuffDecompress") } +} + +/** + * https://www.sourceware.org/bzip2/manual/manual.html + */ +module Bzip2TaintConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + source.asExpr() instanceof BzStreamVar and + state = "" + or + source.asExpr() instanceof BZFILEVar and + state = "" + or + // will flow into BZ2BzReadOpenFunction + exists(FunctionCall fc | fopenCall(fc) | + fc = source.asExpr() and + state = "" + ) + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzDecompressFunction | + fc.getArgument(0) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzReadFunction | + fc.getArgument(1) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzBuffToBuffDecompressFunction | + fc.getArgument(2) = sink.asExpr() and + state = "" + ) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzReadOpenFunction | + node1.asExpr() = fc.getArgument(1) and + node2.asExpr() = fc and + state1 = "" and + state2 = "" + ) + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } +} + +module Bzip2Taint = TaintTracking::GlobalWithState; + +import Bzip2Taint::PathGraph + +from Bzip2Taint::PathNode source, Bzip2Taint::PathNode sink +where Bzip2Taint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql new file mode 100644 index 00000000000..b8cd89fc542 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql @@ -0,0 +1,102 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression-minizip + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A `unzFile` Variable as a Flow source + */ +private class UnzFileVar extends VariableAccess { + UnzFileVar() { this.getType().hasName("unzFile") } +} + +/** + * The `UnzOpen` function as a Flow source + */ +private class UnzOpenFunction extends Function { + UnzOpenFunction() { this.hasGlobalName(["UnzOpen", "unzOpen64", "unzOpen2", "unzOpen2_64"]) } +} + +/** + * The `mz_stream_open` function is used in Flow source + */ +private class MzStreamOpenFunction extends Function { + MzStreamOpenFunction() { this.hasGlobalName("mz_stream_open") } +} + +/** + * The `unzReadCurrentFile` function is used in Flow sink + */ +private class UnzReadCurrentFileFunction extends Function { + UnzReadCurrentFileFunction() { this.hasGlobalName(["unzReadCurrentFile"]) } +} + +module MiniZipTaintConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction | + fc.getArgument(0) = source.asExpr() and + state = "unzFile" + ) + or + source.asExpr() instanceof UnzFileVar and + state = "unzFile" + or + // TO Check + exists(FunctionCall fc | fc.getTarget() instanceof MzStreamOpenFunction | + fc.getArgument(0).getEnclosingVariable() = source.asVariable() and + state = "MzStream" + ) + or + // TO Check + exists(FunctionCall fc | fc.getTarget() instanceof MzStreamOpenFunction | + fc.getArgument(0).getEnclosingVariable() = source.asVariable() and + state = "MzStream" + ) + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof UnzReadCurrentFileFunction | + fc.getArgument(0) = sink.asExpr() and + state = "unzFile" + // and not sanitizer(fc) + ) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc and + state1 = "" and + state2 = "unzFile" + ) + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } +} + + +module MiniZipTaint = TaintTracking::GlobalWithState; + +import MiniZipTaint::PathGraph + +from MiniZipTaint::PathNode source, MiniZipTaint::PathNode sink +where MiniZipTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsXZ.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsXZ.ql new file mode 100644 index 00000000000..dadbf7a5a8a --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsXZ.ql @@ -0,0 +1,100 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression-xz + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A Pointer Variable as a Flow source + */ +private class Uint8Var extends VariableAccess { + Uint8Var() { this.getType() instanceof UInt8_t } +} + +/** + * A `lzma_stream` Variable as a Flow source + */ +private class LzmaStreamVar extends VariableAccess { + LzmaStreamVar() { this.getType().hasName("lzma_stream") } +} + +/** + * The `lzma_*_decoder` function is used as a required condition for decompression + */ +private class LzmaDecoderFunction extends Function { + LzmaDecoderFunction() { + this.hasGlobalName(["lzma_stream_decoder", "lzma_auto_decoder", "lzma_alone_decoder"]) + } +} + +/** + * The `lzma_code` function is used in Flow sink + */ +private class LzmaCodeFunction extends Function { + LzmaCodeFunction() { this.hasGlobalName(["lzma_code"]) } +} + +/** + * The `lzma_stream_buffer_decode` function is used in Flow sink + */ +private class LzmaStreamBufferDecodeFunction extends Function { + LzmaStreamBufferDecodeFunction() { this.hasGlobalName(["lzma_stream_buffer_decode"]) } +} + +/** + * https://github.com/tukaani-project/xz + */ +module XzTaintConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + source.asExpr() instanceof LzmaStreamVar and + state = "" + or + source.asExpr() instanceof Uint8Var and + state = "" + // and not exists(FunctionCall fc | fc.getTarget() instanceof LzmaStreamDecoderFunction) + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof LzmaStreamBufferDecodeFunction | + fc.getArgument(1) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof LzmaCodeFunction | + fc.getArgument(0) = sink.asExpr() and + state = "" + ) and + exists(FunctionCall fc2 | fc2.getTarget() instanceof LzmaDecoderFunction) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } +} + +module XzTaint = TaintTracking::GlobalWithState; + +import XzTaint::PathGraph + +from XzTaint::PathNode source, XzTaint::PathNode sink +where XzTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZSTD.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZSTD.ql new file mode 100644 index 00000000000..9e984bb89e2 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZSTD.ql @@ -0,0 +1,140 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression-zstd + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +// https://github.com/facebook/zstd/blob/dev/examples/streaming_decompression.c +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.commons.File + +// /** +// * A Pointer Variable as a Flow source +// */ +// private class PointerVar extends VariableAccess { +// PointerVar() { this.getType() instanceof PointerType } +// } +/** + * A ZSTD_inBuffer Variable as a Flow source + */ +private class ZSTDinBufferVar extends VariableAccess { + ZSTDinBufferVar() { this.getType().hasName("ZSTD_inBuffer") } +} + +/** + * A ZSTD_inBuffer_s Variable as a Flow source + */ +private class ZSTDinBufferSVar extends VariableAccess { + ZSTDinBufferSVar() { this.getType().hasName("ZSTD_inBuffer_s") } +} + +/** + * The `ZSTD_decompress` function is used in Flow sink + */ +private class ZSTDDecompressFunction extends Function { + ZSTDDecompressFunction() { this.hasGlobalName(["ZSTD_decompress"]) } +} + +/** + * The `ZSTD_decompressDCtx` function is used in Flow sink + */ +private class ZSTDDecompressDCtxFunction extends Function { + ZSTDDecompressDCtxFunction() { this.hasGlobalName(["ZSTD_decompressDCtx"]) } +} + +/** + * The `ZSTD_decompressStream` function is used in Flow sink + */ +private class ZSTDDecompressStreamFunction extends Function { + ZSTDDecompressStreamFunction() { this.hasGlobalName(["ZSTD_decompressStream"]) } +} + +/** + * The `ZSTD_decompress_usingDDict` function is used in Flow sink + */ +private class ZSTDDecompressUsingDictFunction extends Function { + ZSTDDecompressUsingDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) } +} + +/** + * The `ZSTD_decompress_usingDDict` function is used in Flow sink + */ +private class ZSTDDecompressUsingDDictFunction extends Function { + ZSTDDecompressUsingDDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) } +} + +module ZstdTaintConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof AllocationFunction | + fc = source.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fopenCall(fc) | + fc = source.asExpr() and + state = "" + ) + or + source.asExpr() instanceof ZSTDinBufferSVar and + state = "" + or + source.asExpr() instanceof ZSTDinBufferVar and + state = "" + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressFunction | + fc.getArgument(2) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressDCtxFunction | + fc.getArgument(3) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressStreamFunction | + fc.getArgument(2) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDictFunction | + fc.getArgument(3) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDDictFunction | + fc.getArgument(3) = sink.asExpr() and + state = "" + ) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + none() + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } +} + +module ZstdTaint = TaintTracking::GlobalWithState; + +import ZstdTaint::PathGraph + +from ZstdTaint::PathNode source, ZstdTaint::PathNode sink +where ZstdTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompression depends on a $@.", source.getNode(), + "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibGzopen.ql similarity index 98% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql rename to cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibGzopen.ql index 6c0804404cd..ce7324eded0 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsGzopen.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibGzopen.ql @@ -5,7 +5,7 @@ * @problem.severity error * @security-severity 7.8 * @precision high - * @id cpp/user-controlled-file-decompression1 + * @id cpp/user-controlled-file-zlibgz * @tags security * experimental * external/cwe/cwe-409 diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibInflator.ql similarity index 84% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql rename to cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibInflator.ql index fdd11e1fc16..e526b4d9273 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsInflator.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibInflator.ql @@ -5,7 +5,7 @@ * @problem.severity error * @security-severity 7.8 * @precision high - * @id cpp/user-controlled-file-decompression2 + * @id cpp/user-controlled-file-zlibinflator * @tags security * experimental * external/cwe/cwe-409 @@ -41,13 +41,6 @@ module ZlibTaintConfig implements DataFlow::ConfigSig { fc.getArgument(0) = sink.asExpr() ) } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(FunctionCall fc | fc.getTarget() instanceof InflateFunction | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc - ) - } } module ZlibTaint = TaintTracking::Global; diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsUncompress.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibUncompress.ql similarity index 83% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsUncompress.ql rename to cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibUncompress.ql index 09327616fd9..b385523f185 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsUncompress.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibUncompress.ql @@ -5,7 +5,7 @@ * @problem.severity error * @security-severity 7.8 * @precision high - * @id cpp/user-controlled-file-decompression3 + * @id cpp/user-controlled-file-zlibuncompress * @tags security * experimental * external/cwe/cwe-409 @@ -37,13 +37,6 @@ module ZlibTaintConfig implements DataFlow::ConfigSig { fc.getArgument(0) = sink.asExpr() ) } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(FunctionCall fc | fc.getTarget() instanceof UncompressFunction | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc - ) - } } module ZlibTaint = TaintTracking::Global; diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp index 94e3e969a51..af513817386 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp @@ -1,3 +1,8 @@ +#include +#include +#include "zlib.h" +#include +#include int UnsafeInflate(int argc, char *argv[]) { // original string len = 36 diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp index e3a2d4b2e50..7ad34658367 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp @@ -1,3 +1,8 @@ +#include +#include +#include "zlib.h" +#include +#include int SafeGzread() { std::cout << "enter compressed file name!\n" << std::endl; From d4d505d7af7195a3163bcf962b652ef0148f68f2 Mon Sep 17 00:00:00 2001 From: amammad Date: Mon, 3 Jul 2023 20:39:08 +1000 Subject: [PATCH 007/404] complete the minizip query --- .../DecompressionBombsMiniZip.ql | 84 +++++++++++++++---- 1 file changed, 67 insertions(+), 17 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql index b8cd89fc542..67999bff3d6 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql @@ -15,6 +15,43 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources +/** + * The `mz_zip_reader_create` function as a Flow source + * create a `mz_zip_reader` instance + */ +private class Mz_zip_reader_create extends Function { + Mz_zip_reader_create() { this.hasGlobalName("mz_zip_reader_create") } +} + +/** + * The `mz_zip_create` function as a Flow source + * create a `mz_zip` instance + */ +private class Mz_zip_create extends Function { + Mz_zip_create() { this.hasGlobalName("mz_zip_create") } +} + +/** + * The `mz_zip_entry` function is used in Flow source + * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md) + */ +private class Mz_zip_entry extends Function { + Mz_zip_entry() { this.hasGlobalName("mz_zip_entry_read") } +} + +/** + * The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in Flow source + * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md) + */ +private class Mz_zip_reader_entry extends Function { + Mz_zip_reader_entry() { + this.hasGlobalName([ + "mz_zip_reader_entry_save", "mz_zip_reader_entry_read", "mz_zip_reader_entry_save_process", + "mz_zip_reader_entry_save_file", "mz_zip_reader_entry_save_buffer", "mz_zip_reader_save_all" + ]) + } +} + /** * A `unzFile` Variable as a Flow source */ @@ -29,13 +66,6 @@ private class UnzOpenFunction extends Function { UnzOpenFunction() { this.hasGlobalName(["UnzOpen", "unzOpen64", "unzOpen2", "unzOpen2_64"]) } } -/** - * The `mz_stream_open` function is used in Flow source - */ -private class MzStreamOpenFunction extends Function { - MzStreamOpenFunction() { this.hasGlobalName("mz_stream_open") } -} - /** * The `unzReadCurrentFile` function is used in Flow sink */ @@ -55,16 +85,14 @@ module MiniZipTaintConfig implements DataFlow::StateConfigSig { source.asExpr() instanceof UnzFileVar and state = "unzFile" or - // TO Check - exists(FunctionCall fc | fc.getTarget() instanceof MzStreamOpenFunction | - fc.getArgument(0).getEnclosingVariable() = source.asVariable() and - state = "MzStream" + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_create | + fc = source.asExpr() and + state = "mz_zip_reader" ) or - // TO Check - exists(FunctionCall fc | fc.getTarget() instanceof MzStreamOpenFunction | - fc.getArgument(0).getEnclosingVariable() = source.asVariable() and - state = "MzStream" + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_create | + fc = source.asExpr() and + state = "mz_zip" ) } @@ -72,7 +100,16 @@ module MiniZipTaintConfig implements DataFlow::StateConfigSig { exists(FunctionCall fc | fc.getTarget() instanceof UnzReadCurrentFileFunction | fc.getArgument(0) = sink.asExpr() and state = "unzFile" - // and not sanitizer(fc) + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | + fc.getArgument(1) = sink.asExpr() and + state = "mz_zip_reader" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | + fc.getArgument(1) = sink.asExpr() and + state = "mz_zip" ) } @@ -86,12 +123,25 @@ module MiniZipTaintConfig implements DataFlow::StateConfigSig { state1 = "" and state2 = "unzFile" ) + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) and + state1 = "" and + state2 = "mz_zip_reader" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) and + state1 = "" and + state2 = "mz_zip" + ) } predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } } - module MiniZipTaint = TaintTracking::GlobalWithState; import MiniZipTaint::PathGraph From 56bc32ff916f4ea0e87748fac3712bccb1058371 Mon Sep 17 00:00:00 2001 From: amammad Date: Tue, 4 Jul 2023 01:17:22 +1000 Subject: [PATCH 008/404] add libarchive --- .../DecompressionBombsLibArchive.ql | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibArchive.ql diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibArchive.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibArchive.ql new file mode 100644 index 00000000000..57a9a4f72c9 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibArchive.ql @@ -0,0 +1,75 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression-libarchive + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * The `archive_read_new` function as a Flow source + * create a `archive` instance + */ +private class Archive_read_new extends Function { + Archive_read_new() { this.hasGlobalName("archive_read_new") } +} + +/** + * The `archive_read_data*` functions are used in Flow Sink + * [Examples](https://github.com/libarchive/libarchive/wiki/Examples) + */ +private class Archive_read_data_block extends Function { + Archive_read_data_block() { + this.hasGlobalName(["archive_read_data_block", "archive_read_data", "archive_read_data_into_fd"]) + } +} + +module LibArchiveTaintConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_new | + fc.getArgument(0) = source.asExpr() and + state = "unzFile" + ) + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_data_block | + fc.getArgument(1) = sink.asExpr() and + state = "unzFile" + ) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_data_block | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) and + state1 = "" and + state2 = "mz_zip_reader" + ) + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } +} + +module LibArchiveTaint = TaintTracking::GlobalWithState; + +import LibArchiveTaint::PathGraph + +from LibArchiveTaint::PathNode source, LibArchiveTaint::PathNode sink +where LibArchiveTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), + "potentially untrusted source" From 16be908cb38f35036e82ae13f112524e7b7d6d9b Mon Sep 17 00:00:00 2001 From: amammad Date: Tue, 4 Jul 2023 06:56:30 +1000 Subject: [PATCH 009/404] add Miniz --- .../DecompressionBombsLibMiniz.ql | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql new file mode 100644 index 00000000000..b7e5ea913f3 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql @@ -0,0 +1,187 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/user-controlled-file-decompression-miniz + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A unsigned char Variable is used in Flow source + */ +private class Uint8Var extends VariableAccess { + Uint8Var() { this.getType().stripType().resolveTypedefs() instanceof UnsignedCharType } +} + +/** + * The `mz_streamp`, `z_stream` Variables are used in Flow source + */ +private class MzStreampVar extends VariableAccess { + MzStreampVar() { this.getType().hasName(["mz_streamp", "z_stream"]) } +} + +/** + * A Char Variable is used in Flow source + */ +private class CharVar extends VariableAccess { + CharVar() { this.getType().stripType() instanceof CharType } +} + +/** + * A `mz_zip_archive` Variable is used in Flow source + */ +private class MzZipArchiveVar extends VariableAccess { + MzZipArchiveVar() { this.getType().hasName("mz_zip_archive") } +} + +/** + * The `mz_uncompress` functions are used in Flow Sink + */ +private class MzUncompress extends Function { + MzUncompress() { this.hasGlobalName(["uncompress", "mz_uncompress", "mz_uncompress2"]) } +} + +/** + * The `mz_inflate` functions are used in Flow Sink + */ +private class MzInflate extends Function { + MzInflate() { this.hasGlobalName(["mz_inflate", "inflate"]) } +} + +/** + * The `mz_inflateInit` functions are used in Flow Sink + */ +private class MzInflateInit extends Function { + MzInflateInit() { this.hasGlobalName(["inflateInit", "mz_inflateInit"]) } +} + +/** + * The `mz_zip_reader_extract_*` functions are used in Flow Sink + */ +private class MzZipReaderExtract extends Function { + MzZipReaderExtract() { + this.hasGlobalName([ + "mz_zip_reader_extract_file_to_heap", "mz_zip_reader_extract_to_heap", + "mz_zip_reader_extract_to_callback" + ]) + } +} + +/** + * The `mz_zip_reader_locate_file_*` functions are used in Flow Sink + */ +private class MzZipReaderLocateFile extends Function { + MzZipReaderLocateFile() { + this.hasGlobalName(["mz_zip_reader_locate_file", "mz_zip_reader_locate_file_v2"]) + } +} + +/** + * The `tinfl_decompress_mem_*` functions are used in Flow Sink + */ +private class TinflDecompressMem extends Function { + TinflDecompressMem() { + this.hasGlobalName([ + "tinfl_decompress_mem_to_callback", "tinfl_decompress_mem_to_mem", + "tinfl_decompress_mem_to_heap" + ]) + } +} + +/** + * The `tinfl_decompress_*` functions are used in Flow Sink + */ +private class TinflDecompress extends Function { + TinflDecompress() { this.hasGlobalName(["tinfl_decompress"]) } +} + +module MinizTaintConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + source.asExpr() instanceof Uint8Var and + state = "" + or + source.asExpr() instanceof CharVar and + state = "" + or + source.asExpr() instanceof MzZipArchiveVar and + state = "" + or + source.asExpr() instanceof MzStreampVar and + state = "" + or + // source of inflate(&arg0) is OK + // but the sink which is a call to MzInflate Function first arg can not be determined + // if I debug the query we'll reach to the first arg, it is weird I think. + source.asDefiningArgument() = + any(Call call | call.getTarget() instanceof MzInflateInit).getArgument(0) and + state = "inflate" + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress | + fc.getArgument(2) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderExtract | + fc.getArgument(1) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof MzInflate | + fc.getArgument(0) = sink.asExpr() and + state = "inflate" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompress | + fc.getArgument(1) = sink.asExpr() and + state = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompressMem | + fc.getArgument(0) = sink.asExpr() and + state = "" + ) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress | + node1.asExpr() = fc.getArgument(2) and + node2.asExpr() = fc.getArgument(0) and + state1 = "" and + state2 = "" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderLocateFile | + node1.asExpr() = fc.getArgument(1) and + node2.asExpr() = fc.getArgument(3) and + state1 = "" and + state2 = "" + ) + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } +} + +module MinizTaint = TaintTracking::GlobalWithState; + +import MinizTaint::PathGraph + +from MinizTaint::PathNode source, MinizTaint::PathNode sink +where MinizTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), + "potentially untrusted source" From 065c52761510535c976c53f3b1bf5d67006a4cfa Mon Sep 17 00:00:00 2001 From: amammad Date: Tue, 4 Jul 2023 07:19:33 +1000 Subject: [PATCH 010/404] update Miniz --- .../DecompressionBombsLibMiniz.ql | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql index b7e5ea913f3..9f694b07cdd 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql @@ -15,11 +15,17 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources +/** + * A Pointer Variable is used in Flow source + */ +private class PointerVar extends VariableAccess { + PointerVar() { this.getType() instanceof PointerType } +} /** * A unsigned char Variable is used in Flow source */ private class Uint8Var extends VariableAccess { - Uint8Var() { this.getType().stripType().resolveTypedefs() instanceof UnsignedCharType } + Uint8Var() { this.getType().stripType().resolveTypedefs*() instanceof UnsignedCharType } } /** @@ -33,7 +39,7 @@ private class MzStreampVar extends VariableAccess { * A Char Variable is used in Flow source */ private class CharVar extends VariableAccess { - CharVar() { this.getType().stripType() instanceof CharType } + CharVar() { this.getType().stripType().resolveTypedefs*() instanceof CharType } } /** @@ -71,7 +77,10 @@ private class MzZipReaderExtract extends Function { MzZipReaderExtract() { this.hasGlobalName([ "mz_zip_reader_extract_file_to_heap", "mz_zip_reader_extract_to_heap", - "mz_zip_reader_extract_to_callback" + "mz_zip_reader_extract_to_callback", "mz_zip_reader_extract_file_to_callback", + "mz_zip_reader_extract_to_mem", "mz_zip_reader_extract_file_to_mem", + "mz_zip_reader_extract_iter_read", "mz_zip_reader_extract_to_file", + "mz_zip_reader_extract_file_to_file" ]) } } @@ -111,6 +120,9 @@ module MinizTaintConfig implements DataFlow::StateConfigSig { source.asExpr() instanceof Uint8Var and state = "" or + source.asExpr() instanceof PointerVar and + state = "" + or source.asExpr() instanceof CharVar and state = "" or From e0798b29da1e2c87d77e1e19169a9c5d01eebdb3 Mon Sep 17 00:00:00 2001 From: amammad Date: Tue, 4 Jul 2023 18:28:00 +1000 Subject: [PATCH 011/404] stash: change sinks to zip handles and sources to the zip handle initializers --- .../DecompressionBombsLibMiniz.ql | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql index 9f694b07cdd..e0310704af2 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql @@ -21,6 +21,7 @@ import semmle.code.cpp.security.FlowSources private class PointerVar extends VariableAccess { PointerVar() { this.getType() instanceof PointerType } } + /** * A unsigned char Variable is used in Flow source */ @@ -56,6 +57,18 @@ private class MzUncompress extends Function { MzUncompress() { this.hasGlobalName(["uncompress", "mz_uncompress", "mz_uncompress2"]) } } +/** + * A `zip handle` is used in Flow source + */ +private class MzZip extends Function { + MzZip() { + this.hasGlobalName([ + "mz_zip_reader_open", "mz_zip_reader_open_file", "mz_zip_reader_open_file_in_memory", + "mz_zip_reader_open_buffer", "mz_zip_reader_entry_open" + ]) + } +} + /** * The `mz_inflate` functions are used in Flow Sink */ @@ -138,6 +151,9 @@ module MinizTaintConfig implements DataFlow::StateConfigSig { source.asDefiningArgument() = any(Call call | call.getTarget() instanceof MzInflateInit).getArgument(0) and state = "inflate" + or + source.asDefiningArgument() = any(Call call | call.getTarget() instanceof MzZip).getArgument(0) and + state = "" } predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { From e37ceac3b137e7a453a8be032692fbca061505c6 Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Fri, 7 Jun 2024 05:26:51 +0200 Subject: [PATCH 012/404] merge all query files into one query file --- .../CWE/CWE-409-DecompressionBomb/Brotli.qll | 38 ++ .../CWE/CWE-409-DecompressionBomb/Bzip2.qll | 50 +++ .../DecompressionBombs.ql | 330 ++++++++++++++++++ .../DecompressionBombsBrotli.ql | 107 ------ .../DecompressionBombsBzip2.ql | 126 ------- .../DecompressionBombsLibArchive.ql | 75 ---- .../DecompressionBombsLibMiniz.ql | 215 ------------ .../DecompressionBombsMiniZip.ql | 152 -------- .../DecompressionBombsXZ.ql | 100 ------ .../DecompressionBombsZSTD.ql | 140 -------- .../DecompressionBombsZlibGzopen.ql | 150 -------- .../DecompressionBombsZlibInflator.ql | 53 --- .../DecompressionBombsZlibUncompress.ql | 49 --- .../CWE-409-DecompressionBomb/LibArchive.qll | 25 ++ .../CWE-409-DecompressionBomb/LibMiniz.qll | 102 ++++++ .../CWE/CWE-409-DecompressionBomb/MiniZip.qll | 65 ++++ .../CWE/CWE-409-DecompressionBomb/XZ.qll | 37 ++ .../CWE/CWE-409-DecompressionBomb/ZSTD.qll | 57 +++ .../CWE-409-DecompressionBomb/ZlibGzopen.qll | 75 ++++ .../ZlibInflator.qll | 25 ++ .../ZlibUncompress.qll | 21 ++ 21 files changed, 825 insertions(+), 1167 deletions(-) create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Brotli.qll create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bzip2.qll create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBrotli.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBzip2.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibArchive.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsXZ.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZSTD.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibGzopen.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibInflator.ql delete mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibUncompress.ql create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibArchive.qll create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibMiniz.qll create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/MiniZip.qll create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZSTD.qll create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibGzopen.qll create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibInflator.qll create mode 100644 cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Brotli.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Brotli.qll new file mode 100644 index 00000000000..46314826a62 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Brotli.qll @@ -0,0 +1,38 @@ +/** + * https://github.com/google/brotli + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.commons.File + +/** + * A Pointer Variable is used in Flow source + */ +class PointerVar extends VariableAccess { + PointerVar() { this.getType() instanceof PointerType } +} + +/** + * A Pointer Variable is used in Flow source + */ +class Uint8Var extends VariableAccess { + Uint8Var() { this.getType() instanceof UInt8_t } +} + +/** + * The `BrotliDecoderDecompress` function is used in Flow sink + * Ref: https://www.brotli.org/decode.html#af68 + */ +class BrotliDecoderDecompressFunction extends Function { + BrotliDecoderDecompressFunction() { this.hasGlobalName(["BrotliDecoderDecompress"]) } +} + +/** + * The `BrotliDecoderDecompressStream` function is used in Flow sink + * Ref: https://www.brotli.org/decode.html#a234 + */ +class BrotliDecoderDecompressStreamFunction extends Function { + BrotliDecoderDecompressStreamFunction() { this.hasGlobalName(["BrotliDecoderDecompressStream"]) } +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bzip2.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bzip2.qll new file mode 100644 index 00000000000..662424b022a --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bzip2.qll @@ -0,0 +1,50 @@ +/** + * https://www.sourceware.org/bzip2/manual/manual.html + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.commons.File + +/** + * A `bz_stream` Variable as a Flow source + */ +class BzStreamVar extends VariableAccess { + BzStreamVar() { this.getType().hasName("bz_stream") } +} + +/** + * A `BZFILE` Variable as a Flow source + */ +class BzFileVar extends VariableAccess { + BzFileVar() { this.getType().hasName("BZFILE") } +} + +/** + * The `BZ2_bzDecompress` function as a Flow source + */ +class BZ2BzDecompressFunction extends Function { + BZ2BzDecompressFunction() { this.hasGlobalName(["BZ2_bzDecompress"]) } +} + +/** + * The `BZ2_bzReadOpen` function + */ +class BZ2BzReadOpenFunction extends Function { + BZ2BzReadOpenFunction() { this.hasGlobalName(["BZ2_bzReadOpen"]) } +} + +/** + * The `BZ2_bzRead` function is used in Flow sink + */ +class BZ2BzReadFunction extends Function { + BZ2BzReadFunction() { this.hasGlobalName("BZ2_bzRead") } +} + +/** + * The `BZ2_bzBuffToBuffDecompress` function is used in Flow sink + */ +class BZ2BzBuffToBuffDecompressFunction extends Function { + BZ2BzBuffToBuffDecompressFunction() { this.hasGlobalName("BZ2_bzBuffToBuffDecompress") } +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql new file mode 100644 index 00000000000..8506dccaea7 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql @@ -0,0 +1,330 @@ +/** + * @name User-controlled file decompression + * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous + * @kind path-problem + * @problem.severity error + * @security-severity 7.8 + * @precision high + * @id cpp/data-decompression + * @tags security + * experimental + * external/cwe/cwe-409 + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.commons.File +import Bzip2 +import Brotli +import LibArchive +import LibMiniz +import ZSTD +import MiniZip +import XZ +import ZlibGzopen +import ZlibUncompress +import ZlibInflator +import Brotli + +module DecompressionTaintConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + ( + exists(FunctionCall fc | fc.getTarget() instanceof AllocationFunction | fc = source.asExpr()) + or + exists(FunctionCall fc | fopenCall(fc) | fc = source.asExpr()) + or + source.asExpr() instanceof PointerVar + or + source.asExpr() instanceof Uint8Var + ) and + state = "brotli" + or + ( + source.asExpr() instanceof BzStreamVar + or + source.asExpr() instanceof BzFileVar + or + exists(FunctionCall fc | fopenCall(fc) | fc = source.asExpr()) + ) and + state = "bzip2" + or + exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_new | + fc.getArgument(0) = source.asExpr() + ) and + state = "libarchive" + or + ( + source.asExpr() instanceof UnsignedCharVar + or + source.asExpr() instanceof PointerVar + or + source.asExpr() instanceof CharVar + or + source.asExpr() instanceof MzZipArchiveVar + or + source.asExpr() instanceof MzStreampVar + or + source.asDefiningArgument() = + any(Call call | call.getTarget() instanceof MzInflateInit).getArgument(0) + or + source.asDefiningArgument() = + any(Call call | call.getTarget() instanceof MzZip).getArgument(0) + ) and + state = "libminiz" + or + ( + exists(FunctionCall fc | fc.getTarget() instanceof AllocationFunction | fc = source.asExpr()) + or + exists(FunctionCall fc | fopenCall(fc) | fc = source.asExpr()) + or + source.asExpr() instanceof ZSTDinBufferSVar + or + source.asExpr() instanceof ZSTDinBufferVar + ) and + state = "zstd" + or + ( + exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction | + fc.getArgument(0) = source.asExpr() + ) + or + source.asExpr() instanceof UnzFileVar + ) and + state = "unzFile" + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_create | + fc = source.asExpr() and + state = "mz_zip_reader" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_create | + fc = source.asExpr() and + state = "mz_zip" + ) + or + ( + source.asExpr() instanceof LzmaStreamVar + or + source.asExpr() instanceof Uint8Var + ) and + state = "xz" + or + ( + exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | + fc.getArgument(0) = source.asExpr() and + // arg 0 can be a path string whichwe must do following check + not fc.getArgument(0).isConstant() + ) + or + // IDK whether it is good to use all file decriptors function returns as source or not + // because we can do more sanitization from fd function sources + exists(FunctionCall fc | fc.getTarget() instanceof GzdopenFunction | + fc.getArgument(0) = source.asExpr() + ) + or + source.asExpr() instanceof GzFileVar + ) and + state = "zlibgzopen" + or + source.asExpr() instanceof ZStreamVar and state = "zlifinflator" + or + source.asExpr() instanceof BytefVar and state = "zlibuncompress" + } + + predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + ( + exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressStreamFunction | + fc.getArgument(2) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressFunction | + fc.getArgument(1) = sink.asExpr() + ) + ) and + state = "brotli" + or + ( + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzDecompressFunction | + fc.getArgument(0) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzReadFunction | + fc.getArgument(1) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzBuffToBuffDecompressFunction | + fc.getArgument(2) = sink.asExpr() + ) + ) and + state = "bzip2" + or + exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_data_block | + fc.getArgument(0) = sink.asExpr() and + state = "libarchive" + ) + or + ( + exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress | + fc.getArgument(0) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderExtract | + fc.getArgument(1) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof MzInflate | + fc.getArgument(0) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompress | + fc.getArgument(1) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompressMem | + fc.getArgument(0) = sink.asExpr() + ) + ) and + state = "libminiz" + or + ( + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressFunction | + fc.getArgument(2) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressDCtxFunction | + fc.getArgument(3) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressStreamFunction | + fc.getArgument(2) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDictFunction | + fc.getArgument(3) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDDictFunction | + fc.getArgument(3) = sink.asExpr() + ) + ) and + state = "zstd" + or + exists(FunctionCall fc | fc.getTarget() instanceof UnzReadCurrentFileFunction | + fc.getArgument(0) = sink.asExpr() and + state = "unzFile" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | + fc.getArgument(1) = sink.asExpr() and + state = "mz_zip_reader" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | + fc.getArgument(1) = sink.asExpr() and + state = "mz_zip" + ) + or + ( + exists(FunctionCall fc | fc.getTarget() instanceof LzmaStreamBufferDecodeFunction | + fc.getArgument(1) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof LzmaCodeFunction | + fc.getArgument(0) = sink.asExpr() + ) + ) and + state = "xz" and + exists(FunctionCall fc2 | fc2.getTarget() instanceof LzmaDecoderFunction) + or + ( + exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction | + fc.getArgument(0) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction | + sink.asExpr() = fc.getArgument(3) + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction | + sink.asExpr() = fc.getArgument(0) + ) + ) and + state = "zlibgzopen" + or + exists(FunctionCall fc | fc.getTarget() instanceof InflateFunction | + fc.getArgument(0) = sink.asExpr() + ) and + state = "zlifinflator" + or + exists(FunctionCall fc | fc.getTarget() instanceof UncompressFunction | + fc.getArgument(0) = sink.asExpr() + ) and + state = "zlibuncompress" + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, + DataFlow::FlowState state2 + ) { + exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc and + state1 = "" and + state2 = "unzFile" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) and + state1 = "" and + state2 = "mz_zip_reader" + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) and + state1 = "" and + state2 = "mz_zip" + ) + or + ( + exists(FunctionCall fc | + fc.getTarget() instanceof GzopenFunction or fc.getTarget() instanceof GzdopenFunction + | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction | + node1.asExpr() = fc.getArgument(3) and + node2.asExpr() = fc.getArgument(0) + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction | + node1.asExpr() = fc.getArgument(0) and + node1.asExpr() = fc.getArgument(1) + ) + ) and + state1 = "" and + state2 = "gzopen" + } + + predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } +} + +module DecompressionTaint = TaintTracking::GlobalWithState; + +import DecompressionTaint::PathGraph + +from DecompressionTaint::PathNode source, DecompressionTaint::PathNode sink +where DecompressionTaint::flowPath(source, sink) +select sink.getNode(), source, sink, "This Decompression output $@.", source.getNode(), + "is not limited" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBrotli.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBrotli.ql deleted file mode 100644 index b09858d6471..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBrotli.ql +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-decompression-brotli - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -// https://github.com/google/brotli -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources -import semmle.code.cpp.commons.File - -/** - * A Pointer Variable is used in Flow source - */ -private class PointerVar extends VariableAccess { - PointerVar() { this.getType() instanceof PointerType } -} - -/** - * A Pointer Variable is used in Flow source - */ -private class Uint8Var extends VariableAccess { - Uint8Var() { this.getType() instanceof UInt8_t } -} - -/** - * A ZSTD_inBuffer Variable is used in Flow source - */ -private class ZSTDinBufferVar extends VariableAccess { - ZSTDinBufferVar() { this.getType().hasName("ZSTD_inBuffer") } -} - -/** - * The `ZSTD_decompress_usingDDict` function is used in Flow sink - * Ref: https://www.brotli.org/decode.html#af68 - */ -private class BrotliDecoderDecompressFunction extends Function { - BrotliDecoderDecompressFunction() { this.hasGlobalName(["BrotliDecoderDecompress"]) } -} - -/** - * The `BrotliDecoderDecompressStream` function is used in Flow sink - * Ref: https://www.brotli.org/decode.html#a234 - */ -private class BrotliDecoderDecompressStreamFunction extends Function { - BrotliDecoderDecompressStreamFunction() { this.hasGlobalName(["BrotliDecoderDecompressStream"]) } -} - -module BrotliTaintConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; - - predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof AllocationFunction | - fc = source.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fopenCall(fc) | - fc = source.asExpr() and - state = "" - ) - or - source.asExpr() instanceof PointerVar and - state = "" - or - source.asExpr() instanceof Uint8Var and - state = "" - } - - predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressStreamFunction | - fc.getArgument(2) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressFunction | - fc.getArgument(1) = sink.asExpr() and - state = "" - ) - } - - predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } -} - -module BrotliTaint = TaintTracking::GlobalWithState; - -import BrotliTaint::PathGraph - -from BrotliTaint::PathNode source, BrotliTaint::PathNode sink -where BrotliTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompression depends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBzip2.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBzip2.ql deleted file mode 100644 index e9b7d60715d..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsBzip2.ql +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-decompression-bzip2 - * experimental - * external/cwe/cwe-409 - */ - -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources -import semmle.code.cpp.commons.File - -/** - * A `bz_stream` Variable as a Flow source - */ -private class BzStreamVar extends VariableAccess { - BzStreamVar() { this.getType().hasName("bz_stream") } -} - -/** - * A `BZFILE` Variable as a Flow source - */ -private class BZFILEVar extends VariableAccess { - BZFILEVar() { this.getType().hasName("BZFILE") } -} - -/** - * The `BZ2_bzopen`,`BZ2_bzdopen` functions as a Flow source - */ -private class BZ2BzopenFunction extends Function { - BZ2BzopenFunction() { this.hasGlobalName(["BZ2_bzopen", "BZ2_bzdopen"]) } -} - -/** - * The `BZ2_bzDecompress` function as a Flow source - */ -private class BZ2BzDecompressFunction extends Function { - BZ2BzDecompressFunction() { this.hasGlobalName(["BZ2_bzDecompress"]) } -} - -/** - * The `BZ2_bzReadOpen` function - */ -private class BZ2BzReadOpenFunction extends Function { - BZ2BzReadOpenFunction() { this.hasGlobalName(["BZ2_bzReadOpen"]) } -} - -/** - * The `BZ2_bzRead` function is used in Flow sink - */ -private class BZ2BzReadFunction extends Function { - BZ2BzReadFunction() { this.hasGlobalName("BZ2_bzRead") } -} - -/** - * The `BZ2_bzRead` function is used in Flow sink - */ -private class BZ2BzBuffToBuffDecompressFunction extends Function { - BZ2BzBuffToBuffDecompressFunction() { this.hasGlobalName("BZ2_bzBuffToBuffDecompress") } -} - -/** - * https://www.sourceware.org/bzip2/manual/manual.html - */ -module Bzip2TaintConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; - - predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - source.asExpr() instanceof BzStreamVar and - state = "" - or - source.asExpr() instanceof BZFILEVar and - state = "" - or - // will flow into BZ2BzReadOpenFunction - exists(FunctionCall fc | fopenCall(fc) | - fc = source.asExpr() and - state = "" - ) - } - - predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzDecompressFunction | - fc.getArgument(0) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzReadFunction | - fc.getArgument(1) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzBuffToBuffDecompressFunction | - fc.getArgument(2) = sink.asExpr() and - state = "" - ) - } - - predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzReadOpenFunction | - node1.asExpr() = fc.getArgument(1) and - node2.asExpr() = fc and - state1 = "" and - state2 = "" - ) - } - - predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } -} - -module Bzip2Taint = TaintTracking::GlobalWithState; - -import Bzip2Taint::PathGraph - -from Bzip2Taint::PathNode source, Bzip2Taint::PathNode sink -where Bzip2Taint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibArchive.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibArchive.ql deleted file mode 100644 index 57a9a4f72c9..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibArchive.ql +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-decompression-libarchive - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources - -/** - * The `archive_read_new` function as a Flow source - * create a `archive` instance - */ -private class Archive_read_new extends Function { - Archive_read_new() { this.hasGlobalName("archive_read_new") } -} - -/** - * The `archive_read_data*` functions are used in Flow Sink - * [Examples](https://github.com/libarchive/libarchive/wiki/Examples) - */ -private class Archive_read_data_block extends Function { - Archive_read_data_block() { - this.hasGlobalName(["archive_read_data_block", "archive_read_data", "archive_read_data_into_fd"]) - } -} - -module LibArchiveTaintConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; - - predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_new | - fc.getArgument(0) = source.asExpr() and - state = "unzFile" - ) - } - - predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_data_block | - fc.getArgument(1) = sink.asExpr() and - state = "unzFile" - ) - } - - predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_data_block | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) and - state1 = "" and - state2 = "mz_zip_reader" - ) - } - - predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } -} - -module LibArchiveTaint = TaintTracking::GlobalWithState; - -import LibArchiveTaint::PathGraph - -from LibArchiveTaint::PathNode source, LibArchiveTaint::PathNode sink -where LibArchiveTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql deleted file mode 100644 index e0310704af2..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsLibMiniz.ql +++ /dev/null @@ -1,215 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-decompression-miniz - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources - -/** - * A Pointer Variable is used in Flow source - */ -private class PointerVar extends VariableAccess { - PointerVar() { this.getType() instanceof PointerType } -} - -/** - * A unsigned char Variable is used in Flow source - */ -private class Uint8Var extends VariableAccess { - Uint8Var() { this.getType().stripType().resolveTypedefs*() instanceof UnsignedCharType } -} - -/** - * The `mz_streamp`, `z_stream` Variables are used in Flow source - */ -private class MzStreampVar extends VariableAccess { - MzStreampVar() { this.getType().hasName(["mz_streamp", "z_stream"]) } -} - -/** - * A Char Variable is used in Flow source - */ -private class CharVar extends VariableAccess { - CharVar() { this.getType().stripType().resolveTypedefs*() instanceof CharType } -} - -/** - * A `mz_zip_archive` Variable is used in Flow source - */ -private class MzZipArchiveVar extends VariableAccess { - MzZipArchiveVar() { this.getType().hasName("mz_zip_archive") } -} - -/** - * The `mz_uncompress` functions are used in Flow Sink - */ -private class MzUncompress extends Function { - MzUncompress() { this.hasGlobalName(["uncompress", "mz_uncompress", "mz_uncompress2"]) } -} - -/** - * A `zip handle` is used in Flow source - */ -private class MzZip extends Function { - MzZip() { - this.hasGlobalName([ - "mz_zip_reader_open", "mz_zip_reader_open_file", "mz_zip_reader_open_file_in_memory", - "mz_zip_reader_open_buffer", "mz_zip_reader_entry_open" - ]) - } -} - -/** - * The `mz_inflate` functions are used in Flow Sink - */ -private class MzInflate extends Function { - MzInflate() { this.hasGlobalName(["mz_inflate", "inflate"]) } -} - -/** - * The `mz_inflateInit` functions are used in Flow Sink - */ -private class MzInflateInit extends Function { - MzInflateInit() { this.hasGlobalName(["inflateInit", "mz_inflateInit"]) } -} - -/** - * The `mz_zip_reader_extract_*` functions are used in Flow Sink - */ -private class MzZipReaderExtract extends Function { - MzZipReaderExtract() { - this.hasGlobalName([ - "mz_zip_reader_extract_file_to_heap", "mz_zip_reader_extract_to_heap", - "mz_zip_reader_extract_to_callback", "mz_zip_reader_extract_file_to_callback", - "mz_zip_reader_extract_to_mem", "mz_zip_reader_extract_file_to_mem", - "mz_zip_reader_extract_iter_read", "mz_zip_reader_extract_to_file", - "mz_zip_reader_extract_file_to_file" - ]) - } -} - -/** - * The `mz_zip_reader_locate_file_*` functions are used in Flow Sink - */ -private class MzZipReaderLocateFile extends Function { - MzZipReaderLocateFile() { - this.hasGlobalName(["mz_zip_reader_locate_file", "mz_zip_reader_locate_file_v2"]) - } -} - -/** - * The `tinfl_decompress_mem_*` functions are used in Flow Sink - */ -private class TinflDecompressMem extends Function { - TinflDecompressMem() { - this.hasGlobalName([ - "tinfl_decompress_mem_to_callback", "tinfl_decompress_mem_to_mem", - "tinfl_decompress_mem_to_heap" - ]) - } -} - -/** - * The `tinfl_decompress_*` functions are used in Flow Sink - */ -private class TinflDecompress extends Function { - TinflDecompress() { this.hasGlobalName(["tinfl_decompress"]) } -} - -module MinizTaintConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; - - predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - source.asExpr() instanceof Uint8Var and - state = "" - or - source.asExpr() instanceof PointerVar and - state = "" - or - source.asExpr() instanceof CharVar and - state = "" - or - source.asExpr() instanceof MzZipArchiveVar and - state = "" - or - source.asExpr() instanceof MzStreampVar and - state = "" - or - // source of inflate(&arg0) is OK - // but the sink which is a call to MzInflate Function first arg can not be determined - // if I debug the query we'll reach to the first arg, it is weird I think. - source.asDefiningArgument() = - any(Call call | call.getTarget() instanceof MzInflateInit).getArgument(0) and - state = "inflate" - or - source.asDefiningArgument() = any(Call call | call.getTarget() instanceof MzZip).getArgument(0) and - state = "" - } - - predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress | - fc.getArgument(2) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderExtract | - fc.getArgument(1) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof MzInflate | - fc.getArgument(0) = sink.asExpr() and - state = "inflate" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompress | - fc.getArgument(1) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompressMem | - fc.getArgument(0) = sink.asExpr() and - state = "" - ) - } - - predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress | - node1.asExpr() = fc.getArgument(2) and - node2.asExpr() = fc.getArgument(0) and - state1 = "" and - state2 = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderLocateFile | - node1.asExpr() = fc.getArgument(1) and - node2.asExpr() = fc.getArgument(3) and - state1 = "" and - state2 = "" - ) - } - - predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } -} - -module MinizTaint = TaintTracking::GlobalWithState; - -import MinizTaint::PathGraph - -from MinizTaint::PathNode source, MinizTaint::PathNode sink -where MinizTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql deleted file mode 100644 index 67999bff3d6..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsMiniZip.ql +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-decompression-minizip - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources - -/** - * The `mz_zip_reader_create` function as a Flow source - * create a `mz_zip_reader` instance - */ -private class Mz_zip_reader_create extends Function { - Mz_zip_reader_create() { this.hasGlobalName("mz_zip_reader_create") } -} - -/** - * The `mz_zip_create` function as a Flow source - * create a `mz_zip` instance - */ -private class Mz_zip_create extends Function { - Mz_zip_create() { this.hasGlobalName("mz_zip_create") } -} - -/** - * The `mz_zip_entry` function is used in Flow source - * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md) - */ -private class Mz_zip_entry extends Function { - Mz_zip_entry() { this.hasGlobalName("mz_zip_entry_read") } -} - -/** - * The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in Flow source - * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md) - */ -private class Mz_zip_reader_entry extends Function { - Mz_zip_reader_entry() { - this.hasGlobalName([ - "mz_zip_reader_entry_save", "mz_zip_reader_entry_read", "mz_zip_reader_entry_save_process", - "mz_zip_reader_entry_save_file", "mz_zip_reader_entry_save_buffer", "mz_zip_reader_save_all" - ]) - } -} - -/** - * A `unzFile` Variable as a Flow source - */ -private class UnzFileVar extends VariableAccess { - UnzFileVar() { this.getType().hasName("unzFile") } -} - -/** - * The `UnzOpen` function as a Flow source - */ -private class UnzOpenFunction extends Function { - UnzOpenFunction() { this.hasGlobalName(["UnzOpen", "unzOpen64", "unzOpen2", "unzOpen2_64"]) } -} - -/** - * The `unzReadCurrentFile` function is used in Flow sink - */ -private class UnzReadCurrentFileFunction extends Function { - UnzReadCurrentFileFunction() { this.hasGlobalName(["unzReadCurrentFile"]) } -} - -module MiniZipTaintConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; - - predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction | - fc.getArgument(0) = source.asExpr() and - state = "unzFile" - ) - or - source.asExpr() instanceof UnzFileVar and - state = "unzFile" - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_create | - fc = source.asExpr() and - state = "mz_zip_reader" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_create | - fc = source.asExpr() and - state = "mz_zip" - ) - } - - predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof UnzReadCurrentFileFunction | - fc.getArgument(0) = sink.asExpr() and - state = "unzFile" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | - fc.getArgument(1) = sink.asExpr() and - state = "mz_zip_reader" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | - fc.getArgument(1) = sink.asExpr() and - state = "mz_zip" - ) - } - - predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc and - state1 = "" and - state2 = "unzFile" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) and - state1 = "" and - state2 = "mz_zip_reader" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) and - state1 = "" and - state2 = "mz_zip" - ) - } - - predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } -} - -module MiniZipTaint = TaintTracking::GlobalWithState; - -import MiniZipTaint::PathGraph - -from MiniZipTaint::PathNode source, MiniZipTaint::PathNode sink -where MiniZipTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsXZ.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsXZ.ql deleted file mode 100644 index dadbf7a5a8a..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsXZ.ql +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-decompression-xz - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources - -/** - * A Pointer Variable as a Flow source - */ -private class Uint8Var extends VariableAccess { - Uint8Var() { this.getType() instanceof UInt8_t } -} - -/** - * A `lzma_stream` Variable as a Flow source - */ -private class LzmaStreamVar extends VariableAccess { - LzmaStreamVar() { this.getType().hasName("lzma_stream") } -} - -/** - * The `lzma_*_decoder` function is used as a required condition for decompression - */ -private class LzmaDecoderFunction extends Function { - LzmaDecoderFunction() { - this.hasGlobalName(["lzma_stream_decoder", "lzma_auto_decoder", "lzma_alone_decoder"]) - } -} - -/** - * The `lzma_code` function is used in Flow sink - */ -private class LzmaCodeFunction extends Function { - LzmaCodeFunction() { this.hasGlobalName(["lzma_code"]) } -} - -/** - * The `lzma_stream_buffer_decode` function is used in Flow sink - */ -private class LzmaStreamBufferDecodeFunction extends Function { - LzmaStreamBufferDecodeFunction() { this.hasGlobalName(["lzma_stream_buffer_decode"]) } -} - -/** - * https://github.com/tukaani-project/xz - */ -module XzTaintConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; - - predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - source.asExpr() instanceof LzmaStreamVar and - state = "" - or - source.asExpr() instanceof Uint8Var and - state = "" - // and not exists(FunctionCall fc | fc.getTarget() instanceof LzmaStreamDecoderFunction) - } - - predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof LzmaStreamBufferDecodeFunction | - fc.getArgument(1) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof LzmaCodeFunction | - fc.getArgument(0) = sink.asExpr() and - state = "" - ) and - exists(FunctionCall fc2 | fc2.getTarget() instanceof LzmaDecoderFunction) - } - - predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } -} - -module XzTaint = TaintTracking::GlobalWithState; - -import XzTaint::PathGraph - -from XzTaint::PathNode source, XzTaint::PathNode sink -where XzTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZSTD.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZSTD.ql deleted file mode 100644 index 9e984bb89e2..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZSTD.ql +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-decompression-zstd - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -// https://github.com/facebook/zstd/blob/dev/examples/streaming_decompression.c -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources -import semmle.code.cpp.commons.File - -// /** -// * A Pointer Variable as a Flow source -// */ -// private class PointerVar extends VariableAccess { -// PointerVar() { this.getType() instanceof PointerType } -// } -/** - * A ZSTD_inBuffer Variable as a Flow source - */ -private class ZSTDinBufferVar extends VariableAccess { - ZSTDinBufferVar() { this.getType().hasName("ZSTD_inBuffer") } -} - -/** - * A ZSTD_inBuffer_s Variable as a Flow source - */ -private class ZSTDinBufferSVar extends VariableAccess { - ZSTDinBufferSVar() { this.getType().hasName("ZSTD_inBuffer_s") } -} - -/** - * The `ZSTD_decompress` function is used in Flow sink - */ -private class ZSTDDecompressFunction extends Function { - ZSTDDecompressFunction() { this.hasGlobalName(["ZSTD_decompress"]) } -} - -/** - * The `ZSTD_decompressDCtx` function is used in Flow sink - */ -private class ZSTDDecompressDCtxFunction extends Function { - ZSTDDecompressDCtxFunction() { this.hasGlobalName(["ZSTD_decompressDCtx"]) } -} - -/** - * The `ZSTD_decompressStream` function is used in Flow sink - */ -private class ZSTDDecompressStreamFunction extends Function { - ZSTDDecompressStreamFunction() { this.hasGlobalName(["ZSTD_decompressStream"]) } -} - -/** - * The `ZSTD_decompress_usingDDict` function is used in Flow sink - */ -private class ZSTDDecompressUsingDictFunction extends Function { - ZSTDDecompressUsingDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) } -} - -/** - * The `ZSTD_decompress_usingDDict` function is used in Flow sink - */ -private class ZSTDDecompressUsingDDictFunction extends Function { - ZSTDDecompressUsingDDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) } -} - -module ZstdTaintConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; - - predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof AllocationFunction | - fc = source.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fopenCall(fc) | - fc = source.asExpr() and - state = "" - ) - or - source.asExpr() instanceof ZSTDinBufferSVar and - state = "" - or - source.asExpr() instanceof ZSTDinBufferVar and - state = "" - } - - predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressFunction | - fc.getArgument(2) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressDCtxFunction | - fc.getArgument(3) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressStreamFunction | - fc.getArgument(2) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDictFunction | - fc.getArgument(3) = sink.asExpr() and - state = "" - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDDictFunction | - fc.getArgument(3) = sink.asExpr() and - state = "" - ) - } - - predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { - none() - } - - predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } -} - -module ZstdTaint = TaintTracking::GlobalWithState; - -import ZstdTaint::PathGraph - -from ZstdTaint::PathNode source, ZstdTaint::PathNode sink -where ZstdTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompression depends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibGzopen.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibGzopen.ql deleted file mode 100644 index ce7324eded0..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibGzopen.ql +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-zlibgz - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources - -/** - * A `gzFile` Variable as a Flow source - */ -private class GzFileVar extends VariableAccess { - GzFileVar() { this.getType().hasName("gzFile") } -} - -/** - * The `gzopen` function as a Flow source - * - * `gzopen(const char *path, const char *mode)` - */ -private class GzopenFunction extends Function { - GzopenFunction() { this.hasGlobalName("gzopen") } -} - -/** - * The `gzdopen` function as a Flow source - * - * `gzdopen(int fd, const char *mode)` - */ -private class GzdopenFunction extends Function { - GzdopenFunction() { this.hasGlobalName("gzdopen") } -} - -/** - * The `gzfread` function is used in Flow sink - * - * `gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file)` - */ -private class GzfreadFunction extends Function { - GzfreadFunction() { this.hasGlobalName("gzfread") } -} - -/** - * The `gzgets` function is used in Flow sink. - * - * `gzgets(gzFile file, char *buf, int len)` - */ -private class GzgetsFunction extends Function { - GzgetsFunction() { this.hasGlobalName("gzgets") } -} - -/** - * The `gzread` function is used in Flow sink - * - * `gzread(gzFile file, voidp buf, unsigned len)` - */ -private class GzreadFunction extends Function { - GzreadFunction() { this.hasGlobalName("gzread") } -} - -module ZlibTaintConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | - fc.getArgument(0) = source.asExpr() and - // arg 0 can be a path string whichwe must do following check - not fc.getArgument(0).isConstant() - ) - or - // IDK whether it is good to use all file decriptors function returns as source or not - // because we can do more sanitization from fd function sources - exists(FunctionCall fc | fc.getTarget() instanceof GzdopenFunction | - fc.getArgument(0) = source.asExpr() - ) - or - source.asExpr() instanceof GzFileVar - } - - predicate isSink(DataFlow::Node sink) { - exists(FunctionCall fc | fc.getTarget() instanceof GzreadFunction | - fc.getArgument(0) = sink.asExpr() and - not sanitizer(fc) - // TODO: and not sanitizer2(fc.getArgument(2)) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzfreadFunction | - sink.asExpr() = fc.getArgument(3) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzgetsFunction | - sink.asExpr() = fc.getArgument(0) - ) - } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(FunctionCall fc | - fc.getTarget() instanceof GzopenFunction or fc.getTarget() instanceof GzdopenFunction - | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzreadFunction | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzfreadFunction | - node1.asExpr() = fc.getArgument(3) and - node2.asExpr() = fc.getArgument(0) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzgetsFunction | - node1.asExpr() = fc.getArgument(0) and - node1.asExpr() = fc.getArgument(1) - ) - } -} - -predicate sanitizer(FunctionCall fc) { - exists(Expr e | - // a RelationalOperation which isn't compared with a Literal that using for end of read - TaintTracking::localExprTaint(fc, e.(RelationalOperation).getAChild*()) and - not e.getAChild*().(Literal).getValue() = ["0", "1", "-1"] - ) -} - -// TODO: -// predicate sanitizer2(FunctionCall fc) { -// exists(Expr e | -// // a RelationalOperation which isn't compared with a Literal that using for end of read -// TaintTracking::localExprTaint(fc.getArgument(2), e) -// ) -// } -module ZlibTaint = TaintTracking::Global; - -import ZlibTaint::PathGraph - -from ZlibTaint::PathNode source, ZlibTaint::PathNode sink -where ZlibTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibInflator.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibInflator.ql deleted file mode 100644 index e526b4d9273..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibInflator.ql +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-zlibinflator - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources - -/** - * A `z_stream` Variable as a Flow source - */ -private class ZStreamVar extends VariableAccess { - ZStreamVar() { this.getType().hasName("z_stream") } -} - -/** - * The `inflate`/`inflateSync` functions are used in Flow sink - * - * `inflate(z_streamp strm, int flush)` - * - * `inflateSync(z_streamp strm)` - */ -private class InflateFunction extends Function { - InflateFunction() { this.hasGlobalName(["inflate", "inflateSync"]) } -} - -module ZlibTaintConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source.asExpr() instanceof ZStreamVar } - - predicate isSink(DataFlow::Node sink) { - exists(FunctionCall fc | fc.getTarget() instanceof InflateFunction | - fc.getArgument(0) = sink.asExpr() - ) - } -} - -module ZlibTaint = TaintTracking::Global; - -import ZlibTaint::PathGraph - -from ZlibTaint::PathNode source, ZlibTaint::PathNode sink -where ZlibTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompression depends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibUncompress.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibUncompress.ql deleted file mode 100644 index b385523f185..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombsZlibUncompress.ql +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @name User-controlled file decompression - * @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous - * @kind path-problem - * @problem.severity error - * @security-severity 7.8 - * @precision high - * @id cpp/user-controlled-file-zlibuncompress - * @tags security - * experimental - * external/cwe/cwe-409 - */ - -import cpp -import semmle.code.cpp.ir.dataflow.TaintTracking -import semmle.code.cpp.security.FlowSources - -/** - * A Bytef Variable as a Flow source - */ -private class BytefVar extends VariableAccess { - BytefVar() { this.getType().hasName("Bytef") } -} - -/** - * The `uncompress`/`uncompress2` function is used in Flow sink - */ -private class UncompressFunction extends Function { - UncompressFunction() { hasGlobalName(["uncompress", "uncompress2"]) } -} - -module ZlibTaintConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source.asExpr() instanceof BytefVar } - - predicate isSink(DataFlow::Node sink) { - exists(FunctionCall fc | fc.getTarget() instanceof UncompressFunction | - fc.getArgument(0) = sink.asExpr() - ) - } -} - -module ZlibTaint = TaintTracking::Global; - -import ZlibTaint::PathGraph - -from ZlibTaint::PathNode source, ZlibTaint::PathNode sink -where ZlibTaint::flowPath(source, sink) -select sink.getNode(), source, sink, "This Decompression depends on a $@.", source.getNode(), - "potentially untrusted source" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibArchive.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibArchive.qll new file mode 100644 index 00000000000..4d96e83c195 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibArchive.qll @@ -0,0 +1,25 @@ +/** + * https://github.com/libarchive/libarchive/wiki + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * The `archive_read_new` function as a Flow source + * create a `archive` instance + */ +class Archive_read_new extends Function { + Archive_read_new() { this.hasGlobalName("archive_read_new") } +} + +/** + * The `archive_read_data*` functions are used in Flow Sink + * [Examples](https://github.com/libarchive/libarchive/wiki/Examples) + */ +class Archive_read_data_block extends Function { + Archive_read_data_block() { + this.hasGlobalName(["archive_read_data_block", "archive_read_data", "archive_read_data_into_fd"]) + } +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibMiniz.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibMiniz.qll new file mode 100644 index 00000000000..64eba1e7b28 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibMiniz.qll @@ -0,0 +1,102 @@ +/** + * https://github.com/richgel999/miniz + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A unsigned char Variable is used in Flow source + */ +class UnsignedCharVar extends VariableAccess { + UnsignedCharVar() { this.getType().stripType().resolveTypedefs*() instanceof UnsignedCharType } +} + +/** + * The `mz_streamp`, `z_stream` Variables are used in Flow source + */ +class MzStreampVar extends VariableAccess { + MzStreampVar() { this.getType().hasName(["mz_streamp", "z_stream"]) } +} + +/** + * A Char Variable is used in Flow source + */ +class CharVar extends VariableAccess { + CharVar() { this.getType().stripType().resolveTypedefs*() instanceof CharType } +} + +/** + * A `mz_zip_archive` Variable is used in Flow source + */ +class MzZipArchiveVar extends VariableAccess { + MzZipArchiveVar() { this.getType().hasName("mz_zip_archive") } +} + +/** + * The `mz_uncompress` functions are used in Flow Sink + */ +class MzUncompress extends Function { + MzUncompress() { this.hasGlobalName(["uncompress", "mz_uncompress", "mz_uncompress2"]) } +} + +/** + * A `zip handle` is used in Flow source + */ +class MzZip extends Function { + MzZip() { + this.hasGlobalName([ + "mz_zip_reader_open", "mz_zip_reader_open_file", "mz_zip_reader_open_file_in_memory", + "mz_zip_reader_open_buffer", "mz_zip_reader_entry_open" + ]) + } +} + +/** + * The `mz_inflate` functions are used in Flow Sink + */ +class MzInflate extends Function { + MzInflate() { this.hasGlobalName(["mz_inflate", "inflate"]) } +} + +/** + * The `mz_inflateInit` functions are used in Flow Sink + */ +class MzInflateInit extends Function { + MzInflateInit() { this.hasGlobalName(["inflateInit", "mz_inflateInit"]) } +} + +/** + * The `mz_zip_reader_extract_*` functions are used in Flow Sink + */ +class MzZipReaderExtract extends Function { + MzZipReaderExtract() { + this.hasGlobalName([ + "mz_zip_reader_extract_file_to_heap", "mz_zip_reader_extract_to_heap", + "mz_zip_reader_extract_to_callback", "mz_zip_reader_extract_file_to_callback", + "mz_zip_reader_extract_to_mem", "mz_zip_reader_extract_file_to_mem", + "mz_zip_reader_extract_iter_read", "mz_zip_reader_extract_to_file", + "mz_zip_reader_extract_file_to_file" + ]) + } +} + +/** + * The `tinfl_decompress_mem_*` functions are used in Flow Sink + */ +class TinflDecompressMem extends Function { + TinflDecompressMem() { + this.hasGlobalName([ + "tinfl_decompress_mem_to_callback", "tinfl_decompress_mem_to_mem", + "tinfl_decompress_mem_to_heap" + ]) + } +} + +/** + * The `tinfl_decompress_*` functions are used in Flow Sink + */ +class TinflDecompress extends Function { + TinflDecompress() { this.hasGlobalName(["tinfl_decompress"]) } +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/MiniZip.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/MiniZip.qll new file mode 100644 index 00000000000..7d2280166e0 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/MiniZip.qll @@ -0,0 +1,65 @@ +/** + * https://github.com/zlib-ng/minizip-ng + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * The `mz_zip_reader_create` function as a Flow source + * create a `mz_zip_reader` instance + */ +class Mz_zip_reader_create extends Function { + Mz_zip_reader_create() { this.hasGlobalName("mz_zip_reader_create") } +} + +/** + * The `mz_zip_create` function as a Flow source + * create a `mz_zip` instance + */ +class Mz_zip_create extends Function { + Mz_zip_create() { this.hasGlobalName("mz_zip_create") } +} + +/** + * The `mz_zip_entry` function is used in Flow source + * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md) + */ +class Mz_zip_entry extends Function { + Mz_zip_entry() { this.hasGlobalName("mz_zip_entry_read") } +} + +/** + * The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in Flow source + * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md) + */ +class Mz_zip_reader_entry extends Function { + Mz_zip_reader_entry() { + this.hasGlobalName([ + "mz_zip_reader_entry_save", "mz_zip_reader_entry_read", "mz_zip_reader_entry_save_process", + "mz_zip_reader_entry_save_file", "mz_zip_reader_entry_save_buffer", "mz_zip_reader_save_all" + ]) + } +} + +/** + * A `unzFile` Variable as a Flow source + */ +class UnzFileVar extends VariableAccess { + UnzFileVar() { this.getType().hasName("unzFile") } +} + +/** + * The `UnzOpen` function as a Flow source + */ +class UnzOpenFunction extends Function { + UnzOpenFunction() { this.hasGlobalName(["UnzOpen", "unzOpen64", "unzOpen2", "unzOpen2_64"]) } +} + +/** + * The `unzReadCurrentFile` function is used in Flow sink + */ +class UnzReadCurrentFileFunction extends Function { + UnzReadCurrentFileFunction() { this.hasGlobalName(["unzReadCurrentFile"]) } +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll new file mode 100644 index 00000000000..84b6a311f86 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll @@ -0,0 +1,37 @@ +/** + * https://github.com/tukaani-project/xz + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A `lzma_stream` Variable as a Flow source + */ +class LzmaStreamVar extends VariableAccess { + LzmaStreamVar() { this.getType().hasName("lzma_stream") } +} + +/** + * The `lzma_*_decoder` function is used as a required condition for decompression + */ +class LzmaDecoderFunction extends Function { + LzmaDecoderFunction() { + this.hasGlobalName(["lzma_stream_decoder", "lzma_auto_decoder", "lzma_alone_decoder"]) + } +} + +/** + * The `lzma_code` function is used in Flow sink + */ +class LzmaCodeFunction extends Function { + LzmaCodeFunction() { this.hasGlobalName(["lzma_code"]) } +} + +/** + * The `lzma_stream_buffer_decode` function is used in Flow sink + */ +class LzmaStreamBufferDecodeFunction extends Function { + LzmaStreamBufferDecodeFunction() { this.hasGlobalName(["lzma_stream_buffer_decode"]) } +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZSTD.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZSTD.qll new file mode 100644 index 00000000000..902903efb78 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZSTD.qll @@ -0,0 +1,57 @@ +/** + * https://github.com/facebook/zstd/blob/dev/examples/streaming_decompression.c + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources +import semmle.code.cpp.commons.File + +/** + * A ZSTD_inBuffer Variable as a Flow source + */ +class ZSTDinBufferVar extends VariableAccess { + ZSTDinBufferVar() { this.getType().hasName("ZSTD_inBuffer") } +} + +/** + * A ZSTD_inBuffer_s Variable as a Flow source + */ +class ZSTDinBufferSVar extends VariableAccess { + ZSTDinBufferSVar() { this.getType().hasName("ZSTD_inBuffer_s") } +} + +/** + * The `ZSTD_decompress` function is used in Flow sink + */ +class ZSTDDecompressFunction extends Function { + ZSTDDecompressFunction() { this.hasGlobalName(["ZSTD_decompress"]) } +} + +/** + * The `ZSTD_decompressDCtx` function is used in Flow sink + */ +class ZSTDDecompressDCtxFunction extends Function { + ZSTDDecompressDCtxFunction() { this.hasGlobalName(["ZSTD_decompressDCtx"]) } +} + +/** + * The `ZSTD_decompressStream` function is used in Flow sink + */ +class ZSTDDecompressStreamFunction extends Function { + ZSTDDecompressStreamFunction() { this.hasGlobalName(["ZSTD_decompressStream"]) } +} + +/** + * The `ZSTD_decompress_usingDDict` function is used in Flow sink + */ +class ZSTDDecompressUsingDictFunction extends Function { + ZSTDDecompressUsingDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) } +} + +/** + * The `ZSTD_decompress_usingDDict` function is used in Flow sink + */ +class ZSTDDecompressUsingDDictFunction extends Function { + ZSTDDecompressUsingDDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) } +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibGzopen.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibGzopen.qll new file mode 100644 index 00000000000..306130ac8f2 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibGzopen.qll @@ -0,0 +1,75 @@ +/** + * https://www.zlib.net/ + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A `gzFile` Variable as a Flow source + */ +class GzFileVar extends VariableAccess { + GzFileVar() { this.getType().hasName("gzFile") } +} + +/** + * The `gzopen` function as a Flow source + * + * `gzopen(const char *path, const char *mode)` + */ +class GzopenFunction extends Function { + GzopenFunction() { this.hasGlobalName("gzopen") } +} + +/** + * The `gzdopen` function as a Flow source + * + * `gzdopen(int fd, const char *mode)` + */ +class GzdopenFunction extends Function { + GzdopenFunction() { this.hasGlobalName("gzdopen") } +} + +/** + * The `gzfread` function is used in Flow sink + * + * `gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file)` + */ +class GzFreadFunction extends Function { + GzFreadFunction() { this.hasGlobalName("gzfread") } +} + +/** + * The `gzgets` function is used in Flow sink. + * + * `gzgets(gzFile file, char *buf, int len)` + */ +class GzGetsFunction extends Function { + GzGetsFunction() { this.hasGlobalName("gzgets") } +} + +/** + * The `gzread` function is used in Flow sink + * + * `gzread(gzFile file, voidp buf, unsigned len)` + */ +class GzReadFunction extends Function { + GzReadFunction() { this.hasGlobalName("gzread") } +} + +predicate isSource(DataFlow::Node source) { + exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | + fc.getArgument(0) = source.asExpr() and + // arg 0 can be a path string whichwe must do following check + not fc.getArgument(0).isConstant() + ) + or + // IDK whether it is good to use all file decriptors function returns as source or not + // because we can do more sanitization from fd function sources + exists(FunctionCall fc | fc.getTarget() instanceof GzdopenFunction | + fc.getArgument(0) = source.asExpr() + ) + or + source.asExpr() instanceof GzFileVar +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibInflator.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibInflator.qll new file mode 100644 index 00000000000..b67caecfcbd --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibInflator.qll @@ -0,0 +1,25 @@ +/** + * https://www.zlib.net/ + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A `z_stream` Variable as a Flow source + */ +class ZStreamVar extends VariableAccess { + ZStreamVar() { this.getType().hasName("z_stream") } +} + +/** + * The `inflate`/`inflateSync` functions are used in Flow sink + * + * `inflate(z_streamp strm, int flush)` + * + * `inflateSync(z_streamp strm)` + */ +class InflateFunction extends Function { + InflateFunction() { this.hasGlobalName(["inflate", "inflateSync"]) } +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll new file mode 100644 index 00000000000..3518719bc87 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll @@ -0,0 +1,21 @@ +/** + * https://www.zlib.net/ + */ + +import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking +import semmle.code.cpp.security.FlowSources + +/** + * A Bytef Variable as a Flow source + */ +class BytefVar extends VariableAccess { + BytefVar() { this.getType().hasName("Bytef") } +} + +/** + * The `uncompress`/`uncompress2` function is used in Flow sink + */ +class UncompressFunction extends Function { + UncompressFunction() { hasGlobalName(["uncompress", "uncompress2"]) } +} From a5363286f1a184914aaa43cdee9f937ec6def845 Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Fri, 7 Jun 2024 05:37:58 +0200 Subject: [PATCH 013/404] add implicit this --- .../Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll index 3518719bc87..1f33b065409 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll @@ -17,5 +17,5 @@ class BytefVar extends VariableAccess { * The `uncompress`/`uncompress2` function is used in Flow sink */ class UncompressFunction extends Function { - UncompressFunction() { hasGlobalName(["uncompress", "uncompress2"]) } + UncompressFunction() { this.hasGlobalName(["uncompress", "uncompress2"]) } } From 273848c8796f02c4b583c99144b6bc4ca9d7af31 Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Fri, 7 Jun 2024 05:40:17 +0200 Subject: [PATCH 014/404] remove old comments --- .../CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql index 8506dccaea7..d75eae39056 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql @@ -115,12 +115,10 @@ module DecompressionTaintConfig implements DataFlow::StateConfigSig { ( exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | fc.getArgument(0) = source.asExpr() and - // arg 0 can be a path string whichwe must do following check + // arg 0 can be a path string which we must do following check not fc.getArgument(0).isConstant() ) or - // IDK whether it is good to use all file decriptors function returns as source or not - // because we can do more sanitization from fd function sources exists(FunctionCall fc | fc.getTarget() instanceof GzdopenFunction | fc.getArgument(0) = source.asExpr() ) From 11a416ea7c80493d44cbd6e02c218cb2f0164ead Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Thu, 13 Jun 2024 03:30:07 +0200 Subject: [PATCH 015/404] add FlowSources as a common source for all sinks, so we don't need States anymore --- .../DecompressionBombs.ql | 350 ++++++------------ .../CWE/CWE-409-DecompressionBomb/XZ.qll | 8 - 2 files changed, 104 insertions(+), 254 deletions(-) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql index d75eae39056..03eab33a6ce 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql @@ -27,298 +27,156 @@ import ZlibUncompress import ZlibInflator import Brotli -module DecompressionTaintConfig implements DataFlow::StateConfigSig { - class FlowState = DataFlow::FlowState; +module DecompressionTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof FlowSource } - predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { - ( - exists(FunctionCall fc | fc.getTarget() instanceof AllocationFunction | fc = source.asExpr()) - or - exists(FunctionCall fc | fopenCall(fc) | fc = source.asExpr()) - or - source.asExpr() instanceof PointerVar - or - source.asExpr() instanceof Uint8Var - ) and - state = "brotli" - or - ( - source.asExpr() instanceof BzStreamVar - or - source.asExpr() instanceof BzFileVar - or - exists(FunctionCall fc | fopenCall(fc) | fc = source.asExpr()) - ) and - state = "bzip2" - or - exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_new | - fc.getArgument(0) = source.asExpr() - ) and - state = "libarchive" - or - ( - source.asExpr() instanceof UnsignedCharVar - or - source.asExpr() instanceof PointerVar - or - source.asExpr() instanceof CharVar - or - source.asExpr() instanceof MzZipArchiveVar - or - source.asExpr() instanceof MzStreampVar - or - source.asDefiningArgument() = - any(Call call | call.getTarget() instanceof MzInflateInit).getArgument(0) - or - source.asDefiningArgument() = - any(Call call | call.getTarget() instanceof MzZip).getArgument(0) - ) and - state = "libminiz" - or - ( - exists(FunctionCall fc | fc.getTarget() instanceof AllocationFunction | fc = source.asExpr()) - or - exists(FunctionCall fc | fopenCall(fc) | fc = source.asExpr()) - or - source.asExpr() instanceof ZSTDinBufferSVar - or - source.asExpr() instanceof ZSTDinBufferVar - ) and - state = "zstd" - or - ( - exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction | - fc.getArgument(0) = source.asExpr() - ) - or - source.asExpr() instanceof UnzFileVar - ) and - state = "unzFile" - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_create | - fc = source.asExpr() and - state = "mz_zip_reader" + predicate isSink(DataFlow::Node sink) { + exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressStreamFunction | + fc.getArgument(2) = sink.asExpr() ) or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_create | - fc = source.asExpr() and - state = "mz_zip" + exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressFunction | + fc.getArgument(1) = sink.asExpr() ) or - ( - source.asExpr() instanceof LzmaStreamVar - or - source.asExpr() instanceof Uint8Var - ) and - state = "xz" + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzDecompressFunction | + fc.getArgument(0) = sink.asExpr() + ) or - ( - exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | - fc.getArgument(0) = source.asExpr() and - // arg 0 can be a path string which we must do following check - not fc.getArgument(0).isConstant() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzdopenFunction | - fc.getArgument(0) = source.asExpr() - ) - or - source.asExpr() instanceof GzFileVar - ) and - state = "zlibgzopen" + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzReadFunction | + fc.getArgument(1) = sink.asExpr() + ) or - source.asExpr() instanceof ZStreamVar and state = "zlifinflator" - or - source.asExpr() instanceof BytefVar and state = "zlibuncompress" - } - - predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { - ( - exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressStreamFunction | - fc.getArgument(2) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressFunction | - fc.getArgument(1) = sink.asExpr() - ) - ) and - state = "brotli" - or - ( - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzDecompressFunction | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzReadFunction | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzBuffToBuffDecompressFunction | - fc.getArgument(2) = sink.asExpr() - ) - ) and - state = "bzip2" + exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzBuffToBuffDecompressFunction | + fc.getArgument(2) = sink.asExpr() + ) or exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_data_block | - fc.getArgument(0) = sink.asExpr() and - state = "libarchive" + fc.getArgument(0) = sink.asExpr() ) or - ( - exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderExtract | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof MzInflate | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompress | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompressMem | - fc.getArgument(0) = sink.asExpr() - ) - ) and - state = "libminiz" + exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress | + fc.getArgument(0) = sink.asExpr() + ) or - ( - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressFunction | - fc.getArgument(2) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressDCtxFunction | - fc.getArgument(3) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressStreamFunction | - fc.getArgument(2) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDictFunction | - fc.getArgument(3) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDDictFunction | - fc.getArgument(3) = sink.asExpr() - ) - ) and - state = "zstd" + exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderExtract | + fc.getArgument(1) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof MzInflate | + fc.getArgument(0) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompress | + fc.getArgument(1) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompressMem | + fc.getArgument(0) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressFunction | + fc.getArgument(2) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressDCtxFunction | + fc.getArgument(3) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressStreamFunction | + fc.getArgument(2) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDictFunction | + fc.getArgument(3) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDDictFunction | + fc.getArgument(3) = sink.asExpr() + ) or exists(FunctionCall fc | fc.getTarget() instanceof UnzReadCurrentFileFunction | - fc.getArgument(0) = sink.asExpr() and - state = "unzFile" + fc.getArgument(0) = sink.asExpr() ) or exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | - fc.getArgument(1) = sink.asExpr() and - state = "mz_zip_reader" + fc.getArgument(1) = sink.asExpr() ) or exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | - fc.getArgument(1) = sink.asExpr() and - state = "mz_zip" + fc.getArgument(1) = sink.asExpr() ) or - ( - exists(FunctionCall fc | fc.getTarget() instanceof LzmaStreamBufferDecodeFunction | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof LzmaCodeFunction | - fc.getArgument(0) = sink.asExpr() - ) - ) and - state = "xz" and - exists(FunctionCall fc2 | fc2.getTarget() instanceof LzmaDecoderFunction) + exists(FunctionCall fc | fc.getTarget() instanceof LzmaStreamBufferDecodeFunction | + fc.getArgument(1) = sink.asExpr() + ) or - ( - exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction | - sink.asExpr() = fc.getArgument(3) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction | - sink.asExpr() = fc.getArgument(0) - ) - ) and - state = "zlibgzopen" + exists(FunctionCall fc | fc.getTarget() instanceof LzmaCodeFunction | + fc.getArgument(0) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction | + fc.getArgument(0) = sink.asExpr() + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction | + sink.asExpr() = fc.getArgument(3) + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction | + sink.asExpr() = fc.getArgument(0) + ) or exists(FunctionCall fc | fc.getTarget() instanceof InflateFunction | fc.getArgument(0) = sink.asExpr() - ) and - state = "zlifinflator" + ) or exists(FunctionCall fc | fc.getTarget() instanceof UncompressFunction | fc.getArgument(0) = sink.asExpr() - ) and - state = "zlibuncompress" + ) } - predicate isAdditionalFlowStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 - ) { + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction | node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc and - state1 = "" and - state2 = "unzFile" + node2.asExpr() = fc ) or exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) and - state1 = "" and - state2 = "mz_zip_reader" + node2.asExpr() = fc.getArgument(1) ) or exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) and - state1 = "" and - state2 = "mz_zip" + node2.asExpr() = fc.getArgument(1) ) or - ( - exists(FunctionCall fc | - fc.getTarget() instanceof GzopenFunction or fc.getTarget() instanceof GzdopenFunction - | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction | - node1.asExpr() = fc.getArgument(3) and - node2.asExpr() = fc.getArgument(0) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction | - node1.asExpr() = fc.getArgument(0) and - node1.asExpr() = fc.getArgument(1) - ) - ) and - state1 = "" and - state2 = "gzopen" + exists(FunctionCall fc | + fc.getTarget() instanceof GzopenFunction or fc.getTarget() instanceof GzdopenFunction + | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction | + node1.asExpr() = fc.getArgument(3) and + node2.asExpr() = fc.getArgument(0) + ) + or + exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction | + node1.asExpr() = fc.getArgument(0) and + node1.asExpr() = fc.getArgument(1) + ) } - - predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() } } -module DecompressionTaint = TaintTracking::GlobalWithState; +module DecompressionTaint = TaintTracking::Global; import DecompressionTaint::PathGraph diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll index 84b6a311f86..621558e07fd 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll +++ b/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll @@ -13,14 +13,6 @@ class LzmaStreamVar extends VariableAccess { LzmaStreamVar() { this.getType().hasName("lzma_stream") } } -/** - * The `lzma_*_decoder` function is used as a required condition for decompression - */ -class LzmaDecoderFunction extends Function { - LzmaDecoderFunction() { - this.hasGlobalName(["lzma_stream_decoder", "lzma_auto_decoder", "lzma_alone_decoder"]) - } -} /** * The `lzma_code` function is used in Flow sink From 13f697c0569c2266ec10f0d47979ee0a80c82a0c Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Tue, 25 Jun 2024 17:31:40 +0200 Subject: [PATCH 016/404] relocate the query --- .../Security/CWE/CWE-409}/Brotli.qll | 0 .../Security/CWE/CWE-409}/Bzip2.qll | 0 .../Security/CWE/CWE-409}/DecompressionBomb.qhelp | 0 .../Security/CWE/CWE-409}/DecompressionBombs.ql | 0 .../Security/CWE/CWE-409}/LibArchive.qll | 0 .../Security/CWE/CWE-409}/LibMiniz.qll | 0 .../Security/CWE/CWE-409}/MiniZip.qll | 0 .../Security/CWE/CWE-409}/XZ.qll | 0 .../Security/CWE/CWE-409}/ZSTD.qll | 0 .../Security/CWE/CWE-409}/ZlibGzopen.qll | 0 .../Security/CWE/CWE-409}/ZlibInflator.qll | 0 .../Security/CWE/CWE-409}/ZlibUncompress.qll | 0 .../Security/CWE/CWE-409}/example_bad.cpp | 0 .../Security/CWE/CWE-409}/example_good.cpp | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/Brotli.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/Bzip2.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/DecompressionBomb.qhelp (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/DecompressionBombs.ql (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/LibArchive.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/LibMiniz.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/MiniZip.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/XZ.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/ZSTD.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/ZlibGzopen.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/ZlibInflator.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/ZlibUncompress.qll (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/example_bad.cpp (100%) rename cpp/ql/src/experimental/{Security/CWE/CWE-409-DecompressionBomb => query-tests/Security/CWE/CWE-409}/example_good.cpp (100%) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Brotli.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Brotli.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Brotli.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Brotli.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bzip2.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Bzip2.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/Bzip2.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Bzip2.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qhelp similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBomb.qhelp rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qhelp diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/DecompressionBombs.ql rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibArchive.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibArchive.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibArchive.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibArchive.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibMiniz.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibMiniz.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/LibMiniz.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibMiniz.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/MiniZip.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/MiniZip.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/XZ.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/XZ.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/XZ.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZSTD.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZSTD.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZSTD.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZSTD.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibGzopen.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibGzopen.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibInflator.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibInflator.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibUncompress.qll similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/ZlibUncompress.qll rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibUncompress.qll diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/example_bad.cpp similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_bad.cpp rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/example_bad.cpp diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/example_good.cpp similarity index 100% rename from cpp/ql/src/experimental/Security/CWE/CWE-409-DecompressionBomb/example_good.cpp rename to cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/example_good.cpp From 656dc4e2760a36c3eab87475d5e450f4fa606096 Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Tue, 25 Jun 2024 18:09:27 +0200 Subject: [PATCH 017/404] use abstract class for decompression sinks --- .../Security/CWE/CWE-409/Brotli.qll | 29 ++-- .../Security/CWE/CWE-409/Bzip2.qll | 35 ++--- .../CWE/CWE-409/DecompressionBomb.qll | 8 ++ .../CWE/CWE-409/DecompressionBombs.ql | 129 +----------------- .../Security/CWE/CWE-409/LibArchive.qll | 15 +- .../Security/CWE/CWE-409/LibMiniz.qll | 70 ++++------ .../Security/CWE/CWE-409/MiniZip.qll | 45 ++---- .../query-tests/Security/CWE/CWE-409/XZ.qll | 21 ++- .../query-tests/Security/CWE/CWE-409/ZSTD.qll | 45 +++--- .../Security/CWE/CWE-409/ZlibGzopen.qll | 84 +++++------- .../Security/CWE/CWE-409/ZlibInflator.qll | 14 +- .../Security/CWE/CWE-409/ZlibUncompress.qll | 14 +- 12 files changed, 148 insertions(+), 361 deletions(-) create mode 100644 cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Brotli.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Brotli.qll index 46314826a62..5c19e53df07 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Brotli.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Brotli.qll @@ -6,33 +6,22 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources import semmle.code.cpp.commons.File +import DecompressionBomb /** - * A Pointer Variable is used in Flow source + * The `BrotliDecoderDecompress` function is used in flow sink. * Ref: https://www.brotli.org/decode.html#af68 */ -class PointerVar extends VariableAccess { - PointerVar() { this.getType() instanceof PointerType } -} - -/** - * A Pointer Variable is used in Flow source - */ -class Uint8Var extends VariableAccess { - Uint8Var() { this.getType() instanceof UInt8_t } -} - -/** - * The `BrotliDecoderDecompress` function is used in Flow sink - * Ref: https://www.brotli.org/decode.html#af68 - */ -class BrotliDecoderDecompressFunction extends Function { +class BrotliDecoderDecompressFunction extends DecompressionFunction { BrotliDecoderDecompressFunction() { this.hasGlobalName(["BrotliDecoderDecompress"]) } + + override int getArchiveParameterIndex() { result = 1 } } /** - * The `BrotliDecoderDecompressStream` function is used in Flow sink - * Ref: https://www.brotli.org/decode.html#a234 + * The `BrotliDecoderDecompressStream` function is used in flow sink. * Ref: https://www.brotli.org/decode.html#a234 */ -class BrotliDecoderDecompressStreamFunction extends Function { +class BrotliDecoderDecompressStreamFunction extends DecompressionFunction { BrotliDecoderDecompressStreamFunction() { this.hasGlobalName(["BrotliDecoderDecompressStream"]) } + + override int getArchiveParameterIndex() { result = 2 } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Bzip2.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Bzip2.qll index 662424b022a..7f69aa494c6 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Bzip2.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/Bzip2.qll @@ -6,45 +6,40 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources import semmle.code.cpp.commons.File - -/** - * A `bz_stream` Variable as a Flow source - */ -class BzStreamVar extends VariableAccess { - BzStreamVar() { this.getType().hasName("bz_stream") } -} - -/** - * A `BZFILE` Variable as a Flow source - */ -class BzFileVar extends VariableAccess { - BzFileVar() { this.getType().hasName("BZFILE") } -} +import DecompressionBomb /** * The `BZ2_bzDecompress` function as a Flow source */ -class BZ2BzDecompressFunction extends Function { +class BZ2BzDecompressFunction extends DecompressionFunction { BZ2BzDecompressFunction() { this.hasGlobalName(["BZ2_bzDecompress"]) } + + override int getArchiveParameterIndex() { result = 0 } } /** * The `BZ2_bzReadOpen` function */ -class BZ2BzReadOpenFunction extends Function { +class BZ2BzReadOpenFunction extends DecompressionFunction { BZ2BzReadOpenFunction() { this.hasGlobalName(["BZ2_bzReadOpen"]) } + + override int getArchiveParameterIndex() { result = 0 } } /** - * The `BZ2_bzRead` function is used in Flow sink + * The `BZ2_bzRead` function is used in flow sink. */ -class BZ2BzReadFunction extends Function { +class BZ2BzReadFunction extends DecompressionFunction { BZ2BzReadFunction() { this.hasGlobalName("BZ2_bzRead") } + + override int getArchiveParameterIndex() { result = 1 } } /** - * The `BZ2_bzBuffToBuffDecompress` function is used in Flow sink + * The `BZ2_bzBuffToBuffDecompress` function is used in flow sink. */ -class BZ2BzBuffToBuffDecompressFunction extends Function { +class BZ2BzBuffToBuffDecompressFunction extends DecompressionFunction { BZ2BzBuffToBuffDecompressFunction() { this.hasGlobalName("BZ2_bzBuffToBuffDecompress") } + + override int getArchiveParameterIndex() { result = 2 } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll new file mode 100644 index 00000000000..2cca1453d2f --- /dev/null +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll @@ -0,0 +1,8 @@ +import cpp + +/** + * The Decompression Sink instances, extend this class to defind new decompression sinks. + */ +abstract class DecompressionFunction extends Function { + abstract int getArchiveParameterIndex(); +} diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql index 03eab33a6ce..b7eda35f2c7 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql @@ -15,124 +15,16 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources import semmle.code.cpp.commons.File -import Bzip2 -import Brotli -import LibArchive -import LibMiniz -import ZSTD import MiniZip -import XZ import ZlibGzopen -import ZlibUncompress -import ZlibInflator -import Brotli +import DecompressionBomb module DecompressionTaintConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof FlowSource } predicate isSink(DataFlow::Node sink) { - exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressStreamFunction | - fc.getArgument(2) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BrotliDecoderDecompressFunction | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzDecompressFunction | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzReadFunction | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof BZ2BzBuffToBuffDecompressFunction | - fc.getArgument(2) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Archive_read_data_block | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderExtract | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof MzInflate | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompress | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompressMem | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressFunction | - fc.getArgument(2) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressDCtxFunction | - fc.getArgument(3) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressStreamFunction | - fc.getArgument(2) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDictFunction | - fc.getArgument(3) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof ZSTDDecompressUsingDDictFunction | - fc.getArgument(3) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof UnzReadCurrentFileFunction | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof LzmaStreamBufferDecodeFunction | - fc.getArgument(1) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof LzmaCodeFunction | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction | - sink.asExpr() = fc.getArgument(3) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction | - sink.asExpr() = fc.getArgument(0) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof InflateFunction | - fc.getArgument(0) = sink.asExpr() - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof UncompressFunction | - fc.getArgument(0) = sink.asExpr() + exists(FunctionCall fc, DecompressionFunction f | fc.getTarget() = f | + fc.getArgument(f.getArchiveParameterIndex()) = sink.asExpr() ) } @@ -158,21 +50,6 @@ module DecompressionTaintConfig implements DataFlow::ConfigSig { node1.asExpr() = fc.getArgument(0) and node2.asExpr() = fc ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzReadFunction | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzFreadFunction | - node1.asExpr() = fc.getArgument(3) and - node2.asExpr() = fc.getArgument(0) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof GzGetsFunction | - node1.asExpr() = fc.getArgument(0) and - node1.asExpr() = fc.getArgument(1) - ) } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibArchive.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibArchive.qll index 4d96e83c195..e5124006504 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibArchive.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibArchive.qll @@ -5,21 +5,16 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources +import DecompressionBomb /** - * The `archive_read_new` function as a Flow source - * create a `archive` instance - */ -class Archive_read_new extends Function { - Archive_read_new() { this.hasGlobalName("archive_read_new") } -} - -/** - * The `archive_read_data*` functions are used in Flow Sink + * The `archive_read_data*` functions are used in flow sink. * [Examples](https://github.com/libarchive/libarchive/wiki/Examples) */ -class Archive_read_data_block extends Function { +class Archive_read_data_block extends DecompressionFunction { Archive_read_data_block() { this.hasGlobalName(["archive_read_data_block", "archive_read_data", "archive_read_data_into_fd"]) } + + override int getArchiveParameterIndex() { result = 0 } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibMiniz.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibMiniz.qll index 64eba1e7b28..0025ecca97d 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibMiniz.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/LibMiniz.qll @@ -5,72 +5,44 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources +import DecompressionBomb /** - * A unsigned char Variable is used in Flow source + * The `mz_uncompress` functions are used in flow sink. */ -class UnsignedCharVar extends VariableAccess { - UnsignedCharVar() { this.getType().stripType().resolveTypedefs*() instanceof UnsignedCharType } -} - -/** - * The `mz_streamp`, `z_stream` Variables are used in Flow source - */ -class MzStreampVar extends VariableAccess { - MzStreampVar() { this.getType().hasName(["mz_streamp", "z_stream"]) } -} - -/** - * A Char Variable is used in Flow source - */ -class CharVar extends VariableAccess { - CharVar() { this.getType().stripType().resolveTypedefs*() instanceof CharType } -} - -/** - * A `mz_zip_archive` Variable is used in Flow source - */ -class MzZipArchiveVar extends VariableAccess { - MzZipArchiveVar() { this.getType().hasName("mz_zip_archive") } -} - -/** - * The `mz_uncompress` functions are used in Flow Sink - */ -class MzUncompress extends Function { +class MzUncompress extends DecompressionFunction { MzUncompress() { this.hasGlobalName(["uncompress", "mz_uncompress", "mz_uncompress2"]) } + + override int getArchiveParameterIndex() { result = 0 } } /** * A `zip handle` is used in Flow source */ -class MzZip extends Function { +class MzZip extends DecompressionFunction { MzZip() { this.hasGlobalName([ "mz_zip_reader_open", "mz_zip_reader_open_file", "mz_zip_reader_open_file_in_memory", "mz_zip_reader_open_buffer", "mz_zip_reader_entry_open" ]) } + + override int getArchiveParameterIndex() { result = 1 } } /** - * The `mz_inflate` functions are used in Flow Sink + * The `mz_inflate` functions are used in flow sink. */ -class MzInflate extends Function { +class MzInflate extends DecompressionFunction { MzInflate() { this.hasGlobalName(["mz_inflate", "inflate"]) } + + override int getArchiveParameterIndex() { result = 0 } } /** - * The `mz_inflateInit` functions are used in Flow Sink + * The `mz_zip_reader_extract_*` functions are used in flow sink. */ -class MzInflateInit extends Function { - MzInflateInit() { this.hasGlobalName(["inflateInit", "mz_inflateInit"]) } -} - -/** - * The `mz_zip_reader_extract_*` functions are used in Flow Sink - */ -class MzZipReaderExtract extends Function { +class MzZipReaderExtract extends DecompressionFunction { MzZipReaderExtract() { this.hasGlobalName([ "mz_zip_reader_extract_file_to_heap", "mz_zip_reader_extract_to_heap", @@ -80,23 +52,29 @@ class MzZipReaderExtract extends Function { "mz_zip_reader_extract_file_to_file" ]) } + + override int getArchiveParameterIndex() { result = 1 } } /** - * The `tinfl_decompress_mem_*` functions are used in Flow Sink + * The `tinfl_decompress_mem_*` functions are used in flow sink. */ -class TinflDecompressMem extends Function { +class TinflDecompressMem extends DecompressionFunction { TinflDecompressMem() { this.hasGlobalName([ "tinfl_decompress_mem_to_callback", "tinfl_decompress_mem_to_mem", "tinfl_decompress_mem_to_heap" ]) } + + override int getArchiveParameterIndex() { result = 0 } } /** - * The `tinfl_decompress_*` functions are used in Flow Sink + * The `tinfl_decompress_*` functions are used in flow sink. */ -class TinflDecompress extends Function { +class TinflDecompress extends DecompressionFunction { TinflDecompress() { this.hasGlobalName(["tinfl_decompress"]) } + + override int getArchiveParameterIndex() { result = 1 } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll index 7d2280166e0..4bfa9a13b2c 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll @@ -5,61 +5,36 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources +import DecompressionBomb /** - * The `mz_zip_reader_create` function as a Flow source - * create a `mz_zip_reader` instance - */ -class Mz_zip_reader_create extends Function { - Mz_zip_reader_create() { this.hasGlobalName("mz_zip_reader_create") } -} - -/** - * The `mz_zip_create` function as a Flow source - * create a `mz_zip` instance - */ -class Mz_zip_create extends Function { - Mz_zip_create() { this.hasGlobalName("mz_zip_create") } -} - -/** - * The `mz_zip_entry` function is used in Flow source + * The `mz_zip_entry` function is used in flow source. * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md) */ -class Mz_zip_entry extends Function { +class Mz_zip_entry extends DecompressionFunction { Mz_zip_entry() { this.hasGlobalName("mz_zip_entry_read") } + + override int getArchiveParameterIndex() { result = 1 } } /** - * The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in Flow source + * The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in flow source. * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md) */ -class Mz_zip_reader_entry extends Function { +class Mz_zip_reader_entry extends DecompressionFunction { Mz_zip_reader_entry() { this.hasGlobalName([ "mz_zip_reader_entry_save", "mz_zip_reader_entry_read", "mz_zip_reader_entry_save_process", "mz_zip_reader_entry_save_file", "mz_zip_reader_entry_save_buffer", "mz_zip_reader_save_all" ]) } + + override int getArchiveParameterIndex() { result = 1 } } /** - * A `unzFile` Variable as a Flow source - */ -class UnzFileVar extends VariableAccess { - UnzFileVar() { this.getType().hasName("unzFile") } -} - -/** - * The `UnzOpen` function as a Flow source + * The `UnzOpen` function as a flow source. */ class UnzOpenFunction extends Function { UnzOpenFunction() { this.hasGlobalName(["UnzOpen", "unzOpen64", "unzOpen2", "unzOpen2_64"]) } } - -/** - * The `unzReadCurrentFile` function is used in Flow sink - */ -class UnzReadCurrentFileFunction extends Function { - UnzReadCurrentFileFunction() { this.hasGlobalName(["unzReadCurrentFile"]) } -} diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/XZ.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/XZ.qll index 621558e07fd..a0b17388b93 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/XZ.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/XZ.qll @@ -5,25 +5,22 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources +import DecompressionBomb /** - * A `lzma_stream` Variable as a Flow source + * The `lzma_code` function is used in flow sink. */ -class LzmaStreamVar extends VariableAccess { - LzmaStreamVar() { this.getType().hasName("lzma_stream") } -} - - -/** - * The `lzma_code` function is used in Flow sink - */ -class LzmaCodeFunction extends Function { +class LzmaCodeFunction extends DecompressionFunction { LzmaCodeFunction() { this.hasGlobalName(["lzma_code"]) } + + override int getArchiveParameterIndex() { result = 0 } } /** - * The `lzma_stream_buffer_decode` function is used in Flow sink + * The `lzma_stream_buffer_decode` function is used in flow sink. */ -class LzmaStreamBufferDecodeFunction extends Function { +class LzmaStreamBufferDecodeFunction extends DecompressionFunction { LzmaStreamBufferDecodeFunction() { this.hasGlobalName(["lzma_stream_buffer_decode"]) } + + override int getArchiveParameterIndex() { result = 1 } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZSTD.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZSTD.qll index 902903efb78..c34170df625 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZSTD.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZSTD.qll @@ -6,52 +6,49 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources import semmle.code.cpp.commons.File +import DecompressionBomb /** - * A ZSTD_inBuffer Variable as a Flow source + * The `ZSTD_decompress` function is used in flow sink. */ -class ZSTDinBufferVar extends VariableAccess { - ZSTDinBufferVar() { this.getType().hasName("ZSTD_inBuffer") } -} - -/** - * A ZSTD_inBuffer_s Variable as a Flow source - */ -class ZSTDinBufferSVar extends VariableAccess { - ZSTDinBufferSVar() { this.getType().hasName("ZSTD_inBuffer_s") } -} - -/** - * The `ZSTD_decompress` function is used in Flow sink - */ -class ZSTDDecompressFunction extends Function { +class ZSTDDecompressFunction extends DecompressionFunction { ZSTDDecompressFunction() { this.hasGlobalName(["ZSTD_decompress"]) } + + override int getArchiveParameterIndex() { result = 2 } } /** - * The `ZSTD_decompressDCtx` function is used in Flow sink + * The `ZSTD_decompressDCtx` function is used in flow sink. */ -class ZSTDDecompressDCtxFunction extends Function { +class ZSTDDecompressDCtxFunction extends DecompressionFunction { ZSTDDecompressDCtxFunction() { this.hasGlobalName(["ZSTD_decompressDCtx"]) } + + override int getArchiveParameterIndex() { result = 3 } } /** - * The `ZSTD_decompressStream` function is used in Flow sink + * The `ZSTD_decompressStream` function is used in flow sink. */ -class ZSTDDecompressStreamFunction extends Function { +class ZSTDDecompressStreamFunction extends DecompressionFunction { ZSTDDecompressStreamFunction() { this.hasGlobalName(["ZSTD_decompressStream"]) } + + override int getArchiveParameterIndex() { result = 2 } } /** - * The `ZSTD_decompress_usingDDict` function is used in Flow sink + * The `ZSTD_decompress_usingDDict` function is used in flow sink. */ -class ZSTDDecompressUsingDictFunction extends Function { +class ZSTDDecompressUsingDictFunction extends DecompressionFunction { ZSTDDecompressUsingDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) } + + override int getArchiveParameterIndex() { result = 3 } } /** - * The `ZSTD_decompress_usingDDict` function is used in Flow sink + * The `ZSTD_decompress_usingDDict` function is used in flow sink. */ -class ZSTDDecompressUsingDDictFunction extends Function { +class ZSTDDecompressUsingDDictFunction extends DecompressionFunction { ZSTDDecompressUsingDDictFunction() { this.hasGlobalName(["ZSTD_decompress_usingDDict"]) } + + override int getArchiveParameterIndex() { result = 3 } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll index 306130ac8f2..df2381220fd 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll @@ -5,25 +5,43 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources +import DecompressionBomb /** - * A `gzFile` Variable as a Flow source - */ -class GzFileVar extends VariableAccess { - GzFileVar() { this.getType().hasName("gzFile") } -} - -/** - * The `gzopen` function as a Flow source + * The `gzfread` function is used in flow sink. * - * `gzopen(const char *path, const char *mode)` + * `gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file)` */ -class GzopenFunction extends Function { - GzopenFunction() { this.hasGlobalName("gzopen") } +class GzFreadFunction extends DecompressionFunction { + GzFreadFunction() { this.hasGlobalName("gzfread") } + + override int getArchiveParameterIndex() { result = 3 } } /** - * The `gzdopen` function as a Flow source + * The `gzgets` function is used in flow sink. + * + * `gzgets(gzFile file, char *buf, int len)` + */ +class GzGetsFunction extends DecompressionFunction { + GzGetsFunction() { this.hasGlobalName("gzgets") } + + override int getArchiveParameterIndex() { result = 0 } +} + +/** + * The `gzread` function is used in flow sink. + * + * `gzread(gzFile file, voidp buf, unsigned len)` + */ +class GzReadFunction extends DecompressionFunction { + GzReadFunction() { this.hasGlobalName("gzread") } + + override int getArchiveParameterIndex() { result = 1 } +} + +/** + * The `gzdopen` function. * * `gzdopen(int fd, const char *mode)` */ @@ -32,44 +50,10 @@ class GzdopenFunction extends Function { } /** - * The `gzfread` function is used in Flow sink + * The `gzopen` function. * - * `gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file)` + * `gzopen(const char *path, const char *mode)` */ -class GzFreadFunction extends Function { - GzFreadFunction() { this.hasGlobalName("gzfread") } -} - -/** - * The `gzgets` function is used in Flow sink. - * - * `gzgets(gzFile file, char *buf, int len)` - */ -class GzGetsFunction extends Function { - GzGetsFunction() { this.hasGlobalName("gzgets") } -} - -/** - * The `gzread` function is used in Flow sink - * - * `gzread(gzFile file, voidp buf, unsigned len)` - */ -class GzReadFunction extends Function { - GzReadFunction() { this.hasGlobalName("gzread") } -} - -predicate isSource(DataFlow::Node source) { - exists(FunctionCall fc | fc.getTarget() instanceof GzopenFunction | - fc.getArgument(0) = source.asExpr() and - // arg 0 can be a path string whichwe must do following check - not fc.getArgument(0).isConstant() - ) - or - // IDK whether it is good to use all file decriptors function returns as source or not - // because we can do more sanitization from fd function sources - exists(FunctionCall fc | fc.getTarget() instanceof GzdopenFunction | - fc.getArgument(0) = source.asExpr() - ) - or - source.asExpr() instanceof GzFileVar +class GzopenFunction extends Function { + GzopenFunction() { this.hasGlobalName("gzopen") } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll index b67caecfcbd..1897b8e09d3 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll @@ -5,21 +5,17 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources +import DecompressionBomb /** - * A `z_stream` Variable as a Flow source - */ -class ZStreamVar extends VariableAccess { - ZStreamVar() { this.getType().hasName("z_stream") } -} - -/** - * The `inflate`/`inflateSync` functions are used in Flow sink + * The `inflate` and `inflateSync` functions are used in flow sink. * * `inflate(z_streamp strm, int flush)` * * `inflateSync(z_streamp strm)` */ -class InflateFunction extends Function { +class InflateFunction extends DecompressionFunction { InflateFunction() { this.hasGlobalName(["inflate", "inflateSync"]) } + + override int getArchiveParameterIndex() { result = 0 } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibUncompress.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibUncompress.qll index 1f33b065409..f69c71ec01c 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibUncompress.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibUncompress.qll @@ -5,17 +5,13 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources +import DecompressionBomb /** - * A Bytef Variable as a Flow source + * The `uncompress`/`uncompress2` function is used in flow sink. */ -class BytefVar extends VariableAccess { - BytefVar() { this.getType().hasName("Bytef") } -} - -/** - * The `uncompress`/`uncompress2` function is used in Flow sink - */ -class UncompressFunction extends Function { +class UncompressFunction extends DecompressionFunction { UncompressFunction() { this.hasGlobalName(["uncompress", "uncompress2"]) } + + override int getArchiveParameterIndex() { result = 0 } } From 361ad6be6a663c04c4d6c6b5777129fc194c5be2 Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:45:31 +0200 Subject: [PATCH 018/404] use abstract class for decompression flow steps --- .../CWE/CWE-409/DecompressionBomb.qll | 10 ++++- .../CWE/CWE-409/DecompressionBombs.ql | 22 +--------- .../Security/CWE/CWE-409/MiniZip.qll | 41 ++++++++++++++++++- .../Security/CWE/CWE-409/ZlibGzopen.qll | 22 ++++++++-- 4 files changed, 67 insertions(+), 28 deletions(-) diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll index 2cca1453d2f..ecc32a9ba0d 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll @@ -1,8 +1,16 @@ import cpp +import semmle.code.cpp.ir.dataflow.TaintTracking /** - * The Decompression Sink instances, extend this class to defind new decompression sinks. + * The Decompression Sink instances, extend this class to define new decompression sinks. */ abstract class DecompressionFunction extends Function { abstract int getArchiveParameterIndex(); } + +/** + * The Decompression Flow Steps, extend this class to define new decompression sinks. + */ +abstract class DecompressionFlowStep extends Function { + abstract predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2); +} diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql index b7eda35f2c7..6f68390fdd2 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql @@ -29,27 +29,7 @@ module DecompressionTaintConfig implements DataFlow::ConfigSig { } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) - ) - or - exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc.getArgument(1) - ) - or - exists(FunctionCall fc | - fc.getTarget() instanceof GzopenFunction or fc.getTarget() instanceof GzdopenFunction - | - node1.asExpr() = fc.getArgument(0) and - node2.asExpr() = fc - ) + any(DecompressionFlowStep f).isAdditionalFlowStep(node1, node2) } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll index 4bfa9a13b2c..a76abff8f6a 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/MiniZip.qll @@ -8,7 +8,7 @@ import semmle.code.cpp.security.FlowSources import DecompressionBomb /** - * The `mz_zip_entry` function is used in flow source. + * The `mz_zip_entry` function is used in flow sink. * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md) */ class Mz_zip_entry extends DecompressionFunction { @@ -17,6 +17,21 @@ class Mz_zip_entry extends DecompressionFunction { override int getArchiveParameterIndex() { result = 1 } } +/** + * The `mz_zip_entry` function is used in flow steps. + * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md) + */ +class Mz_zip_entry_flow_steps extends DecompressionFlowStep { + Mz_zip_entry_flow_steps() { this.hasGlobalName("mz_zip_entry_read") } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall fc | fc.getTarget() = this | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) + ) + } +} + /** * The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in flow source. * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md) @@ -32,9 +47,31 @@ class Mz_zip_reader_entry extends DecompressionFunction { override int getArchiveParameterIndex() { result = 1 } } +/** + * The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in flow steps. + * [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md) + */ +class Mz_zip_reader_entry_flow_steps extends DecompressionFlowStep { + Mz_zip_reader_entry_flow_steps() { this instanceof Mz_zip_reader_entry } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall fc | fc.getTarget() = this | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc.getArgument(1) + ) + } +} + /** * The `UnzOpen` function as a flow source. */ -class UnzOpenFunction extends Function { +class UnzOpenFunction extends DecompressionFlowStep { UnzOpenFunction() { this.hasGlobalName(["UnzOpen", "unzOpen64", "unzOpen2", "unzOpen2_64"]) } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall fc | fc.getTarget() = this | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc + ) + } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll index df2381220fd..5c4f367b1b4 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll @@ -41,19 +41,33 @@ class GzReadFunction extends DecompressionFunction { } /** - * The `gzdopen` function. + * The `gzdopen` function is used in flow steps. * * `gzdopen(int fd, const char *mode)` */ -class GzdopenFunction extends Function { +class GzdopenFunction extends DecompressionFlowStep { GzdopenFunction() { this.hasGlobalName("gzdopen") } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall fc | fc.getTarget() = this | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc + ) + } } /** - * The `gzopen` function. + * The `gzopen` function is used in flow steps. * * `gzopen(const char *path, const char *mode)` */ -class GzopenFunction extends Function { +class GzopenFunction extends DecompressionFlowStep { GzopenFunction() { this.hasGlobalName("gzopen") } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall fc | fc.getTarget() = this | + node1.asExpr() = fc.getArgument(0) and + node2.asExpr() = fc + ) + } } From 87b6495c917efe78751cc80cf9bb7a353c4a82bf Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Sun, 14 Jul 2024 21:10:56 +0200 Subject: [PATCH 019/404] add zlib tests with stubs :) --- .../CWE/CWE-409/DecompressionBombs.qlref | 1 + .../Security/CWE/CWE-409/zlibTest.cpp | 182 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.qlref create mode 100644 cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.qlref new file mode 100644 index 00000000000..b3f71c4891a --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.qlref @@ -0,0 +1 @@ +experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql \ No newline at end of file diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp new file mode 100644 index 00000000000..c55e18475fe --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp @@ -0,0 +1,182 @@ + +#define Z_NULL 0 +# define FAR +typedef unsigned char Byte; +typedef Byte FAR Bytef; +typedef unsigned int uInt; +#define Z_BEST_COMPRESSION 9 +#define Z_FINISH 4 +#define Z_NO_FLUSH 0 + + +typedef struct { + int *zalloc; + int *zfree; + Bytef *next_in; + Bytef *next_out; + int *opaque; + uInt avail_out; + uInt avail_in; +} z_stream; + + +void deflateInit(z_stream *defstream, int i); + +void deflate(z_stream *defstream, int i); + +void deflateEnd(z_stream *defstream); + +void inflateInit(z_stream *infstream); + +void inflate(z_stream *infstream, int i); + +void inflateEnd(z_stream *infstream); + +namespace std { + template + struct char_traits; + + template > + class basic_ostream { + public: + typedef charT char_type; + }; + + template + basic_ostream &operator<<(basic_ostream &, const charT *); + + typedef basic_ostream ostream; + + extern ostream cout; +} + +int UnsafeInflate(int argc, char *argv[]) { + // original string len = 36 + char a[50] = "Hello Hello Hello Hello Hello Hello!"; + // placeholder for the compressed (deflated) version of "a" + char b[50]; + // placeholder for the Uncompressed (inflated) version of "b" + char c[50]; + + + // STEP 1. + // zlib struct + z_stream defstream; + defstream.zalloc = Z_NULL; + defstream.zfree = Z_NULL; + defstream.opaque = Z_NULL; + // setup "a" as the input and "b" as the compressed output + defstream.avail_in = (uInt) 50 + 1; // size of input, string + terminator + defstream.next_in = (Bytef *) a; // input char array + defstream.avail_out = (uInt) sizeof(b); // size of output + defstream.next_out = (Bytef *) b; // output char array + + // the actual compression work. + deflateInit(&defstream, Z_BEST_COMPRESSION); + deflate(&defstream, Z_FINISH); + deflateEnd(&defstream); + + // This is one way of getting the size of the output + // STEP 2. + // inflate b into c + // zlib struct + z_stream infstream; + infstream.zalloc = Z_NULL; + infstream.zfree = Z_NULL; + infstream.opaque = Z_NULL; + // setup "b" as the input and "c" as the compressed output + // TOTHINK: Here we can add additional step from Right operand to z_stream variable access + infstream.avail_in = (uInt) ((char *) defstream.next_out - b); // size of input + infstream.next_in = (Bytef *) b; // input char array + infstream.avail_out = (uInt) sizeof(c); // size of output + infstream.next_out = (Bytef *) c; // output char array + + // uLong total_out; /* total number of bytes output so far */ + // the actual DE-compression work. + inflateInit(&infstream); + inflate(&infstream, Z_NO_FLUSH); + inflateEnd(&infstream); + + + return 0; +} + + +typedef struct { +} gzFile; + +gzFile gzopen(char *str, const char *rb); + + +void exit(int i); + +unsigned int gzread(gzFile gz_file, unsigned char *str, int i); + +void gzclose(gzFile gz_file); + +std::ostream operator<<(const std::ostream &lhs, unsigned char rhs); + + +int send(int, const void *, int, int); + + +int UnsafeGzread(char **argv) { + char *fileName; + send(0, fileName, 0, 0); + gzFile inFileZ = gzopen(fileName, "rb"); + if (&inFileZ == nullptr) { + exit(0); + } + unsigned char unzipBuffer[8192]; + unsigned int unzippedBytes; + while (true) { + unzippedBytes = gzread(inFileZ, unzipBuffer, 8192); + if (unzippedBytes > 0) { + std::cout << unzippedBytes; + } else { + break; + } + } + gzclose(inFileZ); + return 0; +} + +bool gzfread(char *str, int i, int i1, gzFile gz_file); + +int UnsafeGzfread(char **argv) { + char *fileName; + send(0, fileName, 0, 0); + gzFile inFileZ = gzopen(fileName, "rb"); + if (&inFileZ == nullptr) { + exit(0); + } + while (true) { + char buffer[1000]; + if (!gzfread(buffer, 999, 1, inFileZ)) { + break; + } + } + gzclose(inFileZ); + return 0; +} + +char *gzgets(gzFile gz_file, char *buffer, int i); + +int UnsafeGzgets(char **argv) { + char *fileName; + send(0, fileName, 0, 0); + gzFile inFileZ = gzopen(fileName, "rb"); + if (&inFileZ == nullptr) { + exit(0); + } + char *buffer = new char[4000000000]; + char *result; + result = gzgets(inFileZ, buffer, 1000000000); + while (true) { + result = gzgets(inFileZ, buffer, 1000000000); + if (result == nullptr) { + break; + } + } + return 0; +} From a10b5021b4b70cbc8e86817539568cd757b4132b Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Mon, 15 Jul 2024 10:13:57 +0200 Subject: [PATCH 020/404] fix tests, it is not fixed 100% --- .../CWE/CWE-409/DecompressionBomb.qll | 10 +++++++ .../CWE/CWE-409/DecompressionBombs.ql | 2 -- .../Security/CWE/CWE-409/zlibTest.cpp | 27 ++++++++----------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll index ecc32a9ba0d..c17616d020d 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBomb.qll @@ -1,5 +1,15 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking +import MiniZip +import ZlibGzopen +import ZlibInflator +import ZlibUncompress +import LibArchive +import LibMiniz +import XZ +import ZSTD +import Bzip2 +import Brotli /** * The Decompression Sink instances, extend this class to define new decompression sinks. diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql index 6f68390fdd2..896c15f7a80 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql @@ -15,8 +15,6 @@ import cpp import semmle.code.cpp.ir.dataflow.TaintTracking import semmle.code.cpp.security.FlowSources import semmle.code.cpp.commons.File -import MiniZip -import ZlibGzopen import DecompressionBomb module DecompressionTaintConfig implements DataFlow::ConfigSig { diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp index c55e18475fe..b829cfaa61d 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp @@ -50,15 +50,12 @@ namespace std { extern ostream cout; } -int UnsafeInflate(int argc, char *argv[]) { - // original string len = 36 - char a[50] = "Hello Hello Hello Hello Hello Hello!"; +int UnsafeInflate(char *a) { // placeholder for the compressed (deflated) version of "a" char b[50]; // placeholder for the Uncompressed (inflated) version of "b" char c[50]; - // STEP 1. // zlib struct z_stream defstream; @@ -117,12 +114,7 @@ void gzclose(gzFile gz_file); std::ostream operator<<(const std::ostream &lhs, unsigned char rhs); -int send(int, const void *, int, int); - - -int UnsafeGzread(char **argv) { - char *fileName; - send(0, fileName, 0, 0); +int UnsafeGzread(char *fileName) { gzFile inFileZ = gzopen(fileName, "rb"); if (&inFileZ == nullptr) { exit(0); @@ -143,9 +135,7 @@ int UnsafeGzread(char **argv) { bool gzfread(char *str, int i, int i1, gzFile gz_file); -int UnsafeGzfread(char **argv) { - char *fileName; - send(0, fileName, 0, 0); +int UnsafeGzfread(char *fileName) { gzFile inFileZ = gzopen(fileName, "rb"); if (&inFileZ == nullptr) { exit(0); @@ -162,9 +152,7 @@ int UnsafeGzfread(char **argv) { char *gzgets(gzFile gz_file, char *buffer, int i); -int UnsafeGzgets(char **argv) { - char *fileName; - send(0, fileName, 0, 0); +int UnsafeGzgets(char *fileName) { gzFile inFileZ = gzopen(fileName, "rb"); if (&inFileZ == nullptr) { exit(0); @@ -180,3 +168,10 @@ int UnsafeGzgets(char **argv) { } return 0; } + +int main(int argc, char **argv) { + UnsafeGzfread(argv[2]); + UnsafeGzgets(argv[2]); + UnsafeInflate(argv[2]); + UnsafeGzread(argv[2]); +} From f97b1039cd3a1f19d18ef1a775dbd66eef08bb19 Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Tue, 30 Jul 2024 17:49:34 +0200 Subject: [PATCH 021/404] update test files, add one more additional flow step for inflate function, fix gzopen additional flow step thanks to @jketema --- .../CWE/CWE-409/DecompressionBombs.ql | 5 +-- .../Security/CWE/CWE-409/ZlibGzopen.qll | 4 +-- .../Security/CWE/CWE-409/ZlibInflator.qll | 19 +++++++++-- .../Security/CWE/CWE-409/zlibTest.cpp | 32 +++---------------- 4 files changed, 26 insertions(+), 34 deletions(-) diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql index 896c15f7a80..05f39c47e13 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql @@ -22,12 +22,13 @@ module DecompressionTaintConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { exists(FunctionCall fc, DecompressionFunction f | fc.getTarget() = f | - fc.getArgument(f.getArchiveParameterIndex()) = sink.asExpr() + fc.getArgument(f.getArchiveParameterIndex()) = sink.asExpr() ) } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - any(DecompressionFlowStep f).isAdditionalFlowStep(node1, node2) + any(DecompressionFlowStep f).isAdditionalFlowStep(node1, node2) or + nextInAdditionalFlowStep(node1, node2) } } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll index 5c4f367b1b4..edb8ef7ff68 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll @@ -37,7 +37,7 @@ class GzGetsFunction extends DecompressionFunction { class GzReadFunction extends DecompressionFunction { GzReadFunction() { this.hasGlobalName("gzread") } - override int getArchiveParameterIndex() { result = 1 } + override int getArchiveParameterIndex() { result = 0 } } /** @@ -66,7 +66,7 @@ class GzopenFunction extends DecompressionFlowStep { override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall fc | fc.getTarget() = this | - node1.asExpr() = fc.getArgument(0) and + node1.asIndirectExpr() = fc.getArgument(0) and node2.asExpr() = fc ) } diff --git a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll index 1897b8e09d3..464dce3ac45 100644 --- a/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll +++ b/cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll @@ -10,12 +10,27 @@ import DecompressionBomb /** * The `inflate` and `inflateSync` functions are used in flow sink. * - * `inflate(z_streamp strm, int flush)` + * `inflate(z_stream strm, int flush)` * - * `inflateSync(z_streamp strm)` + * `inflateSync(z_stream strm)` */ class InflateFunction extends DecompressionFunction { InflateFunction() { this.hasGlobalName(["inflate", "inflateSync"]) } override int getArchiveParameterIndex() { result = 0 } } + +/** + * The `next_in` member of a `z_stream` variable is used in flow steps. + */ +predicate nextInAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(Variable nextInVar, VariableAccess zStreamAccess | + nextInVar.getDeclaringType().hasName("z_stream") and + nextInVar.hasName("next_in") and + zStreamAccess.getType().hasName("z_stream") + | + nextInVar.getAnAccess().getQualifier().(VariableAccess).getTarget() = zStreamAccess.getTarget() and + node1.asIndirectExpr() = nextInVar.getAnAssignedValue() and + node2.asExpr() = zStreamAccess + ) +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp index b829cfaa61d..07805f6c83f 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp @@ -51,40 +51,17 @@ namespace std { } int UnsafeInflate(char *a) { - // placeholder for the compressed (deflated) version of "a" - char b[50]; - // placeholder for the Uncompressed (inflated) version of "b" - char c[50]; + // placeholder for the Uncompressed (inflated) version of "a" + char c[1024000]; - // STEP 1. - // zlib struct - z_stream defstream; - defstream.zalloc = Z_NULL; - defstream.zfree = Z_NULL; - defstream.opaque = Z_NULL; - // setup "a" as the input and "b" as the compressed output - defstream.avail_in = (uInt) 50 + 1; // size of input, string + terminator - defstream.next_in = (Bytef *) a; // input char array - defstream.avail_out = (uInt) sizeof(b); // size of output - defstream.next_out = (Bytef *) b; // output char array - - // the actual compression work. - deflateInit(&defstream, Z_BEST_COMPRESSION); - deflate(&defstream, Z_FINISH); - deflateEnd(&defstream); - - // This is one way of getting the size of the output - // STEP 2. - // inflate b into c - // zlib struct z_stream infstream; infstream.zalloc = Z_NULL; infstream.zfree = Z_NULL; infstream.opaque = Z_NULL; // setup "b" as the input and "c" as the compressed output // TOTHINK: Here we can add additional step from Right operand to z_stream variable access - infstream.avail_in = (uInt) ((char *) defstream.next_out - b); // size of input - infstream.next_in = (Bytef *) b; // input char array + infstream.avail_in = (uInt) (1000); // size of input + infstream.next_in = (Bytef *) a; // input char array infstream.avail_out = (uInt) sizeof(c); // size of output infstream.next_out = (Bytef *) c; // output char array @@ -159,7 +136,6 @@ int UnsafeGzgets(char *fileName) { } char *buffer = new char[4000000000]; char *result; - result = gzgets(inFileZ, buffer, 1000000000); while (true) { result = gzgets(inFileZ, buffer, 1000000000); if (result == nullptr) { From be0a60a7f65f7de42062a617b1566768bb9ed398 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Tue, 13 Aug 2024 14:45:03 +0200 Subject: [PATCH 022/404] Add support for importing NPM modules in XSJS sources --- javascript/ql/lib/semmle/javascript/NodeJS.qll | 9 +++++++++ .../Security/CWE-326/InsufficientKeySize.expected | 1 + javascript/ql/test/query-tests/Security/CWE-326/tst.xsjs | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 javascript/ql/test/query-tests/Security/CWE-326/tst.xsjs diff --git a/javascript/ql/lib/semmle/javascript/NodeJS.qll b/javascript/ql/lib/semmle/javascript/NodeJS.qll index 221cee084b6..823ddae93c4 100644 --- a/javascript/ql/lib/semmle/javascript/NodeJS.qll +++ b/javascript/ql/lib/semmle/javascript/NodeJS.qll @@ -295,6 +295,15 @@ private predicate isRequire(DataFlow::Node nd) { isCreateRequire(call.getCallee().flow()) and nd = call.flow() ) + or + // `$.require('underscore');`. + // NPM as supported in [XSJS files](https://www.npmjs.com/package/@sap/async-xsjs#npm-packages-support). + exists(MethodCallExpr require | + nd.getFile().getExtension() = ["xsjs", "xsjslib"] and + require.getCalleeName() = "require" and + require.getReceiver().(GlobalVarAccess).getName() = "$" and + nd = require.getCallee().flow() + ) } /** diff --git a/javascript/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.expected b/javascript/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.expected index 95bb8d45832..323e5b24875 100644 --- a/javascript/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.expected +++ b/javascript/ql/test/query-tests/Security/CWE-326/InsufficientKeySize.expected @@ -9,3 +9,4 @@ | tst.js:35:13:35:43 | crypto. ... an(512) | Creation of an asymmetric key uses 512 bits, which is below 2048 and considered breakable. | | tst.js:39:13:39:33 | new Nod ... : 512}) | Creation of an asymmetric RSA key uses 512 bits, which is below 2048 and considered breakable. | | tst.js:43:1:43:31 | key.gen ... 65537) | Creation of an asymmetric RSA key uses 512 bits, which is below 2048 and considered breakable. | +| tst.xsjs:3:14:3:71 | crypto. ... 1024 }) | Creation of an asymmetric RSA key uses 1024 bits, which is below 2048 and considered breakable. | diff --git a/javascript/ql/test/query-tests/Security/CWE-326/tst.xsjs b/javascript/ql/test/query-tests/Security/CWE-326/tst.xsjs new file mode 100644 index 00000000000..d5e5051af66 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-326/tst.xsjs @@ -0,0 +1,5 @@ +const crypto = $.require("crypto"); + +const bad1 = crypto.generateKeyPairSync("rsa", { modulusLength: 1024 }); // NOT OK + +const good1 = crypto.generateKeyPairSync("rsa", { modulusLength: 4096 }); // OK From f6ec56a977ede420d4be1bc041ad72b8abf4fc31 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 13 Aug 2024 09:16:36 +0200 Subject: [PATCH 023/404] C#: Implement `ContentSet` --- .../dataflow/internal/DataFlowPrivate.qll | 186 ++++++++++-------- .../dataflow/internal/DataFlowPublic.qll | 72 ++++++- .../dataflow/internal/FlowSummaryImpl.qll | 49 +++-- .../internal/TaintTrackingPrivate.qll | 12 +- .../csharp/frameworks/EntityFramework.qll | 42 ++-- .../modelgenerator/internal/CaptureModels.qll | 18 +- .../internal/CaptureModelsSpecific.qll | 25 ++- .../dataflow/external-models/steps.ql | 4 +- 8 files changed, 267 insertions(+), 141 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index f1c51f222d5..fd31d2a3a38 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -908,19 +908,20 @@ private class Argument extends Expr { * * `postUpdate` indicates whether the store targets a post-update node. */ -private predicate fieldOrPropertyStore(Expr e, Content c, Expr src, Expr q, boolean postUpdate) { +private predicate fieldOrPropertyStore(Expr e, ContentSet c, Expr src, Expr q, boolean postUpdate) { exists(FieldOrProperty f | - c = f.getContent() and + c = f.getContentSet() and ( f.isFieldLike() and f instanceof InstanceFieldOrProperty or exists( FlowSummaryImpl::Private::SummarizedCallableImpl sc, - FlowSummaryImpl::Private::SummaryComponentStack input + FlowSummaryImpl::Private::SummaryComponentStack input, ContentSet readSet | sc.propagatesFlow(input, _, _, _) and - input.contains(FlowSummaryImpl::Private::SummaryComponent::content(f.getContent())) + input.contains(FlowSummaryImpl::Private::SummaryComponent::content(readSet)) and + c.getAStoreContent() = readSet.getAReadContent() ) ) | @@ -970,28 +971,13 @@ private predicate fieldOrPropertyStore(Expr e, Content c, Expr src, Expr q, bool ) } -/** Holds if property `p1` overrides or implements source declaration property `p2`. */ -private predicate overridesOrImplementsSourceDecl(Property p1, Property p2) { - p1.getOverridee*().getUnboundDeclaration() = p2 - or - p1.getAnUltimateImplementee().getUnboundDeclaration() = p2 -} - /** * Holds if `e2` is an expression that reads field or property `c` from - * expression `e1`. This takes overriding into account for properties written - * from library code. + * expression `e1`. */ -private predicate fieldOrPropertyRead(Expr e1, Content c, FieldOrPropertyRead e2) { +private predicate fieldOrPropertyRead(Expr e1, ContentSet c, FieldOrPropertyRead e2) { e1 = e2.getQualifier() and - exists(FieldOrProperty ret | c = ret.getContent() | - ret = e2.getTarget() - or - exists(Property target | - target.getGetter() = e2.(PropertyCall).getARuntimeTarget() and - overridesOrImplementsSourceDecl(target, ret) - ) - ) + c = e2.getTarget().(FieldOrProperty).getContentSet() } /** @@ -1208,6 +1194,11 @@ private module Cached { } or TCapturedVariableContent(VariableCapture::CapturedVariable v) + cached + newtype TContentSet = + TSingletonContent(Content c) { not c instanceof PropertyContent } or + TPropertyContentSet(Property p) { p.isUnboundDeclaration() } + cached newtype TContentApprox = TFieldApproxContent(string firstChar) { firstChar = approximateFieldContent(_) } or @@ -2076,10 +2067,10 @@ class FieldOrProperty extends Assignable, Modifiable { } /** Gets the content that matches this field or property. */ - Content getContent() { - result.(FieldContent).getField() = this.getUnboundDeclaration() + ContentSet getContentSet() { + result.isField(this.getUnboundDeclaration()) or - result.(PropertyContent).getProperty() = this.getUnboundDeclaration() + result.isProperty(this.getUnboundDeclaration()) } } @@ -2209,8 +2200,8 @@ private class StoreStepConfiguration extends ControlFlowReachabilityConfiguratio } pragma[nomagic] -private PropertyContent getResultContent() { - result.getProperty() = any(SystemThreadingTasksTaskTClass c_).getResultProperty() +private ContentSet getResultContent() { + result.isProperty(any(SystemThreadingTasksTaskTClass c_).getResultProperty()) } private predicate primaryConstructorParameterStore( @@ -2224,17 +2215,16 @@ private predicate primaryConstructorParameterStore( ) } -/** - * Holds if data can flow from `node1` to `node2` via an assignment to - * content `c`. - */ -predicate storeStep(Node node1, ContentSet c, Node node2) { +pragma[nomagic] +private predicate recordParameter(RecordType t, Parameter p, string name) { + p.getName() = name and p.getCallable().getDeclaringType() = t +} + +private predicate storeContentStep(Node node1, Content c, Node node2) { exists(StoreStepConfiguration x, ExprNode node, boolean postUpdate | hasNodePath(x, node1, node) and if postUpdate = true then node = node2.(PostUpdateNode).getPreUpdateNode() else node = node2 | - fieldOrPropertyStore(_, c, node1.asExpr(), node.getExpr(), postUpdate) - or arrayStore(_, node1.asExpr(), node.getExpr(), postUpdate) and c instanceof ElementContent ) or @@ -2255,26 +2245,59 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { c instanceof ElementContent ) or + primaryConstructorParameterStore(node1, c, node2) + or + exists(Parameter p, DataFlowCallable callable | + node1 = TExplicitParameterNode(p, callable) and + node2 = TPrimaryConstructorThisAccessNode(p, true, callable) and + not recordParameter(_, p, _) and + c.(PrimaryConstructorParameterContent).getParameter() = p + ) + or + VariableCapture::storeStep(node1, c, node2) +} + +pragma[nomagic] +private predicate recordProperty(RecordType t, ContentSet c, string name) { + exists(Property p | + c.isProperty(p) and + p.getName() = name and + p.getDeclaringType() = t + ) +} + +/** + * Holds if data can flow from `node1` to `node2` via an assignment to + * content `c`. + */ +predicate storeStep(Node node1, ContentSet c, Node node2) { + exists(Content cont | + storeContentStep(node1, cont, node2) and + c.isSingleton(cont) + ) + or + exists(StoreStepConfiguration x, ExprNode node, boolean postUpdate | + hasNodePath(x, node1, node) and + if postUpdate = true then node = node2.(PostUpdateNode).getPreUpdateNode() else node = node2 + | + fieldOrPropertyStore(_, c, node1.asExpr(), node.getExpr(), postUpdate) + ) + or exists(Expr e | e = node1.asExpr() and node2.(AsyncReturnNode).getExpr() = e and c = getResultContent() ) or - primaryConstructorParameterStore(node1, c, node2) - or - exists(Parameter p, DataFlowCallable callable | + exists(Parameter p, DataFlowCallable callable, RecordType t, string name | node1 = TExplicitParameterNode(p, callable) and node2 = TPrimaryConstructorThisAccessNode(p, true, callable) and - if p.getCallable().getDeclaringType() instanceof RecordType - then c.(PropertyContent).getProperty().getName() = p.getName() - else c.(PrimaryConstructorParameterContent).getParameter() = p + recordParameter(t, p, name) and + recordProperty(t, c, name) ) or FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), c, node2.(FlowSummaryNode).getSummaryNode()) - or - VariableCapture::storeStep(node1, c, node2) } private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration { @@ -2342,14 +2365,8 @@ private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration } } -/** - * Holds if data can flow from `node1` to `node2` via a read of content `c`. - */ -predicate readStep(Node node1, ContentSet c, Node node2) { +private predicate readContentStep(Node node1, Content c, Node node2) { exists(ReadStepConfiguration x | - hasNodePath(x, node1, node2) and - fieldOrPropertyRead(node1.asExpr(), c, node2.asExpr()) - or hasNodePath(x, node1, node2) and arrayRead(node1.asExpr(), node2.asExpr()) and c instanceof ElementContent @@ -2361,10 +2378,6 @@ predicate readStep(Node node1, ContentSet c, Node node2) { c instanceof ElementContent ) or - hasNodePath(x, node1, node2) and - node2.asExpr().(AwaitExpr).getExpr() = node1.asExpr() and - c = getResultContent() - or node1 = any(InstanceParameterAccessPreNode n | n.getUnderlyingControlFlowNode() = node2.(ExprNode).getControlFlowNode() and @@ -2402,31 +2415,30 @@ predicate readStep(Node node1, ContentSet c, Node node2) { ) ) or - FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c, - node2.(FlowSummaryNode).getSummaryNode()) - or VariableCapture::readStep(node1, c, node2) } /** - * Holds if values stored inside content `c` are cleared at node `n`. For example, - * any value stored inside `f` is cleared at the pre-update node associated with `x` - * in `x.f = newValue`. + * Holds if data can flow from `node1` to `node2` via a read of content `c`. */ -predicate clearsContent(Node n, ContentSet c) { - fieldOrPropertyStore(_, c, _, n.asExpr(), true) - or - fieldOrPropertyStore(_, c, _, n.(ObjectInitializerNode).getInitializer(), false) - or - FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) - or - exists(WithExpr we, ObjectInitializer oi, FieldOrProperty f | - oi = we.getInitializer() and - n.asExpr() = oi and - f = oi.getAMemberInitializer().getInitializedMember() and - c = f.getContent() +predicate readStep(Node node1, ContentSet c, Node node2) { + exists(Content cont | + readContentStep(node1, cont, node2) and + c.isSingleton(cont) ) or + exists(ReadStepConfiguration x | hasNodePath(x, node1, node2) | + fieldOrPropertyRead(node1.asExpr(), c, node2.asExpr()) + or + node2.asExpr().(AwaitExpr).getExpr() = node1.asExpr() and + c = getResultContent() + ) + or + FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), c, + node2.(FlowSummaryNode).getSummaryNode()) +} + +private predicate clearsCont(Node n, Content c) { exists(Argument a, Struct s, Field f | a = n.(PostUpdateNode).getPreUpdateNode().asExpr() and a.getType() = s and @@ -2440,6 +2452,31 @@ predicate clearsContent(Node n, ContentSet c) { VariableCapture::clearsContent(n, c) } +/** + * Holds if values stored inside content `c` are cleared at node `n`. For example, + * any value stored inside `f` is cleared at the pre-update node associated with `x` + * in `x.f = newValue`. + */ +predicate clearsContent(Node n, ContentSet c) { + exists(Content cont | + clearsCont(n, cont) and + c.isSingleton(cont) + ) + or + fieldOrPropertyStore(_, c, _, n.asExpr(), true) + or + fieldOrPropertyStore(_, c, _, n.(ObjectInitializerNode).getInitializer(), false) + or + FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c) + or + exists(WithExpr we, ObjectInitializer oi, FieldOrProperty f | + oi = we.getInitializer() and + n.asExpr() = oi and + f = oi.getAMemberInitializer().getInitializedMember() and + c = f.getContentSet() + ) +} + /** * Holds if the value that is being tracked is expected to be stored inside content `c` * at node `n`. @@ -2447,7 +2484,7 @@ predicate clearsContent(Node n, ContentSet c) { predicate expectsContent(Node n, ContentSet c) { FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c) or - n.asExpr() instanceof SpreadElementExpr and c instanceof ElementContent + n.asExpr() instanceof SpreadElementExpr and c.isElement() } class NodeRegion instanceof ControlFlow::BasicBlock { @@ -3048,8 +3085,3 @@ abstract class SyntheticField extends string { /** Gets the type of this synthetic field. */ Type getType() { result instanceof ObjectType } } - -/** - * Holds if the the content `c` is a container. - */ -predicate containerContent(DataFlow::Content c) { c instanceof DataFlow::ElementContent } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index 4d1dc25f6e9..84e486c7a55 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -267,22 +267,84 @@ class CapturedVariableContent extends Content, TCapturedVariableContent { override Location getLocation() { result = v.getLocation() } } +/** Holds if property `p1` overrides or implements source declaration property `p2`. */ +private predicate overridesOrImplementsSourceDecl(Property p1, Property p2) { + p1.getOverridee*().getUnboundDeclaration() = p2 + or + p1.getAnUltimateImplementee().getUnboundDeclaration() = p2 +} + /** * An entity that represents a set of `Content`s. * * The set may be interpreted differently depending on whether it is * stored into (`getAStoreContent`) or read from (`getAReadContent`). */ -class ContentSet instanceof Content { +class ContentSet extends TContentSet { + /** Holds if this content set is the singleton `{c}`. */ + predicate isSingleton(Content c) { this = TSingletonContent(c) } + + /** + * Holds if this content set represents the property `p`. + * + * + * For `getAReadContent`, this set represents all properties that may + * (reflexively and transitively) override/implement `p` (or vice versa). + */ + predicate isProperty(Property p) { this = TPropertyContentSet(p) } + + /** Holds if this content set represent the field `f`. */ + predicate isField(Field f) { this.isSingleton(TFieldContent(f)) } + + /** Holds if this content set represents an element in a collection. */ + predicate isElement() { this.isSingleton(TElementContent()) } + /** Gets a content that may be stored into when storing into this set. */ - Content getAStoreContent() { result = this } + Content getAStoreContent() { + this.isSingleton(result) + or + this.isProperty(result.(PropertyContent).getProperty()) + } /** Gets a content that may be read from when reading from this set. */ - Content getAReadContent() { result = this } + Content getAReadContent() { + this.isSingleton(result) + or + exists(Property p1, Property p2 | + this.isProperty(p1) and + p2 = result.(PropertyContent).getProperty() + | + p1 = p2 + or + overridesOrImplementsSourceDecl(p2, p1) + or + overridesOrImplementsSourceDecl(p1, p2) + ) + } /** Gets a textual representation of this content set. */ - string toString() { result = super.toString() } + string toString() { + exists(Content c | + this.isSingleton(c) and + result = c.toString() + ) + or + exists(Property p | + this.isProperty(p) and + result = "property " + p.getName() + ) + } /** Gets the location of this content set. */ - Location getLocation() { result = super.getLocation() } + Location getLocation() { + exists(Content c | + this.isSingleton(c) and + result = c.getLocation() + ) + or + exists(Property p | + this.isProperty(p) and + result = p.getLocation() + ) + } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index d70f66f2cbe..d777566a336 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -46,7 +46,7 @@ module Input implements InputSig result = "delegate-self" } - string encodeContent(ContentSet c, string arg) { + private string encodeCont(Content c, string arg) { c = TElementContent() and result = "Element" and arg = "" or exists(Field f, string qualifier, string name | @@ -56,27 +56,34 @@ module Input implements InputSig result = "Field" ) or - exists(Property p, string qualifier, string name | - c = TPropertyContent(p) and - p.hasFullyQualifiedName(qualifier, name) and - arg = getQualifiedName(qualifier, name) and - result = "Property" - ) - or exists(SyntheticField f | c = TSyntheticFieldContent(f) and result = "SyntheticField" and arg = f ) } + string encodeContent(ContentSet c, string arg) { + exists(Content cont | + c.isSingleton(cont) and + result = encodeCont(cont, arg) + ) + or + exists(Property p, string qualifier, string name | + c.isProperty(p) and + p.hasFullyQualifiedName(qualifier, name) and + arg = getQualifiedName(qualifier, name) and + result = "Property" + ) + } + string encodeWithoutContent(ContentSet c, string arg) { result = "WithoutElement" and - c = TElementContent() and + c.isElement() and arg = "" } string encodeWithContent(ContentSet c, string arg) { result = "WithElement" and - c = TElementContent() and + c.isElement() and arg = "" } @@ -103,12 +110,10 @@ private module TypesInput implements Impl::Private::TypesInputSig { result.asGvnType() = Gvn::getGlobalValueNumber(any(ObjectType t)) } - DataFlowType getContentType(ContentSet c) { + private DataFlowType getContType(Content c) { exists(Type t | result.asGvnType() = Gvn::getGlobalValueNumber(t) | t = c.(FieldContent).getField().getType() or - t = c.(PropertyContent).getProperty().getType() - or t = c.(SyntheticFieldContent).getField().getType() or c instanceof ElementContent and @@ -116,6 +121,17 @@ private module TypesInput implements Impl::Private::TypesInputSig { ) } + DataFlowType getContentType(ContentSet c) { + exists(Content cont | + c.isSingleton(cont) and + result = getContType(cont) + ) + or + exists(Property p | + c.isProperty(p) and result.asGvnType() = Gvn::getGlobalValueNumber(p.getType()) + ) + } + DataFlowType getParameterType(Impl::Public::SummarizedCallable c, ParameterPosition pos) { exists(Type t | result.asGvnType() = Gvn::getGlobalValueNumber(t) | exists(int i | @@ -311,17 +327,16 @@ module Private { } /** Gets a summary component that represents an element in a collection. */ - SummaryComponent element() { result = content(any(DataFlow::ElementContent c)) } + SummaryComponent element() { result = content(any(ContentSet cs | cs.isElement())) } /** Gets a summary component for property `p`. */ SummaryComponent property(Property p) { - result = - content(any(DataFlow::PropertyContent c | c.getProperty() = p.getUnboundDeclaration())) + result = content(any(DataFlow::ContentSet c | c.isProperty(p.getUnboundDeclaration()))) } /** Gets a summary component for field `f`. */ SummaryComponent field(Field f) { - result = content(any(DataFlow::FieldContent c | c.getField() = f.getUnboundDeclaration())) + result = content(any(DataFlow::ContentSet c | c.isField(f.getUnboundDeclaration()))) } /** Gets a summary component that represents the return value of a call. */ diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll index 11c47c1d37e..25de2681862 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll @@ -122,22 +122,22 @@ private module Cached { FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(nodeFrom, nodeTo, _) or // Taint collection by adding a tainted element - exists(DataFlow::ElementContent c | + exists(DataFlow::ContentSet c | c.isElement() | storeStep(nodeFrom, c, nodeTo) or FlowSummaryImpl::Private::Steps::summarySetterStep(nodeFrom, c, nodeTo, _) ) or - exists(DataFlow::Content c | + exists(DataFlow::ContentSet c | readStep(nodeFrom, c, nodeTo) or FlowSummaryImpl::Private::Steps::summaryGetterStep(nodeFrom, c, nodeTo, _) | // Taint members - c = any(TaintedMember m).(FieldOrProperty).getContent() + c = any(TaintedMember m).(FieldOrProperty).getContentSet() or // Read from a tainted collection - c = TElementContent() + c.isElement() ) ) } @@ -152,12 +152,12 @@ private module Cached { localTaintStepCommon(nodeFrom, nodeTo) or // Taint members - readStep(nodeFrom, any(TaintedMember m).(FieldOrProperty).getContent(), nodeTo) + readStep(nodeFrom, any(TaintedMember m).(FieldOrProperty).getContentSet(), nodeTo) or // Although flow through collections is modeled precisely using stores/reads, we still // allow flow out of a _tainted_ collection. This is needed in order to support taint- // tracking configurations where the source is a collection - readStep(nodeFrom, TElementContent(), nodeTo) + readStep(nodeFrom, any(DataFlow::ContentSet c | c.isElement()), nodeTo) or nodeTo = nodeFrom.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false) ) and diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll index deeccdbf020..9bf516bc876 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll @@ -282,12 +282,12 @@ module EntityFramework { * If `t2` is a column type, `c2` will be included in the model (see * https://docs.microsoft.com/en-us/ef/core/modeling/entity-types?tabs=data-annotations). */ - private predicate step(Content c1, Type t1, Content c2, Type t2, int dist) { + private predicate step(ContentSet c1, Type t1, ContentSet c2, Type t2, int dist) { exists(Property p1 | p1 = this.getADbSetProperty(t2) and - c1.(PropertyContent).getProperty() = p1 and + c1.isProperty(p1) and t1 = p1.getType() and - c2 instanceof ElementContent and + c2.isElement() and dist = 0 ) or @@ -299,17 +299,17 @@ module EntityFramework { exists(Property p2 | p2.getDeclaringType().(Class) = t1 and not isColumnType(t1) and - c2.(PropertyContent).getProperty() = p2 and + c2.isProperty(p2) and t2 = p2.getType() and not isNotMapped(p2) ) or exists(ConstructedInterface ci | - c1 instanceof PropertyContent and + c1.isProperty(_) and t1.(ValueOrRefType).getABaseType*() = ci and not t1 instanceof StringType and ci.getUnboundDeclaration() instanceof SystemCollectionsGenericIEnumerableTInterface and - c2 instanceof ElementContent and + c2.isElement() and t2 = ci.getTypeArgument(0) ) ) @@ -340,16 +340,16 @@ module EntityFramework { * ``` */ Property getAColumnProperty(int dist) { - exists(PropertyContent c, Type t | + exists(ContentSet c, Type t | this.step(_, _, c, t, dist) and - c.getProperty() = result and + c.isProperty(result) and isColumnType(t) ) } - private predicate stepRev(Content c1, Type t1, Content c2, Type t2, int dist) { + private predicate stepRev(ContentSet c1, Type t1, ContentSet c2, Type t2, int dist) { this.step(c1, t1, c2, t2, dist) and - c2.(PropertyContent).getProperty() = this.getAColumnProperty(dist) + c2.isProperty(this.getAColumnProperty(dist)) or this.stepRev(c2, t2, _, _, dist + 1) and this.step(c1, t1, c2, t2, dist) @@ -364,13 +364,13 @@ module EntityFramework { /** Holds if component stack `head :: tail` is required for the input specification. */ predicate requiresComponentStackIn( - Content head, Type headType, SummaryComponentStack tail, int dist + ContentSet head, Type headType, SummaryComponentStack tail, int dist ) { tail = SummaryComponentStack::qualifier() and this.stepRev(head, headType, _, _, 0) and dist = -1 or - exists(Content tailHead, Type tailType, SummaryComponentStack tailTail | + exists(ContentSet tailHead, Type tailType, SummaryComponentStack tailTail | this.requiresComponentStackIn(tailHead, tailType, tailTail, dist - 1) and tail = SummaryComponentStack::push(SummaryComponent::content(tailHead), tailTail) and this.stepRev(tailHead, tailType, head, headType, dist) @@ -379,18 +379,18 @@ module EntityFramework { /** Holds if component stack `head :: tail` is required for the output specification. */ predicate requiresComponentStackOut( - Content head, Type headType, SummaryComponentStack tail, int dist, + ContentSet head, Type headType, SummaryComponentStack tail, int dist, DbContextClassSetProperty dbSetProp ) { - exists(PropertyContent c1 | + exists(ContentSet c1 | dbSetProp = this.getADbSetProperty(headType) and this.stepRev(c1, _, head, headType, 0) and - c1.getProperty() = dbSetProp and + c1.isProperty(dbSetProp) and tail = SummaryComponentStack::return() and dist = 0 ) or - exists(Content tailHead, SummaryComponentStack tailTail, Type tailType | + exists(ContentSet tailHead, SummaryComponentStack tailTail, Type tailType | this.requiresComponentStackOut(tailHead, tailType, tailTail, dist - 1, dbSetProp) and tail = SummaryComponentStack::push(SummaryComponent::content(tailHead), tailTail) and this.stepRev(tailHead, tailType, head, headType, dist) @@ -402,9 +402,9 @@ module EntityFramework { */ pragma[noinline] predicate input(SummaryComponentStack input, Property mapped) { - exists(PropertyContent head, SummaryComponentStack tail | + exists(ContentSet head, SummaryComponentStack tail | this.requiresComponentStackIn(head, _, tail, _) and - head.getProperty() = mapped and + head.isProperty(mapped) and mapped = this.getAColumnProperty(_) and input = SummaryComponentStack::push(SummaryComponent::content(head), tail) ) @@ -418,9 +418,9 @@ module EntityFramework { private predicate output( SummaryComponentStack output, Property mapped, DbContextClassSetProperty dbSet ) { - exists(PropertyContent head, SummaryComponentStack tail | + exists(ContentSet head, SummaryComponentStack tail | this.requiresComponentStackOut(head, _, tail, _, dbSet) and - head.getProperty() = mapped and + head.isProperty(mapped) and mapped = this.getAColumnProperty(_) and output = SummaryComponentStack::push(SummaryComponent::content(head), tail) ) @@ -505,7 +505,7 @@ module EntityFramework { private class DbContextSaveChangesRequiredSummaryComponentStack extends RequiredSummaryComponentStack { override predicate required(SummaryComponent head, SummaryComponentStack tail) { - exists(Content c | head = SummaryComponent::content(c) | + exists(ContentSet c | head = SummaryComponent::content(c) | any(DbContextClass cls).requiresComponentStackIn(c, _, tail, _) or any(DbContextClass cls).requiresComponentStackOut(c, _, tail, _, _) diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll index b8bc01f0800..b5eff2664d2 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -50,7 +50,7 @@ module Printing = ModelPrinting; /** * Holds if `c` is a relevant content kind, where the underlying type is relevant. */ -private predicate isRelevantTypeInContent(DataFlow::Content c) { +private predicate isRelevantTypeInContent(DataFlow::ContentSet c) { isRelevantType(getUnderlyingContentType(c)) } @@ -58,24 +58,22 @@ private predicate isRelevantTypeInContent(DataFlow::Content c) { * Holds if data can flow from `node1` to `node2` either via a read or a write of an intermediate field `f`. */ private predicate isRelevantTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(DataFlow::Content f | + exists(DataFlow::ContentSet f | DataFlowPrivate::readStep(node1, f, node2) and // Partially restrict the content types used for intermediate steps. (not exists(getUnderlyingContentType(f)) or isRelevantTypeInContent(f)) ) or - exists(DataFlow::Content f | DataFlowPrivate::storeStep(node1, f, node2) | - DataFlowPrivate::containerContent(f) - ) + exists(DataFlow::ContentSet f | DataFlowPrivate::storeStep(node1, f, node2) | containerContent(f)) } /** * Holds if content `c` is either a field, a synthetic field or language specific * content of a relevant type or a container like content. */ -private predicate isRelevantContent(DataFlow::Content c) { +private predicate isRelevantContent(DataFlow::ContentSet c) { isRelevantTypeInContent(c) or - DataFlowPrivate::containerContent(c) + containerContent(c) } /** @@ -170,8 +168,8 @@ module PropagateFlowConfig implements DataFlow::StateConfigSig { predicate isAdditionalFlowStep( DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 ) { - exists(DataFlow::Content c | - DataFlowImplCommon::store(node1, c, node2, _, _) and + exists(DataFlow::ContentSet c | + DataFlowImplCommon::store(node1, c.getAStoreContent(), node2, _, _) and isRelevantContent(c) and ( state1 instanceof TaintRead and state2.(TaintStore).getStep() = 1 @@ -180,7 +178,7 @@ module PropagateFlowConfig implements DataFlow::StateConfigSig { ) ) or - exists(DataFlow::Content c | + exists(DataFlow::ContentSet c | DataFlowPrivate::readStep(node1, c, node2) and isRelevantContent(c) and state1.(TaintRead).getStep() + 1 = state2.(TaintRead).getStep() diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index c442261d780..89d721b300d 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -210,10 +210,24 @@ predicate isRelevantType(CS::Type t) { /** * Gets the underlying type of the content `c`. */ -CS::Type getUnderlyingContentType(DataFlow::Content c) { +private CS::Type getUnderlyingContType(DataFlow::Content c) { result = c.(DataFlow::FieldContent).getField().getType() or - result = c.(DataFlow::SyntheticFieldContent).getField().getType() or - result = c.(DataFlow::PropertyContent).getProperty().getType() + result = c.(DataFlow::SyntheticFieldContent).getField().getType() +} + +/** + * Gets the underlying type of the content `c`. + */ +CS::Type getUnderlyingContentType(DataFlow::ContentSet c) { + exists(DataFlow::Content cont | + c.isSingleton(cont) and + result = getUnderlyingContType(cont) + ) + or + exists(CS::Property p | + c.isProperty(p) and + result = p.getType() + ) } /** @@ -325,3 +339,8 @@ predicate isRelevantSinkKind(string kind) { any() } */ bindingset[kind] predicate isRelevantSourceKind(string kind) { any() } + +/** + * Holds if the the content `c` is a container. + */ +predicate containerContent(DataFlow::ContentSet c) { c.isElement() } diff --git a/csharp/ql/test/library-tests/dataflow/external-models/steps.ql b/csharp/ql/test/library-tests/dataflow/external-models/steps.ql index 05d96df8f32..aaeda41c163 100644 --- a/csharp/ql/test/library-tests/dataflow/external-models/steps.ql +++ b/csharp/ql/test/library-tests/dataflow/external-models/steps.ql @@ -16,10 +16,10 @@ query predicate summaryThroughStep( preservesValue = false } -query predicate summaryGetterStep(DataFlow::Node arg, DataFlow::Node out, Content c) { +query predicate summaryGetterStep(DataFlow::Node arg, DataFlow::Node out, ContentSet c) { FlowSummaryImpl::Private::Steps::summaryGetterStep(arg, c, out, _) } -query predicate summarySetterStep(DataFlow::Node arg, DataFlow::Node out, Content c) { +query predicate summarySetterStep(DataFlow::Node arg, DataFlow::Node out, ContentSet c) { FlowSummaryImpl::Private::Steps::summarySetterStep(arg, c, out, _) } From d638b5c7d4efbabc7ca4101de05cc98fc3c21219 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 13 Aug 2024 13:26:48 +0200 Subject: [PATCH 024/404] Sync shared file --- .../modelgenerator/internal/CaptureModels.qll | 18 ++++++++---------- .../internal/CaptureModelsSpecific.qll | 2 ++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll index b8bc01f0800..b5eff2664d2 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -50,7 +50,7 @@ module Printing = ModelPrinting; /** * Holds if `c` is a relevant content kind, where the underlying type is relevant. */ -private predicate isRelevantTypeInContent(DataFlow::Content c) { +private predicate isRelevantTypeInContent(DataFlow::ContentSet c) { isRelevantType(getUnderlyingContentType(c)) } @@ -58,24 +58,22 @@ private predicate isRelevantTypeInContent(DataFlow::Content c) { * Holds if data can flow from `node1` to `node2` either via a read or a write of an intermediate field `f`. */ private predicate isRelevantTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(DataFlow::Content f | + exists(DataFlow::ContentSet f | DataFlowPrivate::readStep(node1, f, node2) and // Partially restrict the content types used for intermediate steps. (not exists(getUnderlyingContentType(f)) or isRelevantTypeInContent(f)) ) or - exists(DataFlow::Content f | DataFlowPrivate::storeStep(node1, f, node2) | - DataFlowPrivate::containerContent(f) - ) + exists(DataFlow::ContentSet f | DataFlowPrivate::storeStep(node1, f, node2) | containerContent(f)) } /** * Holds if content `c` is either a field, a synthetic field or language specific * content of a relevant type or a container like content. */ -private predicate isRelevantContent(DataFlow::Content c) { +private predicate isRelevantContent(DataFlow::ContentSet c) { isRelevantTypeInContent(c) or - DataFlowPrivate::containerContent(c) + containerContent(c) } /** @@ -170,8 +168,8 @@ module PropagateFlowConfig implements DataFlow::StateConfigSig { predicate isAdditionalFlowStep( DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 ) { - exists(DataFlow::Content c | - DataFlowImplCommon::store(node1, c, node2, _, _) and + exists(DataFlow::ContentSet c | + DataFlowImplCommon::store(node1, c.getAStoreContent(), node2, _, _) and isRelevantContent(c) and ( state1 instanceof TaintRead and state2.(TaintStore).getStep() = 1 @@ -180,7 +178,7 @@ module PropagateFlowConfig implements DataFlow::StateConfigSig { ) ) or - exists(DataFlow::Content c | + exists(DataFlow::ContentSet c | DataFlowPrivate::readStep(node1, c, node2) and isRelevantContent(c) and state1.(TaintRead).getStep() + 1 = state2.(TaintRead).getStep() diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index eb37aa93dbe..b881deb6e6a 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -303,3 +303,5 @@ predicate isRelevantSinkKind(string kind) { */ bindingset[kind] predicate isRelevantSourceKind(string kind) { any() } + +predicate containerContent = DataFlowPrivate::containerContent/1; From e84dda4fa66a3b0388dd3f92b271ca3be955d470 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Thu, 15 Aug 2024 16:08:48 -0400 Subject: [PATCH 025/404] Update JS helmet model structure --- .../helmet/Helmet.Required.Setting.model.yml | 2 +- .../javascript/frameworks/helmet/Helmet.qll | 27 +++++++++++++++++++ .../ql/src/Security/CWE-693/CUSTOMIZING.md | 2 +- .../ql/src/Security/CWE-693/InsecureHelmet.ql | 24 +---------------- 4 files changed, 30 insertions(+), 25 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll diff --git a/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.Required.Setting.model.yml b/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.Required.Setting.model.yml index ab01ec5206d..a8c14532152 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.Required.Setting.model.yml +++ b/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.Required.Setting.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: - pack: codeql/javascript-queries + pack: codeql/javascript-all extensible: requiredHelmetSecuritySetting data: - ["frameguard"] diff --git a/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll b/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll new file mode 100644 index 00000000000..9e241ee59c7 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll @@ -0,0 +1,27 @@ +/** + * Provides classes for working with Helmet + */ + +import javascript + +class HelmetProperty extends DataFlow::Node instanceof DataFlow::PropWrite { + ExpressLibraries::HelmetRouteHandler helmet; + + HelmetProperty() { + this = helmet.(DataFlow::CallNode).getAnArgument().getALocalSource().getAPropertyWrite() + } + + ExpressLibraries::HelmetRouteHandler getHelmet() { result = helmet } + + predicate isFalse() { DataFlow::PropWrite.super.getRhs().mayHaveBooleanValue(false) } + + string getName() { result = DataFlow::PropWrite.super.getPropertyName() } + + predicate isImportantSecuritySetting() { + // read from data extensions to allow enforcing custom settings + // defaults are located in javascript/ql/lib/semmle/frameworks/helmet/Helmet.Required.Setting.model.yml + requiredHelmetSecuritySetting(this.getName()) + } +} + +extensible predicate requiredHelmetSecuritySetting(string name); diff --git a/javascript/ql/src/Security/CWE-693/CUSTOMIZING.md b/javascript/ql/src/Security/CWE-693/CUSTOMIZING.md index 34ae2851a85..7eeb9e9b19a 100644 --- a/javascript/ql/src/Security/CWE-693/CUSTOMIZING.md +++ b/javascript/ql/src/Security/CWE-693/CUSTOMIZING.md @@ -24,7 +24,7 @@ A suitable [model pack](https://docs.github.com/en/code-security/codeql-cli/usin name: my-org/javascript-helmet-insecure-config-model-pack version: 1.0.0 extensionTargets: - codeql/java-all: '*' + codeql/javascript-all: '*' dataExtensions: - models/**/*.yml ``` diff --git a/javascript/ql/src/Security/CWE-693/InsecureHelmet.ql b/javascript/ql/src/Security/CWE-693/InsecureHelmet.ql index 8f837669ffc..66652e9e58a 100644 --- a/javascript/ql/src/Security/CWE-693/InsecureHelmet.ql +++ b/javascript/ql/src/Security/CWE-693/InsecureHelmet.ql @@ -12,30 +12,8 @@ */ import javascript -import DataFlow import semmle.javascript.frameworks.ExpressModules - -class HelmetProperty extends DataFlow::Node instanceof DataFlow::PropWrite { - ExpressLibraries::HelmetRouteHandler helmet; - - HelmetProperty() { - this = helmet.(DataFlow::CallNode).getAnArgument().getALocalSource().getAPropertyWrite() - } - - ExpressLibraries::HelmetRouteHandler getHelmet() { result = helmet } - - predicate isFalse() { DataFlow::PropWrite.super.getRhs().mayHaveBooleanValue(false) } - - string getName() { result = DataFlow::PropWrite.super.getPropertyName() } - - predicate isImportantSecuritySetting() { - // read from data extensions to allow enforcing custom settings - // defaults are located in javascript/ql/lib/semmle/frameworks/helmet/Helmet.Required.Setting.model.yml - requiredHelmetSecuritySetting(this.getName()) - } -} - -extensible predicate requiredHelmetSecuritySetting(string name); +import semmle.javascript.frameworks.helmet.Helmet from HelmetProperty helmetProperty, ExpressLibraries::HelmetRouteHandler helmet where From 81787a159e00136292bf9e1d0d63ddd737d77261 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Thu, 15 Aug 2024 16:32:37 -0400 Subject: [PATCH 026/404] Add QL docs to helmet model --- .../javascript/frameworks/helmet/Helmet.qll | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll b/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll index 9e241ee59c7..765b5a36fc4 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll @@ -4,6 +4,9 @@ import javascript +/** + * A write to a property of a route handler from the "helmet" module. + */ class HelmetProperty extends DataFlow::Node instanceof DataFlow::PropWrite { ExpressLibraries::HelmetRouteHandler helmet; @@ -11,17 +14,28 @@ class HelmetProperty extends DataFlow::Node instanceof DataFlow::PropWrite { this = helmet.(DataFlow::CallNode).getAnArgument().getALocalSource().getAPropertyWrite() } + /** + * Gets the route handler associated to this property. + */ ExpressLibraries::HelmetRouteHandler getHelmet() { result = helmet } + /** + * Gets the boolean value of this property, if it may evaluate to a `Boolean`. + */ predicate isFalse() { DataFlow::PropWrite.super.getRhs().mayHaveBooleanValue(false) } + /** + * Gets the name of the `HelmetProperty`. + */ string getName() { result = DataFlow::PropWrite.super.getPropertyName() } - predicate isImportantSecuritySetting() { - // read from data extensions to allow enforcing custom settings - // defaults are located in javascript/ql/lib/semmle/frameworks/helmet/Helmet.Required.Setting.model.yml - requiredHelmetSecuritySetting(this.getName()) - } + /** + * read from data extensions to allow enforcing custom settings + */ + predicate isImportantSecuritySetting() { requiredHelmetSecuritySetting(this.getName()) } } +/** + * defaults are located in `javascript/ql/lib/semmle/frameworks/helmet/Helmet.Required.Setting.model.yml` + */ extensible predicate requiredHelmetSecuritySetting(string name); From 7dcdad066f474637ca14351c5b5817bc98aa8f24 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 16 Aug 2024 09:44:53 +0200 Subject: [PATCH 027/404] Update javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll --- .../ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll b/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll index 765b5a36fc4..375e87e9646 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll @@ -2,7 +2,7 @@ * Provides classes for working with Helmet */ -import javascript +private import javascript /** * A write to a property of a route handler from the "helmet" module. From 0e3c867cb9920197cbc48d1fc5e977d4cd318d39 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 16 Aug 2024 10:37:49 +0200 Subject: [PATCH 028/404] Toy rust program listing definitions of a cargo project --- rust/.gitignore | 2 + rust/Cargo.lock | 1561 ++++++++++++++++++++++++++++++++++++++++++++++ rust/Cargo.toml | 9 + rust/src/main.rs | 66 ++ 4 files changed, 1638 insertions(+) create mode 100644 rust/.gitignore create mode 100644 rust/Cargo.lock create mode 100644 rust/Cargo.toml create mode 100644 rust/src/main.rs diff --git a/rust/.gitignore b/rust/.gitignore new file mode 100644 index 00000000000..d81f12ed1b1 --- /dev/null +++ b/rust/.gitignore @@ -0,0 +1,2 @@ +/target +/.idea diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 00000000000..3c02ab3803a --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,1561 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "always-assert" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1078fa1ce1e34b1872d8611ad921196d76bdd7027e949fbe31231abde201892" +dependencies = [ + "tracing", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "camino" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chalk-derive" +version = "0.98.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9426c8fd0fe61c3da880b801d3b510524df17843a8f9ec1f5b9cec24fb7412df" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "chalk-ir" +version = "0.98.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f2eb1cd6054da221bd1ac0197fb2fe5e2caf3dcb93619398fc1433f8f09093" +dependencies = [ + "bitflags 2.6.0", + "chalk-derive", +] + +[[package]] +name = "chalk-recursive" +version = "0.98.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129dc03458f71cfb9c3cd621c9c68166a94e87b85b16ccd29af015d7ff9a1c61" +dependencies = [ + "chalk-derive", + "chalk-ir", + "chalk-solve", + "rustc-hash", + "tracing", +] + +[[package]] +name = "chalk-solve" +version = "0.98.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7e8a8c1e928f98cdf227b868416ef21dcd8cc3c61b347576d783713444d41c8" +dependencies = [ + "chalk-derive", + "chalk-ir", + "ena", + "indexmap", + "itertools", + "petgraph", + "rustc-hash", + "tracing", +] + +[[package]] +name = "codeql-rust" +version = "0.1.0" +dependencies = [ + "ra_ap_hir", + "ra_ap_load-cargo", + "ra_ap_project_model", +] + +[[package]] +name = "countme" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" + +[[package]] +name = "cov-mark" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0570650661aa447e7335f1d5e4f499d8e58796e617bedc9267d971e51c8b49d4" + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "drop_bomb" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "filetime" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "fst" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "indexmap" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jod-thread" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b23360e99b8717f20aaa4598f5a6541efbe30630039fbc7706cf954a87947ae" + +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "la-arena" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3752f229dcc5a481d60f385fa479ff46818033d881d2d801aa27dffcfb5e8306" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall", +] + +[[package]] +name = "line-index" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67d61795376ae2683928c218fda7d7d7db136fd38c06b7552904667f0d55580a" +dependencies = [ + "nohash-hasher", + "text-size", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lz4_flex" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "miow" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "359f76430b20a79f9e20e115b3428614e654f04fab314482fc0fda0ebd3c6044" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "notify" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +dependencies = [ + "bitflags 2.6.0", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "walkdir", + "windows-sys 0.48.0", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "oorandom" +version = "11.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "perf-event" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5396562cd2eaa828445d6d34258ae21ee1eb9d40fe626ca7f51c8dccb4af9d66" +dependencies = [ + "libc", + "perf-event-open-sys", +] + +[[package]] +name = "perf-event-open-sys" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce9bedf5da2c234fdf2391ede2b90fabf585355f33100689bc364a3ea558561a" +dependencies = [ + "libc", +] + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ra-ap-rustc_abi" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80b1d613eee933486c0613a7bc26e515e46f43adf479d1edd5e537f983e9ce46" +dependencies = [ + "bitflags 2.6.0", + "ra-ap-rustc_index", + "tracing", +] + +[[package]] +name = "ra-ap-rustc_index" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f072060ac77e9e1a02cc20028095993af7e72cc0804779c68bcbf47b16de49c9" +dependencies = [ + "arrayvec", + "ra-ap-rustc_index_macros", + "smallvec", +] + +[[package]] +name = "ra-ap-rustc_index_macros" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82f3d6dcb30a66905388e14756b8f2216131d9f8004922c07f13335840e058d1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "ra-ap-rustc_lexer" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd8a2b0bdcba9892cbce0b25f6c953d31b0febc1f3420fc692884fce5a23ad8" +dependencies = [ + "unicode-properties", + "unicode-xid", +] + +[[package]] +name = "ra-ap-rustc_parse_format" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dad7a491c2554590222e0c9212dcb7c2e7aceb668875075012a35ea780d135" +dependencies = [ + "ra-ap-rustc_index", + "ra-ap-rustc_lexer", +] + +[[package]] +name = "ra-ap-rustc_pattern_analysis" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34768e1faf88c31f2e9ad57b48318a52b507dafac0cddbf01b5d63bfc0b0a365" +dependencies = [ + "ra-ap-rustc_index", + "rustc-hash", + "rustc_apfloat", + "smallvec", + "tracing", +] + +[[package]] +name = "ra_ap_base_db" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aae8f3b0315876c1aa11dc0aac7795b27cb9e21a2a870667842e97e6b7dc3b5" +dependencies = [ + "la-arena", + "lz4_flex", + "ra_ap_cfg", + "ra_ap_intern", + "ra_ap_salsa", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_vfs", + "rustc-hash", + "semver", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_cfg" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac59191045154789b3b3f9f8c67f35439c3cbd9e36107dd62d04d4a4b2c95322" +dependencies = [ + "ra_ap_intern", + "ra_ap_tt", + "rustc-hash", +] + +[[package]] +name = "ra_ap_hir" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b321e9c63fd434ac7b1617d6ddaed7329b8e21f6cae06ca05fec91c6361bb40d" +dependencies = [ + "arrayvec", + "either", + "itertools", + "once_cell", + "ra_ap_base_db", + "ra_ap_cfg", + "ra_ap_hir_def", + "ra_ap_hir_expand", + "ra_ap_hir_ty", + "ra_ap_intern", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_tt", + "rustc-hash", + "smallvec", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_hir_def" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc0e2dd39d1162650dd6668f1e179d24aec336e3ff12aae9f0e50c10928d1158" +dependencies = [ + "arrayvec", + "bitflags 2.6.0", + "cov-mark", + "dashmap", + "drop_bomb", + "either", + "fst", + "hashbrown", + "indexmap", + "itertools", + "la-arena", + "once_cell", + "ra-ap-rustc_abi", + "ra-ap-rustc_parse_format", + "ra_ap_base_db", + "ra_ap_cfg", + "ra_ap_hir_expand", + "ra_ap_intern", + "ra_ap_limit", + "ra_ap_mbe", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_tt", + "rustc-hash", + "rustc_apfloat", + "smallvec", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_hir_expand" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e3c27bb239be9c6f835790f32d1a6e82345713c2ea63605d3270f06daf5caf" +dependencies = [ + "cov-mark", + "either", + "hashbrown", + "itertools", + "la-arena", + "ra_ap_base_db", + "ra_ap_cfg", + "ra_ap_intern", + "ra_ap_limit", + "ra_ap_mbe", + "ra_ap_parser", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_syntax-bridge", + "ra_ap_tt", + "rustc-hash", + "smallvec", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_hir_ty" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c437b9971d421dea75d72f137ccd49612cff401b9118da0d5b31c033ea0bcf3d" +dependencies = [ + "arrayvec", + "bitflags 2.6.0", + "chalk-derive", + "chalk-ir", + "chalk-recursive", + "chalk-solve", + "cov-mark", + "either", + "ena", + "indexmap", + "itertools", + "la-arena", + "nohash-hasher", + "once_cell", + "oorandom", + "ra-ap-rustc_abi", + "ra-ap-rustc_index", + "ra-ap-rustc_pattern_analysis", + "ra_ap_base_db", + "ra_ap_hir_def", + "ra_ap_hir_expand", + "ra_ap_intern", + "ra_ap_limit", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "rustc-hash", + "rustc_apfloat", + "scoped-tls", + "smallvec", + "tracing", + "triomphe", + "typed-arena", +] + +[[package]] +name = "ra_ap_ide_db" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa72d28b51a29efd6416979b43976663708894cee98fb44cabaa222cb049417" +dependencies = [ + "arrayvec", + "bitflags 2.6.0", + "cov-mark", + "crossbeam-channel", + "either", + "fst", + "indexmap", + "itertools", + "line-index", + "memchr", + "nohash-hasher", + "once_cell", + "ra_ap_base_db", + "ra_ap_hir", + "ra_ap_limit", + "ra_ap_parser", + "ra_ap_profile", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_text_edit", + "rayon", + "rustc-hash", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_intern" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeec56dfe875fd865cc9afb7d0a0a6af832bf323b6db461844ba1de2fa7006b" +dependencies = [ + "dashmap", + "hashbrown", + "rustc-hash", + "sptr", + "triomphe", +] + +[[package]] +name = "ra_ap_limit" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6d33f2d8eda04460315de38992e3681dd799c27e712788a7aeee9909bc1c0f5" + +[[package]] +name = "ra_ap_load-cargo" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b7a4626cb8477733b02d836a7215db629249dd0076b2c9edcfe3f3a4e639f33" +dependencies = [ + "anyhow", + "crossbeam-channel", + "itertools", + "ra_ap_hir_expand", + "ra_ap_ide_db", + "ra_ap_intern", + "ra_ap_paths", + "ra_ap_proc_macro_api", + "ra_ap_project_model", + "ra_ap_span", + "ra_ap_tt", + "ra_ap_vfs", + "ra_ap_vfs-notify", + "tracing", +] + +[[package]] +name = "ra_ap_mbe" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e45337e002d5c0efcba96769da0bd2d94c4e66e2d315f627fea7c877380141" +dependencies = [ + "arrayvec", + "cov-mark", + "ra_ap_intern", + "ra_ap_parser", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_syntax-bridge", + "ra_ap_tt", + "rustc-hash", + "smallvec", + "tracing", +] + +[[package]] +name = "ra_ap_parser" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "094cb41571e0c97501e1171f638bfdf4edb5f376d283b1ab04f3411aa3a44f51" +dependencies = [ + "drop_bomb", + "ra-ap-rustc_lexer", + "ra_ap_limit", + "tracing", +] + +[[package]] +name = "ra_ap_paths" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6602581f62922de09c93fdf3d6ddffa3f4fdcafba6c9dd08827951fb5ad511cc" +dependencies = [ + "camino", + "serde", +] + +[[package]] +name = "ra_ap_proc_macro_api" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2480058c6228d6ccdd6cfe1fa01c081f081ec6a6ea1a241b88618576ae6eff" +dependencies = [ + "indexmap", + "ra_ap_base_db", + "ra_ap_intern", + "ra_ap_paths", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_tt", + "rustc-hash", + "serde", + "serde_json", + "tracing", +] + +[[package]] +name = "ra_ap_profile" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60263554aef637b9143a2d480a7fa93661297d795f7c46108386454a86885d49" +dependencies = [ + "cfg-if", + "libc", + "perf-event", + "windows-sys 0.52.0", +] + +[[package]] +name = "ra_ap_project_model" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ff3383dcd32a63b914c59f42f38e81ebfa5d5d921067ca0d1b01585aed1a4bd" +dependencies = [ + "anyhow", + "cargo_metadata", + "itertools", + "la-arena", + "ra_ap_base_db", + "ra_ap_cfg", + "ra_ap_intern", + "ra_ap_paths", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_toolchain", + "rustc-hash", + "semver", + "serde", + "serde_json", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_salsa" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f6e29648a086801b2bd047a88e9b73782c354fca9117d1208bebbfd6a849a61" +dependencies = [ + "indexmap", + "itertools", + "lock_api", + "oorandom", + "parking_lot", + "ra_ap_salsa-macros", + "rustc-hash", + "smallvec", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_salsa-macros" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d104209e089a63a1aa8f9a5f06c6350b1508d856fca4c25002f1d8e7c04a685b" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ra_ap_span" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d30beb9ac55357e4c56f8f8e5c84571ce204f10ba43b55640c51053e806e6b8" +dependencies = [ + "hashbrown", + "la-arena", + "ra_ap_salsa", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_vfs", + "rustc-hash", + "text-size", +] + +[[package]] +name = "ra_ap_stdx" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51c29e7dfc7282ed14e91419d09b59e8dca27e7cc10c3cfcbf1964d7db0bef34" +dependencies = [ + "always-assert", + "crossbeam-channel", + "itertools", + "jod-thread", + "libc", + "miow", + "windows-sys 0.52.0", +] + +[[package]] +name = "ra_ap_syntax" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "575c1e3deb1cb39e0939a95a4cb4339ee95b1283157cf03bc1bdaf76e6ebca8d" +dependencies = [ + "cov-mark", + "either", + "indexmap", + "itertools", + "once_cell", + "ra-ap-rustc_lexer", + "ra_ap_parser", + "ra_ap_stdx", + "ra_ap_text_edit", + "rowan", + "rustc-hash", + "smol_str", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_syntax-bridge" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f19c53a1f9f50d76f50b7c0c83cda0fa5de09a182d8f4ae3575ea986a24fa234" +dependencies = [ + "ra_ap_intern", + "ra_ap_parser", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_tt", + "rustc-hash", + "tracing", +] + +[[package]] +name = "ra_ap_text_edit" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b38bb92b8924b2267d84524f09cc31851f7f93741811e5374701ceb2be47d0b" +dependencies = [ + "itertools", + "text-size", +] + +[[package]] +name = "ra_ap_toolchain" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18076d6d6b2ef93a9d0396b06d58369231e50916456d2fa4488bc78c97ea6714" +dependencies = [ + "camino", + "home", +] + +[[package]] +name = "ra_ap_tt" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "851bc23c870c67bd729e33056e001a2e07b16a31da13affe73d78e77049b12b8" +dependencies = [ + "arrayvec", + "ra-ap-rustc_lexer", + "ra_ap_intern", + "ra_ap_stdx", + "text-size", +] + +[[package]] +name = "ra_ap_vfs" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3b152d631514508b7322cda383a454e2a56b0b5ecd8562a8f1e40aabe9fb236" +dependencies = [ + "fst", + "indexmap", + "nohash-hasher", + "ra_ap_paths", + "ra_ap_stdx", + "rustc-hash", + "tracing", +] + +[[package]] +name = "ra_ap_vfs-notify" +version = "0.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e516915fb4822a3d480404d35c20f240ae16a297ef52a68dc8cff748093f3abd" +dependencies = [ + "crossbeam-channel", + "notify", + "ra_ap_paths", + "ra_ap_stdx", + "ra_ap_vfs", + "rayon", + "rustc-hash", + "tracing", + "walkdir", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "rowan" +version = "0.15.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49" +dependencies = [ + "countme", + "hashbrown", + "memoffset", + "rustc-hash", + "text-size", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_apfloat" +version = "0.2.1+llvm-462a31f5a5ab" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "886d94c63c812a8037c4faca2607453a0fa4cf82f734665266876b022244543f" +dependencies = [ + "bitflags 1.3.2", + "smallvec", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.207" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.207" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "2.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "text-size" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" + +[[package]] +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "triomphe" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369" +dependencies = [ + "serde", + "stable_deref_trait", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 00000000000..e36cdfced04 --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "codeql-rust" +version = "0.1.0" +edition = "2021" + +[dependencies] +ra_ap_hir = "0.0.229" +ra_ap_load-cargo = "0.0.229" +ra_ap_project_model = "0.0.229" diff --git a/rust/src/main.rs b/rust/src/main.rs new file mode 100644 index 00000000000..f5f966119d7 --- /dev/null +++ b/rust/src/main.rs @@ -0,0 +1,66 @@ +use ra_ap_hir::{Crate, ModuleDef, Name, HirDisplay, DefWithBody}; +use ra_ap_project_model::CargoConfig; +use std::env; +use std::path::Path; +use ra_ap_load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice}; + +fn extract_name(n: Option) -> String { + match n { + Some(v) => v.as_str().to_owned(), + None => String::from(""), + } +} + +fn main() { + let args: Vec = env::args().collect(); + let config = CargoConfig { ..Default::default() }; + let no_progress = &|_| (); + let load_config = LoadCargoConfig { + load_out_dirs_from_check: true, + with_proc_macro_server: ProcMacroServerChoice::Sysroot, + prefill_caches: false, + }; + let (db, vfs, macro_server) = load_workspace_at(&Path::new(&args[1]), &config, &load_config, no_progress).unwrap(); + let mut worklist: Vec<_> = + Crate::all(&db).into_iter().map(|krate| krate.root_module()).collect(); + + while let Some(module) = worklist.pop() { + println!("Module: {}", extract_name(module.name(&db))); + for d in module.declarations(&db) { + match d { + ModuleDef::Module(e) => { + println!(" {}", e.display(&db)); + } + ModuleDef::Function(e) => { + println!(" {}", e.display(&db)); + } + ModuleDef::Adt(e) => { + println!(" {}", e.display(&db)); + } + ModuleDef::Variant(e) => { + println!(" {}", e.display(&db)); + } + ModuleDef::Const(e) => { + println!(" {}", e.display(&db)); + } + ModuleDef::Static(e) => { + println!(" {}", e.display(&db)); + } + ModuleDef::Trait(e) => { + println!(" {}", e.display(&db)); + } + ModuleDef::TraitAlias(e) => { + println!(" {}", e.display(&db)); + } + ModuleDef::TypeAlias(e) => { + println!(" {}", e.display(&db)); + } + ModuleDef::BuiltinType(_e) => {} + ModuleDef::Macro(e) => { + println!(" {}", e.display(&db)); + } + } + } + worklist.extend(module.children(&db)); + } +} From 0126fbcb8f2cb9d7f38f8adce31716981f7a8422 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Aug 2024 10:56:46 +0100 Subject: [PATCH 029/404] Swift: Clear the language for Swift code snippets that are rendering incorrectly. --- .../queries/Security/CWE-020/IncompleteHostnameRegex.qhelp | 4 ++-- swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp | 2 +- swift/ql/src/queries/Security/CWE-1333/ReDoS.qhelp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp index ef374fc9752..347a0ee0e29 100644 --- a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp +++ b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp @@ -46,7 +46,7 @@

    - +

    @@ -63,7 +63,7 @@

    - + diff --git a/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp b/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp index b406faf8e17..c312fb1a6f5 100644 --- a/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp +++ b/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp @@ -28,7 +28,7 @@ likely to handle corner cases correctly than a custom implementation. The following example attempts to filters out all <script> tags.

    - +

    The above sanitizer does not filter out all <script> tags. diff --git a/swift/ql/src/queries/Security/CWE-1333/ReDoS.qhelp b/swift/ql/src/queries/Security/CWE-1333/ReDoS.qhelp index ddbb2835bc2..e641d9b4e61 100644 --- a/swift/ql/src/queries/Security/CWE-1333/ReDoS.qhelp +++ b/swift/ql/src/queries/Security/CWE-1333/ReDoS.qhelp @@ -3,7 +3,7 @@

    Consider the following regular expression:

    - + /^_(__|.)+_$/

    Its sub-expression "(__|.)+" can match the string @@ -19,7 +19,7 @@ the ambiguity between the two branches of the alternative inside the repetition:

    - + /^_(__|[^_])+_$/ From 2d19d6f61ecc12f8a888f5a5cdd76888e0c01763 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Aug 2024 11:40:57 +0100 Subject: [PATCH 030/404] Swift: Fix two of the qhelps by slightly modifying the sample code instead. --- .../queries/Security/CWE-020/IncompleteHostnameRegex.qhelp | 4 ++-- .../queries/Security/CWE-020/IncompleteHostnameRegexBad.swift | 4 ++-- .../Security/CWE-020/IncompleteHostnameRegexGood.swift | 4 ++-- swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp | 2 +- swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp index 347a0ee0e29..ef374fc9752 100644 --- a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp +++ b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp @@ -46,7 +46,7 @@

    - +

    @@ -63,7 +63,7 @@

    - + diff --git a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexBad.swift b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexBad.swift index 3e28022ab98..6f553b2fbee 100644 --- a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexBad.swift +++ b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexBad.swift @@ -1,11 +1,11 @@ -func handleUrl(_ urlString: String) { +func handleUrl(_ urlString: String) throws { // get the 'url=' parameter from the URL let components = URLComponents(string: urlString) let redirectParam = components?.queryItems?.first(where: { $0.name == "url" }) // check we trust the host - let regex = #/^(www|beta).example.com//# // BAD + let regex = try Regex("^(www|beta).example.com/") // BAD if let match = redirectParam?.value?.firstMatch(of: regex) { // ... trust the URL ... } diff --git a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexGood.swift b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexGood.swift index fad4135a263..1413a7ffa73 100644 --- a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexGood.swift +++ b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexGood.swift @@ -1,11 +1,11 @@ -func handleUrl(_ urlString: String) { +func handleUrl(_ urlString: String) throws { // get the 'url=' parameter from the URL let components = URLComponents(string: urlString) let redirectParam = components?.queryItems?.first(where: { $0.name == "url" }) // check we trust the host - let regex = #/^(www|beta)\.example\.com//# // GOOD + let regex = try Regex("^(www|beta)\\.example\\.com/") // GOOD if let match = redirectParam?.value?.firstMatch(of: regex) { // ... trust the URL ... } diff --git a/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp b/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp index c312fb1a6f5..b406faf8e17 100644 --- a/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp +++ b/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp @@ -28,7 +28,7 @@ likely to handle corner cases correctly than a custom implementation. The following example attempts to filters out all <script> tags.

    - +

    The above sanitizer does not filter out all <script> tags. diff --git a/swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift b/swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift index d399bf5a166..f2a8273d31a 100644 --- a/swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift +++ b/swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift @@ -1,4 +1,4 @@ -let script_tag_regex = /]*>.*<\/script>/ +let script_tag_regex = try Regex("]*>.*") var old_html = "" while (html != old_html) { From 0088ece3ea7772811f7c2c75a2a75e16abb49d66 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 16 Aug 2024 13:24:03 +0100 Subject: [PATCH 031/404] Revert "Swift: Fix two of the qhelps by slightly modifying the sample code instead." This reverts commit 2d19d6f61ecc12f8a888f5a5cdd76888e0c01763. --- .../queries/Security/CWE-020/IncompleteHostnameRegex.qhelp | 4 ++-- .../queries/Security/CWE-020/IncompleteHostnameRegexBad.swift | 4 ++-- .../Security/CWE-020/IncompleteHostnameRegexGood.swift | 4 ++-- swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp | 2 +- swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp index ef374fc9752..347a0ee0e29 100644 --- a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp +++ b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegex.qhelp @@ -46,7 +46,7 @@

    - +

    @@ -63,7 +63,7 @@

    - + diff --git a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexBad.swift b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexBad.swift index 6f553b2fbee..3e28022ab98 100644 --- a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexBad.swift +++ b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexBad.swift @@ -1,11 +1,11 @@ -func handleUrl(_ urlString: String) throws { +func handleUrl(_ urlString: String) { // get the 'url=' parameter from the URL let components = URLComponents(string: urlString) let redirectParam = components?.queryItems?.first(where: { $0.name == "url" }) // check we trust the host - let regex = try Regex("^(www|beta).example.com/") // BAD + let regex = #/^(www|beta).example.com//# // BAD if let match = redirectParam?.value?.firstMatch(of: regex) { // ... trust the URL ... } diff --git a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexGood.swift b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexGood.swift index 1413a7ffa73..fad4135a263 100644 --- a/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexGood.swift +++ b/swift/ql/src/queries/Security/CWE-020/IncompleteHostnameRegexGood.swift @@ -1,11 +1,11 @@ -func handleUrl(_ urlString: String) throws { +func handleUrl(_ urlString: String) { // get the 'url=' parameter from the URL let components = URLComponents(string: urlString) let redirectParam = components?.queryItems?.first(where: { $0.name == "url" }) // check we trust the host - let regex = try Regex("^(www|beta)\\.example\\.com/") // GOOD + let regex = #/^(www|beta)\.example\.com//# // GOOD if let match = redirectParam?.value?.firstMatch(of: regex) { // ... trust the URL ... } diff --git a/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp b/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp index b406faf8e17..c312fb1a6f5 100644 --- a/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp +++ b/swift/ql/src/queries/Security/CWE-116/BadTagFilter.qhelp @@ -28,7 +28,7 @@ likely to handle corner cases correctly than a custom implementation. The following example attempts to filters out all <script> tags.

    - +

    The above sanitizer does not filter out all <script> tags. diff --git a/swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift b/swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift index f2a8273d31a..d399bf5a166 100644 --- a/swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift +++ b/swift/ql/src/queries/Security/CWE-116/BadTagFilterBad.swift @@ -1,4 +1,4 @@ -let script_tag_regex = try Regex("]*>.*") +let script_tag_regex = /]*>.*<\/script>/ var old_html = "" while (html != old_html) { From 6d4f3bd0147bbc678539fb4af9712d46aa907077 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 14 Aug 2024 13:41:57 +0200 Subject: [PATCH 032/404] Ruby: Rework splat argument/parameter matching --- .../dataflow/internal/DataFlowDispatch.qll | 60 +- .../dataflow/internal/DataFlowPrivate.qll | 98 +- .../ruby/dataflow/internal/DataFlowPublic.qll | 13 +- .../flow-summaries/semantics.expected | 48 +- .../dataflow/params/TypeTracker.expected | 2221 ++++++----------- .../dataflow/params/params-flow.expected | 5 - .../type-tracker/TypeTracker.expected | 77 +- .../action_controller/params-flow.expected | 18 +- 8 files changed, 957 insertions(+), 1583 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index f4b93490020..8af047e8326 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -563,7 +563,7 @@ private module Cached { THashSplatArgumentPosition() or TSynthHashSplatArgumentPosition() or TSplatArgumentPosition(int pos) { exists(Call c | c.getArgument(pos) instanceof SplatExpr) } or - TSynthSplatArgumentPosition() or + TSynthSplatArgumentPosition(Boolean hasActualSplat) or TAnyArgumentPosition() or TAnyKeywordArgumentPosition() @@ -590,11 +590,11 @@ private module Cached { THashSplatParameterPosition() or TSynthHashSplatParameterPosition() or TSplatParameterPosition(int pos) { - pos = 0 + pos = 0 // needed for flow summaries or exists(Parameter p | p.getPosition() = pos and p instanceof SplatParameter) } or - TSynthSplatParameterPosition() or + TSynthSplatParameterPosition(Boolean hasActualSplat) or TAnyParameterPosition() or TAnyKeywordParameterPosition() } @@ -1383,8 +1383,15 @@ class ParameterPosition extends TParameterPosition { /** Holds if this position represents a splat parameter at position `n`. */ predicate isSplat(int n) { this = TSplatParameterPosition(n) } - /** Holds if this position represents a synthetic splat parameter. */ - predicate isSynthSplat() { this = TSynthSplatParameterPosition() } + /** + * Holds if this position represents a synthetic splat parameter. + * + * `hasActualSplat` indicates whether the method that the parameter belongs + * to also has an actual splat parameter. + */ + predicate isSynthSplat(boolean hasActualSplat) { + this = TSynthSplatParameterPosition(hasActualSplat) + } /** * Holds if this position represents any parameter, except `self` parameters. This @@ -1419,7 +1426,11 @@ class ParameterPosition extends TParameterPosition { or exists(int pos | this.isSplat(pos) and result = "* (position " + pos + ")") or - this.isSynthSplat() and result = "synthetic *" + exists(boolean hasActualSplat, string suffix | + this.isSynthSplat(hasActualSplat) and + result = "synthetic *" + suffix and + if hasActualSplat = true then suffix = " (with actual)" else suffix = "" + ) } } @@ -1458,8 +1469,15 @@ class ArgumentPosition extends TArgumentPosition { /** Holds if this position represents a splat argument at position `n`. */ predicate isSplat(int n) { this = TSplatArgumentPosition(n) } - /** Holds if this position represents a synthetic splat argument. */ - predicate isSynthSplat() { this = TSynthSplatArgumentPosition() } + /** + * Holds if this position represents a synthetic splat argument. + * + * `hasActualSplat` indicates whether the call that the argument belongs + * to also has an actual splat argument. + */ + predicate isSynthSplat(boolean hasActualSplat) { + this = TSynthSplatArgumentPosition(hasActualSplat) + } /** Gets a textual representation of this position. */ string toString() { @@ -1483,7 +1501,11 @@ class ArgumentPosition extends TArgumentPosition { or exists(int pos | this.isSplat(pos) and result = "* (position " + pos + ")") or - this.isSynthSplat() and result = "synthetic *" + exists(boolean hasActualSplat, string suffix | + this.isSynthSplat(hasActualSplat) and + result = "synthetic *" + suffix and + if hasActualSplat = true then suffix = " (with actual)" else suffix = "" + ) } } @@ -1519,16 +1541,26 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { (ppos.isHashSplat() or ppos.isSynthHashSplat()) and (apos.isHashSplat() or apos.isSynthHashSplat()) or - exists(int pos | + exists(int pos, boolean hasActualSplatParam, boolean hasActualSplatArg | ( - ppos.isSplat(pos) + ppos.isSplat(pos) and + hasActualSplatParam = true // allow matching with synthetic splat argument or - ppos.isSynthSplat() and pos = 0 + ppos.isSynthSplat(hasActualSplatParam) and + pos = 0 and + // prevent synthetic splat parameters from matching synthetic splat arguments + // when direct positional matching is possible + ( + hasActualSplatParam = true + or + hasActualSplatArg = true + ) ) and ( - apos.isSplat(pos) + apos.isSplat(pos) and + hasActualSplatArg = true // allow matching with synthetic splat parameter or - apos.isSynthSplat() and pos = 0 + apos.isSynthSplat(hasActualSplatArg) and pos = 0 ) ) or diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index ec58536abe1..5ec24c19901 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -661,7 +661,7 @@ private module Cached { name = [input, output].regexpFind("(?<=(^|\\.)Field\\[)[^\\]]+(?=\\])", _, _).trim() ) } or - TSplatContent(int i, Boolean shifted) { i in [0 .. 10] } or + deprecated TSplatContent(int i, Boolean shifted) { i in [0 .. 10] } or THashSplatContent(ConstantValue::ConstantSymbolValue cv) or TCapturedVariableContent(VariableCapture::CapturedVariable v) or // Only used by type-tracking @@ -686,7 +686,6 @@ private module Cached { TUnknownElementContentApprox() or TKnownIntegerElementContentApprox() or TKnownElementContentApprox(string approx) { approx = approxKnownElementIndex(_) } or - TSplatContentApprox(Boolean shifted) or THashSplatContentApprox(string approx) { approx = approxKnownElementIndex(_) } or TNonElementContentApprox(Content c) { not c instanceof Content::ElementContent } or TCapturedVariableContentApprox(VariableCapture::CapturedVariable v) @@ -701,14 +700,10 @@ private module Cached { TSynthHashSplatArgumentType(string methodName) { methodName = any(SynthHashSplatArgumentNode n).getMethodName() } or - TSynthSplatArgumentType(string methodName) { - methodName = any(SynthSplatArgumentNode n).getMethodName() - } or TUnknownDataFlowType() } -class TElementContent = - TKnownElementContent or TUnknownElementContent or TSplatContent or THashSplatContent; +class TElementContent = TKnownElementContent or TUnknownElementContent or THashSplatContent; import Cached @@ -1188,18 +1183,6 @@ private module ParameterNodes { * by adding read steps out of the synthesized parameter node to the relevant * positional parameters. * - * In order to avoid redundancy (and improve performance) in cases like - * - * ```rb - * foo(a, b, c) - * ``` - * - * where direct positional matching is possible, we use a special `SplatContent` - * (instead of reusing `KnownElementContent`) when we construct a synthesized - * splat argument (`SynthSplatArgumentNode`) at the call site, and then only - * add read steps out of this node for actual splat arguments (which will use - * `KnownElementContent` or `TSplatContent(_, true)`). - * * We don't yet correctly handle cases where a positional argument follows the * splat argument, e.g. in * @@ -1220,9 +1203,6 @@ private module ParameterNodes { isParameterNode(p, callable, any(ParameterPosition pos | pos.isPositional(n))) and not exists(int i | splatParameterAt(callable.asCfgScope(), i) and i < n) | - // Important: do not include `TSplatContent(_, false)` here, as normal parameter matching is possible - c = getSplatContent(n, true) - or c = getArrayContent(n) or c.isSingleton(TUnknownElementContent()) @@ -1232,7 +1212,13 @@ private module ParameterNodes { final override Parameter getParameter() { none() } final override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { - c = callable and pos.isSynthSplat() + c = callable and + exists(boolean hasActualSplat | + pos.isSynthSplat(hasActualSplat) and + if exists(TSynthSplatParameterShiftNode(c, _, _)) + then hasActualSplat = true + else hasActualSplat = false + ) } final override CfgScope getCfgScope() { result = callable.asCfgScope() } @@ -1271,11 +1257,7 @@ private module ParameterNodes { */ predicate readFrom(SynthSplatParameterNode synthSplat, ContentSet cs) { synthSplat.isParameterOf(callable, _) and - ( - cs = getSplatContent(pos + splatPos, _) - or - cs = getArrayContent(pos + splatPos) - ) + cs = getArrayContent(pos + splatPos) } /** @@ -1506,31 +1488,11 @@ module ArgumentNodes { * `call`, into a synthetic splat argument. */ predicate synthSplatStore(CfgNodes::ExprNodes::CallCfgNode call, Argument arg, ContentSet c) { - exists(int n | - exists(ArgumentPosition pos | - arg.isArgumentOf(call, pos) and - pos.isPositional(n) and - not exists(int i | splatArgumentAt(call, i) and i < n) - ) - | - if call instanceof CfgNodes::ExprNodes::ArrayLiteralCfgNode - then - /* - * Needed for cases like - * - * ```rb - * arr = [taint, safe] - * - * def foo(a, b) - * sink(a) - * end - * - * foo(*arr) - * ``` - */ - - c = getArrayContent(n) - else c = getSplatContent(n, false) + exists(int n, ArgumentPosition pos | + arg.isArgumentOf(call, pos) and + pos.isPositional(n) and + not exists(int i | splatArgumentAt(call, i) and i < n) and + c = getArrayContent(n) ) } @@ -1552,7 +1514,12 @@ module ArgumentNodes { override predicate sourceArgumentOf(CfgNodes::ExprNodes::CallCfgNode call, ArgumentPosition pos) { call = call_ and - pos.isSynthSplat() + exists(boolean hasActualSplat | + pos.isSynthSplat(hasActualSplat) and + if any(SynthSplatArgumentShiftNode shift).storeInto(this, _) + then hasActualSplat = true + else hasActualSplat = false + ) } override string toStringImpl() { result = "synthetic splat argument" } @@ -1583,8 +1550,6 @@ module ArgumentNodes { predicate readFrom(Node splatArg, ContentSet cs) { splatArg.asExpr().(Argument).isArgumentOf(c, any(ArgumentPosition p | p.isSplat(splatPos))) and ( - cs = getSplatContent(n - splatPos, _) - or cs = getArrayContent(n - splatPos) or n = -1 and @@ -1599,7 +1564,7 @@ module ArgumentNodes { predicate storeInto(SynthSplatArgumentNode synthSplat, ContentSet cs) { synthSplat = TSynthSplatArgumentNode(c) and ( - cs = getSplatContent(n, true) + cs = getArrayContent(n) or n = -1 and cs.isSingleton(TUnknownElementContent()) @@ -1813,10 +1778,6 @@ private ContentSet getArrayContent(int n) { ) } -private ContentSet getSplatContent(int n, boolean adjusted) { - result.isSingleton(TSplatContent(n, adjusted)) -} - /** * Subset of `storeStep` that should be shared with type-tracking. */ @@ -1979,11 +1940,9 @@ DataFlowType getNodeType(Node n) { or result = TSynthHashSplatArgumentType(n.(SynthHashSplatArgumentNode).getMethodName()) or - result = TSynthSplatArgumentType(n.(SynthSplatArgumentNode).getMethodName()) - or not n instanceof LambdaSelfReferenceNode and not mustHaveLambdaType(n, _) and - not n instanceof SynthHashSplatOrSplatArgumentNode and + not n instanceof SynthHashSplatArgumentNode and result = TUnknownDataFlowType() } @@ -2209,12 +2168,6 @@ class ContentApprox extends TContentApprox { result = "approximated element " + approx ) or - exists(boolean shifted, string s | - this = TSplatContentApprox(shifted) and - (if shifted = true then s = " (shifted)" else s = "") and - result = "approximated splat position" + s - ) - or exists(string s | this = THashSplatContentApprox(s) and result = "approximated hash-splat position " + s @@ -2259,11 +2212,6 @@ ContentApprox getContentApprox(Content c) { result = TKnownElementContentApprox(approxKnownElementIndex(c.(Content::KnownElementContent).getIndex())) or - exists(boolean shifted | - c = TSplatContent(_, shifted) and - result = TSplatContentApprox(shifted) - ) - or result = THashSplatContentApprox(approxKnownElementIndex(c.(Content::HashSplatContent).getKey())) or result = TNonElementContentApprox(c) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll index 33ac82448a9..825c440c9a9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll @@ -586,7 +586,7 @@ module Content { * * we have an implicit splat argument containing `[1, 2, 3]`. */ - class SplatContent extends ElementContent, TSplatContent { + deprecated class SplatContent extends Content, TSplatContent { private int i; private boolean shifted; @@ -797,7 +797,6 @@ class ContentSet extends TContentSet { private Content getAnElementReadContent() { exists(Content::KnownElementContent c | this.isKnownOrUnknownElement(c) | result = c or - result = TSplatContent(c.getIndex().getInt(), _) or result = THashSplatContent(c.getIndex()) or result = TUnknownElementContent() ) @@ -805,12 +804,7 @@ class ContentSet extends TContentSet { exists(int lower, boolean includeUnknown | this = TElementLowerBoundContent(lower, includeUnknown) | - exists(int i | - result.(Content::KnownElementContent).getIndex().isInt(i) or - result = TSplatContent(i, _) - | - i >= lower - ) + exists(int i | result.(Content::KnownElementContent).getIndex().isInt(i) | i >= lower) or includeUnknown = true and result = TUnknownElementContent() @@ -821,9 +815,6 @@ class ContentSet extends TContentSet { | type = result.(Content::KnownElementContent).getIndex().getValueType() or - type = "int" and - result instanceof Content::SplatContent - or type = result.(Content::HashSplatContent).getKey().getValueType() or includeUnknown = true and diff --git a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected index 84dc5fa3728..9f3e900d25d 100644 --- a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected +++ b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected @@ -78,14 +78,14 @@ edges | semantics.rb:60:5:60:5 | a | semantics.rb:66:14:66:15 | &... | provenance | | | semantics.rb:60:9:60:18 | call to source | semantics.rb:60:5:60:5 | a | provenance | | | semantics.rb:60:9:60:18 | call to source | semantics.rb:60:5:60:5 | a | provenance | | -| semantics.rb:61:10:61:15 | call to s10 [splat position 0] | semantics.rb:61:10:61:15 | call to s10 | provenance | | +| semantics.rb:61:10:61:15 | call to s10 [element 0] | semantics.rb:61:10:61:15 | call to s10 | provenance | | | semantics.rb:61:14:61:14 | a | semantics.rb:61:10:61:15 | call to s10 | provenance | | | semantics.rb:61:14:61:14 | a | semantics.rb:61:10:61:15 | call to s10 | provenance | | -| semantics.rb:61:14:61:14 | a | semantics.rb:61:10:61:15 | call to s10 [splat position 0] | provenance | | -| semantics.rb:62:10:62:18 | call to s10 [splat position 1] | semantics.rb:62:10:62:18 | call to s10 | provenance | | +| semantics.rb:61:14:61:14 | a | semantics.rb:61:10:61:15 | call to s10 [element 0] | provenance | | +| semantics.rb:62:10:62:18 | call to s10 [element 1] | semantics.rb:62:10:62:18 | call to s10 | provenance | | | semantics.rb:62:17:62:17 | a | semantics.rb:62:10:62:18 | call to s10 | provenance | | | semantics.rb:62:17:62:17 | a | semantics.rb:62:10:62:18 | call to s10 | provenance | | -| semantics.rb:62:17:62:17 | a | semantics.rb:62:10:62:18 | call to s10 [splat position 1] | provenance | | +| semantics.rb:62:17:62:17 | a | semantics.rb:62:10:62:18 | call to s10 [element 1] | provenance | | | semantics.rb:63:19:63:19 | a | semantics.rb:63:10:63:20 | call to s10 | provenance | | | semantics.rb:63:19:63:19 | a | semantics.rb:63:10:63:20 | call to s10 | provenance | | | semantics.rb:64:27:64:27 | a | semantics.rb:64:10:64:28 | call to s10 | provenance | | @@ -192,18 +192,18 @@ edges | semantics.rb:126:5:126:5 | b | semantics.rb:129:17:129:17 | b | provenance | | | semantics.rb:126:9:126:18 | call to source | semantics.rb:126:5:126:5 | b | provenance | | | semantics.rb:126:9:126:18 | call to source | semantics.rb:126:5:126:5 | b | provenance | | -| semantics.rb:127:10:127:18 | call to s17 [splat position 0] | semantics.rb:127:10:127:18 | call to s17 | provenance | | -| semantics.rb:127:10:127:18 | call to s17 [splat position 1] | semantics.rb:127:10:127:18 | call to s17 | provenance | | -| semantics.rb:127:14:127:14 | a | semantics.rb:127:10:127:18 | call to s17 [splat position 0] | provenance | | -| semantics.rb:127:17:127:17 | b | semantics.rb:127:10:127:18 | call to s17 [splat position 1] | provenance | | -| semantics.rb:128:10:128:18 | call to s17 [splat position 0] | semantics.rb:128:10:128:21 | ...[...] | provenance | | -| semantics.rb:128:10:128:18 | call to s17 [splat position 0] | semantics.rb:128:10:128:21 | ...[...] | provenance | | -| semantics.rb:128:14:128:14 | a | semantics.rb:128:10:128:18 | call to s17 [splat position 0] | provenance | | -| semantics.rb:128:14:128:14 | a | semantics.rb:128:10:128:18 | call to s17 [splat position 0] | provenance | | -| semantics.rb:129:10:129:18 | call to s17 [splat position 1] | semantics.rb:129:10:129:21 | ...[...] | provenance | | -| semantics.rb:129:10:129:18 | call to s17 [splat position 1] | semantics.rb:129:10:129:21 | ...[...] | provenance | | -| semantics.rb:129:17:129:17 | b | semantics.rb:129:10:129:18 | call to s17 [splat position 1] | provenance | | -| semantics.rb:129:17:129:17 | b | semantics.rb:129:10:129:18 | call to s17 [splat position 1] | provenance | | +| semantics.rb:127:10:127:18 | call to s17 [element 0] | semantics.rb:127:10:127:18 | call to s17 | provenance | | +| semantics.rb:127:10:127:18 | call to s17 [element 1] | semantics.rb:127:10:127:18 | call to s17 | provenance | | +| semantics.rb:127:14:127:14 | a | semantics.rb:127:10:127:18 | call to s17 [element 0] | provenance | | +| semantics.rb:127:17:127:17 | b | semantics.rb:127:10:127:18 | call to s17 [element 1] | provenance | | +| semantics.rb:128:10:128:18 | call to s17 [element 0] | semantics.rb:128:10:128:21 | ...[...] | provenance | | +| semantics.rb:128:10:128:18 | call to s17 [element 0] | semantics.rb:128:10:128:21 | ...[...] | provenance | | +| semantics.rb:128:14:128:14 | a | semantics.rb:128:10:128:18 | call to s17 [element 0] | provenance | | +| semantics.rb:128:14:128:14 | a | semantics.rb:128:10:128:18 | call to s17 [element 0] | provenance | | +| semantics.rb:129:10:129:18 | call to s17 [element 1] | semantics.rb:129:10:129:21 | ...[...] | provenance | | +| semantics.rb:129:10:129:18 | call to s17 [element 1] | semantics.rb:129:10:129:21 | ...[...] | provenance | | +| semantics.rb:129:17:129:17 | b | semantics.rb:129:10:129:18 | call to s17 [element 1] | provenance | | +| semantics.rb:129:17:129:17 | b | semantics.rb:129:10:129:18 | call to s17 [element 1] | provenance | | | semantics.rb:133:5:133:5 | a | semantics.rb:135:12:135:12 | a | provenance | | | semantics.rb:133:5:133:5 | a | semantics.rb:135:12:135:12 | a | provenance | | | semantics.rb:133:5:133:5 | a | semantics.rb:137:14:137:14 | a | provenance | | @@ -1191,12 +1191,12 @@ nodes | semantics.rb:60:9:60:18 | call to source | semmle.label | call to source | | semantics.rb:61:10:61:15 | call to s10 | semmle.label | call to s10 | | semantics.rb:61:10:61:15 | call to s10 | semmle.label | call to s10 | -| semantics.rb:61:10:61:15 | call to s10 [splat position 0] | semmle.label | call to s10 [splat position 0] | +| semantics.rb:61:10:61:15 | call to s10 [element 0] | semmle.label | call to s10 [element 0] | | semantics.rb:61:14:61:14 | a | semmle.label | a | | semantics.rb:61:14:61:14 | a | semmle.label | a | | semantics.rb:62:10:62:18 | call to s10 | semmle.label | call to s10 | | semantics.rb:62:10:62:18 | call to s10 | semmle.label | call to s10 | -| semantics.rb:62:10:62:18 | call to s10 [splat position 1] | semmle.label | call to s10 [splat position 1] | +| semantics.rb:62:10:62:18 | call to s10 [element 1] | semmle.label | call to s10 [element 1] | | semantics.rb:62:17:62:17 | a | semmle.label | a | | semantics.rb:62:17:62:17 | a | semmle.label | a | | semantics.rb:63:10:63:20 | call to s10 | semmle.label | call to s10 | @@ -1322,18 +1322,18 @@ nodes | semantics.rb:126:9:126:18 | call to source | semmle.label | call to source | | semantics.rb:126:9:126:18 | call to source | semmle.label | call to source | | semantics.rb:127:10:127:18 | call to s17 | semmle.label | call to s17 | -| semantics.rb:127:10:127:18 | call to s17 [splat position 0] | semmle.label | call to s17 [splat position 0] | -| semantics.rb:127:10:127:18 | call to s17 [splat position 1] | semmle.label | call to s17 [splat position 1] | +| semantics.rb:127:10:127:18 | call to s17 [element 0] | semmle.label | call to s17 [element 0] | +| semantics.rb:127:10:127:18 | call to s17 [element 1] | semmle.label | call to s17 [element 1] | | semantics.rb:127:14:127:14 | a | semmle.label | a | | semantics.rb:127:17:127:17 | b | semmle.label | b | -| semantics.rb:128:10:128:18 | call to s17 [splat position 0] | semmle.label | call to s17 [splat position 0] | -| semantics.rb:128:10:128:18 | call to s17 [splat position 0] | semmle.label | call to s17 [splat position 0] | +| semantics.rb:128:10:128:18 | call to s17 [element 0] | semmle.label | call to s17 [element 0] | +| semantics.rb:128:10:128:18 | call to s17 [element 0] | semmle.label | call to s17 [element 0] | | semantics.rb:128:10:128:21 | ...[...] | semmle.label | ...[...] | | semantics.rb:128:10:128:21 | ...[...] | semmle.label | ...[...] | | semantics.rb:128:14:128:14 | a | semmle.label | a | | semantics.rb:128:14:128:14 | a | semmle.label | a | -| semantics.rb:129:10:129:18 | call to s17 [splat position 1] | semmle.label | call to s17 [splat position 1] | -| semantics.rb:129:10:129:18 | call to s17 [splat position 1] | semmle.label | call to s17 [splat position 1] | +| semantics.rb:129:10:129:18 | call to s17 [element 1] | semmle.label | call to s17 [element 1] | +| semantics.rb:129:10:129:18 | call to s17 [element 1] | semmle.label | call to s17 [element 1] | | semantics.rb:129:10:129:21 | ...[...] | semmle.label | ...[...] | | semantics.rb:129:10:129:21 | ...[...] | semmle.label | ...[...] | | semantics.rb:129:17:129:17 | b | semmle.label | b | diff --git a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected index 09e1598caf5..90b41808613 100644 --- a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected +++ b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected @@ -56,12 +56,43 @@ track | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:181:28:181:29 | p2 | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:200:9:200:9 | x | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:65:5:65:13 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:108:1:112:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:108:40:108:41 | *b | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:109:5:109:10 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:110:5:110:13 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:133:14:133:18 | *args | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:134:5:134:16 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:200:1:205:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 or unknown | params_flow.rb:64:16:64:17 | *x | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:15 | [post] ...[...] | @@ -74,11 +105,26 @@ track | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 or unknown | params_flow.rb:182:5:182:20 | call to insert | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:108:1:112:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:133:14:133:18 | *args | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:167:21:167:28 | *posargs | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:181:1:183:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 2 | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 2 | params_flow.rb:133:14:133:18 | *args | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 3 | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 4 | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 5 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element :p1 | params_flow.rb:25:17:25:24 | **kwargs | @@ -99,69 +145,6 @@ track | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:65:5:65:13 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:108:1:112:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:109:5:109:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:110:5:110:13 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 0 | params_flow.rb:134:5:134:16 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:108:1:112:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:167:21:167:28 | *posargs | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:181:1:183:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:98:1:103:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:98:1:103:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 3 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 3 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 4 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 4 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content splat position 5 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker without call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:1:11:1:11 | x | type tracker without call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:1:11:1:11 | x | type tracker without call steps | params_flow.rb:14:12:14:19 | call to taint | @@ -249,30 +232,41 @@ track | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content attribute [] | params_flow.rb:117:1:117:1 | [post] x | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element | params_flow.rb:117:1:117:1 | [post] x | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element | params_flow.rb:118:12:118:13 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:14:1:14:30 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:43:8:43:18 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:43:8:43:18 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:44:1:44:28 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:44:23:44:27 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:46:8:46:29 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:46:8:46:29 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:47:12:47:16 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:55:1:55:29 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:57:8:57:18 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:57:8:57:18 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:58:20:58:24 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:60:8:60:29 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:60:8:60:29 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:61:9:61:13 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:80:8:80:51 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:81:21:81:25 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:93:8:93:51 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:94:32:94:36 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:96:33:96:65 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:105:27:105:48 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:106:1:106:46 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:114:1:114:67 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:128:10:128:31 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:128:10:128:31 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:128:34:128:60 | call to [] | @@ -287,24 +281,36 @@ track | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:195:12:198:1 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 | params_flow.rb:207:5:207:13 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 0 or unknown | params_flow.rb:67:12:67:16 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:14:1:14:30 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:44:1:44:28 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:46:8:46:29 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:46:8:46:29 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:47:12:47:16 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:55:1:55:29 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:60:8:60:29 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:60:8:60:29 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:61:9:61:13 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:80:8:80:51 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:81:21:81:25 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:93:8:93:51 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:94:32:94:36 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:96:33:96:65 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:105:27:105:48 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:106:1:106:46 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:114:1:114:67 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:117:1:117:15 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:128:10:128:31 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:128:10:128:31 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:128:46:128:59 | call to [] | @@ -318,27 +324,44 @@ track | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:171:11:171:27 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:171:11:171:27 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:173:17:173:24 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:178:1:178:30 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:185:8:185:24 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:185:8:185:24 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:187:20:187:24 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 1 | params_flow.rb:192:1:192:33 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:80:8:80:51 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:81:21:81:25 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:93:8:93:51 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:94:32:94:36 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:96:33:96:65 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:105:1:105:49 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:106:1:106:46 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:137:10:137:43 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:137:11:137:43 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 2 | params_flow.rb:137:11:137:43 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:80:8:80:51 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:81:21:81:25 | * ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:93:8:93:51 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:94:32:94:36 | * ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 3 | params_flow.rb:96:1:96:88 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 4 | params_flow.rb:78:1:78:63 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 4 | params_flow.rb:81:1:81:37 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 4 | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 4 | params_flow.rb:96:1:96:88 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 5 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:37:8:37:44 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:37:8:37:44 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:38:8:38:13 | ** ... | @@ -371,53 +394,13 @@ track | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p3 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:14:1:14:30 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:44:1:44:28 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:55:1:55:29 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:58:1:58:25 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:106:1:106:46 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 0 | params_flow.rb:114:1:114:67 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:14:1:14:30 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:55:1:55:29 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:106:1:106:46 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:114:1:114:67 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:117:1:117:15 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:178:1:178:30 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 | params_flow.rb:192:1:192:33 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:44:1:44:28 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:58:1:58:25 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 2 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 2 | params_flow.rb:106:1:106:46 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 3 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 3 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 3 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 3 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 4 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 4 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 4 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 4 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content splat position 5 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:5:1:7:3 | &block | type tracker without call steps | params_flow.rb:5:1:7:3 | &block | | params_flow.rb:5:1:7:3 | self in sink | type tracker without call steps | params_flow.rb:5:1:7:3 | self in sink | | params_flow.rb:5:1:7:3 | sink | type tracker without call steps | params_flow.rb:5:1:7:3 | sink | | params_flow.rb:5:1:7:3 | synthetic splat parameter | type tracker without call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:5:10:5:10 | x | type tracker without call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:5:10:5:10 | x | type tracker without call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:5:10:5:10 | x | type tracker without call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:5:10:5:10 | x | type tracker without call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:6:5:6:10 | call to puts | type tracker without call steps | params_flow.rb:6:5:6:10 | call to puts | | params_flow.rb:6:5:6:10 | call to puts | type tracker without call steps | params_flow.rb:10:5:10:11 | call to sink | | params_flow.rb:6:5:6:10 | call to puts | type tracker without call steps | params_flow.rb:11:5:11:11 | call to sink | @@ -511,100 +494,79 @@ track | params_flow.rb:9:1:12:3 | self in positional | type tracker without call steps | params_flow.rb:9:1:12:3 | self in positional | | params_flow.rb:9:1:12:3 | synthetic splat parameter | type tracker without call steps | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:9:16:9:17 | p1 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:9:16:9:17 | p1 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:9:16:9:17 | p1 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:9:16:9:17 | p1 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:9:16:9:17 | p1 | type tracker without call steps | params_flow.rb:9:16:9:17 | p1 | | params_flow.rb:9:16:9:17 | p1 | type tracker without call steps | params_flow.rb:9:16:9:17 | p1 | -| params_flow.rb:9:16:9:17 | p1 | type tracker without call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:9:16:9:17 | p1 | type tracker without call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:9:20:9:21 | p2 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:9:20:9:21 | p2 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:9:20:9:21 | p2 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:9:20:9:21 | p2 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:9:20:9:21 | p2 | type tracker without call steps | params_flow.rb:9:20:9:21 | p2 | | params_flow.rb:9:20:9:21 | p2 | type tracker without call steps | params_flow.rb:9:20:9:21 | p2 | -| params_flow.rb:9:20:9:21 | p2 | type tracker without call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | +| params_flow.rb:9:20:9:21 | p2 | type tracker without call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:10:5:10:11 | call to sink | type tracker without call steps | params_flow.rb:10:5:10:11 | call to sink | -| params_flow.rb:10:5:10:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:10:5:10:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:11:5:11:11 | call to sink | type tracker without call steps | params_flow.rb:11:5:11:11 | call to sink | | params_flow.rb:11:5:11:11 | call to sink | type tracker without call steps | params_flow.rb:14:1:14:30 | call to positional | | params_flow.rb:11:5:11:11 | call to sink | type tracker without call steps | params_flow.rb:44:1:44:28 | call to positional | | params_flow.rb:11:5:11:11 | call to sink | type tracker without call steps | params_flow.rb:47:1:47:17 | call to positional | | params_flow.rb:11:5:11:11 | call to sink | type tracker without call steps | params_flow.rb:118:1:118:14 | call to positional | -| params_flow.rb:11:5:11:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:11:5:11:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:14:1:14:30 | call to positional | type tracker without call steps | params_flow.rb:14:1:14:30 | call to positional | -| params_flow.rb:14:1:14:30 | synthetic splat argument | type tracker with call steps | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:14:1:14:30 | synthetic splat argument | type tracker without call steps | params_flow.rb:14:1:14:30 | synthetic splat argument | | params_flow.rb:14:12:14:19 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:14:12:14:19 | call to taint | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | -| params_flow.rb:14:12:14:19 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:14:12:14:19 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:14:12:14:19 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:14:12:14:19 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:14:12:14:19 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:14:12:14:19 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:14:12:14:19 | call to taint | type tracker without call steps | params_flow.rb:14:12:14:19 | call to taint | -| params_flow.rb:14:12:14:19 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:14:1:14:30 | synthetic splat argument | -| params_flow.rb:14:12:14:19 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:14:12:14:19 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:14:1:14:30 | synthetic splat argument | | params_flow.rb:14:12:14:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:14:12:14:19 | synthetic splat argument | | params_flow.rb:14:18:14:18 | 1 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:14:18:14:18 | 1 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:14:18:14:18 | 1 | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | -| params_flow.rb:14:18:14:18 | 1 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:14:18:14:18 | 1 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:14:18:14:18 | 1 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:14:18:14:18 | 1 | type tracker with call steps with content splat position 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:14:18:14:18 | 1 | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:14:18:14:18 | 1 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:14:18:14:18 | 1 | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:14:18:14:18 | 1 | type tracker without call steps | params_flow.rb:14:12:14:19 | call to taint | | params_flow.rb:14:18:14:18 | 1 | type tracker without call steps | params_flow.rb:14:18:14:18 | 1 | -| params_flow.rb:14:18:14:18 | 1 | type tracker without call steps with content splat position 0 | params_flow.rb:14:1:14:30 | synthetic splat argument | -| params_flow.rb:14:18:14:18 | 1 | type tracker without call steps with content splat position 0 | params_flow.rb:14:12:14:19 | synthetic splat argument | +| params_flow.rb:14:18:14:18 | 1 | type tracker without call steps with content element 0 | params_flow.rb:14:1:14:30 | synthetic splat argument | +| params_flow.rb:14:18:14:18 | 1 | type tracker without call steps with content element 0 | params_flow.rb:14:12:14:19 | synthetic splat argument | | params_flow.rb:14:22:14:29 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:14:22:14:29 | call to taint | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | -| params_flow.rb:14:22:14:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:14:22:14:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:14:22:14:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | -| params_flow.rb:14:22:14:29 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:14:22:14:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:14:22:14:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:14:22:14:29 | call to taint | type tracker without call steps | params_flow.rb:14:22:14:29 | call to taint | -| params_flow.rb:14:22:14:29 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:14:1:14:30 | synthetic splat argument | -| params_flow.rb:14:22:14:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:14:22:14:29 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:14:1:14:30 | synthetic splat argument | | params_flow.rb:14:22:14:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:14:22:14:29 | synthetic splat argument | | params_flow.rb:14:28:14:28 | 2 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:14:28:14:28 | 2 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:14:28:14:28 | 2 | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | -| params_flow.rb:14:28:14:28 | 2 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:14:28:14:28 | 2 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:14:28:14:28 | 2 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:14:28:14:28 | 2 | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | -| params_flow.rb:14:28:14:28 | 2 | type tracker with call steps with content splat position 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:14:28:14:28 | 2 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:14:28:14:28 | 2 | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:14:28:14:28 | 2 | type tracker without call steps | params_flow.rb:14:22:14:29 | call to taint | | params_flow.rb:14:28:14:28 | 2 | type tracker without call steps | params_flow.rb:14:28:14:28 | 2 | -| params_flow.rb:14:28:14:28 | 2 | type tracker without call steps with content splat position 0 | params_flow.rb:14:22:14:29 | synthetic splat argument | -| params_flow.rb:14:28:14:28 | 2 | type tracker without call steps with content splat position 1 | params_flow.rb:14:1:14:30 | synthetic splat argument | +| params_flow.rb:14:28:14:28 | 2 | type tracker without call steps with content element 0 | params_flow.rb:14:22:14:29 | synthetic splat argument | +| params_flow.rb:14:28:14:28 | 2 | type tracker without call steps with content element 1 | params_flow.rb:14:1:14:30 | synthetic splat argument | | params_flow.rb:16:1:19:3 | &block | type tracker without call steps | params_flow.rb:16:1:19:3 | &block | | params_flow.rb:16:1:19:3 | keyword | type tracker without call steps | params_flow.rb:16:1:19:3 | keyword | | params_flow.rb:16:1:19:3 | self in keyword | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | | params_flow.rb:16:1:19:3 | self in keyword | type tracker without call steps | params_flow.rb:16:1:19:3 | self in keyword | | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | type tracker without call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:16:13:16:14 | p1 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:16:13:16:14 | p1 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:16:13:16:14 | p1 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:16:13:16:14 | p1 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:16:13:16:14 | p1 | type tracker without call steps | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:16:13:16:14 | p1 | type tracker without call steps | params_flow.rb:16:13:16:14 | p1 | -| params_flow.rb:16:13:16:14 | p1 | type tracker without call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | +| params_flow.rb:16:13:16:14 | p1 | type tracker without call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:16:18:16:19 | p2 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:16:18:16:19 | p2 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:16:18:16:19 | p2 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:16:18:16:19 | p2 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:16:18:16:19 | p2 | type tracker without call steps | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:16:18:16:19 | p2 | type tracker without call steps | params_flow.rb:16:18:16:19 | p2 | -| params_flow.rb:16:18:16:19 | p2 | type tracker without call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | +| params_flow.rb:16:18:16:19 | p2 | type tracker without call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:17:5:17:11 | call to sink | type tracker without call steps | params_flow.rb:17:5:17:11 | call to sink | -| params_flow.rb:17:5:17:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:17:5:17:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:18:5:18:11 | call to sink | type tracker without call steps | params_flow.rb:18:5:18:11 | call to sink | | params_flow.rb:18:5:18:11 | call to sink | type tracker without call steps | params_flow.rb:21:1:21:35 | call to keyword | | params_flow.rb:18:5:18:11 | call to sink | type tracker without call steps | params_flow.rb:22:1:22:35 | call to keyword | | params_flow.rb:18:5:18:11 | call to sink | type tracker without call steps | params_flow.rb:23:1:23:41 | call to keyword | | params_flow.rb:18:5:18:11 | call to sink | type tracker without call steps | params_flow.rb:41:1:41:30 | call to keyword | -| params_flow.rb:18:5:18:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:18:5:18:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:21:1:21:35 | call to keyword | type tracker without call steps | params_flow.rb:21:1:21:35 | call to keyword | | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | @@ -613,50 +575,42 @@ track | params_flow.rb:21:9:21:20 | Pair | type tracker without call steps | params_flow.rb:21:9:21:20 | Pair | | params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | +| params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:21:13:21:20 | call to taint | type tracker without call steps | params_flow.rb:21:13:21:20 | call to taint | | params_flow.rb:21:13:21:20 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | -| params_flow.rb:21:13:21:20 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:21:13:21:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:21:13:21:20 | synthetic splat argument | | params_flow.rb:21:19:21:19 | 3 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:21:19:21:19 | 3 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:21:19:21:19 | 3 | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | +| params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:21:19:21:19 | 3 | type tracker without call steps | params_flow.rb:21:13:21:20 | call to taint | | params_flow.rb:21:19:21:19 | 3 | type tracker without call steps | params_flow.rb:21:19:21:19 | 3 | +| params_flow.rb:21:19:21:19 | 3 | type tracker without call steps with content element 0 | params_flow.rb:21:13:21:20 | synthetic splat argument | | params_flow.rb:21:19:21:19 | 3 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | -| params_flow.rb:21:19:21:19 | 3 | type tracker without call steps with content splat position 0 | params_flow.rb:21:13:21:20 | synthetic splat argument | | params_flow.rb:21:23:21:24 | :p2 | type tracker without call steps | params_flow.rb:21:23:21:24 | :p2 | | params_flow.rb:21:23:21:34 | Pair | type tracker without call steps | params_flow.rb:21:23:21:34 | Pair | | params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | +| params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:21:27:21:34 | call to taint | type tracker without call steps | params_flow.rb:21:27:21:34 | call to taint | | params_flow.rb:21:27:21:34 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | -| params_flow.rb:21:27:21:34 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:21:27:21:34 | synthetic splat argument | type tracker without call steps | params_flow.rb:21:27:21:34 | synthetic splat argument | | params_flow.rb:21:33:21:33 | 4 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:21:33:21:33 | 4 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:21:33:21:33 | 4 | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | +| params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:21:33:21:33 | 4 | type tracker without call steps | params_flow.rb:21:27:21:34 | call to taint | | params_flow.rb:21:33:21:33 | 4 | type tracker without call steps | params_flow.rb:21:33:21:33 | 4 | +| params_flow.rb:21:33:21:33 | 4 | type tracker without call steps with content element 0 | params_flow.rb:21:27:21:34 | synthetic splat argument | | params_flow.rb:21:33:21:33 | 4 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | -| params_flow.rb:21:33:21:33 | 4 | type tracker without call steps with content splat position 0 | params_flow.rb:21:27:21:34 | synthetic splat argument | | params_flow.rb:22:1:22:35 | call to keyword | type tracker without call steps | params_flow.rb:22:1:22:35 | call to keyword | | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | @@ -664,50 +618,42 @@ track | params_flow.rb:22:9:22:20 | Pair | type tracker without call steps | params_flow.rb:22:9:22:20 | Pair | | params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | +| params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:22:13:22:20 | call to taint | type tracker without call steps | params_flow.rb:22:13:22:20 | call to taint | | params_flow.rb:22:13:22:20 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | -| params_flow.rb:22:13:22:20 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:22:13:22:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:22:13:22:20 | synthetic splat argument | | params_flow.rb:22:19:22:19 | 5 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:22:19:22:19 | 5 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:22:19:22:19 | 5 | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | +| params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:22:19:22:19 | 5 | type tracker without call steps | params_flow.rb:22:13:22:20 | call to taint | | params_flow.rb:22:19:22:19 | 5 | type tracker without call steps | params_flow.rb:22:19:22:19 | 5 | +| params_flow.rb:22:19:22:19 | 5 | type tracker without call steps with content element 0 | params_flow.rb:22:13:22:20 | synthetic splat argument | | params_flow.rb:22:19:22:19 | 5 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | -| params_flow.rb:22:19:22:19 | 5 | type tracker without call steps with content splat position 0 | params_flow.rb:22:13:22:20 | synthetic splat argument | | params_flow.rb:22:23:22:24 | :p1 | type tracker without call steps | params_flow.rb:22:23:22:24 | :p1 | | params_flow.rb:22:23:22:34 | Pair | type tracker without call steps | params_flow.rb:22:23:22:34 | Pair | | params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | +| params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:22:27:22:34 | call to taint | type tracker without call steps | params_flow.rb:22:27:22:34 | call to taint | | params_flow.rb:22:27:22:34 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | -| params_flow.rb:22:27:22:34 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:22:27:22:34 | synthetic splat argument | type tracker without call steps | params_flow.rb:22:27:22:34 | synthetic splat argument | | params_flow.rb:22:33:22:33 | 6 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:22:33:22:33 | 6 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:22:33:22:33 | 6 | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | +| params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:22:33:22:33 | 6 | type tracker without call steps | params_flow.rb:22:27:22:34 | call to taint | | params_flow.rb:22:33:22:33 | 6 | type tracker without call steps | params_flow.rb:22:33:22:33 | 6 | +| params_flow.rb:22:33:22:33 | 6 | type tracker without call steps with content element 0 | params_flow.rb:22:27:22:34 | synthetic splat argument | | params_flow.rb:22:33:22:33 | 6 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | -| params_flow.rb:22:33:22:33 | 6 | type tracker without call steps with content splat position 0 | params_flow.rb:22:27:22:34 | synthetic splat argument | | params_flow.rb:23:1:23:41 | call to keyword | type tracker without call steps | params_flow.rb:23:1:23:41 | call to keyword | | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | @@ -715,113 +661,95 @@ track | params_flow.rb:23:9:23:23 | Pair | type tracker without call steps | params_flow.rb:23:9:23:23 | Pair | | params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | +| params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:23:16:23:23 | call to taint | type tracker without call steps | params_flow.rb:23:16:23:23 | call to taint | | params_flow.rb:23:16:23:23 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | -| params_flow.rb:23:16:23:23 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:23:16:23:23 | synthetic splat argument | type tracker without call steps | params_flow.rb:23:16:23:23 | synthetic splat argument | | params_flow.rb:23:22:23:22 | 7 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:23:22:23:22 | 7 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:23:22:23:22 | 7 | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | +| params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:23:22:23:22 | 7 | type tracker without call steps | params_flow.rb:23:16:23:23 | call to taint | | params_flow.rb:23:22:23:22 | 7 | type tracker without call steps | params_flow.rb:23:22:23:22 | 7 | +| params_flow.rb:23:22:23:22 | 7 | type tracker without call steps with content element 0 | params_flow.rb:23:16:23:23 | synthetic splat argument | | params_flow.rb:23:22:23:22 | 7 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | -| params_flow.rb:23:22:23:22 | 7 | type tracker without call steps with content splat position 0 | params_flow.rb:23:16:23:23 | synthetic splat argument | | params_flow.rb:23:26:23:28 | :p1 | type tracker without call steps | params_flow.rb:23:26:23:28 | :p1 | | params_flow.rb:23:26:23:40 | Pair | type tracker without call steps | params_flow.rb:23:26:23:40 | Pair | | params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | +| params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:23:33:23:40 | call to taint | type tracker without call steps | params_flow.rb:23:33:23:40 | call to taint | | params_flow.rb:23:33:23:40 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | -| params_flow.rb:23:33:23:40 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:23:33:23:40 | synthetic splat argument | type tracker without call steps | params_flow.rb:23:33:23:40 | synthetic splat argument | | params_flow.rb:23:39:23:39 | 8 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:23:39:23:39 | 8 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:23:39:23:39 | 8 | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | +| params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:23:39:23:39 | 8 | type tracker without call steps | params_flow.rb:23:33:23:40 | call to taint | | params_flow.rb:23:39:23:39 | 8 | type tracker without call steps | params_flow.rb:23:39:23:39 | 8 | +| params_flow.rb:23:39:23:39 | 8 | type tracker without call steps with content element 0 | params_flow.rb:23:33:23:40 | synthetic splat argument | | params_flow.rb:23:39:23:39 | 8 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | -| params_flow.rb:23:39:23:39 | 8 | type tracker without call steps with content splat position 0 | params_flow.rb:23:33:23:40 | synthetic splat argument | | params_flow.rb:25:1:31:3 | &block | type tracker without call steps | params_flow.rb:25:1:31:3 | &block | | params_flow.rb:25:1:31:3 | kwargs | type tracker without call steps | params_flow.rb:25:1:31:3 | kwargs | | params_flow.rb:25:1:31:3 | self in kwargs | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | | params_flow.rb:25:1:31:3 | self in kwargs | type tracker without call steps | params_flow.rb:25:1:31:3 | self in kwargs | | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | type tracker without call steps | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:25:12:25:13 | p1 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:25:12:25:13 | p1 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:25:12:25:13 | p1 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:25:12:25:13 | p1 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:25:12:25:13 | p1 | type tracker without call steps | params_flow.rb:25:12:25:13 | p1 | | params_flow.rb:25:12:25:13 | p1 | type tracker without call steps | params_flow.rb:25:12:25:13 | p1 | -| params_flow.rb:25:12:25:13 | p1 | type tracker without call steps with content splat position 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | +| params_flow.rb:25:12:25:13 | p1 | type tracker without call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | | params_flow.rb:25:17:25:24 | **kwargs | type tracker without call steps | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:25:19:25:24 | kwargs | type tracker without call steps | params_flow.rb:25:19:25:24 | kwargs | | params_flow.rb:26:5:26:11 | call to sink | type tracker without call steps | params_flow.rb:26:5:26:11 | call to sink | -| params_flow.rb:26:5:26:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:26:5:26:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:26:5:26:11 | synthetic splat argument | | params_flow.rb:27:5:27:22 | call to sink | type tracker without call steps | params_flow.rb:27:5:27:22 | call to sink | -| params_flow.rb:27:5:27:22 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:27:5:27:22 | synthetic splat argument | type tracker without call steps | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:27:11:27:21 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:27:11:27:21 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:27:11:27:21 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:27:11:27:21 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:27:11:27:21 | ...[...] | type tracker without call steps | params_flow.rb:27:11:27:21 | ...[...] | -| params_flow.rb:27:11:27:21 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | +| params_flow.rb:27:11:27:21 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:27:11:27:21 | synthetic splat argument | type tracker without call steps | params_flow.rb:27:11:27:21 | synthetic splat argument | | params_flow.rb:27:18:27:20 | :p1 | type tracker without call steps | params_flow.rb:27:18:27:20 | :p1 | -| params_flow.rb:27:18:27:20 | :p1 | type tracker without call steps with content splat position 0 | params_flow.rb:27:11:27:21 | synthetic splat argument | +| params_flow.rb:27:18:27:20 | :p1 | type tracker without call steps with content element 0 | params_flow.rb:27:11:27:21 | synthetic splat argument | | params_flow.rb:28:5:28:22 | call to sink | type tracker without call steps | params_flow.rb:28:5:28:22 | call to sink | -| params_flow.rb:28:5:28:22 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:28:5:28:22 | synthetic splat argument | type tracker without call steps | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:28:11:28:21 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:28:11:28:21 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:28:11:28:21 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:28:11:28:21 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:28:11:28:21 | ...[...] | type tracker without call steps | params_flow.rb:28:11:28:21 | ...[...] | -| params_flow.rb:28:11:28:21 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | +| params_flow.rb:28:11:28:21 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:28:11:28:21 | synthetic splat argument | type tracker without call steps | params_flow.rb:28:11:28:21 | synthetic splat argument | | params_flow.rb:28:18:28:20 | :p2 | type tracker without call steps | params_flow.rb:28:18:28:20 | :p2 | -| params_flow.rb:28:18:28:20 | :p2 | type tracker without call steps with content splat position 0 | params_flow.rb:28:11:28:21 | synthetic splat argument | +| params_flow.rb:28:18:28:20 | :p2 | type tracker without call steps with content element 0 | params_flow.rb:28:11:28:21 | synthetic splat argument | | params_flow.rb:29:5:29:22 | call to sink | type tracker without call steps | params_flow.rb:29:5:29:22 | call to sink | -| params_flow.rb:29:5:29:22 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:29:5:29:22 | synthetic splat argument | type tracker without call steps | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:29:11:29:21 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:29:11:29:21 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:29:11:29:21 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:29:11:29:21 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:29:11:29:21 | ...[...] | type tracker without call steps | params_flow.rb:29:11:29:21 | ...[...] | -| params_flow.rb:29:11:29:21 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | +| params_flow.rb:29:11:29:21 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:29:11:29:21 | synthetic splat argument | type tracker without call steps | params_flow.rb:29:11:29:21 | synthetic splat argument | | params_flow.rb:29:18:29:20 | :p3 | type tracker without call steps | params_flow.rb:29:18:29:20 | :p3 | -| params_flow.rb:29:18:29:20 | :p3 | type tracker without call steps with content splat position 0 | params_flow.rb:29:11:29:21 | synthetic splat argument | +| params_flow.rb:29:18:29:20 | :p3 | type tracker without call steps with content element 0 | params_flow.rb:29:11:29:21 | synthetic splat argument | | params_flow.rb:30:5:30:22 | call to sink | type tracker without call steps | params_flow.rb:30:5:30:22 | call to sink | | params_flow.rb:30:5:30:22 | call to sink | type tracker without call steps | params_flow.rb:33:1:33:58 | call to kwargs | | params_flow.rb:30:5:30:22 | call to sink | type tracker without call steps | params_flow.rb:35:1:35:29 | call to kwargs | | params_flow.rb:30:5:30:22 | call to sink | type tracker without call steps | params_flow.rb:38:1:38:14 | call to kwargs | -| params_flow.rb:30:5:30:22 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:30:5:30:22 | synthetic splat argument | type tracker without call steps | params_flow.rb:30:5:30:22 | synthetic splat argument | | params_flow.rb:30:11:30:21 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:30:11:30:21 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:30:11:30:21 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:30:11:30:21 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:30:11:30:21 | ...[...] | type tracker without call steps | params_flow.rb:30:11:30:21 | ...[...] | -| params_flow.rb:30:11:30:21 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:30:5:30:22 | synthetic splat argument | +| params_flow.rb:30:11:30:21 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:30:5:30:22 | synthetic splat argument | | params_flow.rb:30:11:30:21 | synthetic splat argument | type tracker without call steps | params_flow.rb:30:11:30:21 | synthetic splat argument | | params_flow.rb:30:18:30:20 | :p4 | type tracker without call steps | params_flow.rb:30:18:30:20 | :p4 | -| params_flow.rb:30:18:30:20 | :p4 | type tracker without call steps with content splat position 0 | params_flow.rb:30:11:30:21 | synthetic splat argument | +| params_flow.rb:30:18:30:20 | :p4 | type tracker without call steps with content element 0 | params_flow.rb:30:11:30:21 | synthetic splat argument | | params_flow.rb:33:1:33:58 | call to kwargs | type tracker without call steps | params_flow.rb:33:1:33:58 | call to kwargs | | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:25:17:25:24 | **kwargs | @@ -831,92 +759,79 @@ track | params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps | params_flow.rb:25:12:25:13 | p1 | | params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps | params_flow.rb:27:11:27:21 | ...[...] | +| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | +| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | -| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:33:12:33:19 | call to taint | type tracker without call steps | params_flow.rb:33:12:33:19 | call to taint | | params_flow.rb:33:12:33:19 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | -| params_flow.rb:33:12:33:19 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:33:12:33:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:33:12:33:19 | synthetic splat argument | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps | params_flow.rb:25:12:25:13 | p1 | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps | params_flow.rb:27:11:27:21 | ...[...] | +| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | +| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content splat position 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | -| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content splat position 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:33:18:33:18 | 9 | type tracker without call steps | params_flow.rb:33:12:33:19 | call to taint | | params_flow.rb:33:18:33:18 | 9 | type tracker without call steps | params_flow.rb:33:18:33:18 | 9 | +| params_flow.rb:33:18:33:18 | 9 | type tracker without call steps with content element 0 | params_flow.rb:33:12:33:19 | synthetic splat argument | | params_flow.rb:33:18:33:18 | 9 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | -| params_flow.rb:33:18:33:18 | 9 | type tracker without call steps with content splat position 0 | params_flow.rb:33:12:33:19 | synthetic splat argument | | params_flow.rb:33:22:33:23 | :p2 | type tracker without call steps | params_flow.rb:33:22:33:23 | :p2 | | params_flow.rb:33:22:33:34 | Pair | type tracker without call steps | params_flow.rb:33:22:33:34 | Pair | | params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps | params_flow.rb:28:11:28:21 | ...[...] | +| params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:33:26:33:34 | call to taint | type tracker without call steps | params_flow.rb:33:26:33:34 | call to taint | | params_flow.rb:33:26:33:34 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | -| params_flow.rb:33:26:33:34 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:33:26:33:34 | synthetic splat argument | type tracker without call steps | params_flow.rb:33:26:33:34 | synthetic splat argument | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps | params_flow.rb:28:11:28:21 | ...[...] | +| params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content element 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content splat position 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:33:32:33:33 | 10 | type tracker without call steps | params_flow.rb:33:26:33:34 | call to taint | | params_flow.rb:33:32:33:33 | 10 | type tracker without call steps | params_flow.rb:33:32:33:33 | 10 | +| params_flow.rb:33:32:33:33 | 10 | type tracker without call steps with content element 0 | params_flow.rb:33:26:33:34 | synthetic splat argument | | params_flow.rb:33:32:33:33 | 10 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | -| params_flow.rb:33:32:33:33 | 10 | type tracker without call steps with content splat position 0 | params_flow.rb:33:26:33:34 | synthetic splat argument | | params_flow.rb:33:37:33:38 | :p3 | type tracker without call steps | params_flow.rb:33:37:33:38 | :p3 | | params_flow.rb:33:37:33:49 | Pair | type tracker without call steps | params_flow.rb:33:37:33:49 | Pair | | params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps | params_flow.rb:29:11:29:21 | ...[...] | +| params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:33:41:33:49 | call to taint | type tracker without call steps | params_flow.rb:33:41:33:49 | call to taint | | params_flow.rb:33:41:33:49 | call to taint | type tracker without call steps with content hash-splat position :p3 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | -| params_flow.rb:33:41:33:49 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:33:41:33:49 | synthetic splat argument | type tracker without call steps | params_flow.rb:33:41:33:49 | synthetic splat argument | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps | params_flow.rb:29:11:29:21 | ...[...] | +| params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content element 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content splat position 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:33:47:33:48 | 11 | type tracker without call steps | params_flow.rb:33:41:33:49 | call to taint | | params_flow.rb:33:47:33:48 | 11 | type tracker without call steps | params_flow.rb:33:47:33:48 | 11 | +| params_flow.rb:33:47:33:48 | 11 | type tracker without call steps with content element 0 | params_flow.rb:33:41:33:49 | synthetic splat argument | | params_flow.rb:33:47:33:48 | 11 | type tracker without call steps with content hash-splat position :p3 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | -| params_flow.rb:33:47:33:48 | 11 | type tracker without call steps with content splat position 0 | params_flow.rb:33:41:33:49 | synthetic splat argument | | params_flow.rb:33:52:33:53 | :p4 | type tracker without call steps | params_flow.rb:33:52:33:53 | :p4 | | params_flow.rb:33:52:33:57 | Pair | type tracker without call steps | params_flow.rb:33:52:33:57 | Pair | | params_flow.rb:33:56:33:57 | "" | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:56:33:57 | "" | type tracker with call steps | params_flow.rb:30:11:30:21 | ...[...] | +| params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content element 0 | params_flow.rb:30:5:30:22 | synthetic splat argument | | params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content hash-splat position :p4 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content hash-splat position :p4 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content splat position 0 | params_flow.rb:30:5:30:22 | synthetic splat argument | | params_flow.rb:33:56:33:57 | "" | type tracker without call steps | params_flow.rb:33:56:33:57 | "" | | params_flow.rb:33:56:33:57 | "" | type tracker without call steps with content hash-splat position :p4 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:34:1:34:4 | args | type tracker without call steps | params_flow.rb:34:1:34:4 | args | @@ -928,41 +843,36 @@ track | params_flow.rb:34:10:34:22 | Pair | type tracker without call steps | params_flow.rb:34:10:34:22 | Pair | | params_flow.rb:34:14:34:22 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:34:14:34:22 | call to taint | type tracker with call steps | params_flow.rb:29:11:29:21 | ...[...] | +| params_flow.rb:34:14:34:22 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:34:14:34:22 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:34:14:34:22 | call to taint | type tracker with call steps with content element :p3 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:34:14:34:22 | call to taint | type tracker with call steps with content element :p3 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:34:14:34:22 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:34:14:34:22 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:34:14:34:22 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:34:14:34:22 | call to taint | type tracker without call steps | params_flow.rb:34:14:34:22 | call to taint | | params_flow.rb:34:14:34:22 | call to taint | type tracker without call steps with content element :p3 | params_flow.rb:34:8:34:32 | call to [] | | params_flow.rb:34:14:34:22 | call to taint | type tracker without call steps with content element :p3 | params_flow.rb:34:8:34:32 | synthetic hash-splat argument | | params_flow.rb:34:14:34:22 | call to taint | type tracker without call steps with content element :p3 | params_flow.rb:35:23:35:28 | ** ... | -| params_flow.rb:34:14:34:22 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:34:14:34:22 | synthetic splat argument | type tracker without call steps | params_flow.rb:34:14:34:22 | synthetic splat argument | | params_flow.rb:34:20:34:21 | 12 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:34:20:34:21 | 12 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:34:20:34:21 | 12 | type tracker with call steps | params_flow.rb:29:11:29:21 | ...[...] | +| params_flow.rb:34:20:34:21 | 12 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:34:20:34:21 | 12 | type tracker with call steps with content element 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:34:20:34:21 | 12 | type tracker with call steps with content element :p3 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:34:20:34:21 | 12 | type tracker with call steps with content element :p3 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:34:20:34:21 | 12 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:34:20:34:21 | 12 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:34:20:34:21 | 12 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:34:20:34:21 | 12 | type tracker with call steps with content splat position 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:34:20:34:21 | 12 | type tracker without call steps | params_flow.rb:34:14:34:22 | call to taint | | params_flow.rb:34:20:34:21 | 12 | type tracker without call steps | params_flow.rb:34:20:34:21 | 12 | +| params_flow.rb:34:20:34:21 | 12 | type tracker without call steps with content element 0 | params_flow.rb:34:14:34:22 | synthetic splat argument | | params_flow.rb:34:20:34:21 | 12 | type tracker without call steps with content element :p3 | params_flow.rb:34:8:34:32 | call to [] | | params_flow.rb:34:20:34:21 | 12 | type tracker without call steps with content element :p3 | params_flow.rb:34:8:34:32 | synthetic hash-splat argument | | params_flow.rb:34:20:34:21 | 12 | type tracker without call steps with content element :p3 | params_flow.rb:35:23:35:28 | ** ... | -| params_flow.rb:34:20:34:21 | 12 | type tracker without call steps with content splat position 0 | params_flow.rb:34:14:34:22 | synthetic splat argument | | params_flow.rb:34:25:34:26 | :p4 | type tracker without call steps | params_flow.rb:34:25:34:26 | :p4 | | params_flow.rb:34:25:34:30 | Pair | type tracker without call steps | params_flow.rb:34:25:34:30 | Pair | | params_flow.rb:34:29:34:30 | "" | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:34:29:34:30 | "" | type tracker with call steps | params_flow.rb:30:11:30:21 | ...[...] | +| params_flow.rb:34:29:34:30 | "" | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:34:29:34:30 | "" | type tracker with call steps with content element 0 | params_flow.rb:30:5:30:22 | synthetic splat argument | | params_flow.rb:34:29:34:30 | "" | type tracker with call steps with content element :p4 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:34:29:34:30 | "" | type tracker with call steps with content element :p4 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:34:29:34:30 | "" | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:34:29:34:30 | "" | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:34:29:34:30 | "" | type tracker with call steps with content splat position 0 | params_flow.rb:30:5:30:22 | synthetic splat argument | | params_flow.rb:34:29:34:30 | "" | type tracker without call steps | params_flow.rb:34:29:34:30 | "" | | params_flow.rb:34:29:34:30 | "" | type tracker without call steps with content element :p4 | params_flow.rb:34:8:34:32 | call to [] | | params_flow.rb:34:29:34:30 | "" | type tracker without call steps with content element :p4 | params_flow.rb:34:8:34:32 | synthetic hash-splat argument | @@ -976,31 +886,27 @@ track | params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps | params_flow.rb:25:12:25:13 | p1 | | params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps | params_flow.rb:27:11:27:21 | ...[...] | +| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | +| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | -| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:35:12:35:20 | call to taint | type tracker without call steps | params_flow.rb:35:12:35:20 | call to taint | | params_flow.rb:35:12:35:20 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | -| params_flow.rb:35:12:35:20 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:35:12:35:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:35:12:35:20 | synthetic splat argument | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps | params_flow.rb:25:12:25:13 | p1 | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps | params_flow.rb:27:11:27:21 | ...[...] | +| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | +| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content splat position 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | -| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content splat position 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:35:18:35:19 | 13 | type tracker without call steps | params_flow.rb:35:12:35:20 | call to taint | | params_flow.rb:35:18:35:19 | 13 | type tracker without call steps | params_flow.rb:35:18:35:19 | 13 | +| params_flow.rb:35:18:35:19 | 13 | type tracker without call steps with content element 0 | params_flow.rb:35:12:35:20 | synthetic splat argument | | params_flow.rb:35:18:35:19 | 13 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | -| params_flow.rb:35:18:35:19 | 13 | type tracker without call steps with content splat position 0 | params_flow.rb:35:12:35:20 | synthetic splat argument | | params_flow.rb:35:23:35:28 | ** ... | type tracker with call steps | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:35:23:35:28 | ** ... | type tracker with call steps | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:35:23:35:28 | ** ... | type tracker without call steps | params_flow.rb:35:23:35:28 | ** ... | @@ -1014,65 +920,57 @@ track | params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps | params_flow.rb:25:12:25:13 | p1 | | params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps | params_flow.rb:27:11:27:21 | ...[...] | +| params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | +| params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps with content element :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps with content element :p1 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | -| params_flow.rb:37:16:37:24 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:37:16:37:24 | call to taint | type tracker without call steps | params_flow.rb:37:16:37:24 | call to taint | | params_flow.rb:37:16:37:24 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:37:8:37:44 | call to [] | | params_flow.rb:37:16:37:24 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:37:8:37:44 | synthetic hash-splat argument | | params_flow.rb:37:16:37:24 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:38:8:38:13 | ** ... | -| params_flow.rb:37:16:37:24 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:37:16:37:24 | synthetic splat argument | type tracker without call steps | params_flow.rb:37:16:37:24 | synthetic splat argument | | params_flow.rb:37:22:37:23 | 14 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:37:22:37:23 | 14 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:37:22:37:23 | 14 | type tracker with call steps | params_flow.rb:25:12:25:13 | p1 | | params_flow.rb:37:22:37:23 | 14 | type tracker with call steps | params_flow.rb:27:11:27:21 | ...[...] | +| params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | +| params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content element :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content element :p1 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content splat position 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | -| params_flow.rb:37:22:37:23 | 14 | type tracker with call steps with content splat position 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:37:22:37:23 | 14 | type tracker without call steps | params_flow.rb:37:16:37:24 | call to taint | | params_flow.rb:37:22:37:23 | 14 | type tracker without call steps | params_flow.rb:37:22:37:23 | 14 | +| params_flow.rb:37:22:37:23 | 14 | type tracker without call steps with content element 0 | params_flow.rb:37:16:37:24 | synthetic splat argument | | params_flow.rb:37:22:37:23 | 14 | type tracker without call steps with content element :p1 | params_flow.rb:37:8:37:44 | call to [] | | params_flow.rb:37:22:37:23 | 14 | type tracker without call steps with content element :p1 | params_flow.rb:37:8:37:44 | synthetic hash-splat argument | | params_flow.rb:37:22:37:23 | 14 | type tracker without call steps with content element :p1 | params_flow.rb:38:8:38:13 | ** ... | -| params_flow.rb:37:22:37:23 | 14 | type tracker without call steps with content splat position 0 | params_flow.rb:37:16:37:24 | synthetic splat argument | | params_flow.rb:37:27:37:29 | :p2 | type tracker without call steps | params_flow.rb:37:27:37:29 | :p2 | | params_flow.rb:37:27:37:42 | Pair | type tracker without call steps | params_flow.rb:37:27:37:42 | Pair | | params_flow.rb:37:34:37:42 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:37:34:37:42 | call to taint | type tracker with call steps | params_flow.rb:28:11:28:21 | ...[...] | +| params_flow.rb:37:34:37:42 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:37:34:37:42 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:37:34:37:42 | call to taint | type tracker with call steps with content element :p2 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:37:34:37:42 | call to taint | type tracker with call steps with content element :p2 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:37:34:37:42 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:37:34:37:42 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:37:34:37:42 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:37:34:37:42 | call to taint | type tracker without call steps | params_flow.rb:37:34:37:42 | call to taint | | params_flow.rb:37:34:37:42 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:37:8:37:44 | call to [] | | params_flow.rb:37:34:37:42 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:37:8:37:44 | synthetic hash-splat argument | | params_flow.rb:37:34:37:42 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:38:8:38:13 | ** ... | -| params_flow.rb:37:34:37:42 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:37:34:37:42 | synthetic splat argument | type tracker without call steps | params_flow.rb:37:34:37:42 | synthetic splat argument | | params_flow.rb:37:40:37:41 | 15 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:37:40:37:41 | 15 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:37:40:37:41 | 15 | type tracker with call steps | params_flow.rb:28:11:28:21 | ...[...] | +| params_flow.rb:37:40:37:41 | 15 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:37:40:37:41 | 15 | type tracker with call steps with content element 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:37:40:37:41 | 15 | type tracker with call steps with content element :p2 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:37:40:37:41 | 15 | type tracker with call steps with content element :p2 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:37:40:37:41 | 15 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:37:40:37:41 | 15 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:37:40:37:41 | 15 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:37:40:37:41 | 15 | type tracker with call steps with content splat position 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:37:40:37:41 | 15 | type tracker without call steps | params_flow.rb:37:34:37:42 | call to taint | | params_flow.rb:37:40:37:41 | 15 | type tracker without call steps | params_flow.rb:37:40:37:41 | 15 | +| params_flow.rb:37:40:37:41 | 15 | type tracker without call steps with content element 0 | params_flow.rb:37:34:37:42 | synthetic splat argument | | params_flow.rb:37:40:37:41 | 15 | type tracker without call steps with content element :p2 | params_flow.rb:37:8:37:44 | call to [] | | params_flow.rb:37:40:37:41 | 15 | type tracker without call steps with content element :p2 | params_flow.rb:37:8:37:44 | synthetic hash-splat argument | | params_flow.rb:37:40:37:41 | 15 | type tracker without call steps with content element :p2 | params_flow.rb:38:8:38:13 | ** ... | -| params_flow.rb:37:40:37:41 | 15 | type tracker without call steps with content splat position 0 | params_flow.rb:37:34:37:42 | synthetic splat argument | | params_flow.rb:38:1:38:14 | call to kwargs | type tracker without call steps | params_flow.rb:38:1:38:14 | call to kwargs | | params_flow.rb:38:8:38:13 | ** ... | type tracker with call steps | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:38:8:38:13 | ** ... | type tracker with call steps | params_flow.rb:25:17:25:24 | **kwargs | @@ -1086,30 +984,26 @@ track | params_flow.rb:40:9:40:24 | Pair | type tracker without call steps | params_flow.rb:40:9:40:24 | Pair | | params_flow.rb:40:16:40:24 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:40:16:40:24 | call to taint | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | +| params_flow.rb:40:16:40:24 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:40:16:40:24 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:40:16:40:24 | call to taint | type tracker with call steps with content element :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:40:16:40:24 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:40:16:40:24 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:40:16:40:24 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:40:16:40:24 | call to taint | type tracker without call steps | params_flow.rb:40:16:40:24 | call to taint | | params_flow.rb:40:16:40:24 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:40:8:40:26 | call to [] | | params_flow.rb:40:16:40:24 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:40:8:40:26 | synthetic hash-splat argument | | params_flow.rb:40:16:40:24 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:41:24:41:29 | ** ... | -| params_flow.rb:40:16:40:24 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:40:16:40:24 | synthetic splat argument | type tracker without call steps | params_flow.rb:40:16:40:24 | synthetic splat argument | | params_flow.rb:40:22:40:23 | 16 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:40:22:40:23 | 16 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:40:22:40:23 | 16 | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | +| params_flow.rb:40:22:40:23 | 16 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:40:22:40:23 | 16 | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:40:22:40:23 | 16 | type tracker with call steps with content element :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:40:22:40:23 | 16 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:40:22:40:23 | 16 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:40:22:40:23 | 16 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:40:22:40:23 | 16 | type tracker with call steps with content splat position 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:40:22:40:23 | 16 | type tracker without call steps | params_flow.rb:40:16:40:24 | call to taint | | params_flow.rb:40:22:40:23 | 16 | type tracker without call steps | params_flow.rb:40:22:40:23 | 16 | +| params_flow.rb:40:22:40:23 | 16 | type tracker without call steps with content element 0 | params_flow.rb:40:16:40:24 | synthetic splat argument | | params_flow.rb:40:22:40:23 | 16 | type tracker without call steps with content element :p1 | params_flow.rb:40:8:40:26 | call to [] | | params_flow.rb:40:22:40:23 | 16 | type tracker without call steps with content element :p1 | params_flow.rb:40:8:40:26 | synthetic hash-splat argument | | params_flow.rb:40:22:40:23 | 16 | type tracker without call steps with content element :p1 | params_flow.rb:41:24:41:29 | ** ... | -| params_flow.rb:40:22:40:23 | 16 | type tracker without call steps with content splat position 0 | params_flow.rb:40:16:40:24 | synthetic splat argument | | params_flow.rb:41:1:41:30 | call to keyword | type tracker without call steps | params_flow.rb:41:1:41:30 | call to keyword | | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | @@ -1117,174 +1011,150 @@ track | params_flow.rb:41:9:41:21 | Pair | type tracker without call steps | params_flow.rb:41:9:41:21 | Pair | | params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | +| params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:41:13:41:21 | call to taint | type tracker without call steps | params_flow.rb:41:13:41:21 | call to taint | | params_flow.rb:41:13:41:21 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | -| params_flow.rb:41:13:41:21 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:41:13:41:21 | synthetic splat argument | type tracker without call steps | params_flow.rb:41:13:41:21 | synthetic splat argument | | params_flow.rb:41:19:41:20 | 17 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:41:19:41:20 | 17 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:41:19:41:20 | 17 | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | +| params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content splat position 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:41:19:41:20 | 17 | type tracker without call steps | params_flow.rb:41:13:41:21 | call to taint | | params_flow.rb:41:19:41:20 | 17 | type tracker without call steps | params_flow.rb:41:19:41:20 | 17 | +| params_flow.rb:41:19:41:20 | 17 | type tracker without call steps with content element 0 | params_flow.rb:41:13:41:21 | synthetic splat argument | | params_flow.rb:41:19:41:20 | 17 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | -| params_flow.rb:41:19:41:20 | 17 | type tracker without call steps with content splat position 0 | params_flow.rb:41:13:41:21 | synthetic splat argument | | params_flow.rb:41:24:41:29 | ** ... | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:41:24:41:29 | ** ... | type tracker without call steps | params_flow.rb:41:24:41:29 | ** ... | | params_flow.rb:43:1:43:4 | args | type tracker without call steps | params_flow.rb:43:1:43:4 | args | | params_flow.rb:43:8:43:18 | Array | type tracker without call steps | params_flow.rb:43:8:43:18 | Array | | params_flow.rb:43:8:43:18 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:43:8:43:18 | call to [] | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | -| params_flow.rb:43:8:43:18 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:43:8:43:18 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:43:8:43:18 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | -| params_flow.rb:43:8:43:18 | call to [] | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:43:8:43:18 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:43:8:43:18 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | +| params_flow.rb:43:8:43:18 | call to [] | type tracker with call steps with content element 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:43:8:43:18 | call to [] | type tracker without call steps | params_flow.rb:43:8:43:18 | call to [] | | params_flow.rb:43:8:43:18 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:44:23:44:27 | * ... | -| params_flow.rb:43:8:43:18 | call to [] | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:44:1:44:28 | synthetic splat argument | +| params_flow.rb:43:8:43:18 | call to [] | type tracker without call steps with content element 1 | params_flow.rb:44:1:44:28 | synthetic splat argument | | params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | -| params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | -| params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | +| params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker with call steps with content element 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:43:8:43:18 | call to [] | | params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:43:8:43:18 | synthetic splat argument | | params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:44:23:44:27 | * ... | -| params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:44:1:44:28 | synthetic splat argument | +| params_flow.rb:43:8:43:18 | synthetic splat argument | type tracker without call steps with content element 1 | params_flow.rb:44:1:44:28 | synthetic splat argument | | params_flow.rb:43:9:43:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:43:9:43:17 | call to taint | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | -| params_flow.rb:43:9:43:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:43:9:43:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:43:9:43:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | -| params_flow.rb:43:9:43:17 | call to taint | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:43:9:43:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:43:9:43:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | +| params_flow.rb:43:9:43:17 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:43:9:43:17 | call to taint | type tracker without call steps | params_flow.rb:43:9:43:17 | call to taint | | params_flow.rb:43:9:43:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:43:8:43:18 | call to [] | | params_flow.rb:43:9:43:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:43:8:43:18 | synthetic splat argument | | params_flow.rb:43:9:43:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:44:23:44:27 | * ... | -| params_flow.rb:43:9:43:17 | call to taint | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:44:1:44:28 | synthetic splat argument | -| params_flow.rb:43:9:43:17 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:43:9:43:17 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:44:1:44:28 | synthetic splat argument | | params_flow.rb:43:9:43:17 | synthetic splat argument | type tracker without call steps | params_flow.rb:43:9:43:17 | synthetic splat argument | | params_flow.rb:43:15:43:16 | 17 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:43:15:43:16 | 17 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:43:15:43:16 | 17 | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | -| params_flow.rb:43:15:43:16 | 17 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:43:15:43:16 | 17 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:43:15:43:16 | 17 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:43:15:43:16 | 17 | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | -| params_flow.rb:43:15:43:16 | 17 | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:43:15:43:16 | 17 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:43:15:43:16 | 17 | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | +| params_flow.rb:43:15:43:16 | 17 | type tracker with call steps with content element 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:43:15:43:16 | 17 | type tracker without call steps | params_flow.rb:43:9:43:17 | call to taint | | params_flow.rb:43:15:43:16 | 17 | type tracker without call steps | params_flow.rb:43:15:43:16 | 17 | | params_flow.rb:43:15:43:16 | 17 | type tracker without call steps with content element 0 | params_flow.rb:43:8:43:18 | call to [] | | params_flow.rb:43:15:43:16 | 17 | type tracker without call steps with content element 0 | params_flow.rb:43:8:43:18 | synthetic splat argument | +| params_flow.rb:43:15:43:16 | 17 | type tracker without call steps with content element 0 | params_flow.rb:43:9:43:17 | synthetic splat argument | | params_flow.rb:43:15:43:16 | 17 | type tracker without call steps with content element 0 | params_flow.rb:44:23:44:27 | * ... | -| params_flow.rb:43:15:43:16 | 17 | type tracker without call steps with content splat position 0 | params_flow.rb:43:9:43:17 | synthetic splat argument | -| params_flow.rb:43:15:43:16 | 17 | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:44:1:44:28 | synthetic splat argument | +| params_flow.rb:43:15:43:16 | 17 | type tracker without call steps with content element 1 | params_flow.rb:44:1:44:28 | synthetic splat argument | | params_flow.rb:44:1:44:28 | call to positional | type tracker without call steps | params_flow.rb:44:1:44:28 | call to positional | | params_flow.rb:44:1:44:28 | synthetic splat argument | type tracker with call steps | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:44:1:44:28 | synthetic splat argument | type tracker without call steps | params_flow.rb:44:1:44:28 | synthetic splat argument | | params_flow.rb:44:12:44:20 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:44:12:44:20 | call to taint | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | -| params_flow.rb:44:12:44:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:44:12:44:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:44:12:44:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:44:12:44:20 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:44:12:44:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:44:12:44:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:44:12:44:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:44:12:44:20 | call to taint | type tracker without call steps | params_flow.rb:44:12:44:20 | call to taint | -| params_flow.rb:44:12:44:20 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:44:1:44:28 | synthetic splat argument | -| params_flow.rb:44:12:44:20 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:44:12:44:20 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:44:1:44:28 | synthetic splat argument | | params_flow.rb:44:12:44:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:44:12:44:20 | synthetic splat argument | | params_flow.rb:44:18:44:19 | 16 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:44:18:44:19 | 16 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:44:18:44:19 | 16 | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | -| params_flow.rb:44:18:44:19 | 16 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:44:18:44:19 | 16 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:44:18:44:19 | 16 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:44:18:44:19 | 16 | type tracker with call steps with content splat position 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:44:18:44:19 | 16 | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:44:18:44:19 | 16 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:44:18:44:19 | 16 | type tracker with call steps with content element 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | +| params_flow.rb:44:18:44:19 | 16 | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:44:18:44:19 | 16 | type tracker without call steps | params_flow.rb:44:12:44:20 | call to taint | | params_flow.rb:44:18:44:19 | 16 | type tracker without call steps | params_flow.rb:44:18:44:19 | 16 | -| params_flow.rb:44:18:44:19 | 16 | type tracker without call steps with content splat position 0 | params_flow.rb:44:1:44:28 | synthetic splat argument | -| params_flow.rb:44:18:44:19 | 16 | type tracker without call steps with content splat position 0 | params_flow.rb:44:12:44:20 | synthetic splat argument | +| params_flow.rb:44:18:44:19 | 16 | type tracker without call steps with content element 0 | params_flow.rb:44:1:44:28 | synthetic splat argument | +| params_flow.rb:44:18:44:19 | 16 | type tracker without call steps with content element 0 | params_flow.rb:44:12:44:20 | synthetic splat argument | | params_flow.rb:44:23:44:27 | * ... | type tracker without call steps | params_flow.rb:44:23:44:27 | * ... | | params_flow.rb:46:1:46:4 | args | type tracker without call steps | params_flow.rb:46:1:46:4 | args | | params_flow.rb:46:8:46:29 | Array | type tracker without call steps | params_flow.rb:46:8:46:29 | Array | | params_flow.rb:46:8:46:29 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:46:8:46:29 | call to [] | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | +| params_flow.rb:46:8:46:29 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:46:8:46:29 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:46:8:46:29 | call to [] | type tracker with call steps with content element 0 or unknown | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:46:8:46:29 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:46:8:46:29 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:46:8:46:29 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:46:8:46:29 | call to [] | type tracker without call steps | params_flow.rb:46:8:46:29 | call to [] | | params_flow.rb:46:8:46:29 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:47:12:47:16 | * ... | | params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | +| params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker with call steps with content element 0 or unknown | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:46:8:46:29 | call to [] | | params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:46:8:46:29 | synthetic splat argument | | params_flow.rb:46:8:46:29 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:47:12:47:16 | * ... | | params_flow.rb:46:9:46:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:46:9:46:17 | call to taint | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | +| params_flow.rb:46:9:46:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:46:9:46:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:46:9:46:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:46:9:46:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:46:9:46:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:46:9:46:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:46:9:46:17 | call to taint | type tracker without call steps | params_flow.rb:46:9:46:17 | call to taint | | params_flow.rb:46:9:46:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:46:8:46:29 | call to [] | | params_flow.rb:46:9:46:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:46:8:46:29 | synthetic splat argument | | params_flow.rb:46:9:46:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:47:12:47:16 | * ... | -| params_flow.rb:46:9:46:17 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:46:9:46:17 | synthetic splat argument | type tracker without call steps | params_flow.rb:46:9:46:17 | synthetic splat argument | | params_flow.rb:46:15:46:16 | 18 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:46:15:46:16 | 18 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:46:15:46:16 | 18 | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | +| params_flow.rb:46:15:46:16 | 18 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:46:15:46:16 | 18 | type tracker with call steps with content element 0 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:46:15:46:16 | 18 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:46:15:46:16 | 18 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:46:15:46:16 | 18 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:46:15:46:16 | 18 | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:46:15:46:16 | 18 | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:46:15:46:16 | 18 | type tracker without call steps | params_flow.rb:46:9:46:17 | call to taint | | params_flow.rb:46:15:46:16 | 18 | type tracker without call steps | params_flow.rb:46:15:46:16 | 18 | | params_flow.rb:46:15:46:16 | 18 | type tracker without call steps with content element 0 | params_flow.rb:46:8:46:29 | call to [] | | params_flow.rb:46:15:46:16 | 18 | type tracker without call steps with content element 0 | params_flow.rb:46:8:46:29 | synthetic splat argument | +| params_flow.rb:46:15:46:16 | 18 | type tracker without call steps with content element 0 | params_flow.rb:46:9:46:17 | synthetic splat argument | | params_flow.rb:46:15:46:16 | 18 | type tracker without call steps with content element 0 | params_flow.rb:47:12:47:16 | * ... | -| params_flow.rb:46:15:46:16 | 18 | type tracker without call steps with content splat position 0 | params_flow.rb:46:9:46:17 | synthetic splat argument | | params_flow.rb:46:20:46:28 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:46:20:46:28 | call to taint | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | +| params_flow.rb:46:20:46:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:46:20:46:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:46:20:46:28 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:46:20:46:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:46:20:46:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:46:20:46:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:46:20:46:28 | call to taint | type tracker without call steps | params_flow.rb:46:20:46:28 | call to taint | | params_flow.rb:46:20:46:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:46:8:46:29 | call to [] | | params_flow.rb:46:20:46:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:46:8:46:29 | synthetic splat argument | | params_flow.rb:46:20:46:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:47:12:47:16 | * ... | -| params_flow.rb:46:20:46:28 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:46:20:46:28 | synthetic splat argument | type tracker without call steps | params_flow.rb:46:20:46:28 | synthetic splat argument | | params_flow.rb:46:26:46:27 | 19 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:46:26:46:27 | 19 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:46:26:46:27 | 19 | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | +| params_flow.rb:46:26:46:27 | 19 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:46:26:46:27 | 19 | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:46:26:46:27 | 19 | type tracker with call steps with content element 1 | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:46:26:46:27 | 19 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:46:26:46:27 | 19 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:46:26:46:27 | 19 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:46:26:46:27 | 19 | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:46:26:46:27 | 19 | type tracker without call steps | params_flow.rb:46:20:46:28 | call to taint | | params_flow.rb:46:26:46:27 | 19 | type tracker without call steps | params_flow.rb:46:26:46:27 | 19 | +| params_flow.rb:46:26:46:27 | 19 | type tracker without call steps with content element 0 | params_flow.rb:46:20:46:28 | synthetic splat argument | | params_flow.rb:46:26:46:27 | 19 | type tracker without call steps with content element 1 | params_flow.rb:46:8:46:29 | call to [] | | params_flow.rb:46:26:46:27 | 19 | type tracker without call steps with content element 1 | params_flow.rb:46:8:46:29 | synthetic splat argument | | params_flow.rb:46:26:46:27 | 19 | type tracker without call steps with content element 1 | params_flow.rb:47:12:47:16 | * ... | -| params_flow.rb:46:26:46:27 | 19 | type tracker without call steps with content splat position 0 | params_flow.rb:46:20:46:28 | synthetic splat argument | | params_flow.rb:47:1:47:17 | call to positional | type tracker without call steps | params_flow.rb:47:1:47:17 | call to positional | | params_flow.rb:47:12:47:16 | * ... | type tracker with call steps | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:47:12:47:16 | * ... | type tracker without call steps | params_flow.rb:47:12:47:16 | * ... | @@ -1294,271 +1164,233 @@ track | params_flow.rb:49:1:53:3 | self in posargs | type tracker without call steps | params_flow.rb:49:1:53:3 | self in posargs | | params_flow.rb:49:1:53:3 | synthetic splat parameter | type tracker without call steps | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:49:13:49:14 | p1 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:49:13:49:14 | p1 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:49:13:49:14 | p1 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:49:13:49:14 | p1 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:49:13:49:14 | p1 | type tracker without call steps | params_flow.rb:49:13:49:14 | p1 | | params_flow.rb:49:13:49:14 | p1 | type tracker without call steps | params_flow.rb:49:13:49:14 | p1 | -| params_flow.rb:49:13:49:14 | p1 | type tracker without call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | +| params_flow.rb:49:13:49:14 | p1 | type tracker without call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:49:17:49:24 | *posargs | type tracker without call steps | params_flow.rb:49:17:49:24 | *posargs | | params_flow.rb:49:18:49:24 | posargs | type tracker without call steps | params_flow.rb:49:18:49:24 | posargs | | params_flow.rb:50:5:50:11 | call to sink | type tracker without call steps | params_flow.rb:50:5:50:11 | call to sink | -| params_flow.rb:50:5:50:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:50:5:50:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:51:5:51:21 | call to sink | type tracker without call steps | params_flow.rb:51:5:51:21 | call to sink | -| params_flow.rb:51:5:51:21 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:51:5:51:21 | synthetic splat argument | type tracker without call steps | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:51:11:51:20 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:51:11:51:20 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:51:11:51:20 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:51:11:51:20 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:51:11:51:20 | ...[...] | type tracker without call steps | params_flow.rb:51:11:51:20 | ...[...] | -| params_flow.rb:51:11:51:20 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | +| params_flow.rb:51:11:51:20 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:51:11:51:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:51:11:51:20 | synthetic splat argument | | params_flow.rb:51:19:51:19 | 0 | type tracker without call steps | params_flow.rb:51:19:51:19 | 0 | -| params_flow.rb:51:19:51:19 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:51:11:51:20 | synthetic splat argument | +| params_flow.rb:51:19:51:19 | 0 | type tracker without call steps with content element 0 | params_flow.rb:51:11:51:20 | synthetic splat argument | | params_flow.rb:52:5:52:21 | call to sink | type tracker without call steps | params_flow.rb:52:5:52:21 | call to sink | | params_flow.rb:52:5:52:21 | call to sink | type tracker without call steps | params_flow.rb:55:1:55:29 | call to posargs | | params_flow.rb:52:5:52:21 | call to sink | type tracker without call steps | params_flow.rb:58:1:58:25 | call to posargs | | params_flow.rb:52:5:52:21 | call to sink | type tracker without call steps | params_flow.rb:61:1:61:14 | call to posargs | -| params_flow.rb:52:5:52:21 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:52:5:52:21 | synthetic splat argument | type tracker without call steps | params_flow.rb:52:5:52:21 | synthetic splat argument | | params_flow.rb:52:11:52:20 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:52:11:52:20 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:52:11:52:20 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:52:11:52:20 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:52:11:52:20 | ...[...] | type tracker without call steps | params_flow.rb:52:11:52:20 | ...[...] | -| params_flow.rb:52:11:52:20 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:52:5:52:21 | synthetic splat argument | +| params_flow.rb:52:11:52:20 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:52:5:52:21 | synthetic splat argument | | params_flow.rb:52:11:52:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:52:11:52:20 | synthetic splat argument | | params_flow.rb:52:19:52:19 | 1 | type tracker without call steps | params_flow.rb:52:19:52:19 | 1 | -| params_flow.rb:52:19:52:19 | 1 | type tracker without call steps with content splat position 0 | params_flow.rb:52:11:52:20 | synthetic splat argument | +| params_flow.rb:52:19:52:19 | 1 | type tracker without call steps with content element 0 | params_flow.rb:52:11:52:20 | synthetic splat argument | | params_flow.rb:55:1:55:29 | call to posargs | type tracker without call steps | params_flow.rb:55:1:55:29 | call to posargs | | params_flow.rb:55:1:55:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:55:1:55:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:55:1:55:29 | synthetic splat argument | | params_flow.rb:55:9:55:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:55:9:55:17 | call to taint | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | -| params_flow.rb:55:9:55:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:55:9:55:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:55:9:55:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:55:9:55:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | +| params_flow.rb:55:9:55:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:55:9:55:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:55:9:55:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:55:9:55:17 | call to taint | type tracker without call steps | params_flow.rb:55:9:55:17 | call to taint | -| params_flow.rb:55:9:55:17 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:55:1:55:29 | synthetic splat argument | -| params_flow.rb:55:9:55:17 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:55:9:55:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:55:1:55:29 | synthetic splat argument | | params_flow.rb:55:9:55:17 | synthetic splat argument | type tracker without call steps | params_flow.rb:55:9:55:17 | synthetic splat argument | | params_flow.rb:55:15:55:16 | 20 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:55:15:55:16 | 20 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:55:15:55:16 | 20 | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | -| params_flow.rb:55:15:55:16 | 20 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:55:15:55:16 | 20 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:55:15:55:16 | 20 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:55:15:55:16 | 20 | type tracker with call steps with content splat position 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:55:15:55:16 | 20 | type tracker with call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | +| params_flow.rb:55:15:55:16 | 20 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:55:15:55:16 | 20 | type tracker with call steps with content element 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:55:15:55:16 | 20 | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:55:15:55:16 | 20 | type tracker without call steps | params_flow.rb:55:9:55:17 | call to taint | | params_flow.rb:55:15:55:16 | 20 | type tracker without call steps | params_flow.rb:55:15:55:16 | 20 | -| params_flow.rb:55:15:55:16 | 20 | type tracker without call steps with content splat position 0 | params_flow.rb:55:1:55:29 | synthetic splat argument | -| params_flow.rb:55:15:55:16 | 20 | type tracker without call steps with content splat position 0 | params_flow.rb:55:9:55:17 | synthetic splat argument | +| params_flow.rb:55:15:55:16 | 20 | type tracker without call steps with content element 0 | params_flow.rb:55:1:55:29 | synthetic splat argument | +| params_flow.rb:55:15:55:16 | 20 | type tracker without call steps with content element 0 | params_flow.rb:55:9:55:17 | synthetic splat argument | | params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | +| params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | -| params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | -| params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | +| params_flow.rb:55:20:55:28 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:55:20:55:28 | call to taint | type tracker without call steps | params_flow.rb:55:20:55:28 | call to taint | -| params_flow.rb:55:20:55:28 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:55:1:55:29 | synthetic splat argument | -| params_flow.rb:55:20:55:28 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:55:20:55:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:55:1:55:29 | synthetic splat argument | | params_flow.rb:55:20:55:28 | synthetic splat argument | type tracker without call steps | params_flow.rb:55:20:55:28 | synthetic splat argument | | params_flow.rb:55:26:55:27 | 21 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:55:26:55:27 | 21 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:55:26:55:27 | 21 | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | +| params_flow.rb:55:26:55:27 | 21 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:55:26:55:27 | 21 | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | -| params_flow.rb:55:26:55:27 | 21 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:55:26:55:27 | 21 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:55:26:55:27 | 21 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:55:26:55:27 | 21 | type tracker with call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | -| params_flow.rb:55:26:55:27 | 21 | type tracker with call steps with content splat position 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:55:26:55:27 | 21 | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | +| params_flow.rb:55:26:55:27 | 21 | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:55:26:55:27 | 21 | type tracker without call steps | params_flow.rb:55:20:55:28 | call to taint | | params_flow.rb:55:26:55:27 | 21 | type tracker without call steps | params_flow.rb:55:26:55:27 | 21 | -| params_flow.rb:55:26:55:27 | 21 | type tracker without call steps with content splat position 0 | params_flow.rb:55:20:55:28 | synthetic splat argument | -| params_flow.rb:55:26:55:27 | 21 | type tracker without call steps with content splat position 1 | params_flow.rb:55:1:55:29 | synthetic splat argument | +| params_flow.rb:55:26:55:27 | 21 | type tracker without call steps with content element 0 | params_flow.rb:55:20:55:28 | synthetic splat argument | +| params_flow.rb:55:26:55:27 | 21 | type tracker without call steps with content element 1 | params_flow.rb:55:1:55:29 | synthetic splat argument | | params_flow.rb:57:1:57:4 | args | type tracker without call steps | params_flow.rb:57:1:57:4 | args | | params_flow.rb:57:8:57:18 | Array | type tracker without call steps | params_flow.rb:57:8:57:18 | Array | | params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | +| params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | +| params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 0 or unknown | params_flow.rb:49:17:49:24 | *posargs | -| params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | -| params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:57:8:57:18 | call to [] | type tracker without call steps | params_flow.rb:57:8:57:18 | call to [] | | params_flow.rb:57:8:57:18 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:58:20:58:24 | * ... | -| params_flow.rb:57:8:57:18 | call to [] | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:58:1:58:25 | synthetic splat argument | +| params_flow.rb:57:8:57:18 | call to [] | type tracker without call steps with content element 1 | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | +| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | +| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 0 or unknown | params_flow.rb:49:17:49:24 | *posargs | -| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | -| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:57:8:57:18 | call to [] | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:57:8:57:18 | synthetic splat argument | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:58:20:58:24 | * ... | -| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:58:1:58:25 | synthetic splat argument | +| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker without call steps with content element 1 | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | +| params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | -| params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | -| params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | +| params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:57:9:57:17 | call to taint | type tracker without call steps | params_flow.rb:57:9:57:17 | call to taint | | params_flow.rb:57:9:57:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:57:8:57:18 | call to [] | | params_flow.rb:57:9:57:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:57:8:57:18 | synthetic splat argument | | params_flow.rb:57:9:57:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:58:20:58:24 | * ... | -| params_flow.rb:57:9:57:17 | call to taint | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:58:1:58:25 | synthetic splat argument | -| params_flow.rb:57:9:57:17 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:57:9:57:17 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:57:9:57:17 | synthetic splat argument | type tracker without call steps | params_flow.rb:57:9:57:17 | synthetic splat argument | | params_flow.rb:57:15:57:16 | 22 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:57:15:57:16 | 22 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:57:15:57:16 | 22 | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | +| params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | -| params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | -| params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | +| params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps | params_flow.rb:57:9:57:17 | call to taint | | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps | params_flow.rb:57:15:57:16 | 22 | | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content element 0 | params_flow.rb:57:8:57:18 | call to [] | | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content element 0 | params_flow.rb:57:8:57:18 | synthetic splat argument | +| params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content element 0 | params_flow.rb:57:9:57:17 | synthetic splat argument | | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content element 0 | params_flow.rb:58:20:58:24 | * ... | -| params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content splat position 0 | params_flow.rb:57:9:57:17 | synthetic splat argument | -| params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:58:1:58:25 | synthetic splat argument | +| params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content element 1 | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:58:1:58:25 | call to posargs | type tracker without call steps | params_flow.rb:58:1:58:25 | call to posargs | | params_flow.rb:58:1:58:25 | synthetic splat argument | type tracker with call steps | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:58:1:58:25 | synthetic splat argument | type tracker without call steps | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | -| params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | +| params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:58:9:58:17 | call to taint | type tracker without call steps | params_flow.rb:58:9:58:17 | call to taint | -| params_flow.rb:58:9:58:17 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:58:1:58:25 | synthetic splat argument | -| params_flow.rb:58:9:58:17 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:58:9:58:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:58:9:58:17 | synthetic splat argument | type tracker without call steps | params_flow.rb:58:9:58:17 | synthetic splat argument | | params_flow.rb:58:15:58:16 | 23 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:58:15:58:16 | 23 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:58:15:58:16 | 23 | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | -| params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content splat position 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | +| params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content element 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | +| params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:58:15:58:16 | 23 | type tracker without call steps | params_flow.rb:58:9:58:17 | call to taint | | params_flow.rb:58:15:58:16 | 23 | type tracker without call steps | params_flow.rb:58:15:58:16 | 23 | -| params_flow.rb:58:15:58:16 | 23 | type tracker without call steps with content splat position 0 | params_flow.rb:58:1:58:25 | synthetic splat argument | -| params_flow.rb:58:15:58:16 | 23 | type tracker without call steps with content splat position 0 | params_flow.rb:58:9:58:17 | synthetic splat argument | +| params_flow.rb:58:15:58:16 | 23 | type tracker without call steps with content element 0 | params_flow.rb:58:1:58:25 | synthetic splat argument | +| params_flow.rb:58:15:58:16 | 23 | type tracker without call steps with content element 0 | params_flow.rb:58:9:58:17 | synthetic splat argument | | params_flow.rb:58:20:58:24 | * ... | type tracker with call steps | params_flow.rb:49:17:49:24 | *posargs | | params_flow.rb:58:20:58:24 | * ... | type tracker without call steps | params_flow.rb:58:20:58:24 | * ... | | params_flow.rb:60:1:60:4 | args | type tracker without call steps | params_flow.rb:60:1:60:4 | args | | params_flow.rb:60:8:60:29 | Array | type tracker without call steps | params_flow.rb:60:8:60:29 | Array | | params_flow.rb:60:8:60:29 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:60:8:60:29 | call to [] | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | +| params_flow.rb:60:8:60:29 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:60:8:60:29 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:60:8:60:29 | call to [] | type tracker with call steps with content element 0 or unknown | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:60:8:60:29 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:60:8:60:29 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:60:8:60:29 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:60:8:60:29 | call to [] | type tracker without call steps | params_flow.rb:60:8:60:29 | call to [] | | params_flow.rb:60:8:60:29 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:61:9:61:13 | * ... | | params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | +| params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker with call steps with content element 0 or unknown | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:60:8:60:29 | call to [] | | params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:60:8:60:29 | synthetic splat argument | | params_flow.rb:60:8:60:29 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:61:9:61:13 | * ... | | params_flow.rb:60:9:60:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:60:9:60:17 | call to taint | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | +| params_flow.rb:60:9:60:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:60:9:60:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:60:9:60:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:60:9:60:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:60:9:60:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | +| params_flow.rb:60:9:60:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:60:9:60:17 | call to taint | type tracker without call steps | params_flow.rb:60:9:60:17 | call to taint | | params_flow.rb:60:9:60:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:60:8:60:29 | call to [] | | params_flow.rb:60:9:60:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:60:8:60:29 | synthetic splat argument | | params_flow.rb:60:9:60:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:61:9:61:13 | * ... | -| params_flow.rb:60:9:60:17 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:60:9:60:17 | synthetic splat argument | type tracker without call steps | params_flow.rb:60:9:60:17 | synthetic splat argument | | params_flow.rb:60:15:60:16 | 24 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:60:15:60:16 | 24 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:60:15:60:16 | 24 | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | +| params_flow.rb:60:15:60:16 | 24 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:60:15:60:16 | 24 | type tracker with call steps with content element 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:60:15:60:16 | 24 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:60:15:60:16 | 24 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:60:15:60:16 | 24 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:60:15:60:16 | 24 | type tracker with call steps with content splat position 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | +| params_flow.rb:60:15:60:16 | 24 | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:60:15:60:16 | 24 | type tracker without call steps | params_flow.rb:60:9:60:17 | call to taint | | params_flow.rb:60:15:60:16 | 24 | type tracker without call steps | params_flow.rb:60:15:60:16 | 24 | | params_flow.rb:60:15:60:16 | 24 | type tracker without call steps with content element 0 | params_flow.rb:60:8:60:29 | call to [] | | params_flow.rb:60:15:60:16 | 24 | type tracker without call steps with content element 0 | params_flow.rb:60:8:60:29 | synthetic splat argument | +| params_flow.rb:60:15:60:16 | 24 | type tracker without call steps with content element 0 | params_flow.rb:60:9:60:17 | synthetic splat argument | | params_flow.rb:60:15:60:16 | 24 | type tracker without call steps with content element 0 | params_flow.rb:61:9:61:13 | * ... | -| params_flow.rb:60:15:60:16 | 24 | type tracker without call steps with content splat position 0 | params_flow.rb:60:9:60:17 | synthetic splat argument | | params_flow.rb:60:20:60:28 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:60:20:60:28 | call to taint | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | +| params_flow.rb:60:20:60:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:60:20:60:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | +| params_flow.rb:60:20:60:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:60:20:60:28 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:60:20:60:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:60:20:60:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:60:20:60:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:60:20:60:28 | call to taint | type tracker without call steps | params_flow.rb:60:20:60:28 | call to taint | | params_flow.rb:60:20:60:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:60:8:60:29 | call to [] | | params_flow.rb:60:20:60:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:60:8:60:29 | synthetic splat argument | | params_flow.rb:60:20:60:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:61:9:61:13 | * ... | -| params_flow.rb:60:20:60:28 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:60:20:60:28 | synthetic splat argument | type tracker without call steps | params_flow.rb:60:20:60:28 | synthetic splat argument | | params_flow.rb:60:26:60:27 | 25 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:60:26:60:27 | 25 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:60:26:60:27 | 25 | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | +| params_flow.rb:60:26:60:27 | 25 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:60:26:60:27 | 25 | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | +| params_flow.rb:60:26:60:27 | 25 | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:60:26:60:27 | 25 | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | -| params_flow.rb:60:26:60:27 | 25 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:60:26:60:27 | 25 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:60:26:60:27 | 25 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:60:26:60:27 | 25 | type tracker with call steps with content splat position 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:60:26:60:27 | 25 | type tracker without call steps | params_flow.rb:60:20:60:28 | call to taint | | params_flow.rb:60:26:60:27 | 25 | type tracker without call steps | params_flow.rb:60:26:60:27 | 25 | +| params_flow.rb:60:26:60:27 | 25 | type tracker without call steps with content element 0 | params_flow.rb:60:20:60:28 | synthetic splat argument | | params_flow.rb:60:26:60:27 | 25 | type tracker without call steps with content element 1 | params_flow.rb:60:8:60:29 | call to [] | | params_flow.rb:60:26:60:27 | 25 | type tracker without call steps with content element 1 | params_flow.rb:60:8:60:29 | synthetic splat argument | | params_flow.rb:60:26:60:27 | 25 | type tracker without call steps with content element 1 | params_flow.rb:61:9:61:13 | * ... | -| params_flow.rb:60:26:60:27 | 25 | type tracker without call steps with content splat position 0 | params_flow.rb:60:20:60:28 | synthetic splat argument | | params_flow.rb:61:1:61:14 | call to posargs | type tracker without call steps | params_flow.rb:61:1:61:14 | call to posargs | | params_flow.rb:61:9:61:13 | * ... | type tracker with call steps | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:61:9:61:13 | * ... | type tracker without call steps | params_flow.rb:61:9:61:13 | * ... | | params_flow.rb:63:1:63:4 | args | type tracker without call steps | params_flow.rb:63:1:63:4 | args | | params_flow.rb:63:8:63:16 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:63:8:63:16 | call to taint | type tracker with call steps | params_flow.rb:65:10:65:13 | ...[...] | +| params_flow.rb:63:8:63:16 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:63:8:63:16 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:65:5:65:13 | synthetic splat argument | | params_flow.rb:63:8:63:16 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:64:16:64:17 | *x | -| params_flow.rb:63:8:63:16 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:63:8:63:16 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:63:8:63:16 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:65:5:65:13 | synthetic splat argument | | params_flow.rb:63:8:63:16 | call to taint | type tracker without call steps | params_flow.rb:63:8:63:16 | call to taint | | params_flow.rb:63:8:63:16 | call to taint | type tracker without call steps with content element 0 or unknown | params_flow.rb:67:12:67:16 | * ... | -| params_flow.rb:63:8:63:16 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:63:8:63:16 | synthetic splat argument | type tracker without call steps | params_flow.rb:63:8:63:16 | synthetic splat argument | | params_flow.rb:63:14:63:15 | 26 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:63:14:63:15 | 26 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:63:14:63:15 | 26 | type tracker with call steps | params_flow.rb:65:10:65:13 | ...[...] | +| params_flow.rb:63:14:63:15 | 26 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:63:14:63:15 | 26 | type tracker with call steps with content element 0 | params_flow.rb:65:5:65:13 | synthetic splat argument | | params_flow.rb:63:14:63:15 | 26 | type tracker with call steps with content element 0 or unknown | params_flow.rb:64:16:64:17 | *x | -| params_flow.rb:63:14:63:15 | 26 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:63:14:63:15 | 26 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:63:14:63:15 | 26 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:63:14:63:15 | 26 | type tracker with call steps with content splat position 0 | params_flow.rb:65:5:65:13 | synthetic splat argument | | params_flow.rb:63:14:63:15 | 26 | type tracker without call steps | params_flow.rb:63:8:63:16 | call to taint | | params_flow.rb:63:14:63:15 | 26 | type tracker without call steps | params_flow.rb:63:14:63:15 | 26 | +| params_flow.rb:63:14:63:15 | 26 | type tracker without call steps with content element 0 | params_flow.rb:63:8:63:16 | synthetic splat argument | | params_flow.rb:63:14:63:15 | 26 | type tracker without call steps with content element 0 or unknown | params_flow.rb:67:12:67:16 | * ... | -| params_flow.rb:63:14:63:15 | 26 | type tracker without call steps with content splat position 0 | params_flow.rb:63:8:63:16 | synthetic splat argument | | params_flow.rb:64:1:66:3 | &block | type tracker without call steps | params_flow.rb:64:1:66:3 | &block | | params_flow.rb:64:1:66:3 | self in splatstuff | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | | params_flow.rb:64:1:66:3 | self in splatstuff | type tracker without call steps | params_flow.rb:64:1:66:3 | self in splatstuff | @@ -1567,16 +1399,14 @@ track | params_flow.rb:64:17:64:17 | x | type tracker without call steps | params_flow.rb:64:17:64:17 | x | | params_flow.rb:65:5:65:13 | call to sink | type tracker without call steps | params_flow.rb:65:5:65:13 | call to sink | | params_flow.rb:65:5:65:13 | call to sink | type tracker without call steps | params_flow.rb:67:1:67:17 | call to splatstuff | -| params_flow.rb:65:5:65:13 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:65:5:65:13 | synthetic splat argument | type tracker without call steps | params_flow.rb:65:5:65:13 | synthetic splat argument | | params_flow.rb:65:10:65:13 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:65:10:65:13 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:65:10:65:13 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:65:10:65:13 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:65:10:65:13 | ...[...] | type tracker without call steps | params_flow.rb:65:10:65:13 | ...[...] | -| params_flow.rb:65:10:65:13 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:65:5:65:13 | synthetic splat argument | +| params_flow.rb:65:10:65:13 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:65:5:65:13 | synthetic splat argument | | params_flow.rb:65:10:65:13 | synthetic splat argument | type tracker without call steps | params_flow.rb:65:10:65:13 | synthetic splat argument | | params_flow.rb:65:12:65:12 | 0 | type tracker without call steps | params_flow.rb:65:12:65:12 | 0 | -| params_flow.rb:65:12:65:12 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:65:10:65:13 | synthetic splat argument | +| params_flow.rb:65:12:65:12 | 0 | type tracker without call steps with content element 0 | params_flow.rb:65:10:65:13 | synthetic splat argument | | params_flow.rb:67:1:67:17 | call to splatstuff | type tracker without call steps | params_flow.rb:67:1:67:17 | call to splatstuff | | params_flow.rb:67:12:67:16 | * ... | type tracker with call steps | params_flow.rb:64:16:64:17 | *x | | params_flow.rb:67:12:67:16 | * ... | type tracker without call steps | params_flow.rb:67:12:67:16 | * ... | @@ -1586,905 +1416,765 @@ track | params_flow.rb:69:1:76:3 | splatmid | type tracker without call steps | params_flow.rb:69:1:76:3 | splatmid | | params_flow.rb:69:1:76:3 | synthetic splat parameter | type tracker without call steps | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:69:14:69:14 | x | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:69:14:69:14 | x | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:69:14:69:14 | x | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:69:14:69:14 | x | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:69:14:69:14 | x | type tracker without call steps | params_flow.rb:69:14:69:14 | x | | params_flow.rb:69:14:69:14 | x | type tracker without call steps | params_flow.rb:69:14:69:14 | x | -| params_flow.rb:69:14:69:14 | x | type tracker without call steps with content splat position 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | +| params_flow.rb:69:14:69:14 | x | type tracker without call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:69:17:69:17 | y | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:69:17:69:17 | y | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:69:17:69:17 | y | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:69:17:69:17 | y | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:69:17:69:17 | y | type tracker without call steps | params_flow.rb:69:17:69:17 | y | | params_flow.rb:69:17:69:17 | y | type tracker without call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:69:17:69:17 | y | type tracker without call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:69:17:69:17 | y | type tracker without call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | | params_flow.rb:69:20:69:21 | *z | type tracker without call steps | params_flow.rb:69:20:69:21 | *z | | params_flow.rb:69:21:69:21 | z | type tracker without call steps | params_flow.rb:69:21:69:21 | z | | params_flow.rb:69:24:69:24 | w | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:69:24:69:24 | w | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:69:24:69:24 | w | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:69:24:69:24 | w | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:69:24:69:24 | w | type tracker without call steps | params_flow.rb:69:24:69:24 | w | | params_flow.rb:69:24:69:24 | w | type tracker without call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:69:24:69:24 | w | type tracker without call steps with content splat position 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | +| params_flow.rb:69:24:69:24 | w | type tracker without call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | | params_flow.rb:69:27:69:27 | r | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:69:27:69:27 | r | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:69:27:69:27 | r | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:69:27:69:27 | r | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:69:27:69:27 | r | type tracker without call steps | params_flow.rb:69:27:69:27 | r | | params_flow.rb:69:27:69:27 | r | type tracker without call steps | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:69:27:69:27 | r | type tracker without call steps with content splat position 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | +| params_flow.rb:69:27:69:27 | r | type tracker without call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:70:5:70:10 | call to sink | type tracker without call steps | params_flow.rb:70:5:70:10 | call to sink | -| params_flow.rb:70:5:70:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:70:5:70:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:71:5:71:10 | call to sink | type tracker without call steps | params_flow.rb:71:5:71:10 | call to sink | -| params_flow.rb:71:5:71:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:71:5:71:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:71:5:71:10 | synthetic splat argument | | params_flow.rb:72:5:72:13 | call to sink | type tracker without call steps | params_flow.rb:72:5:72:13 | call to sink | -| params_flow.rb:72:5:72:13 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:72:5:72:13 | synthetic splat argument | type tracker without call steps | params_flow.rb:72:5:72:13 | synthetic splat argument | | params_flow.rb:72:10:72:13 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:72:10:72:13 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:72:10:72:13 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:72:10:72:13 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:72:10:72:13 | ...[...] | type tracker without call steps | params_flow.rb:72:10:72:13 | ...[...] | -| params_flow.rb:72:10:72:13 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:72:5:72:13 | synthetic splat argument | +| params_flow.rb:72:10:72:13 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:72:5:72:13 | synthetic splat argument | | params_flow.rb:72:10:72:13 | synthetic splat argument | type tracker without call steps | params_flow.rb:72:10:72:13 | synthetic splat argument | | params_flow.rb:72:12:72:12 | 0 | type tracker without call steps | params_flow.rb:72:12:72:12 | 0 | -| params_flow.rb:72:12:72:12 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:72:10:72:13 | synthetic splat argument | +| params_flow.rb:72:12:72:12 | 0 | type tracker without call steps with content element 0 | params_flow.rb:72:10:72:13 | synthetic splat argument | | params_flow.rb:73:5:73:13 | call to sink | type tracker without call steps | params_flow.rb:73:5:73:13 | call to sink | -| params_flow.rb:73:5:73:13 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:73:5:73:13 | synthetic splat argument | type tracker without call steps | params_flow.rb:73:5:73:13 | synthetic splat argument | | params_flow.rb:73:10:73:13 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:73:10:73:13 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:73:10:73:13 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:73:10:73:13 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:73:10:73:13 | ...[...] | type tracker without call steps | params_flow.rb:73:10:73:13 | ...[...] | -| params_flow.rb:73:10:73:13 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:73:5:73:13 | synthetic splat argument | +| params_flow.rb:73:10:73:13 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:73:5:73:13 | synthetic splat argument | | params_flow.rb:73:10:73:13 | synthetic splat argument | type tracker without call steps | params_flow.rb:73:10:73:13 | synthetic splat argument | | params_flow.rb:73:12:73:12 | 1 | type tracker without call steps | params_flow.rb:73:12:73:12 | 1 | -| params_flow.rb:73:12:73:12 | 1 | type tracker without call steps with content splat position 0 | params_flow.rb:73:10:73:13 | synthetic splat argument | +| params_flow.rb:73:12:73:12 | 1 | type tracker without call steps with content element 0 | params_flow.rb:73:10:73:13 | synthetic splat argument | | params_flow.rb:74:5:74:10 | call to sink | type tracker without call steps | params_flow.rb:74:5:74:10 | call to sink | -| params_flow.rb:74:5:74:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:74:5:74:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:74:5:74:10 | synthetic splat argument | | params_flow.rb:75:5:75:10 | call to sink | type tracker without call steps | params_flow.rb:75:5:75:10 | call to sink | | params_flow.rb:75:5:75:10 | call to sink | type tracker without call steps | params_flow.rb:78:1:78:63 | call to splatmid | | params_flow.rb:75:5:75:10 | call to sink | type tracker without call steps | params_flow.rb:81:1:81:37 | call to splatmid | | params_flow.rb:75:5:75:10 | call to sink | type tracker without call steps | params_flow.rb:96:1:96:88 | call to splatmid | -| params_flow.rb:75:5:75:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:75:5:75:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:78:1:78:63 | call to splatmid | type tracker without call steps | params_flow.rb:78:1:78:63 | call to splatmid | | params_flow.rb:78:1:78:63 | synthetic splat argument | type tracker with call steps | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:1:78:63 | synthetic splat argument | type tracker without call steps | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:10:78:18 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:78:10:78:18 | call to taint | type tracker with call steps | params_flow.rb:69:14:69:14 | x | -| params_flow.rb:78:10:78:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:78:10:78:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:10:78:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:78:10:78:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | +| params_flow.rb:78:10:78:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:78:10:78:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:10:78:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:78:10:78:18 | call to taint | type tracker without call steps | params_flow.rb:78:10:78:18 | call to taint | -| params_flow.rb:78:10:78:18 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:78:10:78:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:78:10:78:18 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:10:78:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:78:10:78:18 | synthetic splat argument | | params_flow.rb:78:16:78:17 | 27 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:16:78:17 | 27 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:78:16:78:17 | 27 | type tracker with call steps | params_flow.rb:69:14:69:14 | x | -| params_flow.rb:78:16:78:17 | 27 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:78:16:78:17 | 27 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:78:16:78:17 | 27 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:16:78:17 | 27 | type tracker with call steps with content splat position 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:78:16:78:17 | 27 | type tracker with call steps with content splat position 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | +| params_flow.rb:78:16:78:17 | 27 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:78:16:78:17 | 27 | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:16:78:17 | 27 | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:78:16:78:17 | 27 | type tracker without call steps | params_flow.rb:78:10:78:18 | call to taint | | params_flow.rb:78:16:78:17 | 27 | type tracker without call steps | params_flow.rb:78:16:78:17 | 27 | -| params_flow.rb:78:16:78:17 | 27 | type tracker without call steps with content splat position 0 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:78:16:78:17 | 27 | type tracker without call steps with content splat position 0 | params_flow.rb:78:10:78:18 | synthetic splat argument | +| params_flow.rb:78:16:78:17 | 27 | type tracker without call steps with content element 0 | params_flow.rb:78:1:78:63 | synthetic splat argument | +| params_flow.rb:78:16:78:17 | 27 | type tracker without call steps with content element 0 | params_flow.rb:78:10:78:18 | synthetic splat argument | | params_flow.rb:78:21:78:29 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:78:21:78:29 | call to taint | type tracker with call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:78:21:78:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:78:21:78:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:21:78:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:78:21:78:29 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:21:78:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:78:21:78:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:78:21:78:29 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:21:78:29 | call to taint | type tracker without call steps | params_flow.rb:78:21:78:29 | call to taint | -| params_flow.rb:78:21:78:29 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:78:21:78:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:78:21:78:29 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:21:78:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:78:21:78:29 | synthetic splat argument | | params_flow.rb:78:27:78:28 | 28 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:27:78:28 | 28 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:78:27:78:28 | 28 | type tracker with call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:78:27:78:28 | 28 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:78:27:78:28 | 28 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:78:27:78:28 | 28 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:27:78:28 | 28 | type tracker with call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:78:27:78:28 | 28 | type tracker with call steps with content splat position 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:27:78:28 | 28 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:78:27:78:28 | 28 | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:78:27:78:28 | 28 | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:27:78:28 | 28 | type tracker without call steps | params_flow.rb:78:21:78:29 | call to taint | | params_flow.rb:78:27:78:28 | 28 | type tracker without call steps | params_flow.rb:78:27:78:28 | 28 | -| params_flow.rb:78:27:78:28 | 28 | type tracker without call steps with content splat position 0 | params_flow.rb:78:21:78:29 | synthetic splat argument | -| params_flow.rb:78:27:78:28 | 28 | type tracker without call steps with content splat position 1 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:78:32:78:40 | call to taint | type tracker with call steps with content splat position 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:27:78:28 | 28 | type tracker without call steps with content element 0 | params_flow.rb:78:21:78:29 | synthetic splat argument | +| params_flow.rb:78:27:78:28 | 28 | type tracker without call steps with content element 1 | params_flow.rb:78:1:78:63 | synthetic splat argument | +| params_flow.rb:78:32:78:40 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:32:78:40 | call to taint | type tracker without call steps | params_flow.rb:78:32:78:40 | call to taint | -| params_flow.rb:78:32:78:40 | call to taint | type tracker without call steps with content splat position 2 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:78:32:78:40 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:78:32:78:40 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:32:78:40 | synthetic splat argument | type tracker without call steps | params_flow.rb:78:32:78:40 | synthetic splat argument | | params_flow.rb:78:38:78:39 | 29 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:78:38:78:39 | 29 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:78:38:78:39 | 29 | type tracker with call steps with content splat position 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:38:78:39 | 29 | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:38:78:39 | 29 | type tracker without call steps | params_flow.rb:78:32:78:40 | call to taint | | params_flow.rb:78:38:78:39 | 29 | type tracker without call steps | params_flow.rb:78:38:78:39 | 29 | -| params_flow.rb:78:38:78:39 | 29 | type tracker without call steps with content splat position 0 | params_flow.rb:78:32:78:40 | synthetic splat argument | -| params_flow.rb:78:38:78:39 | 29 | type tracker without call steps with content splat position 2 | params_flow.rb:78:1:78:63 | synthetic splat argument | +| params_flow.rb:78:38:78:39 | 29 | type tracker without call steps with content element 0 | params_flow.rb:78:32:78:40 | synthetic splat argument | +| params_flow.rb:78:38:78:39 | 29 | type tracker without call steps with content element 2 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | -| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content splat position 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | +| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:43:78:51 | call to taint | type tracker without call steps | params_flow.rb:78:43:78:51 | call to taint | -| params_flow.rb:78:43:78:51 | call to taint | type tracker without call steps with content splat position 3 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:78:43:78:51 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:78:43:78:51 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:43:78:51 | synthetic splat argument | type tracker without call steps | params_flow.rb:78:43:78:51 | synthetic splat argument | | params_flow.rb:78:49:78:50 | 30 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:49:78:50 | 30 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:78:49:78:50 | 30 | type tracker with call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content splat position 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | -| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content splat position 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | +| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:49:78:50 | 30 | type tracker without call steps | params_flow.rb:78:43:78:51 | call to taint | | params_flow.rb:78:49:78:50 | 30 | type tracker without call steps | params_flow.rb:78:49:78:50 | 30 | -| params_flow.rb:78:49:78:50 | 30 | type tracker without call steps with content splat position 0 | params_flow.rb:78:43:78:51 | synthetic splat argument | -| params_flow.rb:78:49:78:50 | 30 | type tracker without call steps with content splat position 3 | params_flow.rb:78:1:78:63 | synthetic splat argument | +| params_flow.rb:78:49:78:50 | 30 | type tracker without call steps with content element 0 | params_flow.rb:78:43:78:51 | synthetic splat argument | +| params_flow.rb:78:49:78:50 | 30 | type tracker without call steps with content element 3 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | -| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content splat position 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | +| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:54:78:62 | call to taint | type tracker without call steps | params_flow.rb:78:54:78:62 | call to taint | -| params_flow.rb:78:54:78:62 | call to taint | type tracker without call steps with content splat position 4 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:78:54:78:62 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:78:54:78:62 | call to taint | type tracker without call steps with content element 4 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:54:78:62 | synthetic splat argument | type tracker without call steps | params_flow.rb:78:54:78:62 | synthetic splat argument | | params_flow.rb:78:60:78:61 | 31 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:60:78:61 | 31 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:78:60:78:61 | 31 | type tracker with call steps | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content splat position 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | -| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content splat position 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | +| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:60:78:61 | 31 | type tracker without call steps | params_flow.rb:78:54:78:62 | call to taint | | params_flow.rb:78:60:78:61 | 31 | type tracker without call steps | params_flow.rb:78:60:78:61 | 31 | -| params_flow.rb:78:60:78:61 | 31 | type tracker without call steps with content splat position 0 | params_flow.rb:78:54:78:62 | synthetic splat argument | -| params_flow.rb:78:60:78:61 | 31 | type tracker without call steps with content splat position 4 | params_flow.rb:78:1:78:63 | synthetic splat argument | +| params_flow.rb:78:60:78:61 | 31 | type tracker without call steps with content element 0 | params_flow.rb:78:54:78:62 | synthetic splat argument | +| params_flow.rb:78:60:78:61 | 31 | type tracker without call steps with content element 4 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:80:1:80:4 | args | type tracker without call steps | params_flow.rb:80:1:80:4 | args | | params_flow.rb:80:8:80:51 | Array | type tracker without call steps | params_flow.rb:80:8:80:51 | Array | | params_flow.rb:80:8:80:51 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:80:8:80:51 | call to [] | type tracker with call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:80:8:80:51 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:80:8:80:51 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:80:8:80:51 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:80:8:80:51 | call to [] | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:8:80:51 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:80:8:80:51 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:80:8:80:51 | call to [] | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:8:80:51 | call to [] | type tracker without call steps | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:8:80:51 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:8:80:51 | call to [] | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | +| params_flow.rb:80:8:80:51 | call to [] | type tracker without call steps with content element 1 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker with call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker without call steps | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker without call steps | params_flow.rb:80:8:80:51 | synthetic splat argument | | params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | +| params_flow.rb:80:8:80:51 | synthetic splat argument | type tracker without call steps with content element 1 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:80:9:80:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:80:9:80:17 | call to taint | type tracker with call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:80:9:80:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:80:9:80:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:80:9:80:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:80:9:80:17 | call to taint | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:9:80:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:80:9:80:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:80:9:80:17 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:9:80:17 | call to taint | type tracker without call steps | params_flow.rb:80:9:80:17 | call to taint | | params_flow.rb:80:9:80:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:9:80:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:80:8:80:51 | synthetic splat argument | | params_flow.rb:80:9:80:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:9:80:17 | call to taint | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:80:9:80:17 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:80:9:80:17 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:80:9:80:17 | synthetic splat argument | type tracker without call steps | params_flow.rb:80:9:80:17 | synthetic splat argument | | params_flow.rb:80:15:80:16 | 33 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:80:15:80:16 | 33 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:80:15:80:16 | 33 | type tracker with call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:80:15:80:16 | 33 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:80:15:80:16 | 33 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:80:15:80:16 | 33 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:80:15:80:16 | 33 | type tracker with call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:80:15:80:16 | 33 | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:15:80:16 | 33 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:80:15:80:16 | 33 | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:80:15:80:16 | 33 | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:15:80:16 | 33 | type tracker without call steps | params_flow.rb:80:9:80:17 | call to taint | | params_flow.rb:80:15:80:16 | 33 | type tracker without call steps | params_flow.rb:80:15:80:16 | 33 | | params_flow.rb:80:15:80:16 | 33 | type tracker without call steps with content element 0 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:15:80:16 | 33 | type tracker without call steps with content element 0 | params_flow.rb:80:8:80:51 | synthetic splat argument | +| params_flow.rb:80:15:80:16 | 33 | type tracker without call steps with content element 0 | params_flow.rb:80:9:80:17 | synthetic splat argument | | params_flow.rb:80:15:80:16 | 33 | type tracker without call steps with content element 0 | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:15:80:16 | 33 | type tracker without call steps with content splat position 0 | params_flow.rb:80:9:80:17 | synthetic splat argument | -| params_flow.rb:80:15:80:16 | 33 | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:80:20:80:28 | call to taint | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:15:80:16 | 33 | type tracker without call steps with content element 1 | params_flow.rb:81:1:81:37 | synthetic splat argument | +| params_flow.rb:80:20:80:28 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:20:80:28 | call to taint | type tracker without call steps | params_flow.rb:80:20:80:28 | call to taint | | params_flow.rb:80:20:80:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:20:80:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:80:8:80:51 | synthetic splat argument | | params_flow.rb:80:20:80:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:20:80:28 | call to taint | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:80:20:80:28 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:80:20:80:28 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:80:20:80:28 | synthetic splat argument | type tracker without call steps | params_flow.rb:80:20:80:28 | synthetic splat argument | | params_flow.rb:80:26:80:27 | 34 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:80:26:80:27 | 34 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:80:26:80:27 | 34 | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:26:80:27 | 34 | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:26:80:27 | 34 | type tracker without call steps | params_flow.rb:80:20:80:28 | call to taint | | params_flow.rb:80:26:80:27 | 34 | type tracker without call steps | params_flow.rb:80:26:80:27 | 34 | +| params_flow.rb:80:26:80:27 | 34 | type tracker without call steps with content element 0 | params_flow.rb:80:20:80:28 | synthetic splat argument | | params_flow.rb:80:26:80:27 | 34 | type tracker without call steps with content element 1 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:26:80:27 | 34 | type tracker without call steps with content element 1 | params_flow.rb:80:8:80:51 | synthetic splat argument | | params_flow.rb:80:26:80:27 | 34 | type tracker without call steps with content element 1 | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:26:80:27 | 34 | type tracker without call steps with content splat position 0 | params_flow.rb:80:20:80:28 | synthetic splat argument | -| params_flow.rb:80:26:80:27 | 34 | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:80:31:80:39 | call to taint | type tracker with call steps with content splat position 3 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:26:80:27 | 34 | type tracker without call steps with content element 2 | params_flow.rb:81:1:81:37 | synthetic splat argument | +| params_flow.rb:80:31:80:39 | call to taint | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:31:80:39 | call to taint | type tracker without call steps | params_flow.rb:80:31:80:39 | call to taint | | params_flow.rb:80:31:80:39 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:31:80:39 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:80:8:80:51 | synthetic splat argument | | params_flow.rb:80:31:80:39 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:31:80:39 | call to taint | type tracker without call steps with content splat position 3 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:80:31:80:39 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:80:31:80:39 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:80:31:80:39 | synthetic splat argument | type tracker without call steps | params_flow.rb:80:31:80:39 | synthetic splat argument | | params_flow.rb:80:37:80:38 | 35 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:80:37:80:38 | 35 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:80:37:80:38 | 35 | type tracker with call steps with content splat position 3 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:37:80:38 | 35 | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:37:80:38 | 35 | type tracker without call steps | params_flow.rb:80:31:80:39 | call to taint | | params_flow.rb:80:37:80:38 | 35 | type tracker without call steps | params_flow.rb:80:37:80:38 | 35 | +| params_flow.rb:80:37:80:38 | 35 | type tracker without call steps with content element 0 | params_flow.rb:80:31:80:39 | synthetic splat argument | | params_flow.rb:80:37:80:38 | 35 | type tracker without call steps with content element 2 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:37:80:38 | 35 | type tracker without call steps with content element 2 | params_flow.rb:80:8:80:51 | synthetic splat argument | | params_flow.rb:80:37:80:38 | 35 | type tracker without call steps with content element 2 | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:37:80:38 | 35 | type tracker without call steps with content splat position 0 | params_flow.rb:80:31:80:39 | synthetic splat argument | -| params_flow.rb:80:37:80:38 | 35 | type tracker without call steps with content splat position 3 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:80:42:80:50 | call to taint | type tracker with call steps with content splat position 4 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:37:80:38 | 35 | type tracker without call steps with content element 3 | params_flow.rb:81:1:81:37 | synthetic splat argument | +| params_flow.rb:80:42:80:50 | call to taint | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:42:80:50 | call to taint | type tracker without call steps | params_flow.rb:80:42:80:50 | call to taint | | params_flow.rb:80:42:80:50 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:42:80:50 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:80:8:80:51 | synthetic splat argument | | params_flow.rb:80:42:80:50 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:42:80:50 | call to taint | type tracker without call steps with content splat position 4 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:80:42:80:50 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:80:42:80:50 | call to taint | type tracker without call steps with content element 4 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:80:42:80:50 | synthetic splat argument | type tracker without call steps | params_flow.rb:80:42:80:50 | synthetic splat argument | | params_flow.rb:80:48:80:49 | 36 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:80:48:80:49 | 36 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:80:48:80:49 | 36 | type tracker with call steps with content splat position 4 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:80:48:80:49 | 36 | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:80:48:80:49 | 36 | type tracker without call steps | params_flow.rb:80:42:80:50 | call to taint | | params_flow.rb:80:48:80:49 | 36 | type tracker without call steps | params_flow.rb:80:48:80:49 | 36 | +| params_flow.rb:80:48:80:49 | 36 | type tracker without call steps with content element 0 | params_flow.rb:80:42:80:50 | synthetic splat argument | | params_flow.rb:80:48:80:49 | 36 | type tracker without call steps with content element 3 | params_flow.rb:80:8:80:51 | call to [] | | params_flow.rb:80:48:80:49 | 36 | type tracker without call steps with content element 3 | params_flow.rb:80:8:80:51 | synthetic splat argument | | params_flow.rb:80:48:80:49 | 36 | type tracker without call steps with content element 3 | params_flow.rb:81:21:81:25 | * ... | -| params_flow.rb:80:48:80:49 | 36 | type tracker without call steps with content splat position 0 | params_flow.rb:80:42:80:50 | synthetic splat argument | -| params_flow.rb:80:48:80:49 | 36 | type tracker without call steps with content splat position 4 (shifted) | params_flow.rb:81:1:81:37 | synthetic splat argument | +| params_flow.rb:80:48:80:49 | 36 | type tracker without call steps with content element 4 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:81:1:81:37 | call to splatmid | type tracker without call steps | params_flow.rb:81:1:81:37 | call to splatmid | | params_flow.rb:81:1:81:37 | synthetic splat argument | type tracker with call steps | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:81:1:81:37 | synthetic splat argument | type tracker without call steps | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:81:10:81:18 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:81:10:81:18 | call to taint | type tracker with call steps | params_flow.rb:69:14:69:14 | x | -| params_flow.rb:81:10:81:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:81:10:81:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:81:10:81:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:81:10:81:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | +| params_flow.rb:81:10:81:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:81:10:81:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:81:10:81:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:81:10:81:18 | call to taint | type tracker without call steps | params_flow.rb:81:10:81:18 | call to taint | -| params_flow.rb:81:10:81:18 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:81:10:81:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:81:10:81:18 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:81:1:81:37 | synthetic splat argument | | params_flow.rb:81:10:81:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:81:10:81:18 | synthetic splat argument | | params_flow.rb:81:16:81:17 | 32 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:81:16:81:17 | 32 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:81:16:81:17 | 32 | type tracker with call steps | params_flow.rb:69:14:69:14 | x | -| params_flow.rb:81:16:81:17 | 32 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:81:16:81:17 | 32 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:81:16:81:17 | 32 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:81:16:81:17 | 32 | type tracker with call steps with content splat position 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:81:16:81:17 | 32 | type tracker with call steps with content splat position 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | +| params_flow.rb:81:16:81:17 | 32 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:81:16:81:17 | 32 | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:81:16:81:17 | 32 | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:81:16:81:17 | 32 | type tracker without call steps | params_flow.rb:81:10:81:18 | call to taint | | params_flow.rb:81:16:81:17 | 32 | type tracker without call steps | params_flow.rb:81:16:81:17 | 32 | -| params_flow.rb:81:16:81:17 | 32 | type tracker without call steps with content splat position 0 | params_flow.rb:81:1:81:37 | synthetic splat argument | -| params_flow.rb:81:16:81:17 | 32 | type tracker without call steps with content splat position 0 | params_flow.rb:81:10:81:18 | synthetic splat argument | +| params_flow.rb:81:16:81:17 | 32 | type tracker without call steps with content element 0 | params_flow.rb:81:1:81:37 | synthetic splat argument | +| params_flow.rb:81:16:81:17 | 32 | type tracker without call steps with content element 0 | params_flow.rb:81:10:81:18 | synthetic splat argument | | params_flow.rb:81:21:81:25 | * ... | type tracker without call steps | params_flow.rb:81:21:81:25 | * ... | | params_flow.rb:81:28:81:36 | call to taint | type tracker without call steps | params_flow.rb:81:28:81:36 | call to taint | -| params_flow.rb:81:28:81:36 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:81:28:81:36 | synthetic splat argument | type tracker without call steps | params_flow.rb:81:28:81:36 | synthetic splat argument | | params_flow.rb:81:34:81:35 | 37 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:81:34:81:35 | 37 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:81:34:81:35 | 37 | type tracker without call steps | params_flow.rb:81:28:81:36 | call to taint | | params_flow.rb:81:34:81:35 | 37 | type tracker without call steps | params_flow.rb:81:34:81:35 | 37 | -| params_flow.rb:81:34:81:35 | 37 | type tracker without call steps with content splat position 0 | params_flow.rb:81:28:81:36 | synthetic splat argument | +| params_flow.rb:81:34:81:35 | 37 | type tracker without call steps with content element 0 | params_flow.rb:81:28:81:36 | synthetic splat argument | | params_flow.rb:83:1:91:3 | &block | type tracker without call steps | params_flow.rb:83:1:91:3 | &block | | params_flow.rb:83:1:91:3 | pos_many | type tracker without call steps | params_flow.rb:83:1:91:3 | pos_many | | params_flow.rb:83:1:91:3 | self in pos_many | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | | params_flow.rb:83:1:91:3 | self in pos_many | type tracker without call steps | params_flow.rb:83:1:91:3 | self in pos_many | | params_flow.rb:83:1:91:3 | synthetic splat parameter | type tracker without call steps | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:83:14:83:14 | t | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:83:14:83:14 | t | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:83:14:83:14 | t | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:83:14:83:14 | t | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:83:14:83:14 | t | type tracker without call steps | params_flow.rb:83:14:83:14 | t | | params_flow.rb:83:14:83:14 | t | type tracker without call steps | params_flow.rb:83:14:83:14 | t | -| params_flow.rb:83:14:83:14 | t | type tracker without call steps with content splat position 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | +| params_flow.rb:83:14:83:14 | t | type tracker without call steps with content element 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:83:17:83:17 | u | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:83:17:83:17 | u | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:83:17:83:17 | u | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:83:17:83:17 | u | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:83:17:83:17 | u | type tracker without call steps | params_flow.rb:83:17:83:17 | u | | params_flow.rb:83:17:83:17 | u | type tracker without call steps | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:83:17:83:17 | u | type tracker without call steps with content splat position 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | +| params_flow.rb:83:17:83:17 | u | type tracker without call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:83:20:83:20 | v | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:83:20:83:20 | v | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:83:20:83:20 | v | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:83:20:83:20 | v | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:83:20:83:20 | v | type tracker without call steps | params_flow.rb:83:20:83:20 | v | | params_flow.rb:83:20:83:20 | v | type tracker without call steps | params_flow.rb:83:20:83:20 | v | -| params_flow.rb:83:20:83:20 | v | type tracker without call steps with content splat position 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | +| params_flow.rb:83:20:83:20 | v | type tracker without call steps with content element 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | | params_flow.rb:83:23:83:23 | w | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:83:23:83:23 | w | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:83:23:83:23 | w | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:83:23:83:23 | w | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:83:23:83:23 | w | type tracker without call steps | params_flow.rb:83:23:83:23 | w | | params_flow.rb:83:23:83:23 | w | type tracker without call steps | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:83:23:83:23 | w | type tracker without call steps with content splat position 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | +| params_flow.rb:83:23:83:23 | w | type tracker without call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | | params_flow.rb:83:26:83:26 | x | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:83:26:83:26 | x | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:83:26:83:26 | x | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:83:26:83:26 | x | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:83:26:83:26 | x | type tracker without call steps | params_flow.rb:83:26:83:26 | x | | params_flow.rb:83:26:83:26 | x | type tracker without call steps | params_flow.rb:83:26:83:26 | x | -| params_flow.rb:83:26:83:26 | x | type tracker without call steps with content splat position 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | +| params_flow.rb:83:26:83:26 | x | type tracker without call steps with content element 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | | params_flow.rb:83:29:83:29 | y | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:83:29:83:29 | y | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:83:29:83:29 | y | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:83:29:83:29 | y | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:83:29:83:29 | y | type tracker without call steps | params_flow.rb:83:29:83:29 | y | | params_flow.rb:83:29:83:29 | y | type tracker without call steps | params_flow.rb:83:29:83:29 | y | -| params_flow.rb:83:29:83:29 | y | type tracker without call steps with content splat position 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | +| params_flow.rb:83:29:83:29 | y | type tracker without call steps with content element 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | | params_flow.rb:83:32:83:32 | z | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:83:32:83:32 | z | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:83:32:83:32 | z | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:83:32:83:32 | z | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:83:32:83:32 | z | type tracker without call steps | params_flow.rb:83:32:83:32 | z | | params_flow.rb:83:32:83:32 | z | type tracker without call steps | params_flow.rb:83:32:83:32 | z | -| params_flow.rb:83:32:83:32 | z | type tracker without call steps with content splat position 0 | params_flow.rb:90:5:90:10 | synthetic splat argument | +| params_flow.rb:83:32:83:32 | z | type tracker without call steps with content element 0 | params_flow.rb:90:5:90:10 | synthetic splat argument | | params_flow.rb:84:5:84:10 | call to sink | type tracker without call steps | params_flow.rb:84:5:84:10 | call to sink | -| params_flow.rb:84:5:84:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:84:5:84:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:85:5:85:10 | call to sink | type tracker without call steps | params_flow.rb:85:5:85:10 | call to sink | -| params_flow.rb:85:5:85:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:85:5:85:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:86:5:86:10 | call to sink | type tracker without call steps | params_flow.rb:86:5:86:10 | call to sink | -| params_flow.rb:86:5:86:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:86:5:86:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:86:5:86:10 | synthetic splat argument | | params_flow.rb:87:5:87:10 | call to sink | type tracker without call steps | params_flow.rb:87:5:87:10 | call to sink | -| params_flow.rb:87:5:87:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:87:5:87:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:87:5:87:10 | synthetic splat argument | | params_flow.rb:88:5:88:10 | call to sink | type tracker without call steps | params_flow.rb:88:5:88:10 | call to sink | -| params_flow.rb:88:5:88:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:88:5:88:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:88:5:88:10 | synthetic splat argument | | params_flow.rb:89:5:89:10 | call to sink | type tracker without call steps | params_flow.rb:89:5:89:10 | call to sink | -| params_flow.rb:89:5:89:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:89:5:89:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:89:5:89:10 | synthetic splat argument | | params_flow.rb:90:5:90:10 | call to sink | type tracker without call steps | params_flow.rb:90:5:90:10 | call to sink | | params_flow.rb:90:5:90:10 | call to sink | type tracker without call steps | params_flow.rb:94:1:94:48 | call to pos_many | | params_flow.rb:90:5:90:10 | call to sink | type tracker without call steps | params_flow.rb:131:1:131:46 | call to pos_many | -| params_flow.rb:90:5:90:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:90:5:90:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:90:5:90:10 | synthetic splat argument | | params_flow.rb:93:1:93:4 | args | type tracker without call steps | params_flow.rb:93:1:93:4 | args | | params_flow.rb:93:8:93:51 | Array | type tracker without call steps | params_flow.rb:93:8:93:51 | Array | | params_flow.rb:93:8:93:51 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:8:93:51 | call to [] | type tracker with call steps | params_flow.rb:83:20:83:20 | v | -| params_flow.rb:93:8:93:51 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:8:93:51 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:8:93:51 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | -| params_flow.rb:93:8:93:51 | call to [] | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:8:93:51 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:8:93:51 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | +| params_flow.rb:93:8:93:51 | call to [] | type tracker with call steps with content element 2 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:8:93:51 | call to [] | type tracker without call steps | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:8:93:51 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:8:93:51 | call to [] | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:93:8:93:51 | call to [] | type tracker without call steps with content element 2 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker with call steps | params_flow.rb:83:20:83:20 | v | -| params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | -| params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | +| params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker with call steps with content element 2 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker without call steps | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker without call steps | params_flow.rb:93:8:93:51 | synthetic splat argument | | params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:93:8:93:51 | synthetic splat argument | type tracker without call steps with content element 2 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:93:9:93:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:9:93:17 | call to taint | type tracker with call steps | params_flow.rb:83:20:83:20 | v | -| params_flow.rb:93:9:93:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:9:93:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:9:93:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | -| params_flow.rb:93:9:93:17 | call to taint | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:9:93:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:9:93:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | +| params_flow.rb:93:9:93:17 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:9:93:17 | call to taint | type tracker without call steps | params_flow.rb:93:9:93:17 | call to taint | | params_flow.rb:93:9:93:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:9:93:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:93:8:93:51 | synthetic splat argument | | params_flow.rb:93:9:93:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:9:93:17 | call to taint | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:93:9:93:17 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:93:9:93:17 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:93:9:93:17 | synthetic splat argument | type tracker without call steps | params_flow.rb:93:9:93:17 | synthetic splat argument | | params_flow.rb:93:15:93:16 | 40 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:93:15:93:16 | 40 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:15:93:16 | 40 | type tracker with call steps | params_flow.rb:83:20:83:20 | v | -| params_flow.rb:93:15:93:16 | 40 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:93:15:93:16 | 40 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:15:93:16 | 40 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:15:93:16 | 40 | type tracker with call steps with content splat position 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | -| params_flow.rb:93:15:93:16 | 40 | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:15:93:16 | 40 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:15:93:16 | 40 | type tracker with call steps with content element 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | +| params_flow.rb:93:15:93:16 | 40 | type tracker with call steps with content element 2 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:15:93:16 | 40 | type tracker without call steps | params_flow.rb:93:9:93:17 | call to taint | | params_flow.rb:93:15:93:16 | 40 | type tracker without call steps | params_flow.rb:93:15:93:16 | 40 | | params_flow.rb:93:15:93:16 | 40 | type tracker without call steps with content element 0 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:15:93:16 | 40 | type tracker without call steps with content element 0 | params_flow.rb:93:8:93:51 | synthetic splat argument | +| params_flow.rb:93:15:93:16 | 40 | type tracker without call steps with content element 0 | params_flow.rb:93:9:93:17 | synthetic splat argument | | params_flow.rb:93:15:93:16 | 40 | type tracker without call steps with content element 0 | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:15:93:16 | 40 | type tracker without call steps with content splat position 0 | params_flow.rb:93:9:93:17 | synthetic splat argument | -| params_flow.rb:93:15:93:16 | 40 | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:93:15:93:16 | 40 | type tracker without call steps with content element 2 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:93:20:93:28 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:20:93:28 | call to taint | type tracker with call steps | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:93:20:93:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:20:93:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:20:93:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | -| params_flow.rb:93:20:93:28 | call to taint | type tracker with call steps with content splat position 3 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:20:93:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:20:93:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | +| params_flow.rb:93:20:93:28 | call to taint | type tracker with call steps with content element 3 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:20:93:28 | call to taint | type tracker without call steps | params_flow.rb:93:20:93:28 | call to taint | | params_flow.rb:93:20:93:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:20:93:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:93:8:93:51 | synthetic splat argument | | params_flow.rb:93:20:93:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:20:93:28 | call to taint | type tracker without call steps with content splat position 3 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:93:20:93:28 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:93:20:93:28 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:93:20:93:28 | synthetic splat argument | type tracker without call steps | params_flow.rb:93:20:93:28 | synthetic splat argument | | params_flow.rb:93:26:93:27 | 41 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:93:26:93:27 | 41 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:26:93:27 | 41 | type tracker with call steps | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:93:26:93:27 | 41 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:93:26:93:27 | 41 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:26:93:27 | 41 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:26:93:27 | 41 | type tracker with call steps with content splat position 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | -| params_flow.rb:93:26:93:27 | 41 | type tracker with call steps with content splat position 3 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:26:93:27 | 41 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:26:93:27 | 41 | type tracker with call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | +| params_flow.rb:93:26:93:27 | 41 | type tracker with call steps with content element 3 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:26:93:27 | 41 | type tracker without call steps | params_flow.rb:93:20:93:28 | call to taint | | params_flow.rb:93:26:93:27 | 41 | type tracker without call steps | params_flow.rb:93:26:93:27 | 41 | +| params_flow.rb:93:26:93:27 | 41 | type tracker without call steps with content element 0 | params_flow.rb:93:20:93:28 | synthetic splat argument | | params_flow.rb:93:26:93:27 | 41 | type tracker without call steps with content element 1 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:26:93:27 | 41 | type tracker without call steps with content element 1 | params_flow.rb:93:8:93:51 | synthetic splat argument | | params_flow.rb:93:26:93:27 | 41 | type tracker without call steps with content element 1 | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:26:93:27 | 41 | type tracker without call steps with content splat position 0 | params_flow.rb:93:20:93:28 | synthetic splat argument | -| params_flow.rb:93:26:93:27 | 41 | type tracker without call steps with content splat position 3 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:93:26:93:27 | 41 | type tracker without call steps with content element 3 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:93:31:93:39 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:31:93:39 | call to taint | type tracker with call steps | params_flow.rb:83:26:83:26 | x | -| params_flow.rb:93:31:93:39 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:31:93:39 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:31:93:39 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | -| params_flow.rb:93:31:93:39 | call to taint | type tracker with call steps with content splat position 4 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:31:93:39 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:31:93:39 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | +| params_flow.rb:93:31:93:39 | call to taint | type tracker with call steps with content element 4 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:31:93:39 | call to taint | type tracker without call steps | params_flow.rb:93:31:93:39 | call to taint | | params_flow.rb:93:31:93:39 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:31:93:39 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:93:8:93:51 | synthetic splat argument | | params_flow.rb:93:31:93:39 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:31:93:39 | call to taint | type tracker without call steps with content splat position 4 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:93:31:93:39 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:93:31:93:39 | call to taint | type tracker without call steps with content element 4 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:93:31:93:39 | synthetic splat argument | type tracker without call steps | params_flow.rb:93:31:93:39 | synthetic splat argument | | params_flow.rb:93:37:93:38 | 42 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:93:37:93:38 | 42 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:37:93:38 | 42 | type tracker with call steps | params_flow.rb:83:26:83:26 | x | -| params_flow.rb:93:37:93:38 | 42 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:93:37:93:38 | 42 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:37:93:38 | 42 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:37:93:38 | 42 | type tracker with call steps with content splat position 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | -| params_flow.rb:93:37:93:38 | 42 | type tracker with call steps with content splat position 4 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:37:93:38 | 42 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:37:93:38 | 42 | type tracker with call steps with content element 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | +| params_flow.rb:93:37:93:38 | 42 | type tracker with call steps with content element 4 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:37:93:38 | 42 | type tracker without call steps | params_flow.rb:93:31:93:39 | call to taint | | params_flow.rb:93:37:93:38 | 42 | type tracker without call steps | params_flow.rb:93:37:93:38 | 42 | +| params_flow.rb:93:37:93:38 | 42 | type tracker without call steps with content element 0 | params_flow.rb:93:31:93:39 | synthetic splat argument | | params_flow.rb:93:37:93:38 | 42 | type tracker without call steps with content element 2 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:37:93:38 | 42 | type tracker without call steps with content element 2 | params_flow.rb:93:8:93:51 | synthetic splat argument | | params_flow.rb:93:37:93:38 | 42 | type tracker without call steps with content element 2 | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:37:93:38 | 42 | type tracker without call steps with content splat position 0 | params_flow.rb:93:31:93:39 | synthetic splat argument | -| params_flow.rb:93:37:93:38 | 42 | type tracker without call steps with content splat position 4 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:93:37:93:38 | 42 | type tracker without call steps with content element 4 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:93:42:93:50 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:42:93:50 | call to taint | type tracker with call steps | params_flow.rb:83:29:83:29 | y | -| params_flow.rb:93:42:93:50 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:42:93:50 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:42:93:50 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | -| params_flow.rb:93:42:93:50 | call to taint | type tracker with call steps with content splat position 5 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:42:93:50 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:42:93:50 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | +| params_flow.rb:93:42:93:50 | call to taint | type tracker with call steps with content element 5 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:42:93:50 | call to taint | type tracker without call steps | params_flow.rb:93:42:93:50 | call to taint | | params_flow.rb:93:42:93:50 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:42:93:50 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:93:8:93:51 | synthetic splat argument | | params_flow.rb:93:42:93:50 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:42:93:50 | call to taint | type tracker without call steps with content splat position 5 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:93:42:93:50 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:93:42:93:50 | call to taint | type tracker without call steps with content element 5 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:93:42:93:50 | synthetic splat argument | type tracker without call steps | params_flow.rb:93:42:93:50 | synthetic splat argument | | params_flow.rb:93:48:93:49 | 43 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:93:48:93:49 | 43 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:93:48:93:49 | 43 | type tracker with call steps | params_flow.rb:83:29:83:29 | y | -| params_flow.rb:93:48:93:49 | 43 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:93:48:93:49 | 43 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:93:48:93:49 | 43 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:93:48:93:49 | 43 | type tracker with call steps with content splat position 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | -| params_flow.rb:93:48:93:49 | 43 | type tracker with call steps with content splat position 5 (shifted) | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:93:48:93:49 | 43 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:93:48:93:49 | 43 | type tracker with call steps with content element 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | +| params_flow.rb:93:48:93:49 | 43 | type tracker with call steps with content element 5 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:93:48:93:49 | 43 | type tracker without call steps | params_flow.rb:93:42:93:50 | call to taint | | params_flow.rb:93:48:93:49 | 43 | type tracker without call steps | params_flow.rb:93:48:93:49 | 43 | +| params_flow.rb:93:48:93:49 | 43 | type tracker without call steps with content element 0 | params_flow.rb:93:42:93:50 | synthetic splat argument | | params_flow.rb:93:48:93:49 | 43 | type tracker without call steps with content element 3 | params_flow.rb:93:8:93:51 | call to [] | | params_flow.rb:93:48:93:49 | 43 | type tracker without call steps with content element 3 | params_flow.rb:93:8:93:51 | synthetic splat argument | | params_flow.rb:93:48:93:49 | 43 | type tracker without call steps with content element 3 | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:93:48:93:49 | 43 | type tracker without call steps with content splat position 0 | params_flow.rb:93:42:93:50 | synthetic splat argument | -| params_flow.rb:93:48:93:49 | 43 | type tracker without call steps with content splat position 5 (shifted) | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:93:48:93:49 | 43 | type tracker without call steps with content element 5 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:94:1:94:48 | call to pos_many | type tracker without call steps | params_flow.rb:94:1:94:48 | call to pos_many | | params_flow.rb:94:1:94:48 | synthetic splat argument | type tracker with call steps | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:94:1:94:48 | synthetic splat argument | type tracker without call steps | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:94:10:94:18 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:94:10:94:18 | call to taint | type tracker with call steps | params_flow.rb:83:14:83:14 | t | -| params_flow.rb:94:10:94:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:94:10:94:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:94:10:94:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:94:10:94:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | +| params_flow.rb:94:10:94:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:94:10:94:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:94:10:94:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:94:10:94:18 | call to taint | type tracker without call steps | params_flow.rb:94:10:94:18 | call to taint | -| params_flow.rb:94:10:94:18 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:94:10:94:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:94:10:94:18 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:94:10:94:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:94:10:94:18 | synthetic splat argument | | params_flow.rb:94:16:94:17 | 38 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:94:16:94:17 | 38 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:94:16:94:17 | 38 | type tracker with call steps | params_flow.rb:83:14:83:14 | t | -| params_flow.rb:94:16:94:17 | 38 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:94:16:94:17 | 38 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:94:16:94:17 | 38 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:94:16:94:17 | 38 | type tracker with call steps with content splat position 0 | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:94:16:94:17 | 38 | type tracker with call steps with content splat position 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | +| params_flow.rb:94:16:94:17 | 38 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:94:16:94:17 | 38 | type tracker with call steps with content element 0 | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:94:16:94:17 | 38 | type tracker with call steps with content element 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:94:16:94:17 | 38 | type tracker without call steps | params_flow.rb:94:10:94:18 | call to taint | | params_flow.rb:94:16:94:17 | 38 | type tracker without call steps | params_flow.rb:94:16:94:17 | 38 | -| params_flow.rb:94:16:94:17 | 38 | type tracker without call steps with content splat position 0 | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:94:16:94:17 | 38 | type tracker without call steps with content splat position 0 | params_flow.rb:94:10:94:18 | synthetic splat argument | +| params_flow.rb:94:16:94:17 | 38 | type tracker without call steps with content element 0 | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:94:16:94:17 | 38 | type tracker without call steps with content element 0 | params_flow.rb:94:10:94:18 | synthetic splat argument | | params_flow.rb:94:21:94:29 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:94:21:94:29 | call to taint | type tracker with call steps | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:94:21:94:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:94:21:94:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:94:21:94:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | -| params_flow.rb:94:21:94:29 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:94:21:94:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:94:21:94:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | +| params_flow.rb:94:21:94:29 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:94:21:94:29 | call to taint | type tracker without call steps | params_flow.rb:94:21:94:29 | call to taint | -| params_flow.rb:94:21:94:29 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:94:1:94:48 | synthetic splat argument | -| params_flow.rb:94:21:94:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:94:21:94:29 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:94:21:94:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:94:21:94:29 | synthetic splat argument | | params_flow.rb:94:27:94:28 | 39 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:94:27:94:28 | 39 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:94:27:94:28 | 39 | type tracker with call steps | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:94:27:94:28 | 39 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:94:27:94:28 | 39 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:94:27:94:28 | 39 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:94:27:94:28 | 39 | type tracker with call steps with content splat position 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | -| params_flow.rb:94:27:94:28 | 39 | type tracker with call steps with content splat position 1 | params_flow.rb:83:1:91:3 | synthetic splat parameter | +| params_flow.rb:94:27:94:28 | 39 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:94:27:94:28 | 39 | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | +| params_flow.rb:94:27:94:28 | 39 | type tracker with call steps with content element 1 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:94:27:94:28 | 39 | type tracker without call steps | params_flow.rb:94:21:94:29 | call to taint | | params_flow.rb:94:27:94:28 | 39 | type tracker without call steps | params_flow.rb:94:27:94:28 | 39 | -| params_flow.rb:94:27:94:28 | 39 | type tracker without call steps with content splat position 0 | params_flow.rb:94:21:94:29 | synthetic splat argument | -| params_flow.rb:94:27:94:28 | 39 | type tracker without call steps with content splat position 1 | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:94:27:94:28 | 39 | type tracker without call steps with content element 0 | params_flow.rb:94:21:94:29 | synthetic splat argument | +| params_flow.rb:94:27:94:28 | 39 | type tracker without call steps with content element 1 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:94:32:94:36 | * ... | type tracker without call steps | params_flow.rb:94:32:94:36 | * ... | | params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | +| params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | | params_flow.rb:94:39:94:47 | call to taint | type tracker without call steps | params_flow.rb:94:39:94:47 | call to taint | -| params_flow.rb:94:39:94:47 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:94:39:94:47 | synthetic splat argument | type tracker without call steps | params_flow.rb:94:39:94:47 | synthetic splat argument | | params_flow.rb:94:45:94:46 | 44 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:94:45:94:46 | 44 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:94:45:94:46 | 44 | type tracker with call steps | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps with content splat position 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | +| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | | params_flow.rb:94:45:94:46 | 44 | type tracker without call steps | params_flow.rb:94:39:94:47 | call to taint | | params_flow.rb:94:45:94:46 | 44 | type tracker without call steps | params_flow.rb:94:45:94:46 | 44 | -| params_flow.rb:94:45:94:46 | 44 | type tracker without call steps with content splat position 0 | params_flow.rb:94:39:94:47 | synthetic splat argument | +| params_flow.rb:94:45:94:46 | 44 | type tracker without call steps with content element 0 | params_flow.rb:94:39:94:47 | synthetic splat argument | | params_flow.rb:96:1:96:88 | call to splatmid | type tracker without call steps | params_flow.rb:96:1:96:88 | call to splatmid | | params_flow.rb:96:1:96:88 | synthetic splat argument | type tracker with call steps | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:1:96:88 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps | params_flow.rb:69:14:69:14 | x | -| params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | +| params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:96:10:96:18 | call to taint | type tracker without call steps | params_flow.rb:96:10:96:18 | call to taint | -| params_flow.rb:96:10:96:18 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:10:96:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:96:10:96:18 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:10:96:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:10:96:18 | synthetic splat argument | | params_flow.rb:96:16:96:17 | 45 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:16:96:17 | 45 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:16:96:17 | 45 | type tracker with call steps | params_flow.rb:69:14:69:14 | x | -| params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content splat position 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | -| params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content splat position 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | +| params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:96:16:96:17 | 45 | type tracker without call steps | params_flow.rb:96:10:96:18 | call to taint | | params_flow.rb:96:16:96:17 | 45 | type tracker without call steps | params_flow.rb:96:16:96:17 | 45 | -| params_flow.rb:96:16:96:17 | 45 | type tracker without call steps with content splat position 0 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:16:96:17 | 45 | type tracker without call steps with content splat position 0 | params_flow.rb:96:10:96:18 | synthetic splat argument | +| params_flow.rb:96:16:96:17 | 45 | type tracker without call steps with content element 0 | params_flow.rb:96:1:96:88 | synthetic splat argument | +| params_flow.rb:96:16:96:17 | 45 | type tracker without call steps with content element 0 | params_flow.rb:96:10:96:18 | synthetic splat argument | | params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:21:96:29 | call to taint | type tracker without call steps | params_flow.rb:96:21:96:29 | call to taint | -| params_flow.rb:96:21:96:29 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:21:96:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:96:21:96:29 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:21:96:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:21:96:29 | synthetic splat argument | | params_flow.rb:96:27:96:28 | 46 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:27:96:28 | 46 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:27:96:28 | 46 | type tracker with call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content splat position 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content splat position 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | +| params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:27:96:28 | 46 | type tracker without call steps | params_flow.rb:96:21:96:29 | call to taint | | params_flow.rb:96:27:96:28 | 46 | type tracker without call steps | params_flow.rb:96:27:96:28 | 46 | -| params_flow.rb:96:27:96:28 | 46 | type tracker without call steps with content splat position 0 | params_flow.rb:96:21:96:29 | synthetic splat argument | -| params_flow.rb:96:27:96:28 | 46 | type tracker without call steps with content splat position 1 | params_flow.rb:96:1:96:88 | synthetic splat argument | +| params_flow.rb:96:27:96:28 | 46 | type tracker without call steps with content element 0 | params_flow.rb:96:21:96:29 | synthetic splat argument | +| params_flow.rb:96:27:96:28 | 46 | type tracker without call steps with content element 1 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:32:96:65 | * ... | type tracker without call steps | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:33:96:65 | Array | type tracker without call steps | params_flow.rb:96:33:96:65 | Array | -| params_flow.rb:96:33:96:65 | call to [] | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:33:96:65 | call to [] | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:33:96:65 | call to [] | type tracker without call steps | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:33:96:65 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:96:32:96:65 | * ... | -| params_flow.rb:96:33:96:65 | call to [] | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:33:96:65 | call to [] | type tracker without call steps with content element 2 | params_flow.rb:96:1:96:88 | synthetic splat argument | +| params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:33:96:65 | synthetic splat argument | | params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:96:32:96:65 | * ... | -| params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:34:96:42 | call to taint | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker without call steps with content element 2 | params_flow.rb:96:1:96:88 | synthetic splat argument | +| params_flow.rb:96:34:96:42 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps | params_flow.rb:96:34:96:42 | call to taint | | params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:96:33:96:65 | synthetic splat argument | -| params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:34:96:42 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:34:96:42 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:34:96:42 | synthetic splat argument | | params_flow.rb:96:40:96:41 | 47 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:96:40:96:41 | 47 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:96:40:96:41 | 47 | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:40:96:41 | 47 | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps | params_flow.rb:96:34:96:42 | call to taint | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps | params_flow.rb:96:40:96:41 | 47 | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content element 0 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content element 0 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content element 0 | params_flow.rb:96:33:96:65 | synthetic splat argument | -| params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content splat position 0 | params_flow.rb:96:34:96:42 | synthetic splat argument | -| params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:45:96:53 | call to taint | type tracker with call steps with content splat position 3 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content element 0 | params_flow.rb:96:34:96:42 | synthetic splat argument | +| params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content element 2 | params_flow.rb:96:1:96:88 | synthetic splat argument | +| params_flow.rb:96:45:96:53 | call to taint | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps | params_flow.rb:96:45:96:53 | call to taint | | params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:96:33:96:65 | synthetic splat argument | -| params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps with content splat position 3 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:45:96:53 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:45:96:53 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:45:96:53 | synthetic splat argument | | params_flow.rb:96:51:96:52 | 48 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:96:51:96:52 | 48 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:96:51:96:52 | 48 | type tracker with call steps with content splat position 3 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:51:96:52 | 48 | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps | params_flow.rb:96:45:96:53 | call to taint | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps | params_flow.rb:96:51:96:52 | 48 | +| params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content element 0 | params_flow.rb:96:45:96:53 | synthetic splat argument | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content element 1 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content element 1 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content element 1 | params_flow.rb:96:33:96:65 | synthetic splat argument | -| params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content splat position 0 | params_flow.rb:96:45:96:53 | synthetic splat argument | -| params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content splat position 3 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:56:96:64 | call to taint | type tracker with call steps with content splat position 4 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content element 3 | params_flow.rb:96:1:96:88 | synthetic splat argument | +| params_flow.rb:96:56:96:64 | call to taint | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps | params_flow.rb:96:56:96:64 | call to taint | | params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:96:33:96:65 | synthetic splat argument | -| params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps with content splat position 4 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:56:96:64 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps with content element 4 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:56:96:64 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:56:96:64 | synthetic splat argument | | params_flow.rb:96:62:96:63 | 49 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:96:62:96:63 | 49 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:96:62:96:63 | 49 | type tracker with call steps with content splat position 4 (shifted) | params_flow.rb:69:1:76:3 | synthetic splat parameter | +| params_flow.rb:96:62:96:63 | 49 | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps | params_flow.rb:96:56:96:64 | call to taint | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps | params_flow.rb:96:62:96:63 | 49 | +| params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content element 0 | params_flow.rb:96:56:96:64 | synthetic splat argument | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content element 2 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content element 2 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content element 2 | params_flow.rb:96:33:96:65 | synthetic splat argument | -| params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content splat position 0 | params_flow.rb:96:56:96:64 | synthetic splat argument | -| params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content splat position 4 (shifted) | params_flow.rb:96:1:96:88 | synthetic splat argument | +| params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content element 4 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | +| params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | | params_flow.rb:96:68:96:76 | call to taint | type tracker without call steps | params_flow.rb:96:68:96:76 | call to taint | -| params_flow.rb:96:68:96:76 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:96:68:96:76 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:68:96:76 | synthetic splat argument | | params_flow.rb:96:74:96:75 | 50 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:74:96:75 | 50 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:74:96:75 | 50 | type tracker with call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps with content splat position 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | +| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | | params_flow.rb:96:74:96:75 | 50 | type tracker without call steps | params_flow.rb:96:68:96:76 | call to taint | | params_flow.rb:96:74:96:75 | 50 | type tracker without call steps | params_flow.rb:96:74:96:75 | 50 | -| params_flow.rb:96:74:96:75 | 50 | type tracker without call steps with content splat position 0 | params_flow.rb:96:68:96:76 | synthetic splat argument | +| params_flow.rb:96:74:96:75 | 50 | type tracker without call steps with content element 0 | params_flow.rb:96:68:96:76 | synthetic splat argument | | params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | +| params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:96:79:96:87 | call to taint | type tracker without call steps | params_flow.rb:96:79:96:87 | call to taint | -| params_flow.rb:96:79:96:87 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:96:79:96:87 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:79:96:87 | synthetic splat argument | | params_flow.rb:96:85:96:86 | 51 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:85:96:86 | 51 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:85:96:86 | 51 | type tracker with call steps | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps with content splat position 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | +| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:96:85:96:86 | 51 | type tracker without call steps | params_flow.rb:96:79:96:87 | call to taint | | params_flow.rb:96:85:96:86 | 51 | type tracker without call steps | params_flow.rb:96:85:96:86 | 51 | -| params_flow.rb:96:85:96:86 | 51 | type tracker without call steps with content splat position 0 | params_flow.rb:96:79:96:87 | synthetic splat argument | +| params_flow.rb:96:85:96:86 | 51 | type tracker without call steps with content element 0 | params_flow.rb:96:79:96:87 | synthetic splat argument | | params_flow.rb:98:1:103:3 | &block | type tracker without call steps | params_flow.rb:98:1:103:3 | &block | | params_flow.rb:98:1:103:3 | self in splatmidsmall | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | | params_flow.rb:98:1:103:3 | self in splatmidsmall | type tracker without call steps | params_flow.rb:98:1:103:3 | self in splatmidsmall | | params_flow.rb:98:1:103:3 | splatmidsmall | type tracker without call steps | params_flow.rb:98:1:103:3 | splatmidsmall | | params_flow.rb:98:1:103:3 | synthetic splat parameter | type tracker without call steps | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:98:19:98:19 | a | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:98:19:98:19 | a | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:98:19:98:19 | a | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:98:19:98:19 | a | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:98:19:98:19 | a | type tracker without call steps | params_flow.rb:98:19:98:19 | a | | params_flow.rb:98:19:98:19 | a | type tracker without call steps | params_flow.rb:98:19:98:19 | a | -| params_flow.rb:98:19:98:19 | a | type tracker without call steps with content splat position 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | +| params_flow.rb:98:19:98:19 | a | type tracker without call steps with content element 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | | params_flow.rb:98:22:98:28 | *splats | type tracker without call steps | params_flow.rb:98:22:98:28 | *splats | | params_flow.rb:98:23:98:28 | splats | type tracker without call steps | params_flow.rb:98:23:98:28 | splats | | params_flow.rb:98:31:98:31 | b | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:98:31:98:31 | b | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:98:31:98:31 | b | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:98:31:98:31 | b | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:98:31:98:31 | b | type tracker without call steps | params_flow.rb:98:31:98:31 | b | | params_flow.rb:98:31:98:31 | b | type tracker without call steps | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:98:31:98:31 | b | type tracker without call steps with content splat position 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | +| params_flow.rb:98:31:98:31 | b | type tracker without call steps with content element 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | | params_flow.rb:99:5:99:10 | call to sink | type tracker without call steps | params_flow.rb:99:5:99:10 | call to sink | -| params_flow.rb:99:5:99:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:99:5:99:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:99:5:99:10 | synthetic splat argument | | params_flow.rb:100:5:100:18 | call to sink | type tracker without call steps | params_flow.rb:100:5:100:18 | call to sink | -| params_flow.rb:100:5:100:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:100:5:100:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:100:5:100:18 | synthetic splat argument | | params_flow.rb:100:10:100:18 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:100:10:100:18 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:100:10:100:18 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:100:10:100:18 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:100:10:100:18 | ...[...] | type tracker without call steps | params_flow.rb:100:10:100:18 | ...[...] | -| params_flow.rb:100:10:100:18 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:100:5:100:18 | synthetic splat argument | +| params_flow.rb:100:10:100:18 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:100:5:100:18 | synthetic splat argument | | params_flow.rb:100:10:100:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:100:10:100:18 | synthetic splat argument | | params_flow.rb:100:17:100:17 | 0 | type tracker without call steps | params_flow.rb:100:17:100:17 | 0 | -| params_flow.rb:100:17:100:17 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:100:10:100:18 | synthetic splat argument | +| params_flow.rb:100:17:100:17 | 0 | type tracker without call steps with content element 0 | params_flow.rb:100:10:100:18 | synthetic splat argument | | params_flow.rb:101:5:101:18 | call to sink | type tracker without call steps | params_flow.rb:101:5:101:18 | call to sink | -| params_flow.rb:101:5:101:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:101:5:101:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:101:5:101:18 | synthetic splat argument | | params_flow.rb:101:10:101:18 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:101:10:101:18 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:101:10:101:18 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:101:10:101:18 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:101:10:101:18 | ...[...] | type tracker without call steps | params_flow.rb:101:10:101:18 | ...[...] | -| params_flow.rb:101:10:101:18 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:101:5:101:18 | synthetic splat argument | +| params_flow.rb:101:10:101:18 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:101:5:101:18 | synthetic splat argument | | params_flow.rb:101:10:101:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:101:10:101:18 | synthetic splat argument | | params_flow.rb:101:17:101:17 | 1 | type tracker without call steps | params_flow.rb:101:17:101:17 | 1 | -| params_flow.rb:101:17:101:17 | 1 | type tracker without call steps with content splat position 0 | params_flow.rb:101:10:101:18 | synthetic splat argument | +| params_flow.rb:101:17:101:17 | 1 | type tracker without call steps with content element 0 | params_flow.rb:101:10:101:18 | synthetic splat argument | | params_flow.rb:102:5:102:10 | call to sink | type tracker without call steps | params_flow.rb:102:5:102:10 | call to sink | | params_flow.rb:102:5:102:10 | call to sink | type tracker without call steps | params_flow.rb:105:1:105:49 | call to splatmidsmall | | params_flow.rb:102:5:102:10 | call to sink | type tracker without call steps | params_flow.rb:106:1:106:46 | call to splatmidsmall | -| params_flow.rb:102:5:102:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:102:5:102:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:102:5:102:10 | synthetic splat argument | | params_flow.rb:105:1:105:49 | call to splatmidsmall | type tracker without call steps | params_flow.rb:105:1:105:49 | call to splatmidsmall | | params_flow.rb:105:1:105:49 | synthetic splat argument | type tracker with call steps | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:1:105:49 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps | params_flow.rb:98:19:98:19 | a | -| params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | -| params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | +| params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | | params_flow.rb:105:15:105:23 | call to taint | type tracker without call steps | params_flow.rb:105:15:105:23 | call to taint | -| params_flow.rb:105:15:105:23 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:15:105:23 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:105:15:105:23 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:105:15:105:23 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:15:105:23 | synthetic splat argument | | params_flow.rb:105:21:105:22 | 52 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:105:21:105:22 | 52 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:105:21:105:22 | 52 | type tracker with call steps | params_flow.rb:98:19:98:19 | a | -| params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content splat position 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | -| params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content splat position 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | +| params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content element 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content element 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | | params_flow.rb:105:21:105:22 | 52 | type tracker without call steps | params_flow.rb:105:15:105:23 | call to taint | | params_flow.rb:105:21:105:22 | 52 | type tracker without call steps | params_flow.rb:105:21:105:22 | 52 | -| params_flow.rb:105:21:105:22 | 52 | type tracker without call steps with content splat position 0 | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:21:105:22 | 52 | type tracker without call steps with content splat position 0 | params_flow.rb:105:15:105:23 | synthetic splat argument | +| params_flow.rb:105:21:105:22 | 52 | type tracker without call steps with content element 0 | params_flow.rb:105:1:105:49 | synthetic splat argument | +| params_flow.rb:105:21:105:22 | 52 | type tracker without call steps with content element 0 | params_flow.rb:105:15:105:23 | synthetic splat argument | | params_flow.rb:105:26:105:48 | * ... | type tracker without call steps | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:27:105:48 | Array | type tracker without call steps | params_flow.rb:105:27:105:48 | Array | -| params_flow.rb:105:27:105:48 | call to [] | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:105:27:105:48 | call to [] | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:27:105:48 | call to [] | type tracker without call steps | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:105:27:105:48 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:105:26:105:48 | * ... | -| params_flow.rb:105:27:105:48 | call to [] | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:105:27:105:48 | call to [] | type tracker without call steps with content element 1 | params_flow.rb:105:1:105:49 | synthetic splat argument | +| params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:27:105:48 | synthetic splat argument | | params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:105:26:105:48 | * ... | -| params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:28:105:36 | call to taint | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker without call steps with content element 1 | params_flow.rb:105:1:105:49 | synthetic splat argument | +| params_flow.rb:105:28:105:36 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps | params_flow.rb:105:28:105:36 | call to taint | | params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:105:27:105:48 | synthetic splat argument | -| params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:28:105:36 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:105:28:105:36 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:28:105:36 | synthetic splat argument | | params_flow.rb:105:34:105:35 | 53 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:105:34:105:35 | 53 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:105:34:105:35 | 53 | type tracker with call steps with content splat position 1 (shifted) | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:105:34:105:35 | 53 | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps | params_flow.rb:105:28:105:36 | call to taint | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps | params_flow.rb:105:34:105:35 | 53 | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content element 0 | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content element 0 | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content element 0 | params_flow.rb:105:27:105:48 | synthetic splat argument | -| params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content splat position 0 | params_flow.rb:105:28:105:36 | synthetic splat argument | -| params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content splat position 1 (shifted) | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:39:105:47 | call to taint | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content element 0 | params_flow.rb:105:28:105:36 | synthetic splat argument | +| params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content element 1 | params_flow.rb:105:1:105:49 | synthetic splat argument | +| params_flow.rb:105:39:105:47 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps | params_flow.rb:105:39:105:47 | call to taint | | params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:105:27:105:48 | synthetic splat argument | -| params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:39:105:47 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:105:39:105:47 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:39:105:47 | synthetic splat argument | | params_flow.rb:105:45:105:46 | 54 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:105:45:105:46 | 54 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:105:45:105:46 | 54 | type tracker with call steps with content splat position 2 (shifted) | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:105:45:105:46 | 54 | type tracker with call steps with content element 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:45:105:46 | 54 | type tracker without call steps | params_flow.rb:105:39:105:47 | call to taint | | params_flow.rb:105:45:105:46 | 54 | type tracker without call steps | params_flow.rb:105:45:105:46 | 54 | +| params_flow.rb:105:45:105:46 | 54 | type tracker without call steps with content element 0 | params_flow.rb:105:39:105:47 | synthetic splat argument | | params_flow.rb:105:45:105:46 | 54 | type tracker without call steps with content element 1 | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:45:105:46 | 54 | type tracker without call steps with content element 1 | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:105:45:105:46 | 54 | type tracker without call steps with content element 1 | params_flow.rb:105:27:105:48 | synthetic splat argument | -| params_flow.rb:105:45:105:46 | 54 | type tracker without call steps with content splat position 0 | params_flow.rb:105:39:105:47 | synthetic splat argument | -| params_flow.rb:105:45:105:46 | 54 | type tracker without call steps with content splat position 2 (shifted) | params_flow.rb:105:1:105:49 | synthetic splat argument | +| params_flow.rb:105:45:105:46 | 54 | type tracker without call steps with content element 2 | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:106:1:106:46 | call to splatmidsmall | type tracker without call steps | params_flow.rb:106:1:106:46 | call to splatmidsmall | | params_flow.rb:106:1:106:46 | synthetic splat argument | type tracker with call steps | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:106:1:106:46 | synthetic splat argument | type tracker without call steps | params_flow.rb:106:1:106:46 | synthetic splat argument | | params_flow.rb:106:15:106:23 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:106:15:106:23 | call to taint | type tracker with call steps | params_flow.rb:98:19:98:19 | a | -| params_flow.rb:106:15:106:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:106:15:106:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:106:15:106:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | -| params_flow.rb:106:15:106:23 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | +| params_flow.rb:106:15:106:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:106:15:106:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:106:15:106:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | | params_flow.rb:106:15:106:23 | call to taint | type tracker without call steps | params_flow.rb:106:15:106:23 | call to taint | -| params_flow.rb:106:15:106:23 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:106:1:106:46 | synthetic splat argument | -| params_flow.rb:106:15:106:23 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:106:15:106:23 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:106:1:106:46 | synthetic splat argument | | params_flow.rb:106:15:106:23 | synthetic splat argument | type tracker without call steps | params_flow.rb:106:15:106:23 | synthetic splat argument | | params_flow.rb:106:21:106:22 | 55 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:106:21:106:22 | 55 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:106:21:106:22 | 55 | type tracker with call steps | params_flow.rb:98:19:98:19 | a | -| params_flow.rb:106:21:106:22 | 55 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:106:21:106:22 | 55 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:106:21:106:22 | 55 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:106:21:106:22 | 55 | type tracker with call steps with content splat position 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | -| params_flow.rb:106:21:106:22 | 55 | type tracker with call steps with content splat position 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | +| params_flow.rb:106:21:106:22 | 55 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:106:21:106:22 | 55 | type tracker with call steps with content element 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:106:21:106:22 | 55 | type tracker with call steps with content element 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | | params_flow.rb:106:21:106:22 | 55 | type tracker without call steps | params_flow.rb:106:15:106:23 | call to taint | | params_flow.rb:106:21:106:22 | 55 | type tracker without call steps | params_flow.rb:106:21:106:22 | 55 | -| params_flow.rb:106:21:106:22 | 55 | type tracker without call steps with content splat position 0 | params_flow.rb:106:1:106:46 | synthetic splat argument | -| params_flow.rb:106:21:106:22 | 55 | type tracker without call steps with content splat position 0 | params_flow.rb:106:15:106:23 | synthetic splat argument | -| params_flow.rb:106:26:106:34 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:106:21:106:22 | 55 | type tracker without call steps with content element 0 | params_flow.rb:106:1:106:46 | synthetic splat argument | +| params_flow.rb:106:21:106:22 | 55 | type tracker without call steps with content element 0 | params_flow.rb:106:15:106:23 | synthetic splat argument | +| params_flow.rb:106:26:106:34 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:106:26:106:34 | call to taint | type tracker without call steps | params_flow.rb:106:26:106:34 | call to taint | -| params_flow.rb:106:26:106:34 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:106:1:106:46 | synthetic splat argument | -| params_flow.rb:106:26:106:34 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:106:26:106:34 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:106:1:106:46 | synthetic splat argument | | params_flow.rb:106:26:106:34 | synthetic splat argument | type tracker without call steps | params_flow.rb:106:26:106:34 | synthetic splat argument | | params_flow.rb:106:32:106:33 | 56 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:106:32:106:33 | 56 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:106:32:106:33 | 56 | type tracker with call steps with content splat position 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:106:32:106:33 | 56 | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:106:32:106:33 | 56 | type tracker without call steps | params_flow.rb:106:26:106:34 | call to taint | | params_flow.rb:106:32:106:33 | 56 | type tracker without call steps | params_flow.rb:106:32:106:33 | 56 | -| params_flow.rb:106:32:106:33 | 56 | type tracker without call steps with content splat position 0 | params_flow.rb:106:26:106:34 | synthetic splat argument | -| params_flow.rb:106:32:106:33 | 56 | type tracker without call steps with content splat position 1 | params_flow.rb:106:1:106:46 | synthetic splat argument | +| params_flow.rb:106:32:106:33 | 56 | type tracker without call steps with content element 0 | params_flow.rb:106:26:106:34 | synthetic splat argument | +| params_flow.rb:106:32:106:33 | 56 | type tracker without call steps with content element 1 | params_flow.rb:106:1:106:46 | synthetic splat argument | | params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | -| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content splat position 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | +| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:106:37:106:45 | call to taint | type tracker without call steps | params_flow.rb:106:37:106:45 | call to taint | -| params_flow.rb:106:37:106:45 | call to taint | type tracker without call steps with content splat position 2 | params_flow.rb:106:1:106:46 | synthetic splat argument | -| params_flow.rb:106:37:106:45 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:106:37:106:45 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:106:1:106:46 | synthetic splat argument | | params_flow.rb:106:37:106:45 | synthetic splat argument | type tracker without call steps | params_flow.rb:106:37:106:45 | synthetic splat argument | | params_flow.rb:106:43:106:44 | 57 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:106:43:106:44 | 57 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:106:43:106:44 | 57 | type tracker with call steps | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content splat position 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | -| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content splat position 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | +| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content element 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | +| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content element 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:106:43:106:44 | 57 | type tracker without call steps | params_flow.rb:106:37:106:45 | call to taint | | params_flow.rb:106:43:106:44 | 57 | type tracker without call steps | params_flow.rb:106:43:106:44 | 57 | -| params_flow.rb:106:43:106:44 | 57 | type tracker without call steps with content splat position 0 | params_flow.rb:106:37:106:45 | synthetic splat argument | -| params_flow.rb:106:43:106:44 | 57 | type tracker without call steps with content splat position 2 | params_flow.rb:106:1:106:46 | synthetic splat argument | +| params_flow.rb:106:43:106:44 | 57 | type tracker without call steps with content element 0 | params_flow.rb:106:37:106:45 | synthetic splat argument | +| params_flow.rb:106:43:106:44 | 57 | type tracker without call steps with content element 2 | params_flow.rb:106:1:106:46 | synthetic splat argument | | params_flow.rb:108:1:112:3 | &block | type tracker without call steps | params_flow.rb:108:1:112:3 | &block | | params_flow.rb:108:1:112:3 | self in splat_followed_by_keyword_param | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | | params_flow.rb:108:1:112:3 | self in splat_followed_by_keyword_param | type tracker without call steps | params_flow.rb:108:1:112:3 | self in splat_followed_by_keyword_param | @@ -2492,36 +2182,30 @@ track | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | type tracker without call steps | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | | params_flow.rb:108:1:112:3 | synthetic splat parameter | type tracker without call steps | params_flow.rb:108:1:112:3 | synthetic splat parameter | | params_flow.rb:108:37:108:37 | a | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:108:37:108:37 | a | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:108:37:108:37 | a | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:108:37:108:37 | a | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:108:37:108:37 | a | type tracker without call steps | params_flow.rb:108:37:108:37 | a | | params_flow.rb:108:37:108:37 | a | type tracker without call steps | params_flow.rb:108:37:108:37 | a | -| params_flow.rb:108:37:108:37 | a | type tracker without call steps with content splat position 0 | params_flow.rb:109:5:109:10 | synthetic splat argument | +| params_flow.rb:108:37:108:37 | a | type tracker without call steps with content element 0 | params_flow.rb:109:5:109:10 | synthetic splat argument | | params_flow.rb:108:40:108:41 | *b | type tracker without call steps | params_flow.rb:108:40:108:41 | *b | | params_flow.rb:108:41:108:41 | b | type tracker without call steps | params_flow.rb:108:41:108:41 | b | | params_flow.rb:108:44:108:44 | c | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:108:44:108:44 | c | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:108:44:108:44 | c | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:108:44:108:44 | c | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:108:44:108:44 | c | type tracker without call steps | params_flow.rb:108:44:108:44 | c | | params_flow.rb:108:44:108:44 | c | type tracker without call steps | params_flow.rb:108:44:108:44 | c | -| params_flow.rb:108:44:108:44 | c | type tracker without call steps with content splat position 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | +| params_flow.rb:108:44:108:44 | c | type tracker without call steps with content element 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:109:5:109:10 | call to sink | type tracker without call steps | params_flow.rb:109:5:109:10 | call to sink | -| params_flow.rb:109:5:109:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:109:5:109:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:109:5:109:10 | synthetic splat argument | | params_flow.rb:110:5:110:13 | call to sink | type tracker without call steps | params_flow.rb:110:5:110:13 | call to sink | -| params_flow.rb:110:5:110:13 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:110:5:110:13 | synthetic splat argument | type tracker without call steps | params_flow.rb:110:5:110:13 | synthetic splat argument | | params_flow.rb:110:10:110:13 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:110:10:110:13 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:110:10:110:13 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:110:10:110:13 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:110:10:110:13 | ...[...] | type tracker without call steps | params_flow.rb:110:10:110:13 | ...[...] | -| params_flow.rb:110:10:110:13 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:110:5:110:13 | synthetic splat argument | +| params_flow.rb:110:10:110:13 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:110:5:110:13 | synthetic splat argument | | params_flow.rb:110:10:110:13 | synthetic splat argument | type tracker without call steps | params_flow.rb:110:10:110:13 | synthetic splat argument | | params_flow.rb:110:12:110:12 | 0 | type tracker without call steps | params_flow.rb:110:12:110:12 | 0 | -| params_flow.rb:110:12:110:12 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:110:10:110:13 | synthetic splat argument | +| params_flow.rb:110:12:110:12 | 0 | type tracker without call steps with content element 0 | params_flow.rb:110:10:110:13 | synthetic splat argument | | params_flow.rb:111:5:111:10 | call to sink | type tracker without call steps | params_flow.rb:111:5:111:10 | call to sink | | params_flow.rb:111:5:111:10 | call to sink | type tracker without call steps | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | -| params_flow.rb:111:5:111:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:111:5:111:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | type tracker without call steps | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | @@ -2530,129 +2214,111 @@ track | params_flow.rb:114:1:114:67 | synthetic splat argument | type tracker without call steps | params_flow.rb:114:1:114:67 | synthetic splat argument | | params_flow.rb:114:33:114:41 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:114:33:114:41 | call to taint | type tracker with call steps | params_flow.rb:108:37:108:37 | a | -| params_flow.rb:114:33:114:41 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:114:33:114:41 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:114:33:114:41 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:108:1:112:3 | synthetic splat parameter | -| params_flow.rb:114:33:114:41 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:109:5:109:10 | synthetic splat argument | +| params_flow.rb:114:33:114:41 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:114:33:114:41 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:108:1:112:3 | synthetic splat parameter | +| params_flow.rb:114:33:114:41 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:109:5:109:10 | synthetic splat argument | | params_flow.rb:114:33:114:41 | call to taint | type tracker without call steps | params_flow.rb:114:33:114:41 | call to taint | -| params_flow.rb:114:33:114:41 | call to taint | type tracker without call steps with content splat position 0 | params_flow.rb:114:1:114:67 | synthetic splat argument | -| params_flow.rb:114:33:114:41 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:114:33:114:41 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:114:1:114:67 | synthetic splat argument | | params_flow.rb:114:33:114:41 | synthetic splat argument | type tracker without call steps | params_flow.rb:114:33:114:41 | synthetic splat argument | | params_flow.rb:114:39:114:40 | 58 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:114:39:114:40 | 58 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:114:39:114:40 | 58 | type tracker with call steps | params_flow.rb:108:37:108:37 | a | -| params_flow.rb:114:39:114:40 | 58 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:114:39:114:40 | 58 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:114:39:114:40 | 58 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:114:39:114:40 | 58 | type tracker with call steps with content splat position 0 | params_flow.rb:108:1:112:3 | synthetic splat parameter | -| params_flow.rb:114:39:114:40 | 58 | type tracker with call steps with content splat position 0 | params_flow.rb:109:5:109:10 | synthetic splat argument | +| params_flow.rb:114:39:114:40 | 58 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:114:39:114:40 | 58 | type tracker with call steps with content element 0 | params_flow.rb:108:1:112:3 | synthetic splat parameter | +| params_flow.rb:114:39:114:40 | 58 | type tracker with call steps with content element 0 | params_flow.rb:109:5:109:10 | synthetic splat argument | | params_flow.rb:114:39:114:40 | 58 | type tracker without call steps | params_flow.rb:114:33:114:41 | call to taint | | params_flow.rb:114:39:114:40 | 58 | type tracker without call steps | params_flow.rb:114:39:114:40 | 58 | -| params_flow.rb:114:39:114:40 | 58 | type tracker without call steps with content splat position 0 | params_flow.rb:114:1:114:67 | synthetic splat argument | -| params_flow.rb:114:39:114:40 | 58 | type tracker without call steps with content splat position 0 | params_flow.rb:114:33:114:41 | synthetic splat argument | +| params_flow.rb:114:39:114:40 | 58 | type tracker without call steps with content element 0 | params_flow.rb:114:1:114:67 | synthetic splat argument | +| params_flow.rb:114:39:114:40 | 58 | type tracker without call steps with content element 0 | params_flow.rb:114:33:114:41 | synthetic splat argument | | params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps | params_flow.rb:110:10:110:13 | ...[...] | +| params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:108:40:108:41 | *b | -| params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:110:5:110:13 | synthetic splat argument | -| params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:108:1:112:3 | synthetic splat parameter | +| params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:110:5:110:13 | synthetic splat argument | +| params_flow.rb:114:44:114:52 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:108:1:112:3 | synthetic splat parameter | | params_flow.rb:114:44:114:52 | call to taint | type tracker without call steps | params_flow.rb:114:44:114:52 | call to taint | -| params_flow.rb:114:44:114:52 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:114:1:114:67 | synthetic splat argument | -| params_flow.rb:114:44:114:52 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:114:44:114:52 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:114:1:114:67 | synthetic splat argument | | params_flow.rb:114:44:114:52 | synthetic splat argument | type tracker without call steps | params_flow.rb:114:44:114:52 | synthetic splat argument | | params_flow.rb:114:50:114:51 | 59 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:114:50:114:51 | 59 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:114:50:114:51 | 59 | type tracker with call steps | params_flow.rb:110:10:110:13 | ...[...] | +| params_flow.rb:114:50:114:51 | 59 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:114:50:114:51 | 59 | type tracker with call steps with content element 0 | params_flow.rb:108:40:108:41 | *b | -| params_flow.rb:114:50:114:51 | 59 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:114:50:114:51 | 59 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:114:50:114:51 | 59 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:114:50:114:51 | 59 | type tracker with call steps with content splat position 0 | params_flow.rb:110:5:110:13 | synthetic splat argument | -| params_flow.rb:114:50:114:51 | 59 | type tracker with call steps with content splat position 1 | params_flow.rb:108:1:112:3 | synthetic splat parameter | +| params_flow.rb:114:50:114:51 | 59 | type tracker with call steps with content element 0 | params_flow.rb:110:5:110:13 | synthetic splat argument | +| params_flow.rb:114:50:114:51 | 59 | type tracker with call steps with content element 1 | params_flow.rb:108:1:112:3 | synthetic splat parameter | | params_flow.rb:114:50:114:51 | 59 | type tracker without call steps | params_flow.rb:114:44:114:52 | call to taint | | params_flow.rb:114:50:114:51 | 59 | type tracker without call steps | params_flow.rb:114:50:114:51 | 59 | -| params_flow.rb:114:50:114:51 | 59 | type tracker without call steps with content splat position 0 | params_flow.rb:114:44:114:52 | synthetic splat argument | -| params_flow.rb:114:50:114:51 | 59 | type tracker without call steps with content splat position 1 | params_flow.rb:114:1:114:67 | synthetic splat argument | +| params_flow.rb:114:50:114:51 | 59 | type tracker without call steps with content element 0 | params_flow.rb:114:44:114:52 | synthetic splat argument | +| params_flow.rb:114:50:114:51 | 59 | type tracker without call steps with content element 1 | params_flow.rb:114:1:114:67 | synthetic splat argument | | params_flow.rb:114:55:114:55 | :c | type tracker without call steps | params_flow.rb:114:55:114:55 | :c | | params_flow.rb:114:55:114:66 | Pair | type tracker without call steps | params_flow.rb:114:55:114:66 | Pair | | params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps | params_flow.rb:108:44:108:44 | c | +| params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps with content hash-splat position :c | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | -| params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:114:58:114:66 | call to taint | type tracker without call steps | params_flow.rb:114:58:114:66 | call to taint | | params_flow.rb:114:58:114:66 | call to taint | type tracker without call steps with content hash-splat position :c | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | -| params_flow.rb:114:58:114:66 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:114:58:114:66 | synthetic splat argument | type tracker without call steps | params_flow.rb:114:58:114:66 | synthetic splat argument | | params_flow.rb:114:64:114:65 | 60 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:114:64:114:65 | 60 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:114:64:114:65 | 60 | type tracker with call steps | params_flow.rb:108:44:108:44 | c | +| params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content element 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content hash-splat position :c | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | -| params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content splat position 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:114:64:114:65 | 60 | type tracker without call steps | params_flow.rb:114:58:114:66 | call to taint | | params_flow.rb:114:64:114:65 | 60 | type tracker without call steps | params_flow.rb:114:64:114:65 | 60 | +| params_flow.rb:114:64:114:65 | 60 | type tracker without call steps with content element 0 | params_flow.rb:114:58:114:66 | synthetic splat argument | | params_flow.rb:114:64:114:65 | 60 | type tracker without call steps with content hash-splat position :c | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | -| params_flow.rb:114:64:114:65 | 60 | type tracker without call steps with content splat position 0 | params_flow.rb:114:58:114:66 | synthetic splat argument | | params_flow.rb:116:1:116:1 | x | type tracker without call steps | params_flow.rb:116:1:116:1 | x | | params_flow.rb:116:5:116:6 | Array | type tracker without call steps | params_flow.rb:116:5:116:6 | Array | | params_flow.rb:116:5:116:6 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:116:5:116:6 | call to [] | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | +| params_flow.rb:116:5:116:6 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:116:5:116:6 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:116:5:116:6 | call to [] | type tracker with call steps with content element 0 or unknown | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:116:5:116:6 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:116:5:116:6 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:116:5:116:6 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:116:5:116:6 | call to [] | type tracker without call steps | params_flow.rb:116:5:116:6 | call to [] | | params_flow.rb:116:5:116:6 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:118:12:118:13 | * ... | | params_flow.rb:117:1:117:1 | [post] x | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:117:1:117:1 | [post] x | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | +| params_flow.rb:117:1:117:1 | [post] x | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:117:1:117:1 | [post] x | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:117:1:117:1 | [post] x | type tracker with call steps with content element 0 or unknown | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:117:1:117:1 | [post] x | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:117:1:117:1 | [post] x | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:117:1:117:1 | [post] x | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:117:1:117:1 | [post] x | type tracker without call steps | params_flow.rb:117:1:117:1 | [post] x | | params_flow.rb:117:1:117:1 | [post] x | type tracker without call steps with content element 0 or unknown | params_flow.rb:118:12:118:13 | * ... | | params_flow.rb:117:1:117:15 | call to []= | type tracker without call steps | params_flow.rb:117:1:117:15 | call to []= | | params_flow.rb:117:1:117:15 | synthetic splat argument | type tracker without call steps | params_flow.rb:117:1:117:15 | synthetic splat argument | | params_flow.rb:117:3:117:14 | call to some_index | type tracker without call steps | params_flow.rb:117:3:117:14 | call to some_index | -| params_flow.rb:117:3:117:14 | call to some_index | type tracker without call steps with content splat position 0 | params_flow.rb:117:1:117:15 | synthetic splat argument | +| params_flow.rb:117:3:117:14 | call to some_index | type tracker without call steps with content element 0 | params_flow.rb:117:1:117:15 | synthetic splat argument | | params_flow.rb:117:19:117:27 | __synth__0 | type tracker without call steps | params_flow.rb:117:19:117:27 | __synth__0 | | params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | | params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | | params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps with content element | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | -| params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | +| params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:117:19:117:27 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:117:19:117:27 | call to taint | type tracker without call steps | params_flow.rb:117:19:117:27 | call to taint | | params_flow.rb:117:19:117:27 | call to taint | type tracker without call steps with content attribute [] | params_flow.rb:117:1:117:1 | [post] x | | params_flow.rb:117:19:117:27 | call to taint | type tracker without call steps with content element | params_flow.rb:117:1:117:1 | [post] x | | params_flow.rb:117:19:117:27 | call to taint | type tracker without call steps with content element | params_flow.rb:118:12:118:13 | * ... | -| params_flow.rb:117:19:117:27 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:117:1:117:15 | synthetic splat argument | -| params_flow.rb:117:19:117:27 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:117:19:117:27 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:117:1:117:15 | synthetic splat argument | | params_flow.rb:117:19:117:27 | synthetic splat argument | type tracker without call steps | params_flow.rb:117:19:117:27 | synthetic splat argument | | params_flow.rb:117:25:117:26 | 61 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:117:25:117:26 | 61 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:117:25:117:26 | 61 | type tracker with call steps | params_flow.rb:9:16:9:17 | p1 | | params_flow.rb:117:25:117:26 | 61 | type tracker with call steps | params_flow.rb:9:20:9:21 | p2 | | params_flow.rb:117:25:117:26 | 61 | type tracker with call steps with content element | params_flow.rb:9:1:12:3 | synthetic splat parameter | -| params_flow.rb:117:25:117:26 | 61 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:117:25:117:26 | 61 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:117:25:117:26 | 61 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:117:25:117:26 | 61 | type tracker with call steps with content splat position 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | -| params_flow.rb:117:25:117:26 | 61 | type tracker with call steps with content splat position 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | +| params_flow.rb:117:25:117:26 | 61 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:117:25:117:26 | 61 | type tracker with call steps with content element 0 | params_flow.rb:10:5:10:11 | synthetic splat argument | +| params_flow.rb:117:25:117:26 | 61 | type tracker with call steps with content element 0 | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:117:25:117:26 | 61 | type tracker without call steps | params_flow.rb:117:19:117:27 | call to taint | | params_flow.rb:117:25:117:26 | 61 | type tracker without call steps | params_flow.rb:117:25:117:26 | 61 | | params_flow.rb:117:25:117:26 | 61 | type tracker without call steps with content attribute [] | params_flow.rb:117:1:117:1 | [post] x | | params_flow.rb:117:25:117:26 | 61 | type tracker without call steps with content element | params_flow.rb:117:1:117:1 | [post] x | | params_flow.rb:117:25:117:26 | 61 | type tracker without call steps with content element | params_flow.rb:118:12:118:13 | * ... | -| params_flow.rb:117:25:117:26 | 61 | type tracker without call steps with content splat position 0 | params_flow.rb:117:19:117:27 | synthetic splat argument | -| params_flow.rb:117:25:117:26 | 61 | type tracker without call steps with content splat position 1 | params_flow.rb:117:1:117:15 | synthetic splat argument | +| params_flow.rb:117:25:117:26 | 61 | type tracker without call steps with content element 0 | params_flow.rb:117:19:117:27 | synthetic splat argument | +| params_flow.rb:117:25:117:26 | 61 | type tracker without call steps with content element 1 | params_flow.rb:117:1:117:15 | synthetic splat argument | | params_flow.rb:118:1:118:14 | call to positional | type tracker without call steps | params_flow.rb:118:1:118:14 | call to positional | | params_flow.rb:118:12:118:13 | * ... | type tracker with call steps | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:118:12:118:13 | * ... | type tracker without call steps | params_flow.rb:118:12:118:13 | * ... | @@ -2661,101 +2327,85 @@ track | params_flow.rb:120:1:126:3 | self in destruct | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | | params_flow.rb:120:1:126:3 | self in destruct | type tracker without call steps | params_flow.rb:120:1:126:3 | self in destruct | | params_flow.rb:120:15:120:15 | a | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:120:15:120:15 | a | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:120:15:120:15 | a | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:120:15:120:15 | a | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:120:15:120:15 | a | type tracker without call steps | params_flow.rb:120:15:120:15 | a | | params_flow.rb:120:15:120:15 | a | type tracker without call steps | params_flow.rb:120:15:120:15 | a | -| params_flow.rb:120:15:120:15 | a | type tracker without call steps with content splat position 0 | params_flow.rb:121:5:121:10 | synthetic splat argument | +| params_flow.rb:120:15:120:15 | a | type tracker without call steps with content element 0 | params_flow.rb:121:5:121:10 | synthetic splat argument | | params_flow.rb:120:17:120:17 | b | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:120:17:120:17 | b | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:120:17:120:17 | b | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:120:17:120:17 | b | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:120:17:120:17 | b | type tracker without call steps | params_flow.rb:120:17:120:17 | b | | params_flow.rb:120:17:120:17 | b | type tracker without call steps | params_flow.rb:120:17:120:17 | b | -| params_flow.rb:120:17:120:17 | b | type tracker without call steps with content splat position 0 | params_flow.rb:122:5:122:10 | synthetic splat argument | +| params_flow.rb:120:17:120:17 | b | type tracker without call steps with content element 0 | params_flow.rb:122:5:122:10 | synthetic splat argument | | params_flow.rb:120:22:120:22 | c | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:120:22:120:22 | c | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:120:22:120:22 | c | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:120:22:120:22 | c | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:120:22:120:22 | c | type tracker without call steps | params_flow.rb:120:22:120:22 | c | | params_flow.rb:120:22:120:22 | c | type tracker without call steps | params_flow.rb:120:22:120:22 | c | -| params_flow.rb:120:22:120:22 | c | type tracker without call steps with content splat position 0 | params_flow.rb:123:5:123:10 | synthetic splat argument | +| params_flow.rb:120:22:120:22 | c | type tracker without call steps with content element 0 | params_flow.rb:123:5:123:10 | synthetic splat argument | | params_flow.rb:120:25:120:25 | d | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:120:25:120:25 | d | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:120:25:120:25 | d | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:120:25:120:25 | d | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:120:25:120:25 | d | type tracker without call steps | params_flow.rb:120:25:120:25 | d | | params_flow.rb:120:25:120:25 | d | type tracker without call steps | params_flow.rb:120:25:120:25 | d | -| params_flow.rb:120:25:120:25 | d | type tracker without call steps with content splat position 0 | params_flow.rb:124:5:124:10 | synthetic splat argument | +| params_flow.rb:120:25:120:25 | d | type tracker without call steps with content element 0 | params_flow.rb:124:5:124:10 | synthetic splat argument | | params_flow.rb:120:27:120:27 | e | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:120:27:120:27 | e | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:120:27:120:27 | e | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:120:27:120:27 | e | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:120:27:120:27 | e | type tracker without call steps | params_flow.rb:120:27:120:27 | e | | params_flow.rb:120:27:120:27 | e | type tracker without call steps | params_flow.rb:120:27:120:27 | e | -| params_flow.rb:120:27:120:27 | e | type tracker without call steps with content splat position 0 | params_flow.rb:125:5:125:10 | synthetic splat argument | +| params_flow.rb:120:27:120:27 | e | type tracker without call steps with content element 0 | params_flow.rb:125:5:125:10 | synthetic splat argument | | params_flow.rb:121:5:121:10 | call to sink | type tracker without call steps | params_flow.rb:121:5:121:10 | call to sink | -| params_flow.rb:121:5:121:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:121:5:121:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:121:5:121:10 | synthetic splat argument | | params_flow.rb:122:5:122:10 | call to sink | type tracker without call steps | params_flow.rb:122:5:122:10 | call to sink | -| params_flow.rb:122:5:122:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:122:5:122:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:122:5:122:10 | synthetic splat argument | | params_flow.rb:123:5:123:10 | call to sink | type tracker without call steps | params_flow.rb:123:5:123:10 | call to sink | -| params_flow.rb:123:5:123:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:123:5:123:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:123:5:123:10 | synthetic splat argument | | params_flow.rb:124:5:124:10 | call to sink | type tracker without call steps | params_flow.rb:124:5:124:10 | call to sink | -| params_flow.rb:124:5:124:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:124:5:124:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:124:5:124:10 | synthetic splat argument | | params_flow.rb:125:5:125:10 | call to sink | type tracker without call steps | params_flow.rb:125:5:125:10 | call to sink | | params_flow.rb:125:5:125:10 | call to sink | type tracker without call steps | params_flow.rb:128:1:128:61 | call to destruct | -| params_flow.rb:125:5:125:10 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:125:5:125:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:125:5:125:10 | synthetic splat argument | | params_flow.rb:128:1:128:61 | call to destruct | type tracker without call steps | params_flow.rb:128:1:128:61 | call to destruct | | params_flow.rb:128:1:128:61 | synthetic splat argument | type tracker without call steps | params_flow.rb:128:1:128:61 | synthetic splat argument | | params_flow.rb:128:10:128:31 | Array | type tracker without call steps | params_flow.rb:128:10:128:31 | Array | | params_flow.rb:128:10:128:31 | call to [] | type tracker without call steps | params_flow.rb:128:10:128:31 | call to [] | -| params_flow.rb:128:10:128:31 | call to [] | type tracker without call steps with content splat position 0 | params_flow.rb:128:1:128:61 | synthetic splat argument | +| params_flow.rb:128:10:128:31 | call to [] | type tracker without call steps with content element 0 | params_flow.rb:128:1:128:61 | synthetic splat argument | | params_flow.rb:128:10:128:31 | synthetic splat argument | type tracker without call steps | params_flow.rb:128:10:128:31 | call to [] | | params_flow.rb:128:10:128:31 | synthetic splat argument | type tracker without call steps | params_flow.rb:128:10:128:31 | synthetic splat argument | -| params_flow.rb:128:10:128:31 | synthetic splat argument | type tracker without call steps with content splat position 0 | params_flow.rb:128:1:128:61 | synthetic splat argument | +| params_flow.rb:128:10:128:31 | synthetic splat argument | type tracker without call steps with content element 0 | params_flow.rb:128:1:128:61 | synthetic splat argument | | params_flow.rb:128:11:128:19 | call to taint | type tracker without call steps | params_flow.rb:128:11:128:19 | call to taint | | params_flow.rb:128:11:128:19 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:128:10:128:31 | call to [] | | params_flow.rb:128:11:128:19 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:128:10:128:31 | synthetic splat argument | -| params_flow.rb:128:11:128:19 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:11:128:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:128:11:128:19 | synthetic splat argument | | params_flow.rb:128:17:128:18 | 62 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:128:17:128:18 | 62 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:17:128:18 | 62 | type tracker without call steps | params_flow.rb:128:11:128:19 | call to taint | | params_flow.rb:128:17:128:18 | 62 | type tracker without call steps | params_flow.rb:128:17:128:18 | 62 | | params_flow.rb:128:17:128:18 | 62 | type tracker without call steps with content element 0 | params_flow.rb:128:10:128:31 | call to [] | | params_flow.rb:128:17:128:18 | 62 | type tracker without call steps with content element 0 | params_flow.rb:128:10:128:31 | synthetic splat argument | -| params_flow.rb:128:17:128:18 | 62 | type tracker without call steps with content splat position 0 | params_flow.rb:128:11:128:19 | synthetic splat argument | +| params_flow.rb:128:17:128:18 | 62 | type tracker without call steps with content element 0 | params_flow.rb:128:11:128:19 | synthetic splat argument | | params_flow.rb:128:22:128:30 | call to taint | type tracker without call steps | params_flow.rb:128:22:128:30 | call to taint | | params_flow.rb:128:22:128:30 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:128:10:128:31 | call to [] | | params_flow.rb:128:22:128:30 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:128:10:128:31 | synthetic splat argument | -| params_flow.rb:128:22:128:30 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:22:128:30 | synthetic splat argument | type tracker without call steps | params_flow.rb:128:22:128:30 | synthetic splat argument | | params_flow.rb:128:28:128:29 | 63 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:128:28:128:29 | 63 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:28:128:29 | 63 | type tracker without call steps | params_flow.rb:128:22:128:30 | call to taint | | params_flow.rb:128:28:128:29 | 63 | type tracker without call steps | params_flow.rb:128:28:128:29 | 63 | +| params_flow.rb:128:28:128:29 | 63 | type tracker without call steps with content element 0 | params_flow.rb:128:22:128:30 | synthetic splat argument | | params_flow.rb:128:28:128:29 | 63 | type tracker without call steps with content element 1 | params_flow.rb:128:10:128:31 | call to [] | | params_flow.rb:128:28:128:29 | 63 | type tracker without call steps with content element 1 | params_flow.rb:128:10:128:31 | synthetic splat argument | -| params_flow.rb:128:28:128:29 | 63 | type tracker without call steps with content splat position 0 | params_flow.rb:128:22:128:30 | synthetic splat argument | | params_flow.rb:128:34:128:60 | Array | type tracker without call steps | params_flow.rb:128:34:128:60 | Array | | params_flow.rb:128:34:128:60 | call to [] | type tracker without call steps | params_flow.rb:128:34:128:60 | call to [] | -| params_flow.rb:128:34:128:60 | call to [] | type tracker without call steps with content splat position 1 | params_flow.rb:128:1:128:61 | synthetic splat argument | +| params_flow.rb:128:34:128:60 | call to [] | type tracker without call steps with content element 1 | params_flow.rb:128:1:128:61 | synthetic splat argument | | params_flow.rb:128:34:128:60 | synthetic splat argument | type tracker without call steps | params_flow.rb:128:34:128:60 | call to [] | | params_flow.rb:128:34:128:60 | synthetic splat argument | type tracker without call steps | params_flow.rb:128:34:128:60 | synthetic splat argument | -| params_flow.rb:128:34:128:60 | synthetic splat argument | type tracker without call steps with content splat position 1 | params_flow.rb:128:1:128:61 | synthetic splat argument | +| params_flow.rb:128:34:128:60 | synthetic splat argument | type tracker without call steps with content element 1 | params_flow.rb:128:1:128:61 | synthetic splat argument | | params_flow.rb:128:35:128:43 | call to taint | type tracker without call steps | params_flow.rb:128:35:128:43 | call to taint | | params_flow.rb:128:35:128:43 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:128:34:128:60 | call to [] | | params_flow.rb:128:35:128:43 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:128:34:128:60 | synthetic splat argument | -| params_flow.rb:128:35:128:43 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:35:128:43 | synthetic splat argument | type tracker without call steps | params_flow.rb:128:35:128:43 | synthetic splat argument | | params_flow.rb:128:41:128:42 | 64 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:128:41:128:42 | 64 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:41:128:42 | 64 | type tracker without call steps | params_flow.rb:128:35:128:43 | call to taint | | params_flow.rb:128:41:128:42 | 64 | type tracker without call steps | params_flow.rb:128:41:128:42 | 64 | | params_flow.rb:128:41:128:42 | 64 | type tracker without call steps with content element 0 | params_flow.rb:128:34:128:60 | call to [] | | params_flow.rb:128:41:128:42 | 64 | type tracker without call steps with content element 0 | params_flow.rb:128:34:128:60 | synthetic splat argument | -| params_flow.rb:128:41:128:42 | 64 | type tracker without call steps with content splat position 0 | params_flow.rb:128:35:128:43 | synthetic splat argument | +| params_flow.rb:128:41:128:42 | 64 | type tracker without call steps with content element 0 | params_flow.rb:128:35:128:43 | synthetic splat argument | | params_flow.rb:128:46:128:59 | Array | type tracker without call steps | params_flow.rb:128:46:128:59 | Array | | params_flow.rb:128:46:128:59 | call to [] | type tracker without call steps | params_flow.rb:128:46:128:59 | call to [] | | params_flow.rb:128:46:128:59 | call to [] | type tracker without call steps with content element 1 | params_flow.rb:128:34:128:60 | call to [] | @@ -2770,130 +2420,110 @@ track | params_flow.rb:128:50:128:58 | call to taint | type tracker without call steps | params_flow.rb:128:50:128:58 | call to taint | | params_flow.rb:128:50:128:58 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:128:46:128:59 | call to [] | | params_flow.rb:128:50:128:58 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:128:46:128:59 | synthetic splat argument | -| params_flow.rb:128:50:128:58 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:50:128:58 | synthetic splat argument | type tracker without call steps | params_flow.rb:128:50:128:58 | synthetic splat argument | | params_flow.rb:128:56:128:57 | 65 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:128:56:128:57 | 65 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:56:128:57 | 65 | type tracker without call steps | params_flow.rb:128:50:128:58 | call to taint | | params_flow.rb:128:56:128:57 | 65 | type tracker without call steps | params_flow.rb:128:56:128:57 | 65 | +| params_flow.rb:128:56:128:57 | 65 | type tracker without call steps with content element 0 | params_flow.rb:128:50:128:58 | synthetic splat argument | | params_flow.rb:128:56:128:57 | 65 | type tracker without call steps with content element 1 | params_flow.rb:128:46:128:59 | call to [] | | params_flow.rb:128:56:128:57 | 65 | type tracker without call steps with content element 1 | params_flow.rb:128:46:128:59 | synthetic splat argument | -| params_flow.rb:128:56:128:57 | 65 | type tracker without call steps with content splat position 0 | params_flow.rb:128:50:128:58 | synthetic splat argument | | params_flow.rb:130:1:130:4 | args | type tracker without call steps | params_flow.rb:130:1:130:4 | args | | params_flow.rb:130:8:130:29 | Array | type tracker without call steps | params_flow.rb:130:8:130:29 | Array | | params_flow.rb:130:8:130:29 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:130:8:130:29 | call to [] | type tracker with call steps | params_flow.rb:83:14:83:14 | t | +| params_flow.rb:130:8:130:29 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:130:8:130:29 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:130:8:130:29 | call to [] | type tracker with call steps with content element 0 or unknown | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:130:8:130:29 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:130:8:130:29 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:130:8:130:29 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:130:8:130:29 | call to [] | type tracker without call steps | params_flow.rb:130:8:130:29 | call to [] | | params_flow.rb:130:8:130:29 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:131:10:131:14 | * ... | | params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:83:14:83:14 | t | +| params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker with call steps with content element 0 or unknown | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker with call steps with content splat position 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:130:8:130:29 | call to [] | | params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:130:8:130:29 | synthetic splat argument | | params_flow.rb:130:8:130:29 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:131:10:131:14 | * ... | | params_flow.rb:130:9:130:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:130:9:130:17 | call to taint | type tracker with call steps | params_flow.rb:83:14:83:14 | t | +| params_flow.rb:130:9:130:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:130:9:130:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:130:9:130:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:130:9:130:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:130:9:130:17 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | +| params_flow.rb:130:9:130:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:130:9:130:17 | call to taint | type tracker without call steps | params_flow.rb:130:9:130:17 | call to taint | | params_flow.rb:130:9:130:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:130:8:130:29 | call to [] | | params_flow.rb:130:9:130:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:130:8:130:29 | synthetic splat argument | | params_flow.rb:130:9:130:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:131:10:131:14 | * ... | -| params_flow.rb:130:9:130:17 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:130:9:130:17 | synthetic splat argument | type tracker without call steps | params_flow.rb:130:9:130:17 | synthetic splat argument | | params_flow.rb:130:15:130:16 | 66 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:130:15:130:16 | 66 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:130:15:130:16 | 66 | type tracker with call steps | params_flow.rb:83:14:83:14 | t | +| params_flow.rb:130:15:130:16 | 66 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:130:15:130:16 | 66 | type tracker with call steps with content element 0 | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:130:15:130:16 | 66 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:130:15:130:16 | 66 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:130:15:130:16 | 66 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:130:15:130:16 | 66 | type tracker with call steps with content splat position 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | +| params_flow.rb:130:15:130:16 | 66 | type tracker with call steps with content element 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:130:15:130:16 | 66 | type tracker without call steps | params_flow.rb:130:9:130:17 | call to taint | | params_flow.rb:130:15:130:16 | 66 | type tracker without call steps | params_flow.rb:130:15:130:16 | 66 | | params_flow.rb:130:15:130:16 | 66 | type tracker without call steps with content element 0 | params_flow.rb:130:8:130:29 | call to [] | | params_flow.rb:130:15:130:16 | 66 | type tracker without call steps with content element 0 | params_flow.rb:130:8:130:29 | synthetic splat argument | +| params_flow.rb:130:15:130:16 | 66 | type tracker without call steps with content element 0 | params_flow.rb:130:9:130:17 | synthetic splat argument | | params_flow.rb:130:15:130:16 | 66 | type tracker without call steps with content element 0 | params_flow.rb:131:10:131:14 | * ... | -| params_flow.rb:130:15:130:16 | 66 | type tracker without call steps with content splat position 0 | params_flow.rb:130:9:130:17 | synthetic splat argument | | params_flow.rb:130:20:130:28 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:130:20:130:28 | call to taint | type tracker with call steps | params_flow.rb:83:17:83:17 | u | +| params_flow.rb:130:20:130:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:130:20:130:28 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:130:20:130:28 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:130:20:130:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:130:20:130:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:130:20:130:28 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:130:20:130:28 | call to taint | type tracker without call steps | params_flow.rb:130:20:130:28 | call to taint | | params_flow.rb:130:20:130:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:130:8:130:29 | call to [] | | params_flow.rb:130:20:130:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:130:8:130:29 | synthetic splat argument | | params_flow.rb:130:20:130:28 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:131:10:131:14 | * ... | -| params_flow.rb:130:20:130:28 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:130:20:130:28 | synthetic splat argument | type tracker without call steps | params_flow.rb:130:20:130:28 | synthetic splat argument | | params_flow.rb:130:26:130:27 | 67 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:130:26:130:27 | 67 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:130:26:130:27 | 67 | type tracker with call steps | params_flow.rb:83:17:83:17 | u | +| params_flow.rb:130:26:130:27 | 67 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:130:26:130:27 | 67 | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:130:26:130:27 | 67 | type tracker with call steps with content element 1 | params_flow.rb:83:1:91:3 | synthetic splat parameter | -| params_flow.rb:130:26:130:27 | 67 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:130:26:130:27 | 67 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:130:26:130:27 | 67 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:130:26:130:27 | 67 | type tracker with call steps with content splat position 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:130:26:130:27 | 67 | type tracker without call steps | params_flow.rb:130:20:130:28 | call to taint | | params_flow.rb:130:26:130:27 | 67 | type tracker without call steps | params_flow.rb:130:26:130:27 | 67 | +| params_flow.rb:130:26:130:27 | 67 | type tracker without call steps with content element 0 | params_flow.rb:130:20:130:28 | synthetic splat argument | | params_flow.rb:130:26:130:27 | 67 | type tracker without call steps with content element 1 | params_flow.rb:130:8:130:29 | call to [] | | params_flow.rb:130:26:130:27 | 67 | type tracker without call steps with content element 1 | params_flow.rb:130:8:130:29 | synthetic splat argument | | params_flow.rb:130:26:130:27 | 67 | type tracker without call steps with content element 1 | params_flow.rb:131:10:131:14 | * ... | -| params_flow.rb:130:26:130:27 | 67 | type tracker without call steps with content splat position 0 | params_flow.rb:130:20:130:28 | synthetic splat argument | | params_flow.rb:131:1:131:46 | call to pos_many | type tracker without call steps | params_flow.rb:131:1:131:46 | call to pos_many | | params_flow.rb:131:10:131:14 | * ... | type tracker with call steps | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:131:10:131:14 | * ... | type tracker without call steps | params_flow.rb:131:10:131:14 | * ... | | params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | +| params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:131:17:131:25 | call to taint | type tracker without call steps | params_flow.rb:131:17:131:25 | call to taint | -| params_flow.rb:131:17:131:25 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:131:17:131:25 | synthetic splat argument | type tracker without call steps | params_flow.rb:131:17:131:25 | synthetic splat argument | | params_flow.rb:131:23:131:24 | 68 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:131:23:131:24 | 68 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:131:23:131:24 | 68 | type tracker with call steps | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps with content splat position 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | +| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:131:23:131:24 | 68 | type tracker without call steps | params_flow.rb:131:17:131:25 | call to taint | | params_flow.rb:131:23:131:24 | 68 | type tracker without call steps | params_flow.rb:131:23:131:24 | 68 | -| params_flow.rb:131:23:131:24 | 68 | type tracker without call steps with content splat position 0 | params_flow.rb:131:17:131:25 | synthetic splat argument | +| params_flow.rb:131:23:131:24 | 68 | type tracker without call steps with content element 0 | params_flow.rb:131:17:131:25 | synthetic splat argument | | params_flow.rb:131:28:131:30 | nil | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:131:28:131:30 | nil | type tracker with call steps | params_flow.rb:83:20:83:20 | v | -| params_flow.rb:131:28:131:30 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:131:28:131:30 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:28:131:30 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | +| params_flow.rb:131:28:131:30 | nil | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:131:28:131:30 | nil | type tracker with call steps with content element 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | | params_flow.rb:131:28:131:30 | nil | type tracker without call steps | params_flow.rb:131:28:131:30 | nil | | params_flow.rb:131:33:131:35 | nil | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:131:33:131:35 | nil | type tracker with call steps | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:131:33:131:35 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:131:33:131:35 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:33:131:35 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | +| params_flow.rb:131:33:131:35 | nil | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:131:33:131:35 | nil | type tracker with call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | | params_flow.rb:131:33:131:35 | nil | type tracker without call steps | params_flow.rb:131:33:131:35 | nil | | params_flow.rb:131:38:131:40 | nil | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:131:38:131:40 | nil | type tracker with call steps | params_flow.rb:83:26:83:26 | x | -| params_flow.rb:131:38:131:40 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:131:38:131:40 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:38:131:40 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | +| params_flow.rb:131:38:131:40 | nil | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:131:38:131:40 | nil | type tracker with call steps with content element 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | | params_flow.rb:131:38:131:40 | nil | type tracker without call steps | params_flow.rb:131:38:131:40 | nil | | params_flow.rb:131:43:131:45 | nil | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:131:43:131:45 | nil | type tracker with call steps | params_flow.rb:83:29:83:29 | y | -| params_flow.rb:131:43:131:45 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:131:43:131:45 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:43:131:45 | nil | type tracker with call steps with content splat position 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | +| params_flow.rb:131:43:131:45 | nil | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:131:43:131:45 | nil | type tracker with call steps with content element 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | | params_flow.rb:131:43:131:45 | nil | type tracker without call steps | params_flow.rb:131:43:131:45 | nil | | params_flow.rb:133:1:135:3 | &block | type tracker without call steps | params_flow.rb:133:1:135:3 | &block | | params_flow.rb:133:1:135:3 | self in splatall | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | @@ -2903,16 +2533,14 @@ track | params_flow.rb:133:15:133:18 | args | type tracker without call steps | params_flow.rb:133:15:133:18 | args | | params_flow.rb:134:5:134:16 | call to sink | type tracker without call steps | params_flow.rb:134:5:134:16 | call to sink | | params_flow.rb:134:5:134:16 | call to sink | type tracker without call steps | params_flow.rb:137:1:137:44 | call to splatall | -| params_flow.rb:134:5:134:16 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:134:5:134:16 | synthetic splat argument | type tracker without call steps | params_flow.rb:134:5:134:16 | synthetic splat argument | | params_flow.rb:134:10:134:16 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:134:10:134:16 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:134:10:134:16 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:134:10:134:16 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:134:10:134:16 | ...[...] | type tracker without call steps | params_flow.rb:134:10:134:16 | ...[...] | -| params_flow.rb:134:10:134:16 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:134:5:134:16 | synthetic splat argument | +| params_flow.rb:134:10:134:16 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:134:5:134:16 | synthetic splat argument | | params_flow.rb:134:10:134:16 | synthetic splat argument | type tracker without call steps | params_flow.rb:134:10:134:16 | synthetic splat argument | | params_flow.rb:134:15:134:15 | 1 | type tracker without call steps | params_flow.rb:134:15:134:15 | 1 | -| params_flow.rb:134:15:134:15 | 1 | type tracker without call steps with content splat position 0 | params_flow.rb:134:10:134:16 | synthetic splat argument | +| params_flow.rb:134:15:134:15 | 1 | type tracker without call steps with content element 0 | params_flow.rb:134:10:134:16 | synthetic splat argument | | params_flow.rb:137:1:137:44 | call to splatall | type tracker without call steps | params_flow.rb:137:1:137:44 | call to splatall | | params_flow.rb:137:10:137:43 | * ... | type tracker with call steps | params_flow.rb:133:14:133:18 | *args | | params_flow.rb:137:10:137:43 | * ... | type tracker without call steps | params_flow.rb:137:10:137:43 | * ... | @@ -2929,59 +2557,51 @@ track | params_flow.rb:137:12:137:20 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:137:10:137:43 | * ... | | params_flow.rb:137:12:137:20 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:137:11:137:43 | call to [] | | params_flow.rb:137:12:137:20 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:137:11:137:43 | synthetic splat argument | -| params_flow.rb:137:12:137:20 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:137:12:137:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:137:12:137:20 | synthetic splat argument | | params_flow.rb:137:18:137:19 | 69 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:137:18:137:19 | 69 | type tracker with call steps with content element 0 | params_flow.rb:133:14:133:18 | *args | -| params_flow.rb:137:18:137:19 | 69 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:137:18:137:19 | 69 | type tracker without call steps | params_flow.rb:137:12:137:20 | call to taint | | params_flow.rb:137:18:137:19 | 69 | type tracker without call steps | params_flow.rb:137:18:137:19 | 69 | | params_flow.rb:137:18:137:19 | 69 | type tracker without call steps with content element 0 | params_flow.rb:137:10:137:43 | * ... | | params_flow.rb:137:18:137:19 | 69 | type tracker without call steps with content element 0 | params_flow.rb:137:11:137:43 | call to [] | | params_flow.rb:137:18:137:19 | 69 | type tracker without call steps with content element 0 | params_flow.rb:137:11:137:43 | synthetic splat argument | -| params_flow.rb:137:18:137:19 | 69 | type tracker without call steps with content splat position 0 | params_flow.rb:137:12:137:20 | synthetic splat argument | +| params_flow.rb:137:18:137:19 | 69 | type tracker without call steps with content element 0 | params_flow.rb:137:12:137:20 | synthetic splat argument | | params_flow.rb:137:23:137:31 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:137:23:137:31 | call to taint | type tracker with call steps | params_flow.rb:134:10:134:16 | ...[...] | +| params_flow.rb:137:23:137:31 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:137:23:137:31 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:134:5:134:16 | synthetic splat argument | | params_flow.rb:137:23:137:31 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:133:14:133:18 | *args | -| params_flow.rb:137:23:137:31 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:137:23:137:31 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:137:23:137:31 | call to taint | type tracker with call steps with content splat position 0 | params_flow.rb:134:5:134:16 | synthetic splat argument | | params_flow.rb:137:23:137:31 | call to taint | type tracker without call steps | params_flow.rb:137:23:137:31 | call to taint | | params_flow.rb:137:23:137:31 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:137:10:137:43 | * ... | | params_flow.rb:137:23:137:31 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:137:11:137:43 | call to [] | | params_flow.rb:137:23:137:31 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:137:11:137:43 | synthetic splat argument | -| params_flow.rb:137:23:137:31 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:137:23:137:31 | synthetic splat argument | type tracker without call steps | params_flow.rb:137:23:137:31 | synthetic splat argument | | params_flow.rb:137:29:137:30 | 70 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:137:29:137:30 | 70 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:137:29:137:30 | 70 | type tracker with call steps | params_flow.rb:134:10:134:16 | ...[...] | +| params_flow.rb:137:29:137:30 | 70 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:137:29:137:30 | 70 | type tracker with call steps with content element 0 | params_flow.rb:134:5:134:16 | synthetic splat argument | | params_flow.rb:137:29:137:30 | 70 | type tracker with call steps with content element 1 | params_flow.rb:133:14:133:18 | *args | -| params_flow.rb:137:29:137:30 | 70 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:137:29:137:30 | 70 | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:137:29:137:30 | 70 | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:137:29:137:30 | 70 | type tracker with call steps with content splat position 0 | params_flow.rb:134:5:134:16 | synthetic splat argument | | params_flow.rb:137:29:137:30 | 70 | type tracker without call steps | params_flow.rb:137:23:137:31 | call to taint | | params_flow.rb:137:29:137:30 | 70 | type tracker without call steps | params_flow.rb:137:29:137:30 | 70 | +| params_flow.rb:137:29:137:30 | 70 | type tracker without call steps with content element 0 | params_flow.rb:137:23:137:31 | synthetic splat argument | | params_flow.rb:137:29:137:30 | 70 | type tracker without call steps with content element 1 | params_flow.rb:137:10:137:43 | * ... | | params_flow.rb:137:29:137:30 | 70 | type tracker without call steps with content element 1 | params_flow.rb:137:11:137:43 | call to [] | | params_flow.rb:137:29:137:30 | 70 | type tracker without call steps with content element 1 | params_flow.rb:137:11:137:43 | synthetic splat argument | -| params_flow.rb:137:29:137:30 | 70 | type tracker without call steps with content splat position 0 | params_flow.rb:137:23:137:31 | synthetic splat argument | | params_flow.rb:137:34:137:42 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:133:14:133:18 | *args | | params_flow.rb:137:34:137:42 | call to taint | type tracker without call steps | params_flow.rb:137:34:137:42 | call to taint | | params_flow.rb:137:34:137:42 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:137:10:137:43 | * ... | | params_flow.rb:137:34:137:42 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:137:11:137:43 | call to [] | | params_flow.rb:137:34:137:42 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:137:11:137:43 | synthetic splat argument | -| params_flow.rb:137:34:137:42 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:137:34:137:42 | synthetic splat argument | type tracker without call steps | params_flow.rb:137:34:137:42 | synthetic splat argument | | params_flow.rb:137:40:137:41 | 71 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:137:40:137:41 | 71 | type tracker with call steps with content element 2 | params_flow.rb:133:14:133:18 | *args | -| params_flow.rb:137:40:137:41 | 71 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:137:40:137:41 | 71 | type tracker without call steps | params_flow.rb:137:34:137:42 | call to taint | | params_flow.rb:137:40:137:41 | 71 | type tracker without call steps | params_flow.rb:137:40:137:41 | 71 | +| params_flow.rb:137:40:137:41 | 71 | type tracker without call steps with content element 0 | params_flow.rb:137:34:137:42 | synthetic splat argument | | params_flow.rb:137:40:137:41 | 71 | type tracker without call steps with content element 2 | params_flow.rb:137:10:137:43 | * ... | | params_flow.rb:137:40:137:41 | 71 | type tracker without call steps with content element 2 | params_flow.rb:137:11:137:43 | call to [] | | params_flow.rb:137:40:137:41 | 71 | type tracker without call steps with content element 2 | params_flow.rb:137:11:137:43 | synthetic splat argument | -| params_flow.rb:137:40:137:41 | 71 | type tracker without call steps with content splat position 0 | params_flow.rb:137:34:137:42 | synthetic splat argument | | params_flow.rb:139:1:141:3 | &block | type tracker without call steps | params_flow.rb:139:1:141:3 | &block | | params_flow.rb:139:1:141:3 | hashSplatSideEffect | type tracker without call steps | params_flow.rb:139:1:141:3 | hashSplatSideEffect | | params_flow.rb:139:1:141:3 | self in hashSplatSideEffect | type tracker without call steps | params_flow.rb:139:1:141:3 | self in hashSplatSideEffect | @@ -2995,18 +2615,18 @@ track | params_flow.rb:140:5:140:38 | call to insert | type tracker without call steps | params_flow.rb:150:1:150:42 | call to hashSplatSideEffect | | params_flow.rb:140:5:140:38 | synthetic splat argument | type tracker without call steps | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:140:12:140:14 | :p1 | type tracker without call steps | params_flow.rb:140:12:140:14 | :p1 | -| params_flow.rb:140:12:140:14 | :p1 | type tracker without call steps with content splat position 0 | params_flow.rb:140:5:140:15 | synthetic splat argument | +| params_flow.rb:140:12:140:14 | :p1 | type tracker without call steps with content element 0 | params_flow.rb:140:5:140:15 | synthetic splat argument | | params_flow.rb:140:24:140:24 | 0 | type tracker without call steps | params_flow.rb:140:24:140:24 | 0 | -| params_flow.rb:140:24:140:24 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:140:5:140:38 | synthetic splat argument | +| params_flow.rb:140:24:140:24 | 0 | type tracker without call steps with content element 0 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:140:27:140:37 | ...[...] | type tracker without call steps | params_flow.rb:140:27:140:37 | ...[...] | | params_flow.rb:140:27:140:37 | ...[...] | type tracker without call steps with content element 0 or unknown | params_flow.rb:140:5:140:15 | [post] ...[...] | | params_flow.rb:140:27:140:37 | ...[...] | type tracker without call steps with content element 0 or unknown | params_flow.rb:140:5:140:38 | call to insert | | params_flow.rb:140:27:140:37 | ...[...] | type tracker without call steps with content element 0 or unknown | params_flow.rb:145:1:145:29 | call to hashSplatSideEffect | | params_flow.rb:140:27:140:37 | ...[...] | type tracker without call steps with content element 0 or unknown | params_flow.rb:150:1:150:42 | call to hashSplatSideEffect | -| params_flow.rb:140:27:140:37 | ...[...] | type tracker without call steps with content splat position 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | +| params_flow.rb:140:27:140:37 | ...[...] | type tracker without call steps with content element 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:140:27:140:37 | synthetic splat argument | type tracker without call steps | params_flow.rb:140:27:140:37 | synthetic splat argument | | params_flow.rb:140:34:140:36 | :p2 | type tracker without call steps | params_flow.rb:140:34:140:36 | :p2 | -| params_flow.rb:140:34:140:36 | :p2 | type tracker without call steps with content splat position 0 | params_flow.rb:140:27:140:37 | synthetic splat argument | +| params_flow.rb:140:34:140:36 | :p2 | type tracker without call steps with content element 0 | params_flow.rb:140:27:140:37 | synthetic splat argument | | params_flow.rb:143:1:143:6 | kwargs | type tracker without call steps | params_flow.rb:143:1:143:6 | kwargs | | params_flow.rb:143:10:143:34 | Hash | type tracker without call steps | params_flow.rb:143:10:143:34 | Hash | | params_flow.rb:143:10:143:34 | call to [] | type tracker without call steps | params_flow.rb:143:10:143:34 | call to [] | @@ -3028,60 +2648,54 @@ track | params_flow.rb:143:24:143:32 | call to taint | type tracker with call steps | params_flow.rb:140:27:140:37 | ...[...] | | params_flow.rb:143:24:143:32 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:15 | [post] ...[...] | | params_flow.rb:143:24:143:32 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:38 | call to insert | +| params_flow.rb:143:24:143:32 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:143:24:143:32 | call to taint | type tracker with call steps with content element :p2 | params_flow.rb:139:25:139:32 | **kwargs | -| params_flow.rb:143:24:143:32 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:143:24:143:32 | call to taint | type tracker without call steps | params_flow.rb:143:24:143:32 | call to taint | | params_flow.rb:143:24:143:32 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:143:10:143:34 | call to [] | | params_flow.rb:143:24:143:32 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:143:10:143:34 | synthetic hash-splat argument | | params_flow.rb:143:24:143:32 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:145:21:145:28 | ** ... | -| params_flow.rb:143:24:143:32 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:143:24:143:32 | synthetic splat argument | type tracker without call steps | params_flow.rb:143:24:143:32 | synthetic splat argument | | params_flow.rb:143:30:143:31 | 72 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:143:30:143:31 | 72 | type tracker with call steps | params_flow.rb:140:27:140:37 | ...[...] | | params_flow.rb:143:30:143:31 | 72 | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:15 | [post] ...[...] | | params_flow.rb:143:30:143:31 | 72 | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:38 | call to insert | +| params_flow.rb:143:30:143:31 | 72 | type tracker with call steps with content element 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:143:30:143:31 | 72 | type tracker with call steps with content element :p2 | params_flow.rb:139:25:139:32 | **kwargs | -| params_flow.rb:143:30:143:31 | 72 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:143:30:143:31 | 72 | type tracker with call steps with content splat position 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:143:30:143:31 | 72 | type tracker without call steps | params_flow.rb:143:24:143:32 | call to taint | | params_flow.rb:143:30:143:31 | 72 | type tracker without call steps | params_flow.rb:143:30:143:31 | 72 | +| params_flow.rb:143:30:143:31 | 72 | type tracker without call steps with content element 0 | params_flow.rb:143:24:143:32 | synthetic splat argument | | params_flow.rb:143:30:143:31 | 72 | type tracker without call steps with content element :p2 | params_flow.rb:143:10:143:34 | call to [] | | params_flow.rb:143:30:143:31 | 72 | type tracker without call steps with content element :p2 | params_flow.rb:143:10:143:34 | synthetic hash-splat argument | | params_flow.rb:143:30:143:31 | 72 | type tracker without call steps with content element :p2 | params_flow.rb:145:21:145:28 | ** ... | -| params_flow.rb:143:30:143:31 | 72 | type tracker without call steps with content splat position 0 | params_flow.rb:143:24:143:32 | synthetic splat argument | | params_flow.rb:144:1:144:20 | call to sink | type tracker without call steps | params_flow.rb:144:1:144:20 | call to sink | -| params_flow.rb:144:1:144:20 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:144:1:144:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:144:1:144:20 | synthetic splat argument | | params_flow.rb:144:6:144:16 | ...[...] | type tracker without call steps | params_flow.rb:144:6:144:16 | ...[...] | | params_flow.rb:144:6:144:16 | synthetic splat argument | type tracker without call steps | params_flow.rb:144:6:144:16 | synthetic splat argument | | params_flow.rb:144:6:144:19 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:144:6:144:19 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:144:6:144:19 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:144:6:144:19 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:144:6:144:19 | ...[...] | type tracker without call steps | params_flow.rb:144:6:144:19 | ...[...] | -| params_flow.rb:144:6:144:19 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:144:1:144:20 | synthetic splat argument | +| params_flow.rb:144:6:144:19 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:144:1:144:20 | synthetic splat argument | | params_flow.rb:144:6:144:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:144:6:144:19 | synthetic splat argument | | params_flow.rb:144:13:144:15 | :p1 | type tracker without call steps | params_flow.rb:144:13:144:15 | :p1 | -| params_flow.rb:144:13:144:15 | :p1 | type tracker without call steps with content splat position 0 | params_flow.rb:144:6:144:16 | synthetic splat argument | +| params_flow.rb:144:13:144:15 | :p1 | type tracker without call steps with content element 0 | params_flow.rb:144:6:144:16 | synthetic splat argument | | params_flow.rb:144:18:144:18 | 0 | type tracker without call steps | params_flow.rb:144:18:144:18 | 0 | -| params_flow.rb:144:18:144:18 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:144:6:144:19 | synthetic splat argument | +| params_flow.rb:144:18:144:18 | 0 | type tracker without call steps with content element 0 | params_flow.rb:144:6:144:19 | synthetic splat argument | | params_flow.rb:145:1:145:29 | call to hashSplatSideEffect | type tracker without call steps | params_flow.rb:145:1:145:29 | call to hashSplatSideEffect | | params_flow.rb:145:21:145:28 | ** ... | type tracker with call steps | params_flow.rb:139:25:139:32 | **kwargs | | params_flow.rb:145:21:145:28 | ** ... | type tracker without call steps | params_flow.rb:145:21:145:28 | ** ... | | params_flow.rb:146:1:146:20 | call to sink | type tracker without call steps | params_flow.rb:146:1:146:20 | call to sink | -| params_flow.rb:146:1:146:20 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:146:1:146:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:146:1:146:20 | synthetic splat argument | | params_flow.rb:146:6:146:16 | ...[...] | type tracker without call steps | params_flow.rb:146:6:146:16 | ...[...] | | params_flow.rb:146:6:146:16 | synthetic splat argument | type tracker without call steps | params_flow.rb:146:6:146:16 | synthetic splat argument | | params_flow.rb:146:6:146:19 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:146:6:146:19 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:146:6:146:19 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:146:6:146:19 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:146:6:146:19 | ...[...] | type tracker without call steps | params_flow.rb:146:6:146:19 | ...[...] | -| params_flow.rb:146:6:146:19 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:146:1:146:20 | synthetic splat argument | +| params_flow.rb:146:6:146:19 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:146:1:146:20 | synthetic splat argument | | params_flow.rb:146:6:146:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:146:6:146:19 | synthetic splat argument | | params_flow.rb:146:13:146:15 | :p1 | type tracker without call steps | params_flow.rb:146:13:146:15 | :p1 | -| params_flow.rb:146:13:146:15 | :p1 | type tracker without call steps with content splat position 0 | params_flow.rb:146:6:146:16 | synthetic splat argument | +| params_flow.rb:146:13:146:15 | :p1 | type tracker without call steps with content element 0 | params_flow.rb:146:6:146:16 | synthetic splat argument | | params_flow.rb:146:18:146:18 | 0 | type tracker without call steps | params_flow.rb:146:18:146:18 | 0 | -| params_flow.rb:146:18:146:18 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:146:6:146:19 | synthetic splat argument | +| params_flow.rb:146:18:146:18 | 0 | type tracker without call steps with content element 0 | params_flow.rb:146:6:146:19 | synthetic splat argument | | params_flow.rb:148:1:148:2 | p1 | type tracker without call steps | params_flow.rb:148:1:148:2 | p1 | | params_flow.rb:148:6:148:7 | Array | type tracker without call steps | params_flow.rb:148:6:148:7 | Array | | params_flow.rb:148:6:148:7 | call to [] | type tracker with call steps | params_flow.rb:140:5:140:15 | ...[...] | @@ -3089,16 +2703,14 @@ track | params_flow.rb:148:6:148:7 | call to [] | type tracker without call steps | params_flow.rb:148:6:148:7 | call to [] | | params_flow.rb:148:6:148:7 | call to [] | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | | params_flow.rb:149:1:149:11 | call to sink | type tracker without call steps | params_flow.rb:149:1:149:11 | call to sink | -| params_flow.rb:149:1:149:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:149:1:149:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:149:1:149:11 | synthetic splat argument | | params_flow.rb:149:6:149:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:149:6:149:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:149:6:149:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:149:6:149:10 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:149:6:149:10 | ...[...] | type tracker without call steps | params_flow.rb:149:6:149:10 | ...[...] | -| params_flow.rb:149:6:149:10 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:149:1:149:11 | synthetic splat argument | +| params_flow.rb:149:6:149:10 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:149:1:149:11 | synthetic splat argument | | params_flow.rb:149:6:149:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:149:6:149:10 | synthetic splat argument | | params_flow.rb:149:9:149:9 | 0 | type tracker without call steps | params_flow.rb:149:9:149:9 | 0 | -| params_flow.rb:149:9:149:9 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:149:6:149:10 | synthetic splat argument | +| params_flow.rb:149:9:149:9 | 0 | type tracker without call steps with content element 0 | params_flow.rb:149:6:149:10 | synthetic splat argument | | params_flow.rb:150:1:150:42 | call to hashSplatSideEffect | type tracker without call steps | params_flow.rb:150:1:150:42 | call to hashSplatSideEffect | | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:139:25:139:32 | **kwargs | | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | @@ -3109,34 +2721,30 @@ track | params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps | params_flow.rb:140:27:140:37 | ...[...] | | params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:15 | [post] ...[...] | | params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:38 | call to insert | +| params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:139:25:139:32 | **kwargs | -| params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:150:33:150:41 | call to taint | type tracker without call steps | params_flow.rb:150:33:150:41 | call to taint | | params_flow.rb:150:33:150:41 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | -| params_flow.rb:150:33:150:41 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:150:33:150:41 | synthetic splat argument | type tracker without call steps | params_flow.rb:150:33:150:41 | synthetic splat argument | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps | params_flow.rb:140:27:140:37 | ...[...] | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:15 | [post] ...[...] | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:38 | call to insert | +| params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content element 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:139:25:139:32 | **kwargs | -| params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content splat position 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | | params_flow.rb:150:39:150:40 | 73 | type tracker without call steps | params_flow.rb:150:33:150:41 | call to taint | | params_flow.rb:150:39:150:40 | 73 | type tracker without call steps | params_flow.rb:150:39:150:40 | 73 | +| params_flow.rb:150:39:150:40 | 73 | type tracker without call steps with content element 0 | params_flow.rb:150:33:150:41 | synthetic splat argument | | params_flow.rb:150:39:150:40 | 73 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | -| params_flow.rb:150:39:150:40 | 73 | type tracker without call steps with content splat position 0 | params_flow.rb:150:33:150:41 | synthetic splat argument | | params_flow.rb:151:1:151:11 | call to sink | type tracker without call steps | params_flow.rb:151:1:151:11 | call to sink | -| params_flow.rb:151:1:151:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:151:1:151:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:151:1:151:11 | synthetic splat argument | | params_flow.rb:151:6:151:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:151:6:151:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:151:6:151:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:151:6:151:10 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:151:6:151:10 | ...[...] | type tracker without call steps | params_flow.rb:151:6:151:10 | ...[...] | -| params_flow.rb:151:6:151:10 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:151:1:151:11 | synthetic splat argument | +| params_flow.rb:151:6:151:10 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:151:1:151:11 | synthetic splat argument | | params_flow.rb:151:6:151:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:151:6:151:10 | synthetic splat argument | | params_flow.rb:151:9:151:9 | 0 | type tracker without call steps | params_flow.rb:151:9:151:9 | 0 | -| params_flow.rb:151:9:151:9 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:151:6:151:10 | synthetic splat argument | +| params_flow.rb:151:9:151:9 | 0 | type tracker without call steps with content element 0 | params_flow.rb:151:6:151:10 | synthetic splat argument | | params_flow.rb:153:1:155:3 | &block | type tracker without call steps | params_flow.rb:153:1:155:3 | &block | | params_flow.rb:153:1:155:3 | keywordSideEffect | type tracker without call steps | params_flow.rb:153:1:155:3 | keywordSideEffect | | params_flow.rb:153:1:155:3 | self in keywordSideEffect | type tracker without call steps | params_flow.rb:153:1:155:3 | self in keywordSideEffect | @@ -3149,14 +2757,14 @@ track | params_flow.rb:153:28:153:29 | p2 | type tracker without call steps with content element 0 or unknown | params_flow.rb:154:5:154:20 | call to insert | | params_flow.rb:153:28:153:29 | p2 | type tracker without call steps with content element 0 or unknown | params_flow.rb:159:1:159:27 | call to keywordSideEffect | | params_flow.rb:153:28:153:29 | p2 | type tracker without call steps with content element 0 or unknown | params_flow.rb:164:1:164:40 | call to keywordSideEffect | -| params_flow.rb:153:28:153:29 | p2 | type tracker without call steps with content splat position 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | +| params_flow.rb:153:28:153:29 | p2 | type tracker without call steps with content element 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:154:5:154:6 | [post] p1 | type tracker without call steps | params_flow.rb:154:5:154:6 | [post] p1 | | params_flow.rb:154:5:154:20 | call to insert | type tracker without call steps | params_flow.rb:154:5:154:20 | call to insert | | params_flow.rb:154:5:154:20 | call to insert | type tracker without call steps | params_flow.rb:159:1:159:27 | call to keywordSideEffect | | params_flow.rb:154:5:154:20 | call to insert | type tracker without call steps | params_flow.rb:164:1:164:40 | call to keywordSideEffect | | params_flow.rb:154:5:154:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:154:15:154:15 | 0 | type tracker without call steps | params_flow.rb:154:15:154:15 | 0 | -| params_flow.rb:154:15:154:15 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:154:5:154:20 | synthetic splat argument | +| params_flow.rb:154:15:154:15 | 0 | type tracker without call steps with content element 0 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:157:1:157:6 | kwargs | type tracker without call steps | params_flow.rb:157:1:157:6 | kwargs | | params_flow.rb:157:10:157:34 | Hash | type tracker without call steps | params_flow.rb:157:10:157:34 | Hash | | params_flow.rb:157:10:157:34 | call to [] | type tracker without call steps | params_flow.rb:157:10:157:34 | call to [] | @@ -3178,60 +2786,54 @@ track | params_flow.rb:157:24:157:32 | call to taint | type tracker with call steps | params_flow.rb:153:28:153:29 | p2 | | params_flow.rb:157:24:157:32 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:6 | [post] p1 | | params_flow.rb:157:24:157:32 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:20 | call to insert | +| params_flow.rb:157:24:157:32 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:157:24:157:32 | call to taint | type tracker with call steps with content element :p2 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | -| params_flow.rb:157:24:157:32 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:157:24:157:32 | call to taint | type tracker without call steps | params_flow.rb:157:24:157:32 | call to taint | | params_flow.rb:157:24:157:32 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:157:10:157:34 | call to [] | | params_flow.rb:157:24:157:32 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:157:10:157:34 | synthetic hash-splat argument | | params_flow.rb:157:24:157:32 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:159:19:159:26 | ** ... | -| params_flow.rb:157:24:157:32 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:157:24:157:32 | synthetic splat argument | type tracker without call steps | params_flow.rb:157:24:157:32 | synthetic splat argument | | params_flow.rb:157:30:157:31 | 74 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:157:30:157:31 | 74 | type tracker with call steps | params_flow.rb:153:28:153:29 | p2 | | params_flow.rb:157:30:157:31 | 74 | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:6 | [post] p1 | | params_flow.rb:157:30:157:31 | 74 | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:20 | call to insert | +| params_flow.rb:157:30:157:31 | 74 | type tracker with call steps with content element 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:157:30:157:31 | 74 | type tracker with call steps with content element :p2 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | -| params_flow.rb:157:30:157:31 | 74 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:157:30:157:31 | 74 | type tracker with call steps with content splat position 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:157:30:157:31 | 74 | type tracker without call steps | params_flow.rb:157:24:157:32 | call to taint | | params_flow.rb:157:30:157:31 | 74 | type tracker without call steps | params_flow.rb:157:30:157:31 | 74 | +| params_flow.rb:157:30:157:31 | 74 | type tracker without call steps with content element 0 | params_flow.rb:157:24:157:32 | synthetic splat argument | | params_flow.rb:157:30:157:31 | 74 | type tracker without call steps with content element :p2 | params_flow.rb:157:10:157:34 | call to [] | | params_flow.rb:157:30:157:31 | 74 | type tracker without call steps with content element :p2 | params_flow.rb:157:10:157:34 | synthetic hash-splat argument | | params_flow.rb:157:30:157:31 | 74 | type tracker without call steps with content element :p2 | params_flow.rb:159:19:159:26 | ** ... | -| params_flow.rb:157:30:157:31 | 74 | type tracker without call steps with content splat position 0 | params_flow.rb:157:24:157:32 | synthetic splat argument | | params_flow.rb:158:1:158:20 | call to sink | type tracker without call steps | params_flow.rb:158:1:158:20 | call to sink | -| params_flow.rb:158:1:158:20 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:158:1:158:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:158:1:158:20 | synthetic splat argument | | params_flow.rb:158:6:158:16 | ...[...] | type tracker without call steps | params_flow.rb:158:6:158:16 | ...[...] | | params_flow.rb:158:6:158:16 | synthetic splat argument | type tracker without call steps | params_flow.rb:158:6:158:16 | synthetic splat argument | | params_flow.rb:158:6:158:19 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:158:6:158:19 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:158:6:158:19 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:158:6:158:19 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:158:6:158:19 | ...[...] | type tracker without call steps | params_flow.rb:158:6:158:19 | ...[...] | -| params_flow.rb:158:6:158:19 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:158:1:158:20 | synthetic splat argument | +| params_flow.rb:158:6:158:19 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:158:1:158:20 | synthetic splat argument | | params_flow.rb:158:6:158:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:158:6:158:19 | synthetic splat argument | | params_flow.rb:158:13:158:15 | :p1 | type tracker without call steps | params_flow.rb:158:13:158:15 | :p1 | -| params_flow.rb:158:13:158:15 | :p1 | type tracker without call steps with content splat position 0 | params_flow.rb:158:6:158:16 | synthetic splat argument | +| params_flow.rb:158:13:158:15 | :p1 | type tracker without call steps with content element 0 | params_flow.rb:158:6:158:16 | synthetic splat argument | | params_flow.rb:158:18:158:18 | 0 | type tracker without call steps | params_flow.rb:158:18:158:18 | 0 | -| params_flow.rb:158:18:158:18 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:158:6:158:19 | synthetic splat argument | +| params_flow.rb:158:18:158:18 | 0 | type tracker without call steps with content element 0 | params_flow.rb:158:6:158:19 | synthetic splat argument | | params_flow.rb:159:1:159:27 | call to keywordSideEffect | type tracker without call steps | params_flow.rb:159:1:159:27 | call to keywordSideEffect | | params_flow.rb:159:19:159:26 | ** ... | type tracker with call steps | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:159:19:159:26 | ** ... | type tracker without call steps | params_flow.rb:159:19:159:26 | ** ... | | params_flow.rb:160:1:160:20 | call to sink | type tracker without call steps | params_flow.rb:160:1:160:20 | call to sink | -| params_flow.rb:160:1:160:20 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:160:1:160:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:160:1:160:20 | synthetic splat argument | | params_flow.rb:160:6:160:16 | ...[...] | type tracker without call steps | params_flow.rb:160:6:160:16 | ...[...] | | params_flow.rb:160:6:160:16 | synthetic splat argument | type tracker without call steps | params_flow.rb:160:6:160:16 | synthetic splat argument | | params_flow.rb:160:6:160:19 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:160:6:160:19 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:160:6:160:19 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:160:6:160:19 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:160:6:160:19 | ...[...] | type tracker without call steps | params_flow.rb:160:6:160:19 | ...[...] | -| params_flow.rb:160:6:160:19 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:160:1:160:20 | synthetic splat argument | +| params_flow.rb:160:6:160:19 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:160:1:160:20 | synthetic splat argument | | params_flow.rb:160:6:160:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:160:6:160:19 | synthetic splat argument | | params_flow.rb:160:13:160:15 | :p1 | type tracker without call steps | params_flow.rb:160:13:160:15 | :p1 | -| params_flow.rb:160:13:160:15 | :p1 | type tracker without call steps with content splat position 0 | params_flow.rb:160:6:160:16 | synthetic splat argument | +| params_flow.rb:160:13:160:15 | :p1 | type tracker without call steps with content element 0 | params_flow.rb:160:6:160:16 | synthetic splat argument | | params_flow.rb:160:18:160:18 | 0 | type tracker without call steps | params_flow.rb:160:18:160:18 | 0 | -| params_flow.rb:160:18:160:18 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:160:6:160:19 | synthetic splat argument | +| params_flow.rb:160:18:160:18 | 0 | type tracker without call steps with content element 0 | params_flow.rb:160:6:160:19 | synthetic splat argument | | params_flow.rb:162:1:162:2 | p1 | type tracker without call steps | params_flow.rb:162:1:162:2 | p1 | | params_flow.rb:162:6:162:7 | Array | type tracker without call steps | params_flow.rb:162:6:162:7 | Array | | params_flow.rb:162:6:162:7 | call to [] | type tracker with call steps | params_flow.rb:153:23:153:24 | p1 | @@ -3239,16 +2841,14 @@ track | params_flow.rb:162:6:162:7 | call to [] | type tracker without call steps | params_flow.rb:162:6:162:7 | call to [] | | params_flow.rb:162:6:162:7 | call to [] | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | | params_flow.rb:163:1:163:11 | call to sink | type tracker without call steps | params_flow.rb:163:1:163:11 | call to sink | -| params_flow.rb:163:1:163:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:163:1:163:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:163:1:163:11 | synthetic splat argument | | params_flow.rb:163:6:163:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:163:6:163:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:163:6:163:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:163:6:163:10 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:163:6:163:10 | ...[...] | type tracker without call steps | params_flow.rb:163:6:163:10 | ...[...] | -| params_flow.rb:163:6:163:10 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:163:1:163:11 | synthetic splat argument | +| params_flow.rb:163:6:163:10 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:163:1:163:11 | synthetic splat argument | | params_flow.rb:163:6:163:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:163:6:163:10 | synthetic splat argument | | params_flow.rb:163:9:163:9 | 0 | type tracker without call steps | params_flow.rb:163:9:163:9 | 0 | -| params_flow.rb:163:9:163:9 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:163:6:163:10 | synthetic splat argument | +| params_flow.rb:163:9:163:9 | 0 | type tracker without call steps with content element 0 | params_flow.rb:163:6:163:10 | synthetic splat argument | | params_flow.rb:164:1:164:40 | call to keywordSideEffect | type tracker without call steps | params_flow.rb:164:1:164:40 | call to keywordSideEffect | | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | @@ -3259,34 +2859,30 @@ track | params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps | params_flow.rb:153:28:153:29 | p2 | | params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:6 | [post] p1 | | params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:20 | call to insert | +| params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | -| params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:164:31:164:39 | call to taint | type tracker without call steps | params_flow.rb:164:31:164:39 | call to taint | | params_flow.rb:164:31:164:39 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | -| params_flow.rb:164:31:164:39 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:164:31:164:39 | synthetic splat argument | type tracker without call steps | params_flow.rb:164:31:164:39 | synthetic splat argument | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps | params_flow.rb:153:28:153:29 | p2 | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:6 | [post] p1 | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:20 | call to insert | +| params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content element 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | -| params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content splat position 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | | params_flow.rb:164:37:164:38 | 75 | type tracker without call steps | params_flow.rb:164:31:164:39 | call to taint | | params_flow.rb:164:37:164:38 | 75 | type tracker without call steps | params_flow.rb:164:37:164:38 | 75 | +| params_flow.rb:164:37:164:38 | 75 | type tracker without call steps with content element 0 | params_flow.rb:164:31:164:39 | synthetic splat argument | | params_flow.rb:164:37:164:38 | 75 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | -| params_flow.rb:164:37:164:38 | 75 | type tracker without call steps with content splat position 0 | params_flow.rb:164:31:164:39 | synthetic splat argument | | params_flow.rb:165:1:165:11 | call to sink | type tracker without call steps | params_flow.rb:165:1:165:11 | call to sink | -| params_flow.rb:165:1:165:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:165:1:165:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:165:1:165:11 | synthetic splat argument | | params_flow.rb:165:6:165:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:165:6:165:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:165:6:165:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:165:6:165:10 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:165:6:165:10 | ...[...] | type tracker without call steps | params_flow.rb:165:6:165:10 | ...[...] | -| params_flow.rb:165:6:165:10 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:165:1:165:11 | synthetic splat argument | +| params_flow.rb:165:6:165:10 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:165:1:165:11 | synthetic splat argument | | params_flow.rb:165:6:165:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:165:6:165:10 | synthetic splat argument | | params_flow.rb:165:9:165:9 | 0 | type tracker without call steps | params_flow.rb:165:9:165:9 | 0 | -| params_flow.rb:165:9:165:9 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:165:6:165:10 | synthetic splat argument | +| params_flow.rb:165:9:165:9 | 0 | type tracker without call steps with content element 0 | params_flow.rb:165:6:165:10 | synthetic splat argument | | params_flow.rb:167:1:169:3 | &block | type tracker without call steps | params_flow.rb:167:1:169:3 | &block | | params_flow.rb:167:1:169:3 | self in splatSideEffect | type tracker without call steps | params_flow.rb:167:1:169:3 | self in splatSideEffect | | params_flow.rb:167:1:169:3 | splatSideEffect | type tracker without call steps | params_flow.rb:167:1:169:3 | splatSideEffect | @@ -3300,18 +2896,18 @@ track | params_flow.rb:168:5:168:36 | call to insert | type tracker without call steps | params_flow.rb:178:1:178:30 | call to splatSideEffect | | params_flow.rb:168:5:168:36 | synthetic splat argument | type tracker without call steps | params_flow.rb:168:5:168:36 | synthetic splat argument | | params_flow.rb:168:13:168:13 | 0 | type tracker without call steps | params_flow.rb:168:13:168:13 | 0 | -| params_flow.rb:168:13:168:13 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:168:5:168:14 | synthetic splat argument | +| params_flow.rb:168:13:168:13 | 0 | type tracker without call steps with content element 0 | params_flow.rb:168:5:168:14 | synthetic splat argument | | params_flow.rb:168:23:168:23 | 0 | type tracker without call steps | params_flow.rb:168:23:168:23 | 0 | -| params_flow.rb:168:23:168:23 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:168:5:168:36 | synthetic splat argument | +| params_flow.rb:168:23:168:23 | 0 | type tracker without call steps with content element 0 | params_flow.rb:168:5:168:36 | synthetic splat argument | | params_flow.rb:168:26:168:35 | ...[...] | type tracker without call steps | params_flow.rb:168:26:168:35 | ...[...] | | params_flow.rb:168:26:168:35 | ...[...] | type tracker without call steps with content element 0 or unknown | params_flow.rb:168:5:168:14 | [post] ...[...] | | params_flow.rb:168:26:168:35 | ...[...] | type tracker without call steps with content element 0 or unknown | params_flow.rb:168:5:168:36 | call to insert | | params_flow.rb:168:26:168:35 | ...[...] | type tracker without call steps with content element 0 or unknown | params_flow.rb:173:1:173:25 | call to splatSideEffect | | params_flow.rb:168:26:168:35 | ...[...] | type tracker without call steps with content element 0 or unknown | params_flow.rb:178:1:178:30 | call to splatSideEffect | -| params_flow.rb:168:26:168:35 | ...[...] | type tracker without call steps with content splat position 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | +| params_flow.rb:168:26:168:35 | ...[...] | type tracker without call steps with content element 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | | params_flow.rb:168:26:168:35 | synthetic splat argument | type tracker without call steps | params_flow.rb:168:26:168:35 | synthetic splat argument | | params_flow.rb:168:34:168:34 | 1 | type tracker without call steps | params_flow.rb:168:34:168:34 | 1 | -| params_flow.rb:168:34:168:34 | 1 | type tracker without call steps with content splat position 0 | params_flow.rb:168:26:168:35 | synthetic splat argument | +| params_flow.rb:168:34:168:34 | 1 | type tracker without call steps with content element 0 | params_flow.rb:168:26:168:35 | synthetic splat argument | | params_flow.rb:171:1:171:7 | posargs | type tracker without call steps | params_flow.rb:171:1:171:7 | posargs | | params_flow.rb:171:11:171:27 | Array | type tracker without call steps | params_flow.rb:171:11:171:27 | Array | | params_flow.rb:171:11:171:27 | call to [] | type tracker with call steps | params_flow.rb:168:5:168:14 | ...[...] | @@ -3336,110 +2932,98 @@ track | params_flow.rb:171:17:171:25 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:168:5:168:14 | [post] ...[...] | | params_flow.rb:171:17:171:25 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:168:5:168:36 | call to insert | | params_flow.rb:171:17:171:25 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:167:21:167:28 | *posargs | -| params_flow.rb:171:17:171:25 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | +| params_flow.rb:171:17:171:25 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | | params_flow.rb:171:17:171:25 | call to taint | type tracker without call steps | params_flow.rb:171:17:171:25 | call to taint | | params_flow.rb:171:17:171:25 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:171:11:171:27 | call to [] | | params_flow.rb:171:17:171:25 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:171:11:171:27 | synthetic splat argument | | params_flow.rb:171:17:171:25 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:173:17:173:24 | * ... | -| params_flow.rb:171:17:171:25 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:171:17:171:25 | synthetic splat argument | type tracker without call steps | params_flow.rb:171:17:171:25 | synthetic splat argument | | params_flow.rb:171:23:171:24 | 76 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:171:23:171:24 | 76 | type tracker with call steps | params_flow.rb:168:26:168:35 | ...[...] | | params_flow.rb:171:23:171:24 | 76 | type tracker with call steps with content element 0 or unknown | params_flow.rb:168:5:168:14 | [post] ...[...] | | params_flow.rb:171:23:171:24 | 76 | type tracker with call steps with content element 0 or unknown | params_flow.rb:168:5:168:36 | call to insert | | params_flow.rb:171:23:171:24 | 76 | type tracker with call steps with content element 1 | params_flow.rb:167:21:167:28 | *posargs | -| params_flow.rb:171:23:171:24 | 76 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:171:23:171:24 | 76 | type tracker with call steps with content splat position 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | +| params_flow.rb:171:23:171:24 | 76 | type tracker with call steps with content element 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | | params_flow.rb:171:23:171:24 | 76 | type tracker without call steps | params_flow.rb:171:17:171:25 | call to taint | | params_flow.rb:171:23:171:24 | 76 | type tracker without call steps | params_flow.rb:171:23:171:24 | 76 | +| params_flow.rb:171:23:171:24 | 76 | type tracker without call steps with content element 0 | params_flow.rb:171:17:171:25 | synthetic splat argument | | params_flow.rb:171:23:171:24 | 76 | type tracker without call steps with content element 1 | params_flow.rb:171:11:171:27 | call to [] | | params_flow.rb:171:23:171:24 | 76 | type tracker without call steps with content element 1 | params_flow.rb:171:11:171:27 | synthetic splat argument | | params_flow.rb:171:23:171:24 | 76 | type tracker without call steps with content element 1 | params_flow.rb:173:17:173:24 | * ... | -| params_flow.rb:171:23:171:24 | 76 | type tracker without call steps with content splat position 0 | params_flow.rb:171:17:171:25 | synthetic splat argument | | params_flow.rb:172:1:172:19 | call to sink | type tracker without call steps | params_flow.rb:172:1:172:19 | call to sink | -| params_flow.rb:172:1:172:19 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:172:1:172:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:172:1:172:19 | synthetic splat argument | | params_flow.rb:172:6:172:15 | ...[...] | type tracker without call steps | params_flow.rb:172:6:172:15 | ...[...] | | params_flow.rb:172:6:172:15 | synthetic splat argument | type tracker without call steps | params_flow.rb:172:6:172:15 | synthetic splat argument | | params_flow.rb:172:6:172:18 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:172:6:172:18 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:172:6:172:18 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:172:6:172:18 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:172:6:172:18 | ...[...] | type tracker without call steps | params_flow.rb:172:6:172:18 | ...[...] | -| params_flow.rb:172:6:172:18 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:172:1:172:19 | synthetic splat argument | +| params_flow.rb:172:6:172:18 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:172:1:172:19 | synthetic splat argument | | params_flow.rb:172:6:172:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:172:6:172:18 | synthetic splat argument | | params_flow.rb:172:14:172:14 | 0 | type tracker without call steps | params_flow.rb:172:14:172:14 | 0 | -| params_flow.rb:172:14:172:14 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:172:6:172:15 | synthetic splat argument | +| params_flow.rb:172:14:172:14 | 0 | type tracker without call steps with content element 0 | params_flow.rb:172:6:172:15 | synthetic splat argument | | params_flow.rb:172:17:172:17 | 0 | type tracker without call steps | params_flow.rb:172:17:172:17 | 0 | -| params_flow.rb:172:17:172:17 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:172:6:172:18 | synthetic splat argument | +| params_flow.rb:172:17:172:17 | 0 | type tracker without call steps with content element 0 | params_flow.rb:172:6:172:18 | synthetic splat argument | | params_flow.rb:173:1:173:25 | call to splatSideEffect | type tracker without call steps | params_flow.rb:173:1:173:25 | call to splatSideEffect | | params_flow.rb:173:17:173:24 | * ... | type tracker with call steps | params_flow.rb:167:21:167:28 | *posargs | | params_flow.rb:173:17:173:24 | * ... | type tracker without call steps | params_flow.rb:173:17:173:24 | * ... | | params_flow.rb:174:1:174:19 | call to sink | type tracker without call steps | params_flow.rb:174:1:174:19 | call to sink | -| params_flow.rb:174:1:174:19 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:174:1:174:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:174:1:174:19 | synthetic splat argument | | params_flow.rb:174:6:174:15 | ...[...] | type tracker without call steps | params_flow.rb:174:6:174:15 | ...[...] | | params_flow.rb:174:6:174:15 | synthetic splat argument | type tracker without call steps | params_flow.rb:174:6:174:15 | synthetic splat argument | | params_flow.rb:174:6:174:18 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:174:6:174:18 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:174:6:174:18 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:174:6:174:18 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:174:6:174:18 | ...[...] | type tracker without call steps | params_flow.rb:174:6:174:18 | ...[...] | -| params_flow.rb:174:6:174:18 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:174:1:174:19 | synthetic splat argument | +| params_flow.rb:174:6:174:18 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:174:1:174:19 | synthetic splat argument | | params_flow.rb:174:6:174:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:174:6:174:18 | synthetic splat argument | | params_flow.rb:174:14:174:14 | 0 | type tracker without call steps | params_flow.rb:174:14:174:14 | 0 | -| params_flow.rb:174:14:174:14 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:174:6:174:15 | synthetic splat argument | +| params_flow.rb:174:14:174:14 | 0 | type tracker without call steps with content element 0 | params_flow.rb:174:6:174:15 | synthetic splat argument | | params_flow.rb:174:17:174:17 | 0 | type tracker without call steps | params_flow.rb:174:17:174:17 | 0 | -| params_flow.rb:174:17:174:17 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:174:6:174:18 | synthetic splat argument | +| params_flow.rb:174:17:174:17 | 0 | type tracker without call steps with content element 0 | params_flow.rb:174:6:174:18 | synthetic splat argument | | params_flow.rb:176:1:176:2 | p1 | type tracker without call steps | params_flow.rb:176:1:176:2 | p1 | | params_flow.rb:176:6:176:7 | Array | type tracker without call steps | params_flow.rb:176:6:176:7 | Array | | params_flow.rb:176:6:176:7 | call to [] | type tracker with call steps | params_flow.rb:168:5:168:14 | ...[...] | -| params_flow.rb:176:6:176:7 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:167:21:167:28 | *posargs | +| params_flow.rb:176:6:176:7 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:167:21:167:28 | *posargs | | params_flow.rb:176:6:176:7 | call to [] | type tracker without call steps | params_flow.rb:176:6:176:7 | call to [] | -| params_flow.rb:176:6:176:7 | call to [] | type tracker without call steps with content splat position 0 | params_flow.rb:178:1:178:30 | synthetic splat argument | +| params_flow.rb:176:6:176:7 | call to [] | type tracker without call steps with content element 0 | params_flow.rb:178:1:178:30 | synthetic splat argument | | params_flow.rb:177:1:177:11 | call to sink | type tracker without call steps | params_flow.rb:177:1:177:11 | call to sink | -| params_flow.rb:177:1:177:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:177:1:177:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:177:1:177:11 | synthetic splat argument | | params_flow.rb:177:6:177:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:177:6:177:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:177:6:177:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:177:6:177:10 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:177:6:177:10 | ...[...] | type tracker without call steps | params_flow.rb:177:6:177:10 | ...[...] | -| params_flow.rb:177:6:177:10 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:177:1:177:11 | synthetic splat argument | +| params_flow.rb:177:6:177:10 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:177:1:177:11 | synthetic splat argument | | params_flow.rb:177:6:177:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:177:6:177:10 | synthetic splat argument | | params_flow.rb:177:9:177:9 | 0 | type tracker without call steps | params_flow.rb:177:9:177:9 | 0 | -| params_flow.rb:177:9:177:9 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:177:6:177:10 | synthetic splat argument | +| params_flow.rb:177:9:177:9 | 0 | type tracker without call steps with content element 0 | params_flow.rb:177:6:177:10 | synthetic splat argument | | params_flow.rb:178:1:178:30 | call to splatSideEffect | type tracker without call steps | params_flow.rb:178:1:178:30 | call to splatSideEffect | | params_flow.rb:178:1:178:30 | synthetic splat argument | type tracker with call steps | params_flow.rb:167:21:167:28 | *posargs | | params_flow.rb:178:1:178:30 | synthetic splat argument | type tracker without call steps | params_flow.rb:178:1:178:30 | synthetic splat argument | | params_flow.rb:178:21:178:29 | call to taint | type tracker with call steps | params_flow.rb:168:26:168:35 | ...[...] | | params_flow.rb:178:21:178:29 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:168:5:168:14 | [post] ...[...] | | params_flow.rb:178:21:178:29 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:168:5:168:36 | call to insert | -| params_flow.rb:178:21:178:29 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:167:21:167:28 | *posargs | -| params_flow.rb:178:21:178:29 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | +| params_flow.rb:178:21:178:29 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:167:21:167:28 | *posargs | +| params_flow.rb:178:21:178:29 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | | params_flow.rb:178:21:178:29 | call to taint | type tracker without call steps | params_flow.rb:178:21:178:29 | call to taint | -| params_flow.rb:178:21:178:29 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:178:1:178:30 | synthetic splat argument | -| params_flow.rb:178:21:178:29 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:178:21:178:29 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:178:1:178:30 | synthetic splat argument | | params_flow.rb:178:21:178:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:178:21:178:29 | synthetic splat argument | | params_flow.rb:178:27:178:28 | 77 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:178:27:178:28 | 77 | type tracker with call steps | params_flow.rb:168:26:168:35 | ...[...] | | params_flow.rb:178:27:178:28 | 77 | type tracker with call steps with content element 0 or unknown | params_flow.rb:168:5:168:14 | [post] ...[...] | | params_flow.rb:178:27:178:28 | 77 | type tracker with call steps with content element 0 or unknown | params_flow.rb:168:5:168:36 | call to insert | -| params_flow.rb:178:27:178:28 | 77 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:178:27:178:28 | 77 | type tracker with call steps with content splat position 1 | params_flow.rb:167:21:167:28 | *posargs | -| params_flow.rb:178:27:178:28 | 77 | type tracker with call steps with content splat position 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | +| params_flow.rb:178:27:178:28 | 77 | type tracker with call steps with content element 1 | params_flow.rb:167:21:167:28 | *posargs | +| params_flow.rb:178:27:178:28 | 77 | type tracker with call steps with content element 1 | params_flow.rb:168:5:168:36 | synthetic splat argument | | params_flow.rb:178:27:178:28 | 77 | type tracker without call steps | params_flow.rb:178:21:178:29 | call to taint | | params_flow.rb:178:27:178:28 | 77 | type tracker without call steps | params_flow.rb:178:27:178:28 | 77 | -| params_flow.rb:178:27:178:28 | 77 | type tracker without call steps with content splat position 0 | params_flow.rb:178:21:178:29 | synthetic splat argument | -| params_flow.rb:178:27:178:28 | 77 | type tracker without call steps with content splat position 1 | params_flow.rb:178:1:178:30 | synthetic splat argument | +| params_flow.rb:178:27:178:28 | 77 | type tracker without call steps with content element 0 | params_flow.rb:178:21:178:29 | synthetic splat argument | +| params_flow.rb:178:27:178:28 | 77 | type tracker without call steps with content element 1 | params_flow.rb:178:1:178:30 | synthetic splat argument | | params_flow.rb:179:1:179:11 | call to sink | type tracker without call steps | params_flow.rb:179:1:179:11 | call to sink | -| params_flow.rb:179:1:179:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:179:1:179:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:179:1:179:11 | synthetic splat argument | | params_flow.rb:179:6:179:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:179:6:179:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:179:6:179:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:179:6:179:10 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:179:6:179:10 | ...[...] | type tracker without call steps | params_flow.rb:179:6:179:10 | ...[...] | -| params_flow.rb:179:6:179:10 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:179:1:179:11 | synthetic splat argument | +| params_flow.rb:179:6:179:10 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:179:1:179:11 | synthetic splat argument | | params_flow.rb:179:6:179:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:179:6:179:10 | synthetic splat argument | | params_flow.rb:179:9:179:9 | 0 | type tracker without call steps | params_flow.rb:179:9:179:9 | 0 | -| params_flow.rb:179:9:179:9 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:179:6:179:10 | synthetic splat argument | +| params_flow.rb:179:9:179:9 | 0 | type tracker without call steps with content element 0 | params_flow.rb:179:6:179:10 | synthetic splat argument | | params_flow.rb:181:1:183:3 | &block | type tracker without call steps | params_flow.rb:181:1:183:3 | &block | | params_flow.rb:181:1:183:3 | positionSideEffect | type tracker without call steps | params_flow.rb:181:1:183:3 | positionSideEffect | | params_flow.rb:181:1:183:3 | self in positionSideEffect | type tracker without call steps | params_flow.rb:181:1:183:3 | self in positionSideEffect | @@ -3452,14 +3036,14 @@ track | params_flow.rb:181:28:181:29 | p2 | type tracker without call steps with content element 0 or unknown | params_flow.rb:182:5:182:20 | call to insert | | params_flow.rb:181:28:181:29 | p2 | type tracker without call steps with content element 0 or unknown | params_flow.rb:187:1:187:25 | call to positionSideEffect | | params_flow.rb:181:28:181:29 | p2 | type tracker without call steps with content element 0 or unknown | params_flow.rb:192:1:192:33 | call to positionSideEffect | -| params_flow.rb:181:28:181:29 | p2 | type tracker without call steps with content splat position 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | +| params_flow.rb:181:28:181:29 | p2 | type tracker without call steps with content element 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | | params_flow.rb:182:5:182:6 | [post] p1 | type tracker without call steps | params_flow.rb:182:5:182:6 | [post] p1 | | params_flow.rb:182:5:182:20 | call to insert | type tracker without call steps | params_flow.rb:182:5:182:20 | call to insert | | params_flow.rb:182:5:182:20 | call to insert | type tracker without call steps | params_flow.rb:187:1:187:25 | call to positionSideEffect | | params_flow.rb:182:5:182:20 | call to insert | type tracker without call steps | params_flow.rb:192:1:192:33 | call to positionSideEffect | | params_flow.rb:182:5:182:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:182:5:182:20 | synthetic splat argument | | params_flow.rb:182:15:182:15 | 0 | type tracker without call steps | params_flow.rb:182:15:182:15 | 0 | -| params_flow.rb:182:15:182:15 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:182:5:182:20 | synthetic splat argument | +| params_flow.rb:182:15:182:15 | 0 | type tracker without call steps with content element 0 | params_flow.rb:182:5:182:20 | synthetic splat argument | | params_flow.rb:185:1:185:4 | args | type tracker without call steps | params_flow.rb:185:1:185:4 | args | | params_flow.rb:185:8:185:24 | Array | type tracker without call steps | params_flow.rb:185:8:185:24 | Array | | params_flow.rb:185:8:185:24 | call to [] | type tracker with call steps | params_flow.rb:181:24:181:25 | p1 | @@ -3484,110 +3068,94 @@ track | params_flow.rb:185:14:185:22 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:182:5:182:6 | [post] p1 | | params_flow.rb:185:14:185:22 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:182:5:182:20 | call to insert | | params_flow.rb:185:14:185:22 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:181:1:183:3 | synthetic splat parameter | -| params_flow.rb:185:14:185:22 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | +| params_flow.rb:185:14:185:22 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | | params_flow.rb:185:14:185:22 | call to taint | type tracker without call steps | params_flow.rb:185:14:185:22 | call to taint | | params_flow.rb:185:14:185:22 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:185:8:185:24 | call to [] | | params_flow.rb:185:14:185:22 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:185:8:185:24 | synthetic splat argument | | params_flow.rb:185:14:185:22 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:187:20:187:24 | * ... | -| params_flow.rb:185:14:185:22 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:185:14:185:22 | synthetic splat argument | type tracker without call steps | params_flow.rb:185:14:185:22 | synthetic splat argument | | params_flow.rb:185:20:185:21 | 78 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:185:20:185:21 | 78 | type tracker with call steps | params_flow.rb:181:28:181:29 | p2 | | params_flow.rb:185:20:185:21 | 78 | type tracker with call steps with content element 0 or unknown | params_flow.rb:182:5:182:6 | [post] p1 | | params_flow.rb:185:20:185:21 | 78 | type tracker with call steps with content element 0 or unknown | params_flow.rb:182:5:182:20 | call to insert | | params_flow.rb:185:20:185:21 | 78 | type tracker with call steps with content element 1 | params_flow.rb:181:1:183:3 | synthetic splat parameter | -| params_flow.rb:185:20:185:21 | 78 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:185:20:185:21 | 78 | type tracker with call steps with content splat position 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | +| params_flow.rb:185:20:185:21 | 78 | type tracker with call steps with content element 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | | params_flow.rb:185:20:185:21 | 78 | type tracker without call steps | params_flow.rb:185:14:185:22 | call to taint | | params_flow.rb:185:20:185:21 | 78 | type tracker without call steps | params_flow.rb:185:20:185:21 | 78 | +| params_flow.rb:185:20:185:21 | 78 | type tracker without call steps with content element 0 | params_flow.rb:185:14:185:22 | synthetic splat argument | | params_flow.rb:185:20:185:21 | 78 | type tracker without call steps with content element 1 | params_flow.rb:185:8:185:24 | call to [] | | params_flow.rb:185:20:185:21 | 78 | type tracker without call steps with content element 1 | params_flow.rb:185:8:185:24 | synthetic splat argument | | params_flow.rb:185:20:185:21 | 78 | type tracker without call steps with content element 1 | params_flow.rb:187:20:187:24 | * ... | -| params_flow.rb:185:20:185:21 | 78 | type tracker without call steps with content splat position 0 | params_flow.rb:185:14:185:22 | synthetic splat argument | | params_flow.rb:186:1:186:16 | call to sink | type tracker without call steps | params_flow.rb:186:1:186:16 | call to sink | -| params_flow.rb:186:1:186:16 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:186:1:186:16 | synthetic splat argument | type tracker without call steps | params_flow.rb:186:1:186:16 | synthetic splat argument | | params_flow.rb:186:6:186:12 | ...[...] | type tracker without call steps | params_flow.rb:186:6:186:12 | ...[...] | | params_flow.rb:186:6:186:12 | synthetic splat argument | type tracker without call steps | params_flow.rb:186:6:186:12 | synthetic splat argument | | params_flow.rb:186:6:186:15 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:186:6:186:15 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:186:6:186:15 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:186:6:186:15 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:186:6:186:15 | ...[...] | type tracker without call steps | params_flow.rb:186:6:186:15 | ...[...] | -| params_flow.rb:186:6:186:15 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:186:1:186:16 | synthetic splat argument | +| params_flow.rb:186:6:186:15 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:186:1:186:16 | synthetic splat argument | | params_flow.rb:186:6:186:15 | synthetic splat argument | type tracker without call steps | params_flow.rb:186:6:186:15 | synthetic splat argument | | params_flow.rb:186:11:186:11 | 0 | type tracker without call steps | params_flow.rb:186:11:186:11 | 0 | -| params_flow.rb:186:11:186:11 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:186:6:186:12 | synthetic splat argument | +| params_flow.rb:186:11:186:11 | 0 | type tracker without call steps with content element 0 | params_flow.rb:186:6:186:12 | synthetic splat argument | | params_flow.rb:186:14:186:14 | 0 | type tracker without call steps | params_flow.rb:186:14:186:14 | 0 | -| params_flow.rb:186:14:186:14 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:186:6:186:15 | synthetic splat argument | +| params_flow.rb:186:14:186:14 | 0 | type tracker without call steps with content element 0 | params_flow.rb:186:6:186:15 | synthetic splat argument | | params_flow.rb:187:1:187:25 | call to positionSideEffect | type tracker without call steps | params_flow.rb:187:1:187:25 | call to positionSideEffect | | params_flow.rb:187:20:187:24 | * ... | type tracker with call steps | params_flow.rb:181:1:183:3 | synthetic splat parameter | | params_flow.rb:187:20:187:24 | * ... | type tracker without call steps | params_flow.rb:187:20:187:24 | * ... | | params_flow.rb:188:1:188:16 | call to sink | type tracker without call steps | params_flow.rb:188:1:188:16 | call to sink | -| params_flow.rb:188:1:188:16 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:188:1:188:16 | synthetic splat argument | type tracker without call steps | params_flow.rb:188:1:188:16 | synthetic splat argument | | params_flow.rb:188:6:188:12 | ...[...] | type tracker without call steps | params_flow.rb:188:6:188:12 | ...[...] | | params_flow.rb:188:6:188:12 | synthetic splat argument | type tracker without call steps | params_flow.rb:188:6:188:12 | synthetic splat argument | | params_flow.rb:188:6:188:15 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:188:6:188:15 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:188:6:188:15 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:188:6:188:15 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:188:6:188:15 | ...[...] | type tracker without call steps | params_flow.rb:188:6:188:15 | ...[...] | -| params_flow.rb:188:6:188:15 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:188:1:188:16 | synthetic splat argument | +| params_flow.rb:188:6:188:15 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:188:1:188:16 | synthetic splat argument | | params_flow.rb:188:6:188:15 | synthetic splat argument | type tracker without call steps | params_flow.rb:188:6:188:15 | synthetic splat argument | | params_flow.rb:188:11:188:11 | 0 | type tracker without call steps | params_flow.rb:188:11:188:11 | 0 | -| params_flow.rb:188:11:188:11 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:188:6:188:12 | synthetic splat argument | +| params_flow.rb:188:11:188:11 | 0 | type tracker without call steps with content element 0 | params_flow.rb:188:6:188:12 | synthetic splat argument | | params_flow.rb:188:14:188:14 | 0 | type tracker without call steps | params_flow.rb:188:14:188:14 | 0 | -| params_flow.rb:188:14:188:14 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:188:6:188:15 | synthetic splat argument | +| params_flow.rb:188:14:188:14 | 0 | type tracker without call steps with content element 0 | params_flow.rb:188:6:188:15 | synthetic splat argument | | params_flow.rb:190:1:190:2 | p1 | type tracker without call steps | params_flow.rb:190:1:190:2 | p1 | | params_flow.rb:190:6:190:7 | Array | type tracker without call steps | params_flow.rb:190:6:190:7 | Array | | params_flow.rb:190:6:190:7 | call to [] | type tracker with call steps | params_flow.rb:181:24:181:25 | p1 | -| params_flow.rb:190:6:190:7 | call to [] | type tracker with call steps with content splat position 0 | params_flow.rb:181:1:183:3 | synthetic splat parameter | | params_flow.rb:190:6:190:7 | call to [] | type tracker without call steps | params_flow.rb:190:6:190:7 | call to [] | -| params_flow.rb:190:6:190:7 | call to [] | type tracker without call steps with content splat position 0 | params_flow.rb:192:1:192:33 | synthetic splat argument | +| params_flow.rb:190:6:190:7 | call to [] | type tracker without call steps with content element 0 | params_flow.rb:192:1:192:33 | synthetic splat argument | | params_flow.rb:191:1:191:11 | call to sink | type tracker without call steps | params_flow.rb:191:1:191:11 | call to sink | -| params_flow.rb:191:1:191:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:191:1:191:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:191:1:191:11 | synthetic splat argument | | params_flow.rb:191:6:191:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:191:6:191:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:191:6:191:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:191:6:191:10 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:191:6:191:10 | ...[...] | type tracker without call steps | params_flow.rb:191:6:191:10 | ...[...] | -| params_flow.rb:191:6:191:10 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:191:1:191:11 | synthetic splat argument | +| params_flow.rb:191:6:191:10 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:191:1:191:11 | synthetic splat argument | | params_flow.rb:191:6:191:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:191:6:191:10 | synthetic splat argument | | params_flow.rb:191:9:191:9 | 0 | type tracker without call steps | params_flow.rb:191:9:191:9 | 0 | -| params_flow.rb:191:9:191:9 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:191:6:191:10 | synthetic splat argument | +| params_flow.rb:191:9:191:9 | 0 | type tracker without call steps with content element 0 | params_flow.rb:191:6:191:10 | synthetic splat argument | | params_flow.rb:192:1:192:33 | call to positionSideEffect | type tracker without call steps | params_flow.rb:192:1:192:33 | call to positionSideEffect | -| params_flow.rb:192:1:192:33 | synthetic splat argument | type tracker with call steps | params_flow.rb:181:1:183:3 | synthetic splat parameter | | params_flow.rb:192:1:192:33 | synthetic splat argument | type tracker without call steps | params_flow.rb:192:1:192:33 | synthetic splat argument | | params_flow.rb:192:24:192:32 | call to taint | type tracker with call steps | params_flow.rb:181:28:181:29 | p2 | | params_flow.rb:192:24:192:32 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:182:5:182:6 | [post] p1 | | params_flow.rb:192:24:192:32 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:182:5:182:20 | call to insert | -| params_flow.rb:192:24:192:32 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:181:1:183:3 | synthetic splat parameter | -| params_flow.rb:192:24:192:32 | call to taint | type tracker with call steps with content splat position 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | +| params_flow.rb:192:24:192:32 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | | params_flow.rb:192:24:192:32 | call to taint | type tracker without call steps | params_flow.rb:192:24:192:32 | call to taint | -| params_flow.rb:192:24:192:32 | call to taint | type tracker without call steps with content splat position 1 | params_flow.rb:192:1:192:33 | synthetic splat argument | -| params_flow.rb:192:24:192:32 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | +| params_flow.rb:192:24:192:32 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:192:1:192:33 | synthetic splat argument | | params_flow.rb:192:24:192:32 | synthetic splat argument | type tracker without call steps | params_flow.rb:192:24:192:32 | synthetic splat argument | | params_flow.rb:192:30:192:31 | 79 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:192:30:192:31 | 79 | type tracker with call steps | params_flow.rb:181:28:181:29 | p2 | | params_flow.rb:192:30:192:31 | 79 | type tracker with call steps with content element 0 or unknown | params_flow.rb:182:5:182:6 | [post] p1 | | params_flow.rb:192:30:192:31 | 79 | type tracker with call steps with content element 0 or unknown | params_flow.rb:182:5:182:20 | call to insert | -| params_flow.rb:192:30:192:31 | 79 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | -| params_flow.rb:192:30:192:31 | 79 | type tracker with call steps with content splat position 1 | params_flow.rb:181:1:183:3 | synthetic splat parameter | -| params_flow.rb:192:30:192:31 | 79 | type tracker with call steps with content splat position 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | +| params_flow.rb:192:30:192:31 | 79 | type tracker with call steps with content element 1 | params_flow.rb:182:5:182:20 | synthetic splat argument | | params_flow.rb:192:30:192:31 | 79 | type tracker without call steps | params_flow.rb:192:24:192:32 | call to taint | | params_flow.rb:192:30:192:31 | 79 | type tracker without call steps | params_flow.rb:192:30:192:31 | 79 | -| params_flow.rb:192:30:192:31 | 79 | type tracker without call steps with content splat position 0 | params_flow.rb:192:24:192:32 | synthetic splat argument | -| params_flow.rb:192:30:192:31 | 79 | type tracker without call steps with content splat position 1 | params_flow.rb:192:1:192:33 | synthetic splat argument | +| params_flow.rb:192:30:192:31 | 79 | type tracker without call steps with content element 0 | params_flow.rb:192:24:192:32 | synthetic splat argument | +| params_flow.rb:192:30:192:31 | 79 | type tracker without call steps with content element 1 | params_flow.rb:192:1:192:33 | synthetic splat argument | | params_flow.rb:193:1:193:11 | call to sink | type tracker without call steps | params_flow.rb:193:1:193:11 | call to sink | -| params_flow.rb:193:1:193:11 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:193:1:193:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:193:1:193:11 | synthetic splat argument | | params_flow.rb:193:6:193:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:193:6:193:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:193:6:193:10 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:193:6:193:10 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:193:6:193:10 | ...[...] | type tracker without call steps | params_flow.rb:193:6:193:10 | ...[...] | -| params_flow.rb:193:6:193:10 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:193:1:193:11 | synthetic splat argument | +| params_flow.rb:193:6:193:10 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:193:1:193:11 | synthetic splat argument | | params_flow.rb:193:6:193:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:193:6:193:10 | synthetic splat argument | | params_flow.rb:193:9:193:9 | 0 | type tracker without call steps | params_flow.rb:193:9:193:9 | 0 | -| params_flow.rb:193:9:193:9 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:193:6:193:10 | synthetic splat argument | +| params_flow.rb:193:9:193:9 | 0 | type tracker without call steps with content element 0 | params_flow.rb:193:6:193:10 | synthetic splat argument | | params_flow.rb:195:1:195:8 | int_hash | type tracker without call steps | params_flow.rb:195:1:195:8 | int_hash | | params_flow.rb:195:12:198:1 | Hash | type tracker without call steps | params_flow.rb:195:12:198:1 | Hash | | params_flow.rb:195:12:198:1 | call to [] | type tracker with call steps | params_flow.rb:200:9:200:9 | x | @@ -3602,28 +3170,26 @@ track | params_flow.rb:195:12:198:1 | synthetic splat argument | type tracker without call steps | params_flow.rb:195:12:198:1 | synthetic splat argument | | params_flow.rb:196:5:196:5 | 0 | type tracker without call steps | params_flow.rb:196:5:196:5 | 0 | | params_flow.rb:196:5:196:18 | Pair | type tracker without call steps | params_flow.rb:196:5:196:18 | Pair | -| params_flow.rb:196:5:196:18 | Pair | type tracker without call steps with content splat position 0 | params_flow.rb:195:12:198:1 | synthetic splat argument | +| params_flow.rb:196:5:196:18 | Pair | type tracker without call steps with content element 0 | params_flow.rb:195:12:198:1 | synthetic splat argument | | params_flow.rb:196:10:196:18 | call to taint | type tracker with call steps | params_flow.rb:200:9:200:9 | x | | params_flow.rb:196:10:196:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:200:1:205:3 | synthetic splat parameter | | params_flow.rb:196:10:196:18 | call to taint | type tracker without call steps | params_flow.rb:196:10:196:18 | call to taint | | params_flow.rb:196:10:196:18 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:195:12:198:1 | call to [] | | params_flow.rb:196:10:196:18 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:195:12:198:1 | synthetic hash-splat argument | | params_flow.rb:196:10:196:18 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:207:5:207:13 | * ... | -| params_flow.rb:196:10:196:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:196:10:196:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:196:10:196:18 | synthetic splat argument | | params_flow.rb:196:16:196:17 | 80 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:196:16:196:17 | 80 | type tracker with call steps | params_flow.rb:200:9:200:9 | x | | params_flow.rb:196:16:196:17 | 80 | type tracker with call steps with content element 0 | params_flow.rb:200:1:205:3 | synthetic splat parameter | -| params_flow.rb:196:16:196:17 | 80 | type tracker with call steps with content splat position 0 | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:196:16:196:17 | 80 | type tracker without call steps | params_flow.rb:196:10:196:18 | call to taint | | params_flow.rb:196:16:196:17 | 80 | type tracker without call steps | params_flow.rb:196:16:196:17 | 80 | | params_flow.rb:196:16:196:17 | 80 | type tracker without call steps with content element 0 | params_flow.rb:195:12:198:1 | call to [] | | params_flow.rb:196:16:196:17 | 80 | type tracker without call steps with content element 0 | params_flow.rb:195:12:198:1 | synthetic hash-splat argument | +| params_flow.rb:196:16:196:17 | 80 | type tracker without call steps with content element 0 | params_flow.rb:196:10:196:18 | synthetic splat argument | | params_flow.rb:196:16:196:17 | 80 | type tracker without call steps with content element 0 | params_flow.rb:207:5:207:13 | * ... | -| params_flow.rb:196:16:196:17 | 80 | type tracker without call steps with content splat position 0 | params_flow.rb:196:10:196:18 | synthetic splat argument | | params_flow.rb:197:5:197:5 | 1 | type tracker without call steps | params_flow.rb:197:5:197:5 | 1 | | params_flow.rb:197:5:197:12 | Pair | type tracker without call steps | params_flow.rb:197:5:197:12 | Pair | -| params_flow.rb:197:5:197:12 | Pair | type tracker without call steps with content splat position 1 | params_flow.rb:195:12:198:1 | synthetic splat argument | +| params_flow.rb:197:5:197:12 | Pair | type tracker without call steps with content element 1 | params_flow.rb:195:12:198:1 | synthetic splat argument | | params_flow.rb:197:10:197:12 | "B" | type tracker with call steps | params_flow.rb:200:12:200:12 | y | | params_flow.rb:197:10:197:12 | "B" | type tracker with call steps with content element 1 | params_flow.rb:200:1:205:3 | synthetic splat parameter | | params_flow.rb:197:10:197:12 | "B" | type tracker without call steps | params_flow.rb:197:10:197:12 | "B" | @@ -3640,50 +3206,42 @@ track | params_flow.rb:200:12:200:12 | y | type tracker without call steps | params_flow.rb:200:12:200:12 | y | | params_flow.rb:200:12:200:12 | y | type tracker without call steps | params_flow.rb:200:12:200:12 | y | | params_flow.rb:201:5:201:15 | call to sink | type tracker without call steps | params_flow.rb:201:5:201:15 | call to sink | -| params_flow.rb:201:5:201:15 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:201:5:201:15 | synthetic splat argument | type tracker without call steps | params_flow.rb:201:5:201:15 | synthetic splat argument | | params_flow.rb:201:11:201:14 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:201:11:201:14 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:201:11:201:14 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:201:11:201:14 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:201:11:201:14 | ...[...] | type tracker without call steps | params_flow.rb:201:11:201:14 | ...[...] | -| params_flow.rb:201:11:201:14 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:201:5:201:15 | synthetic splat argument | +| params_flow.rb:201:11:201:14 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:201:5:201:15 | synthetic splat argument | | params_flow.rb:201:11:201:14 | synthetic splat argument | type tracker without call steps | params_flow.rb:201:11:201:14 | synthetic splat argument | | params_flow.rb:201:13:201:13 | 0 | type tracker without call steps | params_flow.rb:201:13:201:13 | 0 | -| params_flow.rb:201:13:201:13 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:201:11:201:14 | synthetic splat argument | +| params_flow.rb:201:13:201:13 | 0 | type tracker without call steps with content element 0 | params_flow.rb:201:11:201:14 | synthetic splat argument | | params_flow.rb:202:5:202:15 | call to sink | type tracker without call steps | params_flow.rb:202:5:202:15 | call to sink | -| params_flow.rb:202:5:202:15 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:202:5:202:15 | synthetic splat argument | type tracker without call steps | params_flow.rb:202:5:202:15 | synthetic splat argument | | params_flow.rb:202:11:202:14 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:202:11:202:14 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:202:11:202:14 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:202:11:202:14 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:202:11:202:14 | ...[...] | type tracker without call steps | params_flow.rb:202:11:202:14 | ...[...] | -| params_flow.rb:202:11:202:14 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:202:5:202:15 | synthetic splat argument | +| params_flow.rb:202:11:202:14 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:202:5:202:15 | synthetic splat argument | | params_flow.rb:202:11:202:14 | synthetic splat argument | type tracker without call steps | params_flow.rb:202:11:202:14 | synthetic splat argument | | params_flow.rb:202:13:202:13 | 1 | type tracker without call steps | params_flow.rb:202:13:202:13 | 1 | -| params_flow.rb:202:13:202:13 | 1 | type tracker without call steps with content splat position 0 | params_flow.rb:202:11:202:14 | synthetic splat argument | +| params_flow.rb:202:13:202:13 | 1 | type tracker without call steps with content element 0 | params_flow.rb:202:11:202:14 | synthetic splat argument | | params_flow.rb:203:5:203:15 | call to sink | type tracker without call steps | params_flow.rb:203:5:203:15 | call to sink | -| params_flow.rb:203:5:203:15 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:203:5:203:15 | synthetic splat argument | type tracker without call steps | params_flow.rb:203:5:203:15 | synthetic splat argument | | params_flow.rb:203:11:203:14 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:203:11:203:14 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:203:11:203:14 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:203:11:203:14 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:203:11:203:14 | ...[...] | type tracker without call steps | params_flow.rb:203:11:203:14 | ...[...] | -| params_flow.rb:203:11:203:14 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:203:5:203:15 | synthetic splat argument | +| params_flow.rb:203:11:203:14 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:203:5:203:15 | synthetic splat argument | | params_flow.rb:203:11:203:14 | synthetic splat argument | type tracker without call steps | params_flow.rb:203:11:203:14 | synthetic splat argument | | params_flow.rb:203:13:203:13 | 0 | type tracker without call steps | params_flow.rb:203:13:203:13 | 0 | -| params_flow.rb:203:13:203:13 | 0 | type tracker without call steps with content splat position 0 | params_flow.rb:203:11:203:14 | synthetic splat argument | +| params_flow.rb:203:13:203:13 | 0 | type tracker without call steps with content element 0 | params_flow.rb:203:11:203:14 | synthetic splat argument | | params_flow.rb:204:5:204:15 | call to sink | type tracker without call steps | params_flow.rb:204:5:204:15 | call to sink | | params_flow.rb:204:5:204:15 | call to sink | type tracker without call steps | params_flow.rb:207:1:207:14 | call to foo | -| params_flow.rb:204:5:204:15 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:204:5:204:15 | synthetic splat argument | type tracker without call steps | params_flow.rb:204:5:204:15 | synthetic splat argument | | params_flow.rb:204:11:204:14 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:204:11:204:14 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:5:1:7:3 | synthetic splat parameter | -| params_flow.rb:204:11:204:14 | ...[...] | type tracker with call steps with content splat position 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | +| params_flow.rb:204:11:204:14 | ...[...] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:204:11:204:14 | ...[...] | type tracker without call steps | params_flow.rb:204:11:204:14 | ...[...] | -| params_flow.rb:204:11:204:14 | ...[...] | type tracker without call steps with content splat position 0 | params_flow.rb:204:5:204:15 | synthetic splat argument | +| params_flow.rb:204:11:204:14 | ...[...] | type tracker without call steps with content element 0 | params_flow.rb:204:5:204:15 | synthetic splat argument | | params_flow.rb:204:11:204:14 | synthetic splat argument | type tracker without call steps | params_flow.rb:204:11:204:14 | synthetic splat argument | | params_flow.rb:204:13:204:13 | 1 | type tracker without call steps | params_flow.rb:204:13:204:13 | 1 | -| params_flow.rb:204:13:204:13 | 1 | type tracker without call steps with content splat position 0 | params_flow.rb:204:11:204:14 | synthetic splat argument | +| params_flow.rb:204:13:204:13 | 1 | type tracker without call steps with content element 0 | params_flow.rb:204:11:204:14 | synthetic splat argument | | params_flow.rb:207:1:207:14 | call to foo | type tracker without call steps | params_flow.rb:207:1:207:14 | call to foo | | params_flow.rb:207:5:207:13 | * ... | type tracker with call steps | params_flow.rb:200:1:205:3 | synthetic splat parameter | | params_flow.rb:207:5:207:13 | * ... | type tracker without call steps | params_flow.rb:207:5:207:13 | * ... | @@ -4203,17 +3761,14 @@ trackEnd | params_flow.rb:9:20:9:21 | p2 | params_flow.rb:9:20:9:21 | p2 | | params_flow.rb:9:20:9:21 | p2 | params_flow.rb:11:10:11:11 | p2 | | params_flow.rb:10:5:10:11 | call to sink | params_flow.rb:10:5:10:11 | call to sink | -| params_flow.rb:10:5:10:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:10:5:10:11 | synthetic splat argument | params_flow.rb:10:5:10:11 | synthetic splat argument | | params_flow.rb:11:5:11:11 | call to sink | params_flow.rb:11:5:11:11 | call to sink | | params_flow.rb:11:5:11:11 | call to sink | params_flow.rb:14:1:14:30 | call to positional | | params_flow.rb:11:5:11:11 | call to sink | params_flow.rb:44:1:44:28 | call to positional | | params_flow.rb:11:5:11:11 | call to sink | params_flow.rb:47:1:47:17 | call to positional | | params_flow.rb:11:5:11:11 | call to sink | params_flow.rb:118:1:118:14 | call to positional | -| params_flow.rb:11:5:11:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:11:5:11:11 | synthetic splat argument | params_flow.rb:11:5:11:11 | synthetic splat argument | | params_flow.rb:14:1:14:30 | call to positional | params_flow.rb:14:1:14:30 | call to positional | -| params_flow.rb:14:1:14:30 | synthetic splat argument | params_flow.rb:9:1:12:3 | synthetic splat parameter | | params_flow.rb:14:1:14:30 | synthetic splat argument | params_flow.rb:14:1:14:30 | synthetic splat argument | | params_flow.rb:14:12:14:19 | call to taint | params_flow.rb:5:10:5:10 | x | | params_flow.rb:14:12:14:19 | call to taint | params_flow.rb:5:10:5:10 | x | @@ -4222,7 +3777,6 @@ trackEnd | params_flow.rb:14:12:14:19 | call to taint | params_flow.rb:9:16:9:17 | p1 | | params_flow.rb:14:12:14:19 | call to taint | params_flow.rb:10:10:10:11 | p1 | | params_flow.rb:14:12:14:19 | call to taint | params_flow.rb:14:12:14:19 | call to taint | -| params_flow.rb:14:12:14:19 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:14:12:14:19 | synthetic splat argument | params_flow.rb:14:12:14:19 | synthetic splat argument | | params_flow.rb:14:18:14:18 | 1 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:14:18:14:18 | 1 | params_flow.rb:1:11:1:11 | x | @@ -4242,7 +3796,6 @@ trackEnd | params_flow.rb:14:22:14:29 | call to taint | params_flow.rb:9:20:9:21 | p2 | | params_flow.rb:14:22:14:29 | call to taint | params_flow.rb:11:10:11:11 | p2 | | params_flow.rb:14:22:14:29 | call to taint | params_flow.rb:14:22:14:29 | call to taint | -| params_flow.rb:14:22:14:29 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:14:22:14:29 | synthetic splat argument | params_flow.rb:14:22:14:29 | synthetic splat argument | | params_flow.rb:14:28:14:28 | 2 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:14:28:14:28 | 2 | params_flow.rb:1:11:1:11 | x | @@ -4280,14 +3833,12 @@ trackEnd | params_flow.rb:16:18:16:19 | p2 | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:16:18:16:19 | p2 | params_flow.rb:18:10:18:11 | p2 | | params_flow.rb:17:5:17:11 | call to sink | params_flow.rb:17:5:17:11 | call to sink | -| params_flow.rb:17:5:17:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:17:5:17:11 | synthetic splat argument | params_flow.rb:17:5:17:11 | synthetic splat argument | | params_flow.rb:18:5:18:11 | call to sink | params_flow.rb:18:5:18:11 | call to sink | | params_flow.rb:18:5:18:11 | call to sink | params_flow.rb:21:1:21:35 | call to keyword | | params_flow.rb:18:5:18:11 | call to sink | params_flow.rb:22:1:22:35 | call to keyword | | params_flow.rb:18:5:18:11 | call to sink | params_flow.rb:23:1:23:41 | call to keyword | | params_flow.rb:18:5:18:11 | call to sink | params_flow.rb:41:1:41:30 | call to keyword | -| params_flow.rb:18:5:18:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:18:5:18:11 | synthetic splat argument | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:21:1:21:35 | call to keyword | params_flow.rb:21:1:21:35 | call to keyword | | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | @@ -4301,7 +3852,6 @@ trackEnd | params_flow.rb:21:13:21:20 | call to taint | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:21:13:21:20 | call to taint | params_flow.rb:17:10:17:11 | p1 | | params_flow.rb:21:13:21:20 | call to taint | params_flow.rb:21:13:21:20 | call to taint | -| params_flow.rb:21:13:21:20 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:21:13:21:20 | synthetic splat argument | params_flow.rb:21:13:21:20 | synthetic splat argument | | params_flow.rb:21:19:21:19 | 3 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:21:19:21:19 | 3 | params_flow.rb:1:11:1:11 | x | @@ -4323,7 +3873,6 @@ trackEnd | params_flow.rb:21:27:21:34 | call to taint | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:21:27:21:34 | call to taint | params_flow.rb:18:10:18:11 | p2 | | params_flow.rb:21:27:21:34 | call to taint | params_flow.rb:21:27:21:34 | call to taint | -| params_flow.rb:21:27:21:34 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:21:27:21:34 | synthetic splat argument | params_flow.rb:21:27:21:34 | synthetic splat argument | | params_flow.rb:21:33:21:33 | 4 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:21:33:21:33 | 4 | params_flow.rb:1:11:1:11 | x | @@ -4348,7 +3897,6 @@ trackEnd | params_flow.rb:22:13:22:20 | call to taint | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:22:13:22:20 | call to taint | params_flow.rb:18:10:18:11 | p2 | | params_flow.rb:22:13:22:20 | call to taint | params_flow.rb:22:13:22:20 | call to taint | -| params_flow.rb:22:13:22:20 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:22:13:22:20 | synthetic splat argument | params_flow.rb:22:13:22:20 | synthetic splat argument | | params_flow.rb:22:19:22:19 | 5 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:22:19:22:19 | 5 | params_flow.rb:1:11:1:11 | x | @@ -4370,7 +3918,6 @@ trackEnd | params_flow.rb:22:27:22:34 | call to taint | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:22:27:22:34 | call to taint | params_flow.rb:17:10:17:11 | p1 | | params_flow.rb:22:27:22:34 | call to taint | params_flow.rb:22:27:22:34 | call to taint | -| params_flow.rb:22:27:22:34 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:22:27:22:34 | synthetic splat argument | params_flow.rb:22:27:22:34 | synthetic splat argument | | params_flow.rb:22:33:22:33 | 6 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:22:33:22:33 | 6 | params_flow.rb:1:11:1:11 | x | @@ -4395,7 +3942,6 @@ trackEnd | params_flow.rb:23:16:23:23 | call to taint | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:23:16:23:23 | call to taint | params_flow.rb:18:10:18:11 | p2 | | params_flow.rb:23:16:23:23 | call to taint | params_flow.rb:23:16:23:23 | call to taint | -| params_flow.rb:23:16:23:23 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:23:16:23:23 | synthetic splat argument | params_flow.rb:23:16:23:23 | synthetic splat argument | | params_flow.rb:23:22:23:22 | 7 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:23:22:23:22 | 7 | params_flow.rb:1:11:1:11 | x | @@ -4417,7 +3963,6 @@ trackEnd | params_flow.rb:23:33:23:40 | call to taint | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:23:33:23:40 | call to taint | params_flow.rb:17:10:17:11 | p1 | | params_flow.rb:23:33:23:40 | call to taint | params_flow.rb:23:33:23:40 | call to taint | -| params_flow.rb:23:33:23:40 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:23:33:23:40 | synthetic splat argument | params_flow.rb:23:33:23:40 | synthetic splat argument | | params_flow.rb:23:39:23:39 | 8 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:23:39:23:39 | 8 | params_flow.rb:1:11:1:11 | x | @@ -4458,10 +4003,8 @@ trackEnd | params_flow.rb:25:17:25:24 | **kwargs | params_flow.rb:30:11:30:16 | kwargs | | params_flow.rb:25:19:25:24 | kwargs | params_flow.rb:25:19:25:24 | kwargs | | params_flow.rb:26:5:26:11 | call to sink | params_flow.rb:26:5:26:11 | call to sink | -| params_flow.rb:26:5:26:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:26:5:26:11 | synthetic splat argument | params_flow.rb:26:5:26:11 | synthetic splat argument | | params_flow.rb:27:5:27:22 | call to sink | params_flow.rb:27:5:27:22 | call to sink | -| params_flow.rb:27:5:27:22 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:27:5:27:22 | synthetic splat argument | params_flow.rb:27:5:27:22 | synthetic splat argument | | params_flow.rb:27:11:27:21 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:27:11:27:21 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -4471,7 +4014,6 @@ trackEnd | params_flow.rb:27:11:27:21 | synthetic splat argument | params_flow.rb:27:11:27:21 | synthetic splat argument | | params_flow.rb:27:18:27:20 | :p1 | params_flow.rb:27:18:27:20 | :p1 | | params_flow.rb:28:5:28:22 | call to sink | params_flow.rb:28:5:28:22 | call to sink | -| params_flow.rb:28:5:28:22 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:28:5:28:22 | synthetic splat argument | params_flow.rb:28:5:28:22 | synthetic splat argument | | params_flow.rb:28:11:28:21 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:28:11:28:21 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -4481,7 +4023,6 @@ trackEnd | params_flow.rb:28:11:28:21 | synthetic splat argument | params_flow.rb:28:11:28:21 | synthetic splat argument | | params_flow.rb:28:18:28:20 | :p2 | params_flow.rb:28:18:28:20 | :p2 | | params_flow.rb:29:5:29:22 | call to sink | params_flow.rb:29:5:29:22 | call to sink | -| params_flow.rb:29:5:29:22 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:29:5:29:22 | synthetic splat argument | params_flow.rb:29:5:29:22 | synthetic splat argument | | params_flow.rb:29:11:29:21 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:29:11:29:21 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -4494,7 +4035,6 @@ trackEnd | params_flow.rb:30:5:30:22 | call to sink | params_flow.rb:33:1:33:58 | call to kwargs | | params_flow.rb:30:5:30:22 | call to sink | params_flow.rb:35:1:35:29 | call to kwargs | | params_flow.rb:30:5:30:22 | call to sink | params_flow.rb:38:1:38:14 | call to kwargs | -| params_flow.rb:30:5:30:22 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:30:5:30:22 | synthetic splat argument | params_flow.rb:30:5:30:22 | synthetic splat argument | | params_flow.rb:30:11:30:21 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:30:11:30:21 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -4523,7 +4063,6 @@ trackEnd | params_flow.rb:33:12:33:19 | call to taint | params_flow.rb:27:10:27:22 | ( ... ) | | params_flow.rb:33:12:33:19 | call to taint | params_flow.rb:27:11:27:21 | ...[...] | | params_flow.rb:33:12:33:19 | call to taint | params_flow.rb:33:12:33:19 | call to taint | -| params_flow.rb:33:12:33:19 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:33:12:33:19 | synthetic splat argument | params_flow.rb:33:12:33:19 | synthetic splat argument | | params_flow.rb:33:18:33:18 | 9 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:33:18:33:18 | 9 | params_flow.rb:1:11:1:11 | x | @@ -4546,7 +4085,6 @@ trackEnd | params_flow.rb:33:26:33:34 | call to taint | params_flow.rb:28:10:28:22 | ( ... ) | | params_flow.rb:33:26:33:34 | call to taint | params_flow.rb:28:11:28:21 | ...[...] | | params_flow.rb:33:26:33:34 | call to taint | params_flow.rb:33:26:33:34 | call to taint | -| params_flow.rb:33:26:33:34 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:33:26:33:34 | synthetic splat argument | params_flow.rb:33:26:33:34 | synthetic splat argument | | params_flow.rb:33:32:33:33 | 10 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:33:32:33:33 | 10 | params_flow.rb:1:11:1:11 | x | @@ -4566,7 +4104,6 @@ trackEnd | params_flow.rb:33:41:33:49 | call to taint | params_flow.rb:29:10:29:22 | ( ... ) | | params_flow.rb:33:41:33:49 | call to taint | params_flow.rb:29:11:29:21 | ...[...] | | params_flow.rb:33:41:33:49 | call to taint | params_flow.rb:33:41:33:49 | call to taint | -| params_flow.rb:33:41:33:49 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:33:41:33:49 | synthetic splat argument | params_flow.rb:33:41:33:49 | synthetic splat argument | | params_flow.rb:33:47:33:48 | 11 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:33:47:33:48 | 11 | params_flow.rb:1:11:1:11 | x | @@ -4605,7 +4142,6 @@ trackEnd | params_flow.rb:34:14:34:22 | call to taint | params_flow.rb:29:10:29:22 | ( ... ) | | params_flow.rb:34:14:34:22 | call to taint | params_flow.rb:29:11:29:21 | ...[...] | | params_flow.rb:34:14:34:22 | call to taint | params_flow.rb:34:14:34:22 | call to taint | -| params_flow.rb:34:14:34:22 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:34:14:34:22 | synthetic splat argument | params_flow.rb:34:14:34:22 | synthetic splat argument | | params_flow.rb:34:20:34:21 | 12 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:34:20:34:21 | 12 | params_flow.rb:1:11:1:11 | x | @@ -4645,7 +4181,6 @@ trackEnd | params_flow.rb:35:12:35:20 | call to taint | params_flow.rb:27:10:27:22 | ( ... ) | | params_flow.rb:35:12:35:20 | call to taint | params_flow.rb:27:11:27:21 | ...[...] | | params_flow.rb:35:12:35:20 | call to taint | params_flow.rb:35:12:35:20 | call to taint | -| params_flow.rb:35:12:35:20 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:35:12:35:20 | synthetic splat argument | params_flow.rb:35:12:35:20 | synthetic splat argument | | params_flow.rb:35:18:35:19 | 13 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:35:18:35:19 | 13 | params_flow.rb:1:11:1:11 | x | @@ -4690,7 +4225,6 @@ trackEnd | params_flow.rb:37:16:37:24 | call to taint | params_flow.rb:27:10:27:22 | ( ... ) | | params_flow.rb:37:16:37:24 | call to taint | params_flow.rb:27:11:27:21 | ...[...] | | params_flow.rb:37:16:37:24 | call to taint | params_flow.rb:37:16:37:24 | call to taint | -| params_flow.rb:37:16:37:24 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:37:16:37:24 | synthetic splat argument | params_flow.rb:37:16:37:24 | synthetic splat argument | | params_flow.rb:37:22:37:23 | 14 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:37:22:37:23 | 14 | params_flow.rb:1:11:1:11 | x | @@ -4713,7 +4247,6 @@ trackEnd | params_flow.rb:37:34:37:42 | call to taint | params_flow.rb:28:10:28:22 | ( ... ) | | params_flow.rb:37:34:37:42 | call to taint | params_flow.rb:28:11:28:21 | ...[...] | | params_flow.rb:37:34:37:42 | call to taint | params_flow.rb:37:34:37:42 | call to taint | -| params_flow.rb:37:34:37:42 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:37:34:37:42 | synthetic splat argument | params_flow.rb:37:34:37:42 | synthetic splat argument | | params_flow.rb:37:40:37:41 | 15 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:37:40:37:41 | 15 | params_flow.rb:1:11:1:11 | x | @@ -4754,7 +4287,6 @@ trackEnd | params_flow.rb:40:16:40:24 | call to taint | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:40:16:40:24 | call to taint | params_flow.rb:17:10:17:11 | p1 | | params_flow.rb:40:16:40:24 | call to taint | params_flow.rb:40:16:40:24 | call to taint | -| params_flow.rb:40:16:40:24 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:40:16:40:24 | synthetic splat argument | params_flow.rb:40:16:40:24 | synthetic splat argument | | params_flow.rb:40:22:40:23 | 16 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:40:22:40:23 | 16 | params_flow.rb:1:11:1:11 | x | @@ -4779,7 +4311,6 @@ trackEnd | params_flow.rb:41:13:41:21 | call to taint | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:41:13:41:21 | call to taint | params_flow.rb:18:10:18:11 | p2 | | params_flow.rb:41:13:41:21 | call to taint | params_flow.rb:41:13:41:21 | call to taint | -| params_flow.rb:41:13:41:21 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:41:13:41:21 | synthetic splat argument | params_flow.rb:41:13:41:21 | synthetic splat argument | | params_flow.rb:41:19:41:20 | 17 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:41:19:41:20 | 17 | params_flow.rb:1:11:1:11 | x | @@ -4824,7 +4355,6 @@ trackEnd | params_flow.rb:43:9:43:17 | call to taint | params_flow.rb:9:20:9:21 | p2 | | params_flow.rb:43:9:43:17 | call to taint | params_flow.rb:11:10:11:11 | p2 | | params_flow.rb:43:9:43:17 | call to taint | params_flow.rb:43:9:43:17 | call to taint | -| params_flow.rb:43:9:43:17 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:43:9:43:17 | synthetic splat argument | params_flow.rb:43:9:43:17 | synthetic splat argument | | params_flow.rb:43:15:43:16 | 17 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:43:15:43:16 | 17 | params_flow.rb:1:11:1:11 | x | @@ -4847,7 +4377,6 @@ trackEnd | params_flow.rb:44:12:44:20 | call to taint | params_flow.rb:9:16:9:17 | p1 | | params_flow.rb:44:12:44:20 | call to taint | params_flow.rb:10:10:10:11 | p1 | | params_flow.rb:44:12:44:20 | call to taint | params_flow.rb:44:12:44:20 | call to taint | -| params_flow.rb:44:12:44:20 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:44:12:44:20 | synthetic splat argument | params_flow.rb:44:12:44:20 | synthetic splat argument | | params_flow.rb:44:18:44:19 | 16 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:44:18:44:19 | 16 | params_flow.rb:1:11:1:11 | x | @@ -4891,7 +4420,6 @@ trackEnd | params_flow.rb:46:9:46:17 | call to taint | params_flow.rb:9:16:9:17 | p1 | | params_flow.rb:46:9:46:17 | call to taint | params_flow.rb:10:10:10:11 | p1 | | params_flow.rb:46:9:46:17 | call to taint | params_flow.rb:46:9:46:17 | call to taint | -| params_flow.rb:46:9:46:17 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:46:9:46:17 | synthetic splat argument | params_flow.rb:46:9:46:17 | synthetic splat argument | | params_flow.rb:46:15:46:16 | 18 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:46:15:46:16 | 18 | params_flow.rb:1:11:1:11 | x | @@ -4911,7 +4439,6 @@ trackEnd | params_flow.rb:46:20:46:28 | call to taint | params_flow.rb:9:20:9:21 | p2 | | params_flow.rb:46:20:46:28 | call to taint | params_flow.rb:11:10:11:11 | p2 | | params_flow.rb:46:20:46:28 | call to taint | params_flow.rb:46:20:46:28 | call to taint | -| params_flow.rb:46:20:46:28 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:46:20:46:28 | synthetic splat argument | params_flow.rb:46:20:46:28 | synthetic splat argument | | params_flow.rb:46:26:46:27 | 19 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:46:26:46:27 | 19 | params_flow.rb:1:11:1:11 | x | @@ -4951,10 +4478,8 @@ trackEnd | params_flow.rb:49:17:49:24 | *posargs | params_flow.rb:52:11:52:17 | posargs | | params_flow.rb:49:18:49:24 | posargs | params_flow.rb:49:18:49:24 | posargs | | params_flow.rb:50:5:50:11 | call to sink | params_flow.rb:50:5:50:11 | call to sink | -| params_flow.rb:50:5:50:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:50:5:50:11 | synthetic splat argument | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:51:5:51:21 | call to sink | params_flow.rb:51:5:51:21 | call to sink | -| params_flow.rb:51:5:51:21 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:51:5:51:21 | synthetic splat argument | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:51:11:51:20 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:51:11:51:20 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -4967,7 +4492,6 @@ trackEnd | params_flow.rb:52:5:52:21 | call to sink | params_flow.rb:55:1:55:29 | call to posargs | | params_flow.rb:52:5:52:21 | call to sink | params_flow.rb:58:1:58:25 | call to posargs | | params_flow.rb:52:5:52:21 | call to sink | params_flow.rb:61:1:61:14 | call to posargs | -| params_flow.rb:52:5:52:21 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:52:5:52:21 | synthetic splat argument | params_flow.rb:52:5:52:21 | synthetic splat argument | | params_flow.rb:52:11:52:20 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:52:11:52:20 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -4986,7 +4510,6 @@ trackEnd | params_flow.rb:55:9:55:17 | call to taint | params_flow.rb:49:13:49:14 | p1 | | params_flow.rb:55:9:55:17 | call to taint | params_flow.rb:50:10:50:11 | p1 | | params_flow.rb:55:9:55:17 | call to taint | params_flow.rb:55:9:55:17 | call to taint | -| params_flow.rb:55:9:55:17 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:55:9:55:17 | synthetic splat argument | params_flow.rb:55:9:55:17 | synthetic splat argument | | params_flow.rb:55:15:55:16 | 20 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:55:15:55:16 | 20 | params_flow.rb:1:11:1:11 | x | @@ -5005,7 +4528,6 @@ trackEnd | params_flow.rb:55:20:55:28 | call to taint | params_flow.rb:51:10:51:21 | ( ... ) | | params_flow.rb:55:20:55:28 | call to taint | params_flow.rb:51:11:51:20 | ...[...] | | params_flow.rb:55:20:55:28 | call to taint | params_flow.rb:55:20:55:28 | call to taint | -| params_flow.rb:55:20:55:28 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:55:20:55:28 | synthetic splat argument | params_flow.rb:55:20:55:28 | synthetic splat argument | | params_flow.rb:55:26:55:27 | 21 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:55:26:55:27 | 21 | params_flow.rb:1:11:1:11 | x | @@ -5044,7 +4566,6 @@ trackEnd | params_flow.rb:57:9:57:17 | call to taint | params_flow.rb:51:10:51:21 | ( ... ) | | params_flow.rb:57:9:57:17 | call to taint | params_flow.rb:51:11:51:20 | ...[...] | | params_flow.rb:57:9:57:17 | call to taint | params_flow.rb:57:9:57:17 | call to taint | -| params_flow.rb:57:9:57:17 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:57:9:57:17 | synthetic splat argument | params_flow.rb:57:9:57:17 | synthetic splat argument | | params_flow.rb:57:15:57:16 | 22 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:57:15:57:16 | 22 | params_flow.rb:1:11:1:11 | x | @@ -5066,7 +4587,6 @@ trackEnd | params_flow.rb:58:9:58:17 | call to taint | params_flow.rb:49:13:49:14 | p1 | | params_flow.rb:58:9:58:17 | call to taint | params_flow.rb:50:10:50:11 | p1 | | params_flow.rb:58:9:58:17 | call to taint | params_flow.rb:58:9:58:17 | call to taint | -| params_flow.rb:58:9:58:17 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:58:9:58:17 | synthetic splat argument | params_flow.rb:58:9:58:17 | synthetic splat argument | | params_flow.rb:58:15:58:16 | 23 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:58:15:58:16 | 23 | params_flow.rb:1:11:1:11 | x | @@ -5114,7 +4634,6 @@ trackEnd | params_flow.rb:60:9:60:17 | call to taint | params_flow.rb:49:13:49:14 | p1 | | params_flow.rb:60:9:60:17 | call to taint | params_flow.rb:50:10:50:11 | p1 | | params_flow.rb:60:9:60:17 | call to taint | params_flow.rb:60:9:60:17 | call to taint | -| params_flow.rb:60:9:60:17 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:60:9:60:17 | synthetic splat argument | params_flow.rb:60:9:60:17 | synthetic splat argument | | params_flow.rb:60:15:60:16 | 24 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:60:15:60:16 | 24 | params_flow.rb:1:11:1:11 | x | @@ -5133,7 +4652,6 @@ trackEnd | params_flow.rb:60:20:60:28 | call to taint | params_flow.rb:51:10:51:21 | ( ... ) | | params_flow.rb:60:20:60:28 | call to taint | params_flow.rb:51:11:51:20 | ...[...] | | params_flow.rb:60:20:60:28 | call to taint | params_flow.rb:60:20:60:28 | call to taint | -| params_flow.rb:60:20:60:28 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:60:20:60:28 | synthetic splat argument | params_flow.rb:60:20:60:28 | synthetic splat argument | | params_flow.rb:60:26:60:27 | 25 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:60:26:60:27 | 25 | params_flow.rb:1:11:1:11 | x | @@ -5157,7 +4675,6 @@ trackEnd | params_flow.rb:63:8:63:16 | call to taint | params_flow.rb:63:8:63:16 | call to taint | | params_flow.rb:63:8:63:16 | call to taint | params_flow.rb:65:10:65:13 | ...[...] | | params_flow.rb:63:8:63:16 | call to taint | params_flow.rb:67:13:67:16 | args | -| params_flow.rb:63:8:63:16 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:63:8:63:16 | synthetic splat argument | params_flow.rb:63:8:63:16 | synthetic splat argument | | params_flow.rb:63:14:63:15 | 26 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:63:14:63:15 | 26 | params_flow.rb:1:11:1:11 | x | @@ -5185,7 +4702,6 @@ trackEnd | params_flow.rb:64:17:64:17 | x | params_flow.rb:64:17:64:17 | x | | params_flow.rb:65:5:65:13 | call to sink | params_flow.rb:65:5:65:13 | call to sink | | params_flow.rb:65:5:65:13 | call to sink | params_flow.rb:67:1:67:17 | call to splatstuff | -| params_flow.rb:65:5:65:13 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:65:5:65:13 | synthetic splat argument | params_flow.rb:65:5:65:13 | synthetic splat argument | | params_flow.rb:65:10:65:13 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:65:10:65:13 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -5246,13 +4762,10 @@ trackEnd | params_flow.rb:69:27:69:27 | r | params_flow.rb:69:27:69:27 | r | | params_flow.rb:69:27:69:27 | r | params_flow.rb:75:10:75:10 | r | | params_flow.rb:70:5:70:10 | call to sink | params_flow.rb:70:5:70:10 | call to sink | -| params_flow.rb:70:5:70:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:70:5:70:10 | synthetic splat argument | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:71:5:71:10 | call to sink | params_flow.rb:71:5:71:10 | call to sink | -| params_flow.rb:71:5:71:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:71:5:71:10 | synthetic splat argument | params_flow.rb:71:5:71:10 | synthetic splat argument | | params_flow.rb:72:5:72:13 | call to sink | params_flow.rb:72:5:72:13 | call to sink | -| params_flow.rb:72:5:72:13 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:72:5:72:13 | synthetic splat argument | params_flow.rb:72:5:72:13 | synthetic splat argument | | params_flow.rb:72:10:72:13 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:72:10:72:13 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -5261,7 +4774,6 @@ trackEnd | params_flow.rb:72:10:72:13 | synthetic splat argument | params_flow.rb:72:10:72:13 | synthetic splat argument | | params_flow.rb:72:12:72:12 | 0 | params_flow.rb:72:12:72:12 | 0 | | params_flow.rb:73:5:73:13 | call to sink | params_flow.rb:73:5:73:13 | call to sink | -| params_flow.rb:73:5:73:13 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:73:5:73:13 | synthetic splat argument | params_flow.rb:73:5:73:13 | synthetic splat argument | | params_flow.rb:73:10:73:13 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:73:10:73:13 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -5270,13 +4782,11 @@ trackEnd | params_flow.rb:73:10:73:13 | synthetic splat argument | params_flow.rb:73:10:73:13 | synthetic splat argument | | params_flow.rb:73:12:73:12 | 1 | params_flow.rb:73:12:73:12 | 1 | | params_flow.rb:74:5:74:10 | call to sink | params_flow.rb:74:5:74:10 | call to sink | -| params_flow.rb:74:5:74:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:74:5:74:10 | synthetic splat argument | params_flow.rb:74:5:74:10 | synthetic splat argument | | params_flow.rb:75:5:75:10 | call to sink | params_flow.rb:75:5:75:10 | call to sink | | params_flow.rb:75:5:75:10 | call to sink | params_flow.rb:78:1:78:63 | call to splatmid | | params_flow.rb:75:5:75:10 | call to sink | params_flow.rb:81:1:81:37 | call to splatmid | | params_flow.rb:75:5:75:10 | call to sink | params_flow.rb:96:1:96:88 | call to splatmid | -| params_flow.rb:75:5:75:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:75:5:75:10 | synthetic splat argument | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:78:1:78:63 | call to splatmid | params_flow.rb:78:1:78:63 | call to splatmid | | params_flow.rb:78:1:78:63 | synthetic splat argument | params_flow.rb:69:1:76:3 | synthetic splat parameter | @@ -5288,7 +4798,6 @@ trackEnd | params_flow.rb:78:10:78:18 | call to taint | params_flow.rb:69:14:69:14 | x | | params_flow.rb:78:10:78:18 | call to taint | params_flow.rb:70:10:70:10 | x | | params_flow.rb:78:10:78:18 | call to taint | params_flow.rb:78:10:78:18 | call to taint | -| params_flow.rb:78:10:78:18 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:78:10:78:18 | synthetic splat argument | params_flow.rb:78:10:78:18 | synthetic splat argument | | params_flow.rb:78:16:78:17 | 27 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:16:78:17 | 27 | params_flow.rb:1:11:1:11 | x | @@ -5308,7 +4817,6 @@ trackEnd | params_flow.rb:78:21:78:29 | call to taint | params_flow.rb:69:17:69:17 | y | | params_flow.rb:78:21:78:29 | call to taint | params_flow.rb:71:10:71:10 | y | | params_flow.rb:78:21:78:29 | call to taint | params_flow.rb:78:21:78:29 | call to taint | -| params_flow.rb:78:21:78:29 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:78:21:78:29 | synthetic splat argument | params_flow.rb:78:21:78:29 | synthetic splat argument | | params_flow.rb:78:27:78:28 | 28 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:27:78:28 | 28 | params_flow.rb:1:11:1:11 | x | @@ -5322,7 +4830,6 @@ trackEnd | params_flow.rb:78:27:78:28 | 28 | params_flow.rb:78:21:78:29 | call to taint | | params_flow.rb:78:27:78:28 | 28 | params_flow.rb:78:27:78:28 | 28 | | params_flow.rb:78:32:78:40 | call to taint | params_flow.rb:78:32:78:40 | call to taint | -| params_flow.rb:78:32:78:40 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:78:32:78:40 | synthetic splat argument | params_flow.rb:78:32:78:40 | synthetic splat argument | | params_flow.rb:78:38:78:39 | 29 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:38:78:39 | 29 | params_flow.rb:1:11:1:11 | x | @@ -5336,7 +4843,6 @@ trackEnd | params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:69:24:69:24 | w | | params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:74:10:74:10 | w | | params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:78:43:78:51 | call to taint | -| params_flow.rb:78:43:78:51 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:78:43:78:51 | synthetic splat argument | params_flow.rb:78:43:78:51 | synthetic splat argument | | params_flow.rb:78:49:78:50 | 30 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:49:78:50 | 30 | params_flow.rb:1:11:1:11 | x | @@ -5356,7 +4862,6 @@ trackEnd | params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:69:27:69:27 | r | | params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:75:10:75:10 | r | | params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:78:54:78:62 | call to taint | -| params_flow.rb:78:54:78:62 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:78:54:78:62 | synthetic splat argument | params_flow.rb:78:54:78:62 | synthetic splat argument | | params_flow.rb:78:60:78:61 | 31 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:60:78:61 | 31 | params_flow.rb:1:11:1:11 | x | @@ -5399,7 +4904,6 @@ trackEnd | params_flow.rb:80:9:80:17 | call to taint | params_flow.rb:69:17:69:17 | y | | params_flow.rb:80:9:80:17 | call to taint | params_flow.rb:71:10:71:10 | y | | params_flow.rb:80:9:80:17 | call to taint | params_flow.rb:80:9:80:17 | call to taint | -| params_flow.rb:80:9:80:17 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:80:9:80:17 | synthetic splat argument | params_flow.rb:80:9:80:17 | synthetic splat argument | | params_flow.rb:80:15:80:16 | 33 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:80:15:80:16 | 33 | params_flow.rb:1:11:1:11 | x | @@ -5413,7 +4917,6 @@ trackEnd | params_flow.rb:80:15:80:16 | 33 | params_flow.rb:80:9:80:17 | call to taint | | params_flow.rb:80:15:80:16 | 33 | params_flow.rb:80:15:80:16 | 33 | | params_flow.rb:80:20:80:28 | call to taint | params_flow.rb:80:20:80:28 | call to taint | -| params_flow.rb:80:20:80:28 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:80:20:80:28 | synthetic splat argument | params_flow.rb:80:20:80:28 | synthetic splat argument | | params_flow.rb:80:26:80:27 | 34 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:80:26:80:27 | 34 | params_flow.rb:1:11:1:11 | x | @@ -5421,7 +4924,6 @@ trackEnd | params_flow.rb:80:26:80:27 | 34 | params_flow.rb:80:20:80:28 | call to taint | | params_flow.rb:80:26:80:27 | 34 | params_flow.rb:80:26:80:27 | 34 | | params_flow.rb:80:31:80:39 | call to taint | params_flow.rb:80:31:80:39 | call to taint | -| params_flow.rb:80:31:80:39 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:80:31:80:39 | synthetic splat argument | params_flow.rb:80:31:80:39 | synthetic splat argument | | params_flow.rb:80:37:80:38 | 35 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:80:37:80:38 | 35 | params_flow.rb:1:11:1:11 | x | @@ -5429,7 +4931,6 @@ trackEnd | params_flow.rb:80:37:80:38 | 35 | params_flow.rb:80:31:80:39 | call to taint | | params_flow.rb:80:37:80:38 | 35 | params_flow.rb:80:37:80:38 | 35 | | params_flow.rb:80:42:80:50 | call to taint | params_flow.rb:80:42:80:50 | call to taint | -| params_flow.rb:80:42:80:50 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:80:42:80:50 | synthetic splat argument | params_flow.rb:80:42:80:50 | synthetic splat argument | | params_flow.rb:80:48:80:49 | 36 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:80:48:80:49 | 36 | params_flow.rb:1:11:1:11 | x | @@ -5446,7 +4947,6 @@ trackEnd | params_flow.rb:81:10:81:18 | call to taint | params_flow.rb:69:14:69:14 | x | | params_flow.rb:81:10:81:18 | call to taint | params_flow.rb:70:10:70:10 | x | | params_flow.rb:81:10:81:18 | call to taint | params_flow.rb:81:10:81:18 | call to taint | -| params_flow.rb:81:10:81:18 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:81:10:81:18 | synthetic splat argument | params_flow.rb:81:10:81:18 | synthetic splat argument | | params_flow.rb:81:16:81:17 | 32 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:81:16:81:17 | 32 | params_flow.rb:1:11:1:11 | x | @@ -5461,7 +4961,6 @@ trackEnd | params_flow.rb:81:16:81:17 | 32 | params_flow.rb:81:16:81:17 | 32 | | params_flow.rb:81:21:81:25 | * ... | params_flow.rb:81:21:81:25 | * ... | | params_flow.rb:81:28:81:36 | call to taint | params_flow.rb:81:28:81:36 | call to taint | -| params_flow.rb:81:28:81:36 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:81:28:81:36 | synthetic splat argument | params_flow.rb:81:28:81:36 | synthetic splat argument | | params_flow.rb:81:34:81:35 | 37 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:81:34:81:35 | 37 | params_flow.rb:1:11:1:11 | x | @@ -5533,27 +5032,20 @@ trackEnd | params_flow.rb:83:32:83:32 | z | params_flow.rb:83:32:83:32 | z | | params_flow.rb:83:32:83:32 | z | params_flow.rb:90:10:90:10 | z | | params_flow.rb:84:5:84:10 | call to sink | params_flow.rb:84:5:84:10 | call to sink | -| params_flow.rb:84:5:84:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:84:5:84:10 | synthetic splat argument | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:85:5:85:10 | call to sink | params_flow.rb:85:5:85:10 | call to sink | -| params_flow.rb:85:5:85:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:85:5:85:10 | synthetic splat argument | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:86:5:86:10 | call to sink | params_flow.rb:86:5:86:10 | call to sink | -| params_flow.rb:86:5:86:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:86:5:86:10 | synthetic splat argument | params_flow.rb:86:5:86:10 | synthetic splat argument | | params_flow.rb:87:5:87:10 | call to sink | params_flow.rb:87:5:87:10 | call to sink | -| params_flow.rb:87:5:87:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:87:5:87:10 | synthetic splat argument | params_flow.rb:87:5:87:10 | synthetic splat argument | | params_flow.rb:88:5:88:10 | call to sink | params_flow.rb:88:5:88:10 | call to sink | -| params_flow.rb:88:5:88:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:88:5:88:10 | synthetic splat argument | params_flow.rb:88:5:88:10 | synthetic splat argument | | params_flow.rb:89:5:89:10 | call to sink | params_flow.rb:89:5:89:10 | call to sink | -| params_flow.rb:89:5:89:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:89:5:89:10 | synthetic splat argument | params_flow.rb:89:5:89:10 | synthetic splat argument | | params_flow.rb:90:5:90:10 | call to sink | params_flow.rb:90:5:90:10 | call to sink | | params_flow.rb:90:5:90:10 | call to sink | params_flow.rb:94:1:94:48 | call to pos_many | | params_flow.rb:90:5:90:10 | call to sink | params_flow.rb:131:1:131:46 | call to pos_many | -| params_flow.rb:90:5:90:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:90:5:90:10 | synthetic splat argument | params_flow.rb:90:5:90:10 | synthetic splat argument | | params_flow.rb:93:1:93:4 | args | params_flow.rb:93:1:93:4 | args | | params_flow.rb:93:8:93:51 | Array | params_flow.rb:93:8:93:51 | Array | @@ -5585,7 +5077,6 @@ trackEnd | params_flow.rb:93:9:93:17 | call to taint | params_flow.rb:83:20:83:20 | v | | params_flow.rb:93:9:93:17 | call to taint | params_flow.rb:86:10:86:10 | v | | params_flow.rb:93:9:93:17 | call to taint | params_flow.rb:93:9:93:17 | call to taint | -| params_flow.rb:93:9:93:17 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:93:9:93:17 | synthetic splat argument | params_flow.rb:93:9:93:17 | synthetic splat argument | | params_flow.rb:93:15:93:16 | 40 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:93:15:93:16 | 40 | params_flow.rb:1:11:1:11 | x | @@ -5605,7 +5096,6 @@ trackEnd | params_flow.rb:93:20:93:28 | call to taint | params_flow.rb:83:23:83:23 | w | | params_flow.rb:93:20:93:28 | call to taint | params_flow.rb:87:10:87:10 | w | | params_flow.rb:93:20:93:28 | call to taint | params_flow.rb:93:20:93:28 | call to taint | -| params_flow.rb:93:20:93:28 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:93:20:93:28 | synthetic splat argument | params_flow.rb:93:20:93:28 | synthetic splat argument | | params_flow.rb:93:26:93:27 | 41 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:93:26:93:27 | 41 | params_flow.rb:1:11:1:11 | x | @@ -5625,7 +5115,6 @@ trackEnd | params_flow.rb:93:31:93:39 | call to taint | params_flow.rb:83:26:83:26 | x | | params_flow.rb:93:31:93:39 | call to taint | params_flow.rb:88:10:88:10 | x | | params_flow.rb:93:31:93:39 | call to taint | params_flow.rb:93:31:93:39 | call to taint | -| params_flow.rb:93:31:93:39 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:93:31:93:39 | synthetic splat argument | params_flow.rb:93:31:93:39 | synthetic splat argument | | params_flow.rb:93:37:93:38 | 42 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:93:37:93:38 | 42 | params_flow.rb:1:11:1:11 | x | @@ -5645,7 +5134,6 @@ trackEnd | params_flow.rb:93:42:93:50 | call to taint | params_flow.rb:83:29:83:29 | y | | params_flow.rb:93:42:93:50 | call to taint | params_flow.rb:89:10:89:10 | y | | params_flow.rb:93:42:93:50 | call to taint | params_flow.rb:93:42:93:50 | call to taint | -| params_flow.rb:93:42:93:50 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:93:42:93:50 | synthetic splat argument | params_flow.rb:93:42:93:50 | synthetic splat argument | | params_flow.rb:93:48:93:49 | 43 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:93:48:93:49 | 43 | params_flow.rb:1:11:1:11 | x | @@ -5668,7 +5156,6 @@ trackEnd | params_flow.rb:94:10:94:18 | call to taint | params_flow.rb:83:14:83:14 | t | | params_flow.rb:94:10:94:18 | call to taint | params_flow.rb:84:10:84:10 | t | | params_flow.rb:94:10:94:18 | call to taint | params_flow.rb:94:10:94:18 | call to taint | -| params_flow.rb:94:10:94:18 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:94:10:94:18 | synthetic splat argument | params_flow.rb:94:10:94:18 | synthetic splat argument | | params_flow.rb:94:16:94:17 | 38 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:94:16:94:17 | 38 | params_flow.rb:1:11:1:11 | x | @@ -5688,7 +5175,6 @@ trackEnd | params_flow.rb:94:21:94:29 | call to taint | params_flow.rb:83:17:83:17 | u | | params_flow.rb:94:21:94:29 | call to taint | params_flow.rb:85:10:85:10 | u | | params_flow.rb:94:21:94:29 | call to taint | params_flow.rb:94:21:94:29 | call to taint | -| params_flow.rb:94:21:94:29 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:94:21:94:29 | synthetic splat argument | params_flow.rb:94:21:94:29 | synthetic splat argument | | params_flow.rb:94:27:94:28 | 39 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:94:27:94:28 | 39 | params_flow.rb:1:11:1:11 | x | @@ -5709,7 +5195,6 @@ trackEnd | params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:83:23:83:23 | w | | params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:87:10:87:10 | w | | params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:94:39:94:47 | call to taint | -| params_flow.rb:94:39:94:47 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:94:39:94:47 | synthetic splat argument | params_flow.rb:94:39:94:47 | synthetic splat argument | | params_flow.rb:94:45:94:46 | 44 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:94:45:94:46 | 44 | params_flow.rb:1:11:1:11 | x | @@ -5732,7 +5217,6 @@ trackEnd | params_flow.rb:96:10:96:18 | call to taint | params_flow.rb:69:14:69:14 | x | | params_flow.rb:96:10:96:18 | call to taint | params_flow.rb:70:10:70:10 | x | | params_flow.rb:96:10:96:18 | call to taint | params_flow.rb:96:10:96:18 | call to taint | -| params_flow.rb:96:10:96:18 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:96:10:96:18 | synthetic splat argument | params_flow.rb:96:10:96:18 | synthetic splat argument | | params_flow.rb:96:16:96:17 | 45 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:16:96:17 | 45 | params_flow.rb:1:11:1:11 | x | @@ -5752,7 +5236,6 @@ trackEnd | params_flow.rb:96:21:96:29 | call to taint | params_flow.rb:69:17:69:17 | y | | params_flow.rb:96:21:96:29 | call to taint | params_flow.rb:71:10:71:10 | y | | params_flow.rb:96:21:96:29 | call to taint | params_flow.rb:96:21:96:29 | call to taint | -| params_flow.rb:96:21:96:29 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:96:21:96:29 | synthetic splat argument | params_flow.rb:96:21:96:29 | synthetic splat argument | | params_flow.rb:96:27:96:28 | 46 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:27:96:28 | 46 | params_flow.rb:1:11:1:11 | x | @@ -5771,7 +5254,6 @@ trackEnd | params_flow.rb:96:33:96:65 | synthetic splat argument | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:33:96:65 | synthetic splat argument | params_flow.rb:96:33:96:65 | synthetic splat argument | | params_flow.rb:96:34:96:42 | call to taint | params_flow.rb:96:34:96:42 | call to taint | -| params_flow.rb:96:34:96:42 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:96:34:96:42 | synthetic splat argument | params_flow.rb:96:34:96:42 | synthetic splat argument | | params_flow.rb:96:40:96:41 | 47 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:40:96:41 | 47 | params_flow.rb:1:11:1:11 | x | @@ -5779,7 +5261,6 @@ trackEnd | params_flow.rb:96:40:96:41 | 47 | params_flow.rb:96:34:96:42 | call to taint | | params_flow.rb:96:40:96:41 | 47 | params_flow.rb:96:40:96:41 | 47 | | params_flow.rb:96:45:96:53 | call to taint | params_flow.rb:96:45:96:53 | call to taint | -| params_flow.rb:96:45:96:53 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:96:45:96:53 | synthetic splat argument | params_flow.rb:96:45:96:53 | synthetic splat argument | | params_flow.rb:96:51:96:52 | 48 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:51:96:52 | 48 | params_flow.rb:1:11:1:11 | x | @@ -5787,7 +5268,6 @@ trackEnd | params_flow.rb:96:51:96:52 | 48 | params_flow.rb:96:45:96:53 | call to taint | | params_flow.rb:96:51:96:52 | 48 | params_flow.rb:96:51:96:52 | 48 | | params_flow.rb:96:56:96:64 | call to taint | params_flow.rb:96:56:96:64 | call to taint | -| params_flow.rb:96:56:96:64 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:96:56:96:64 | synthetic splat argument | params_flow.rb:96:56:96:64 | synthetic splat argument | | params_flow.rb:96:62:96:63 | 49 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:62:96:63 | 49 | params_flow.rb:1:11:1:11 | x | @@ -5801,7 +5281,6 @@ trackEnd | params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:69:24:69:24 | w | | params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:74:10:74:10 | w | | params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:96:68:96:76 | call to taint | -| params_flow.rb:96:68:96:76 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:96:68:96:76 | synthetic splat argument | params_flow.rb:96:68:96:76 | synthetic splat argument | | params_flow.rb:96:74:96:75 | 50 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:74:96:75 | 50 | params_flow.rb:1:11:1:11 | x | @@ -5821,7 +5300,6 @@ trackEnd | params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:69:27:69:27 | r | | params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:75:10:75:10 | r | | params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:96:79:96:87 | call to taint | -| params_flow.rb:96:79:96:87 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:96:79:96:87 | synthetic splat argument | params_flow.rb:96:79:96:87 | synthetic splat argument | | params_flow.rb:96:85:96:86 | 51 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:85:96:86 | 51 | params_flow.rb:1:11:1:11 | x | @@ -5866,10 +5344,8 @@ trackEnd | params_flow.rb:98:31:98:31 | b | params_flow.rb:98:31:98:31 | b | | params_flow.rb:98:31:98:31 | b | params_flow.rb:102:10:102:10 | b | | params_flow.rb:99:5:99:10 | call to sink | params_flow.rb:99:5:99:10 | call to sink | -| params_flow.rb:99:5:99:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:99:5:99:10 | synthetic splat argument | params_flow.rb:99:5:99:10 | synthetic splat argument | | params_flow.rb:100:5:100:18 | call to sink | params_flow.rb:100:5:100:18 | call to sink | -| params_flow.rb:100:5:100:18 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:100:5:100:18 | synthetic splat argument | params_flow.rb:100:5:100:18 | synthetic splat argument | | params_flow.rb:100:10:100:18 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:100:10:100:18 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -5878,7 +5354,6 @@ trackEnd | params_flow.rb:100:10:100:18 | synthetic splat argument | params_flow.rb:100:10:100:18 | synthetic splat argument | | params_flow.rb:100:17:100:17 | 0 | params_flow.rb:100:17:100:17 | 0 | | params_flow.rb:101:5:101:18 | call to sink | params_flow.rb:101:5:101:18 | call to sink | -| params_flow.rb:101:5:101:18 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:101:5:101:18 | synthetic splat argument | params_flow.rb:101:5:101:18 | synthetic splat argument | | params_flow.rb:101:10:101:18 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:101:10:101:18 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -5889,7 +5364,6 @@ trackEnd | params_flow.rb:102:5:102:10 | call to sink | params_flow.rb:102:5:102:10 | call to sink | | params_flow.rb:102:5:102:10 | call to sink | params_flow.rb:105:1:105:49 | call to splatmidsmall | | params_flow.rb:102:5:102:10 | call to sink | params_flow.rb:106:1:106:46 | call to splatmidsmall | -| params_flow.rb:102:5:102:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:102:5:102:10 | synthetic splat argument | params_flow.rb:102:5:102:10 | synthetic splat argument | | params_flow.rb:105:1:105:49 | call to splatmidsmall | params_flow.rb:105:1:105:49 | call to splatmidsmall | | params_flow.rb:105:1:105:49 | synthetic splat argument | params_flow.rb:98:1:103:3 | synthetic splat parameter | @@ -5901,7 +5375,6 @@ trackEnd | params_flow.rb:105:15:105:23 | call to taint | params_flow.rb:98:19:98:19 | a | | params_flow.rb:105:15:105:23 | call to taint | params_flow.rb:99:10:99:10 | a | | params_flow.rb:105:15:105:23 | call to taint | params_flow.rb:105:15:105:23 | call to taint | -| params_flow.rb:105:15:105:23 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:105:15:105:23 | synthetic splat argument | params_flow.rb:105:15:105:23 | synthetic splat argument | | params_flow.rb:105:21:105:22 | 52 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:105:21:105:22 | 52 | params_flow.rb:1:11:1:11 | x | @@ -5920,7 +5393,6 @@ trackEnd | params_flow.rb:105:27:105:48 | synthetic splat argument | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:105:27:105:48 | synthetic splat argument | params_flow.rb:105:27:105:48 | synthetic splat argument | | params_flow.rb:105:28:105:36 | call to taint | params_flow.rb:105:28:105:36 | call to taint | -| params_flow.rb:105:28:105:36 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:105:28:105:36 | synthetic splat argument | params_flow.rb:105:28:105:36 | synthetic splat argument | | params_flow.rb:105:34:105:35 | 53 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:105:34:105:35 | 53 | params_flow.rb:1:11:1:11 | x | @@ -5928,7 +5400,6 @@ trackEnd | params_flow.rb:105:34:105:35 | 53 | params_flow.rb:105:28:105:36 | call to taint | | params_flow.rb:105:34:105:35 | 53 | params_flow.rb:105:34:105:35 | 53 | | params_flow.rb:105:39:105:47 | call to taint | params_flow.rb:105:39:105:47 | call to taint | -| params_flow.rb:105:39:105:47 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:105:39:105:47 | synthetic splat argument | params_flow.rb:105:39:105:47 | synthetic splat argument | | params_flow.rb:105:45:105:46 | 54 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:105:45:105:46 | 54 | params_flow.rb:1:11:1:11 | x | @@ -5945,7 +5416,6 @@ trackEnd | params_flow.rb:106:15:106:23 | call to taint | params_flow.rb:98:19:98:19 | a | | params_flow.rb:106:15:106:23 | call to taint | params_flow.rb:99:10:99:10 | a | | params_flow.rb:106:15:106:23 | call to taint | params_flow.rb:106:15:106:23 | call to taint | -| params_flow.rb:106:15:106:23 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:106:15:106:23 | synthetic splat argument | params_flow.rb:106:15:106:23 | synthetic splat argument | | params_flow.rb:106:21:106:22 | 55 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:106:21:106:22 | 55 | params_flow.rb:1:11:1:11 | x | @@ -5959,7 +5429,6 @@ trackEnd | params_flow.rb:106:21:106:22 | 55 | params_flow.rb:106:15:106:23 | call to taint | | params_flow.rb:106:21:106:22 | 55 | params_flow.rb:106:21:106:22 | 55 | | params_flow.rb:106:26:106:34 | call to taint | params_flow.rb:106:26:106:34 | call to taint | -| params_flow.rb:106:26:106:34 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:106:26:106:34 | synthetic splat argument | params_flow.rb:106:26:106:34 | synthetic splat argument | | params_flow.rb:106:32:106:33 | 56 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:106:32:106:33 | 56 | params_flow.rb:1:11:1:11 | x | @@ -5973,7 +5442,6 @@ trackEnd | params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:98:31:98:31 | b | | params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:102:10:102:10 | b | | params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:106:37:106:45 | call to taint | -| params_flow.rb:106:37:106:45 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:106:37:106:45 | synthetic splat argument | params_flow.rb:106:37:106:45 | synthetic splat argument | | params_flow.rb:106:43:106:44 | 57 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:106:43:106:44 | 57 | params_flow.rb:1:11:1:11 | x | @@ -6017,10 +5485,8 @@ trackEnd | params_flow.rb:108:44:108:44 | c | params_flow.rb:108:44:108:44 | c | | params_flow.rb:108:44:108:44 | c | params_flow.rb:111:10:111:10 | c | | params_flow.rb:109:5:109:10 | call to sink | params_flow.rb:109:5:109:10 | call to sink | -| params_flow.rb:109:5:109:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:109:5:109:10 | synthetic splat argument | params_flow.rb:109:5:109:10 | synthetic splat argument | | params_flow.rb:110:5:110:13 | call to sink | params_flow.rb:110:5:110:13 | call to sink | -| params_flow.rb:110:5:110:13 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:110:5:110:13 | synthetic splat argument | params_flow.rb:110:5:110:13 | synthetic splat argument | | params_flow.rb:110:10:110:13 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:110:10:110:13 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6030,7 +5496,6 @@ trackEnd | params_flow.rb:110:12:110:12 | 0 | params_flow.rb:110:12:110:12 | 0 | | params_flow.rb:111:5:111:10 | call to sink | params_flow.rb:111:5:111:10 | call to sink | | params_flow.rb:111:5:111:10 | call to sink | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | -| params_flow.rb:111:5:111:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:111:5:111:10 | synthetic splat argument | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | @@ -6044,7 +5509,6 @@ trackEnd | params_flow.rb:114:33:114:41 | call to taint | params_flow.rb:108:37:108:37 | a | | params_flow.rb:114:33:114:41 | call to taint | params_flow.rb:109:10:109:10 | a | | params_flow.rb:114:33:114:41 | call to taint | params_flow.rb:114:33:114:41 | call to taint | -| params_flow.rb:114:33:114:41 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:114:33:114:41 | synthetic splat argument | params_flow.rb:114:33:114:41 | synthetic splat argument | | params_flow.rb:114:39:114:40 | 58 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:114:39:114:40 | 58 | params_flow.rb:1:11:1:11 | x | @@ -6062,7 +5526,6 @@ trackEnd | params_flow.rb:114:44:114:52 | call to taint | params_flow.rb:6:10:6:10 | x | | params_flow.rb:114:44:114:52 | call to taint | params_flow.rb:110:10:110:13 | ...[...] | | params_flow.rb:114:44:114:52 | call to taint | params_flow.rb:114:44:114:52 | call to taint | -| params_flow.rb:114:44:114:52 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:114:44:114:52 | synthetic splat argument | params_flow.rb:114:44:114:52 | synthetic splat argument | | params_flow.rb:114:50:114:51 | 59 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:114:50:114:51 | 59 | params_flow.rb:1:11:1:11 | x | @@ -6082,7 +5545,6 @@ trackEnd | params_flow.rb:114:58:114:66 | call to taint | params_flow.rb:108:44:108:44 | c | | params_flow.rb:114:58:114:66 | call to taint | params_flow.rb:111:10:111:10 | c | | params_flow.rb:114:58:114:66 | call to taint | params_flow.rb:114:58:114:66 | call to taint | -| params_flow.rb:114:58:114:66 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:114:58:114:66 | synthetic splat argument | params_flow.rb:114:58:114:66 | synthetic splat argument | | params_flow.rb:114:64:114:65 | 60 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:114:64:114:65 | 60 | params_flow.rb:1:11:1:11 | x | @@ -6134,7 +5596,6 @@ trackEnd | params_flow.rb:117:19:117:27 | call to taint | params_flow.rb:117:19:117:27 | ... = ... | | params_flow.rb:117:19:117:27 | call to taint | params_flow.rb:117:19:117:27 | __synth__0 | | params_flow.rb:117:19:117:27 | call to taint | params_flow.rb:117:19:117:27 | call to taint | -| params_flow.rb:117:19:117:27 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:117:19:117:27 | synthetic splat argument | params_flow.rb:117:19:117:27 | synthetic splat argument | | params_flow.rb:117:25:117:26 | 61 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:117:25:117:26 | 61 | params_flow.rb:1:11:1:11 | x | @@ -6200,20 +5661,15 @@ trackEnd | params_flow.rb:120:27:120:27 | e | params_flow.rb:120:27:120:27 | e | | params_flow.rb:120:27:120:27 | e | params_flow.rb:125:10:125:10 | e | | params_flow.rb:121:5:121:10 | call to sink | params_flow.rb:121:5:121:10 | call to sink | -| params_flow.rb:121:5:121:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:121:5:121:10 | synthetic splat argument | params_flow.rb:121:5:121:10 | synthetic splat argument | | params_flow.rb:122:5:122:10 | call to sink | params_flow.rb:122:5:122:10 | call to sink | -| params_flow.rb:122:5:122:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:122:5:122:10 | synthetic splat argument | params_flow.rb:122:5:122:10 | synthetic splat argument | | params_flow.rb:123:5:123:10 | call to sink | params_flow.rb:123:5:123:10 | call to sink | -| params_flow.rb:123:5:123:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:123:5:123:10 | synthetic splat argument | params_flow.rb:123:5:123:10 | synthetic splat argument | | params_flow.rb:124:5:124:10 | call to sink | params_flow.rb:124:5:124:10 | call to sink | -| params_flow.rb:124:5:124:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:124:5:124:10 | synthetic splat argument | params_flow.rb:124:5:124:10 | synthetic splat argument | | params_flow.rb:125:5:125:10 | call to sink | params_flow.rb:125:5:125:10 | call to sink | | params_flow.rb:125:5:125:10 | call to sink | params_flow.rb:128:1:128:61 | call to destruct | -| params_flow.rb:125:5:125:10 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:125:5:125:10 | synthetic splat argument | params_flow.rb:125:5:125:10 | synthetic splat argument | | params_flow.rb:128:1:128:61 | call to destruct | params_flow.rb:128:1:128:61 | call to destruct | | params_flow.rb:128:1:128:61 | synthetic splat argument | params_flow.rb:128:1:128:61 | synthetic splat argument | @@ -6222,7 +5678,6 @@ trackEnd | params_flow.rb:128:10:128:31 | synthetic splat argument | params_flow.rb:128:10:128:31 | call to [] | | params_flow.rb:128:10:128:31 | synthetic splat argument | params_flow.rb:128:10:128:31 | synthetic splat argument | | params_flow.rb:128:11:128:19 | call to taint | params_flow.rb:128:11:128:19 | call to taint | -| params_flow.rb:128:11:128:19 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:11:128:19 | synthetic splat argument | params_flow.rb:128:11:128:19 | synthetic splat argument | | params_flow.rb:128:17:128:18 | 62 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:128:17:128:18 | 62 | params_flow.rb:1:11:1:11 | x | @@ -6230,7 +5685,6 @@ trackEnd | params_flow.rb:128:17:128:18 | 62 | params_flow.rb:128:11:128:19 | call to taint | | params_flow.rb:128:17:128:18 | 62 | params_flow.rb:128:17:128:18 | 62 | | params_flow.rb:128:22:128:30 | call to taint | params_flow.rb:128:22:128:30 | call to taint | -| params_flow.rb:128:22:128:30 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:22:128:30 | synthetic splat argument | params_flow.rb:128:22:128:30 | synthetic splat argument | | params_flow.rb:128:28:128:29 | 63 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:128:28:128:29 | 63 | params_flow.rb:1:11:1:11 | x | @@ -6242,7 +5696,6 @@ trackEnd | params_flow.rb:128:34:128:60 | synthetic splat argument | params_flow.rb:128:34:128:60 | call to [] | | params_flow.rb:128:34:128:60 | synthetic splat argument | params_flow.rb:128:34:128:60 | synthetic splat argument | | params_flow.rb:128:35:128:43 | call to taint | params_flow.rb:128:35:128:43 | call to taint | -| params_flow.rb:128:35:128:43 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:35:128:43 | synthetic splat argument | params_flow.rb:128:35:128:43 | synthetic splat argument | | params_flow.rb:128:41:128:42 | 64 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:128:41:128:42 | 64 | params_flow.rb:1:11:1:11 | x | @@ -6255,7 +5708,6 @@ trackEnd | params_flow.rb:128:46:128:59 | synthetic splat argument | params_flow.rb:128:46:128:59 | synthetic splat argument | | params_flow.rb:128:47:128:47 | 0 | params_flow.rb:128:47:128:47 | 0 | | params_flow.rb:128:50:128:58 | call to taint | params_flow.rb:128:50:128:58 | call to taint | -| params_flow.rb:128:50:128:58 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:128:50:128:58 | synthetic splat argument | params_flow.rb:128:50:128:58 | synthetic splat argument | | params_flow.rb:128:56:128:57 | 65 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:128:56:128:57 | 65 | params_flow.rb:1:11:1:11 | x | @@ -6292,7 +5744,6 @@ trackEnd | params_flow.rb:130:9:130:17 | call to taint | params_flow.rb:83:14:83:14 | t | | params_flow.rb:130:9:130:17 | call to taint | params_flow.rb:84:10:84:10 | t | | params_flow.rb:130:9:130:17 | call to taint | params_flow.rb:130:9:130:17 | call to taint | -| params_flow.rb:130:9:130:17 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:130:9:130:17 | synthetic splat argument | params_flow.rb:130:9:130:17 | synthetic splat argument | | params_flow.rb:130:15:130:16 | 66 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:130:15:130:16 | 66 | params_flow.rb:1:11:1:11 | x | @@ -6312,7 +5763,6 @@ trackEnd | params_flow.rb:130:20:130:28 | call to taint | params_flow.rb:83:17:83:17 | u | | params_flow.rb:130:20:130:28 | call to taint | params_flow.rb:85:10:85:10 | u | | params_flow.rb:130:20:130:28 | call to taint | params_flow.rb:130:20:130:28 | call to taint | -| params_flow.rb:130:20:130:28 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:130:20:130:28 | synthetic splat argument | params_flow.rb:130:20:130:28 | synthetic splat argument | | params_flow.rb:130:26:130:27 | 67 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:130:26:130:27 | 67 | params_flow.rb:1:11:1:11 | x | @@ -6335,7 +5785,6 @@ trackEnd | params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:83:17:83:17 | u | | params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:85:10:85:10 | u | | params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:131:17:131:25 | call to taint | -| params_flow.rb:131:17:131:25 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:131:17:131:25 | synthetic splat argument | params_flow.rb:131:17:131:25 | synthetic splat argument | | params_flow.rb:131:23:131:24 | 68 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:131:23:131:24 | 68 | params_flow.rb:1:11:1:11 | x | @@ -6390,7 +5839,6 @@ trackEnd | params_flow.rb:133:15:133:18 | args | params_flow.rb:133:15:133:18 | args | | params_flow.rb:134:5:134:16 | call to sink | params_flow.rb:134:5:134:16 | call to sink | | params_flow.rb:134:5:134:16 | call to sink | params_flow.rb:137:1:137:44 | call to splatall | -| params_flow.rb:134:5:134:16 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:134:5:134:16 | synthetic splat argument | params_flow.rb:134:5:134:16 | synthetic splat argument | | params_flow.rb:134:10:134:16 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:134:10:134:16 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6408,7 +5856,6 @@ trackEnd | params_flow.rb:137:11:137:43 | synthetic splat argument | params_flow.rb:137:11:137:43 | call to [] | | params_flow.rb:137:11:137:43 | synthetic splat argument | params_flow.rb:137:11:137:43 | synthetic splat argument | | params_flow.rb:137:12:137:20 | call to taint | params_flow.rb:137:12:137:20 | call to taint | -| params_flow.rb:137:12:137:20 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:137:12:137:20 | synthetic splat argument | params_flow.rb:137:12:137:20 | synthetic splat argument | | params_flow.rb:137:18:137:19 | 69 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:137:18:137:19 | 69 | params_flow.rb:1:11:1:11 | x | @@ -6420,7 +5867,6 @@ trackEnd | params_flow.rb:137:23:137:31 | call to taint | params_flow.rb:6:10:6:10 | x | | params_flow.rb:137:23:137:31 | call to taint | params_flow.rb:134:10:134:16 | ...[...] | | params_flow.rb:137:23:137:31 | call to taint | params_flow.rb:137:23:137:31 | call to taint | -| params_flow.rb:137:23:137:31 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:137:23:137:31 | synthetic splat argument | params_flow.rb:137:23:137:31 | synthetic splat argument | | params_flow.rb:137:29:137:30 | 70 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:137:29:137:30 | 70 | params_flow.rb:1:11:1:11 | x | @@ -6432,7 +5878,6 @@ trackEnd | params_flow.rb:137:29:137:30 | 70 | params_flow.rb:137:23:137:31 | call to taint | | params_flow.rb:137:29:137:30 | 70 | params_flow.rb:137:29:137:30 | 70 | | params_flow.rb:137:34:137:42 | call to taint | params_flow.rb:137:34:137:42 | call to taint | -| params_flow.rb:137:34:137:42 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:137:34:137:42 | synthetic splat argument | params_flow.rb:137:34:137:42 | synthetic splat argument | | params_flow.rb:137:40:137:41 | 71 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:137:40:137:41 | 71 | params_flow.rb:1:11:1:11 | x | @@ -6485,7 +5930,6 @@ trackEnd | params_flow.rb:143:20:143:32 | Pair | params_flow.rb:143:20:143:32 | Pair | | params_flow.rb:143:24:143:32 | call to taint | params_flow.rb:140:27:140:37 | ...[...] | | params_flow.rb:143:24:143:32 | call to taint | params_flow.rb:143:24:143:32 | call to taint | -| params_flow.rb:143:24:143:32 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:143:24:143:32 | synthetic splat argument | params_flow.rb:143:24:143:32 | synthetic splat argument | | params_flow.rb:143:30:143:31 | 72 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:143:30:143:31 | 72 | params_flow.rb:1:11:1:11 | x | @@ -6494,7 +5938,6 @@ trackEnd | params_flow.rb:143:30:143:31 | 72 | params_flow.rb:143:24:143:32 | call to taint | | params_flow.rb:143:30:143:31 | 72 | params_flow.rb:143:30:143:31 | 72 | | params_flow.rb:144:1:144:20 | call to sink | params_flow.rb:144:1:144:20 | call to sink | -| params_flow.rb:144:1:144:20 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:144:1:144:20 | synthetic splat argument | params_flow.rb:144:1:144:20 | synthetic splat argument | | params_flow.rb:144:6:144:16 | ...[...] | params_flow.rb:144:6:144:16 | ...[...] | | params_flow.rb:144:6:144:16 | synthetic splat argument | params_flow.rb:144:6:144:16 | synthetic splat argument | @@ -6512,7 +5955,6 @@ trackEnd | params_flow.rb:145:21:145:28 | ** ... | params_flow.rb:140:27:140:32 | kwargs | | params_flow.rb:145:21:145:28 | ** ... | params_flow.rb:145:21:145:28 | ** ... | | params_flow.rb:146:1:146:20 | call to sink | params_flow.rb:146:1:146:20 | call to sink | -| params_flow.rb:146:1:146:20 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:146:1:146:20 | synthetic splat argument | params_flow.rb:146:1:146:20 | synthetic splat argument | | params_flow.rb:146:6:146:16 | ...[...] | params_flow.rb:146:6:146:16 | ...[...] | | params_flow.rb:146:6:146:16 | synthetic splat argument | params_flow.rb:146:6:146:16 | synthetic splat argument | @@ -6533,7 +5975,6 @@ trackEnd | params_flow.rb:148:6:148:7 | call to [] | params_flow.rb:150:25:150:26 | p1 | | params_flow.rb:148:6:148:7 | call to [] | params_flow.rb:151:6:151:7 | p1 | | params_flow.rb:149:1:149:11 | call to sink | params_flow.rb:149:1:149:11 | call to sink | -| params_flow.rb:149:1:149:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:149:1:149:11 | synthetic splat argument | params_flow.rb:149:1:149:11 | synthetic splat argument | | params_flow.rb:149:6:149:10 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:149:6:149:10 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6553,7 +5994,6 @@ trackEnd | params_flow.rb:150:29:150:41 | Pair | params_flow.rb:150:29:150:41 | Pair | | params_flow.rb:150:33:150:41 | call to taint | params_flow.rb:140:27:140:37 | ...[...] | | params_flow.rb:150:33:150:41 | call to taint | params_flow.rb:150:33:150:41 | call to taint | -| params_flow.rb:150:33:150:41 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:150:33:150:41 | synthetic splat argument | params_flow.rb:150:33:150:41 | synthetic splat argument | | params_flow.rb:150:39:150:40 | 73 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:150:39:150:40 | 73 | params_flow.rb:1:11:1:11 | x | @@ -6562,7 +6002,6 @@ trackEnd | params_flow.rb:150:39:150:40 | 73 | params_flow.rb:150:33:150:41 | call to taint | | params_flow.rb:150:39:150:40 | 73 | params_flow.rb:150:39:150:40 | 73 | | params_flow.rb:151:1:151:11 | call to sink | params_flow.rb:151:1:151:11 | call to sink | -| params_flow.rb:151:1:151:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:151:1:151:11 | synthetic splat argument | params_flow.rb:151:1:151:11 | synthetic splat argument | | params_flow.rb:151:6:151:10 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:151:6:151:10 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6618,7 +6057,6 @@ trackEnd | params_flow.rb:157:24:157:32 | call to taint | params_flow.rb:153:28:153:29 | p2 | | params_flow.rb:157:24:157:32 | call to taint | params_flow.rb:154:18:154:19 | p2 | | params_flow.rb:157:24:157:32 | call to taint | params_flow.rb:157:24:157:32 | call to taint | -| params_flow.rb:157:24:157:32 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:157:24:157:32 | synthetic splat argument | params_flow.rb:157:24:157:32 | synthetic splat argument | | params_flow.rb:157:30:157:31 | 74 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:157:30:157:31 | 74 | params_flow.rb:1:11:1:11 | x | @@ -6629,7 +6067,6 @@ trackEnd | params_flow.rb:157:30:157:31 | 74 | params_flow.rb:157:24:157:32 | call to taint | | params_flow.rb:157:30:157:31 | 74 | params_flow.rb:157:30:157:31 | 74 | | params_flow.rb:158:1:158:20 | call to sink | params_flow.rb:158:1:158:20 | call to sink | -| params_flow.rb:158:1:158:20 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:158:1:158:20 | synthetic splat argument | params_flow.rb:158:1:158:20 | synthetic splat argument | | params_flow.rb:158:6:158:16 | ...[...] | params_flow.rb:158:6:158:16 | ...[...] | | params_flow.rb:158:6:158:16 | synthetic splat argument | params_flow.rb:158:6:158:16 | synthetic splat argument | @@ -6644,7 +6081,6 @@ trackEnd | params_flow.rb:159:19:159:26 | ** ... | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:159:19:159:26 | ** ... | params_flow.rb:159:19:159:26 | ** ... | | params_flow.rb:160:1:160:20 | call to sink | params_flow.rb:160:1:160:20 | call to sink | -| params_flow.rb:160:1:160:20 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:160:1:160:20 | synthetic splat argument | params_flow.rb:160:1:160:20 | synthetic splat argument | | params_flow.rb:160:6:160:16 | ...[...] | params_flow.rb:160:6:160:16 | ...[...] | | params_flow.rb:160:6:160:16 | synthetic splat argument | params_flow.rb:160:6:160:16 | synthetic splat argument | @@ -6667,7 +6103,6 @@ trackEnd | params_flow.rb:162:6:162:7 | call to [] | params_flow.rb:164:23:164:24 | p1 | | params_flow.rb:162:6:162:7 | call to [] | params_flow.rb:165:6:165:7 | p1 | | params_flow.rb:163:1:163:11 | call to sink | params_flow.rb:163:1:163:11 | call to sink | -| params_flow.rb:163:1:163:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:163:1:163:11 | synthetic splat argument | params_flow.rb:163:1:163:11 | synthetic splat argument | | params_flow.rb:163:6:163:10 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:163:6:163:10 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6686,7 +6121,6 @@ trackEnd | params_flow.rb:164:31:164:39 | call to taint | params_flow.rb:153:28:153:29 | p2 | | params_flow.rb:164:31:164:39 | call to taint | params_flow.rb:154:18:154:19 | p2 | | params_flow.rb:164:31:164:39 | call to taint | params_flow.rb:164:31:164:39 | call to taint | -| params_flow.rb:164:31:164:39 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:164:31:164:39 | synthetic splat argument | params_flow.rb:164:31:164:39 | synthetic splat argument | | params_flow.rb:164:37:164:38 | 75 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:164:37:164:38 | 75 | params_flow.rb:1:11:1:11 | x | @@ -6697,7 +6131,6 @@ trackEnd | params_flow.rb:164:37:164:38 | 75 | params_flow.rb:164:31:164:39 | call to taint | | params_flow.rb:164:37:164:38 | 75 | params_flow.rb:164:37:164:38 | 75 | | params_flow.rb:165:1:165:11 | call to sink | params_flow.rb:165:1:165:11 | call to sink | -| params_flow.rb:165:1:165:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:165:1:165:11 | synthetic splat argument | params_flow.rb:165:1:165:11 | synthetic splat argument | | params_flow.rb:165:6:165:10 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:165:6:165:10 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6749,7 +6182,6 @@ trackEnd | params_flow.rb:171:13:171:14 | call to [] | params_flow.rb:174:6:174:15 | ...[...] | | params_flow.rb:171:17:171:25 | call to taint | params_flow.rb:168:26:168:35 | ...[...] | | params_flow.rb:171:17:171:25 | call to taint | params_flow.rb:171:17:171:25 | call to taint | -| params_flow.rb:171:17:171:25 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:171:17:171:25 | synthetic splat argument | params_flow.rb:171:17:171:25 | synthetic splat argument | | params_flow.rb:171:23:171:24 | 76 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:171:23:171:24 | 76 | params_flow.rb:1:11:1:11 | x | @@ -6758,7 +6190,6 @@ trackEnd | params_flow.rb:171:23:171:24 | 76 | params_flow.rb:171:17:171:25 | call to taint | | params_flow.rb:171:23:171:24 | 76 | params_flow.rb:171:23:171:24 | 76 | | params_flow.rb:172:1:172:19 | call to sink | params_flow.rb:172:1:172:19 | call to sink | -| params_flow.rb:172:1:172:19 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:172:1:172:19 | synthetic splat argument | params_flow.rb:172:1:172:19 | synthetic splat argument | | params_flow.rb:172:6:172:15 | ...[...] | params_flow.rb:172:6:172:15 | ...[...] | | params_flow.rb:172:6:172:15 | synthetic splat argument | params_flow.rb:172:6:172:15 | synthetic splat argument | @@ -6776,7 +6207,6 @@ trackEnd | params_flow.rb:173:17:173:24 | * ... | params_flow.rb:168:26:168:32 | posargs | | params_flow.rb:173:17:173:24 | * ... | params_flow.rb:173:17:173:24 | * ... | | params_flow.rb:174:1:174:19 | call to sink | params_flow.rb:174:1:174:19 | call to sink | -| params_flow.rb:174:1:174:19 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:174:1:174:19 | synthetic splat argument | params_flow.rb:174:1:174:19 | synthetic splat argument | | params_flow.rb:174:6:174:15 | ...[...] | params_flow.rb:174:6:174:15 | ...[...] | | params_flow.rb:174:6:174:15 | synthetic splat argument | params_flow.rb:174:6:174:15 | synthetic splat argument | @@ -6797,7 +6227,6 @@ trackEnd | params_flow.rb:176:6:176:7 | call to [] | params_flow.rb:178:17:178:18 | p1 | | params_flow.rb:176:6:176:7 | call to [] | params_flow.rb:179:6:179:7 | p1 | | params_flow.rb:177:1:177:11 | call to sink | params_flow.rb:177:1:177:11 | call to sink | -| params_flow.rb:177:1:177:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:177:1:177:11 | synthetic splat argument | params_flow.rb:177:1:177:11 | synthetic splat argument | | params_flow.rb:177:6:177:10 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:177:6:177:10 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6813,7 +6242,6 @@ trackEnd | params_flow.rb:178:1:178:30 | synthetic splat argument | params_flow.rb:178:1:178:30 | synthetic splat argument | | params_flow.rb:178:21:178:29 | call to taint | params_flow.rb:168:26:168:35 | ...[...] | | params_flow.rb:178:21:178:29 | call to taint | params_flow.rb:178:21:178:29 | call to taint | -| params_flow.rb:178:21:178:29 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:178:21:178:29 | synthetic splat argument | params_flow.rb:178:21:178:29 | synthetic splat argument | | params_flow.rb:178:27:178:28 | 77 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:178:27:178:28 | 77 | params_flow.rb:1:11:1:11 | x | @@ -6822,7 +6250,6 @@ trackEnd | params_flow.rb:178:27:178:28 | 77 | params_flow.rb:178:21:178:29 | call to taint | | params_flow.rb:178:27:178:28 | 77 | params_flow.rb:178:27:178:28 | 77 | | params_flow.rb:179:1:179:11 | call to sink | params_flow.rb:179:1:179:11 | call to sink | -| params_flow.rb:179:1:179:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:179:1:179:11 | synthetic splat argument | params_flow.rb:179:1:179:11 | synthetic splat argument | | params_flow.rb:179:6:179:10 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:179:6:179:10 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6880,7 +6307,6 @@ trackEnd | params_flow.rb:185:14:185:22 | call to taint | params_flow.rb:181:28:181:29 | p2 | | params_flow.rb:185:14:185:22 | call to taint | params_flow.rb:182:18:182:19 | p2 | | params_flow.rb:185:14:185:22 | call to taint | params_flow.rb:185:14:185:22 | call to taint | -| params_flow.rb:185:14:185:22 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:185:14:185:22 | synthetic splat argument | params_flow.rb:185:14:185:22 | synthetic splat argument | | params_flow.rb:185:20:185:21 | 78 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:185:20:185:21 | 78 | params_flow.rb:1:11:1:11 | x | @@ -6891,7 +6317,6 @@ trackEnd | params_flow.rb:185:20:185:21 | 78 | params_flow.rb:185:14:185:22 | call to taint | | params_flow.rb:185:20:185:21 | 78 | params_flow.rb:185:20:185:21 | 78 | | params_flow.rb:186:1:186:16 | call to sink | params_flow.rb:186:1:186:16 | call to sink | -| params_flow.rb:186:1:186:16 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:186:1:186:16 | synthetic splat argument | params_flow.rb:186:1:186:16 | synthetic splat argument | | params_flow.rb:186:6:186:12 | ...[...] | params_flow.rb:186:6:186:12 | ...[...] | | params_flow.rb:186:6:186:12 | synthetic splat argument | params_flow.rb:186:6:186:12 | synthetic splat argument | @@ -6906,7 +6331,6 @@ trackEnd | params_flow.rb:187:20:187:24 | * ... | params_flow.rb:181:1:183:3 | synthetic splat parameter | | params_flow.rb:187:20:187:24 | * ... | params_flow.rb:187:20:187:24 | * ... | | params_flow.rb:188:1:188:16 | call to sink | params_flow.rb:188:1:188:16 | call to sink | -| params_flow.rb:188:1:188:16 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:188:1:188:16 | synthetic splat argument | params_flow.rb:188:1:188:16 | synthetic splat argument | | params_flow.rb:188:6:188:12 | ...[...] | params_flow.rb:188:6:188:12 | ...[...] | | params_flow.rb:188:6:188:12 | synthetic splat argument | params_flow.rb:188:6:188:12 | synthetic splat argument | @@ -6929,7 +6353,6 @@ trackEnd | params_flow.rb:190:6:190:7 | call to [] | params_flow.rb:192:20:192:21 | p1 | | params_flow.rb:190:6:190:7 | call to [] | params_flow.rb:193:6:193:7 | p1 | | params_flow.rb:191:1:191:11 | call to sink | params_flow.rb:191:1:191:11 | call to sink | -| params_flow.rb:191:1:191:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:191:1:191:11 | synthetic splat argument | params_flow.rb:191:1:191:11 | synthetic splat argument | | params_flow.rb:191:6:191:10 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:191:6:191:10 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6938,13 +6361,11 @@ trackEnd | params_flow.rb:191:6:191:10 | synthetic splat argument | params_flow.rb:191:6:191:10 | synthetic splat argument | | params_flow.rb:191:9:191:9 | 0 | params_flow.rb:191:9:191:9 | 0 | | params_flow.rb:192:1:192:33 | call to positionSideEffect | params_flow.rb:192:1:192:33 | call to positionSideEffect | -| params_flow.rb:192:1:192:33 | synthetic splat argument | params_flow.rb:181:1:183:3 | synthetic splat parameter | | params_flow.rb:192:1:192:33 | synthetic splat argument | params_flow.rb:192:1:192:33 | synthetic splat argument | | params_flow.rb:192:24:192:32 | call to taint | params_flow.rb:181:28:181:29 | p2 | | params_flow.rb:192:24:192:32 | call to taint | params_flow.rb:181:28:181:29 | p2 | | params_flow.rb:192:24:192:32 | call to taint | params_flow.rb:182:18:182:19 | p2 | | params_flow.rb:192:24:192:32 | call to taint | params_flow.rb:192:24:192:32 | call to taint | -| params_flow.rb:192:24:192:32 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:192:24:192:32 | synthetic splat argument | params_flow.rb:192:24:192:32 | synthetic splat argument | | params_flow.rb:192:30:192:31 | 79 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:192:30:192:31 | 79 | params_flow.rb:1:11:1:11 | x | @@ -6955,7 +6376,6 @@ trackEnd | params_flow.rb:192:30:192:31 | 79 | params_flow.rb:192:24:192:32 | call to taint | | params_flow.rb:192:30:192:31 | 79 | params_flow.rb:192:30:192:31 | 79 | | params_flow.rb:193:1:193:11 | call to sink | params_flow.rb:193:1:193:11 | call to sink | -| params_flow.rb:193:1:193:11 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:193:1:193:11 | synthetic splat argument | params_flow.rb:193:1:193:11 | synthetic splat argument | | params_flow.rb:193:6:193:10 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:193:6:193:10 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -6990,7 +6410,6 @@ trackEnd | params_flow.rb:196:10:196:18 | call to taint | params_flow.rb:200:9:200:9 | x | | params_flow.rb:196:10:196:18 | call to taint | params_flow.rb:201:11:201:11 | x | | params_flow.rb:196:10:196:18 | call to taint | params_flow.rb:202:11:202:11 | x | -| params_flow.rb:196:10:196:18 | synthetic splat argument | params_flow.rb:1:1:3:3 | synthetic splat parameter | | params_flow.rb:196:10:196:18 | synthetic splat argument | params_flow.rb:196:10:196:18 | synthetic splat argument | | params_flow.rb:196:16:196:17 | 80 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:196:16:196:17 | 80 | params_flow.rb:1:11:1:11 | x | @@ -7031,7 +6450,6 @@ trackEnd | params_flow.rb:200:12:200:12 | y | params_flow.rb:203:11:203:11 | y | | params_flow.rb:200:12:200:12 | y | params_flow.rb:204:11:204:11 | y | | params_flow.rb:201:5:201:15 | call to sink | params_flow.rb:201:5:201:15 | call to sink | -| params_flow.rb:201:5:201:15 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:201:5:201:15 | synthetic splat argument | params_flow.rb:201:5:201:15 | synthetic splat argument | | params_flow.rb:201:11:201:14 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:201:11:201:14 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -7041,7 +6459,6 @@ trackEnd | params_flow.rb:201:11:201:14 | synthetic splat argument | params_flow.rb:201:11:201:14 | synthetic splat argument | | params_flow.rb:201:13:201:13 | 0 | params_flow.rb:201:13:201:13 | 0 | | params_flow.rb:202:5:202:15 | call to sink | params_flow.rb:202:5:202:15 | call to sink | -| params_flow.rb:202:5:202:15 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:202:5:202:15 | synthetic splat argument | params_flow.rb:202:5:202:15 | synthetic splat argument | | params_flow.rb:202:11:202:14 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:202:11:202:14 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -7051,7 +6468,6 @@ trackEnd | params_flow.rb:202:11:202:14 | synthetic splat argument | params_flow.rb:202:11:202:14 | synthetic splat argument | | params_flow.rb:202:13:202:13 | 1 | params_flow.rb:202:13:202:13 | 1 | | params_flow.rb:203:5:203:15 | call to sink | params_flow.rb:203:5:203:15 | call to sink | -| params_flow.rb:203:5:203:15 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:203:5:203:15 | synthetic splat argument | params_flow.rb:203:5:203:15 | synthetic splat argument | | params_flow.rb:203:11:203:14 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:203:11:203:14 | ...[...] | params_flow.rb:5:10:5:10 | x | @@ -7062,7 +6478,6 @@ trackEnd | params_flow.rb:203:13:203:13 | 0 | params_flow.rb:203:13:203:13 | 0 | | params_flow.rb:204:5:204:15 | call to sink | params_flow.rb:204:5:204:15 | call to sink | | params_flow.rb:204:5:204:15 | call to sink | params_flow.rb:207:1:207:14 | call to foo | -| params_flow.rb:204:5:204:15 | synthetic splat argument | params_flow.rb:5:1:7:3 | synthetic splat parameter | | params_flow.rb:204:5:204:15 | synthetic splat argument | params_flow.rb:204:5:204:15 | synthetic splat argument | | params_flow.rb:204:11:204:14 | ...[...] | params_flow.rb:5:10:5:10 | x | | params_flow.rb:204:11:204:14 | ...[...] | params_flow.rb:5:10:5:10 | x | diff --git a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected index 74bbbd395b2..4b079e0ebbb 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected @@ -66,8 +66,6 @@ edges | params_flow.rb:47:13:47:16 | args [element 1] | params_flow.rb:47:12:47:16 | * ... [element 1] | provenance | | | params_flow.rb:49:13:49:14 | p1 | params_flow.rb:50:10:50:11 | p1 | provenance | | | params_flow.rb:49:17:49:24 | *posargs [element 0] | params_flow.rb:51:11:51:17 | posargs [element 0] | provenance | | -| params_flow.rb:49:17:49:24 | *posargs [element 0] | params_flow.rb:51:11:51:17 | posargs [element 0] | provenance | | -| params_flow.rb:51:11:51:17 | posargs [element 0] | params_flow.rb:51:11:51:20 | ...[...] | provenance | | | params_flow.rb:51:11:51:17 | posargs [element 0] | params_flow.rb:51:11:51:20 | ...[...] | provenance | | | params_flow.rb:51:11:51:20 | ...[...] | params_flow.rb:51:10:51:21 | ( ... ) | provenance | | | params_flow.rb:55:9:55:17 | call to taint | params_flow.rb:49:13:49:14 | p1 | provenance | | @@ -77,7 +75,6 @@ edges | params_flow.rb:57:9:57:17 | call to taint | params_flow.rb:57:8:57:18 | call to [] [element 0] | provenance | | | params_flow.rb:58:9:58:17 | call to taint | params_flow.rb:49:13:49:14 | p1 | provenance | | | params_flow.rb:58:20:58:24 | * ... [element 0] | params_flow.rb:49:17:49:24 | *posargs [element 0] | provenance | | -| params_flow.rb:58:20:58:24 | * ... [element 0] | params_flow.rb:49:17:49:24 | *posargs [element 0] | provenance | | | params_flow.rb:58:21:58:24 | args [element 0] | params_flow.rb:58:20:58:24 | * ... [element 0] | provenance | | | params_flow.rb:60:1:60:4 | args [element 0] | params_flow.rb:61:10:61:13 | args [element 0] | provenance | | | params_flow.rb:60:1:60:4 | args [element 1] | params_flow.rb:61:10:61:13 | args [element 1] | provenance | | @@ -263,11 +260,9 @@ nodes | params_flow.rb:47:13:47:16 | args [element 1] | semmle.label | args [element 1] | | params_flow.rb:49:13:49:14 | p1 | semmle.label | p1 | | params_flow.rb:49:17:49:24 | *posargs [element 0] | semmle.label | *posargs [element 0] | -| params_flow.rb:49:17:49:24 | *posargs [element 0] | semmle.label | *posargs [element 0] | | params_flow.rb:50:10:50:11 | p1 | semmle.label | p1 | | params_flow.rb:51:10:51:21 | ( ... ) | semmle.label | ( ... ) | | params_flow.rb:51:11:51:17 | posargs [element 0] | semmle.label | posargs [element 0] | -| params_flow.rb:51:11:51:17 | posargs [element 0] | semmle.label | posargs [element 0] | | params_flow.rb:51:11:51:20 | ...[...] | semmle.label | ...[...] | | params_flow.rb:55:9:55:17 | call to taint | semmle.label | call to taint | | params_flow.rb:55:20:55:28 | call to taint | semmle.label | call to taint | diff --git a/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected b/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected index d843d8e3c6d..f0199572d78 100644 --- a/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected +++ b/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected @@ -14,12 +14,12 @@ track | type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field | | type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= | | type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps with content splat position 0 | type_tracker.rb:3:9:3:23 | synthetic splat argument | -| type_tracker.rb:2:16:2:18 | val | type tracker without call steps with content splat position 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument | +| type_tracker.rb:2:16:2:18 | val | type tracker without call steps with content element 0 | type_tracker.rb:3:9:3:23 | synthetic splat argument | +| type_tracker.rb:2:16:2:18 | val | type tracker without call steps with content element 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument | | type_tracker.rb:3:9:3:23 | call to puts | type tracker without call steps | type_tracker.rb:3:9:3:23 | call to puts | | type_tracker.rb:3:9:3:23 | synthetic splat argument | type tracker without call steps | type_tracker.rb:3:9:3:23 | synthetic splat argument | | type_tracker.rb:3:14:3:23 | call to field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field | -| type_tracker.rb:3:14:3:23 | call to field | type tracker without call steps with content splat position 0 | type_tracker.rb:3:9:3:23 | synthetic splat argument | +| type_tracker.rb:3:14:3:23 | call to field | type tracker without call steps with content element 0 | type_tracker.rb:3:9:3:23 | synthetic splat argument | | type_tracker.rb:4:9:4:14 | @field | type tracker without call steps | type_tracker.rb:4:9:4:14 | @field | | type_tracker.rb:7:5:9:7 | &block | type tracker without call steps | type_tracker.rb:7:5:9:7 | &block | | type_tracker.rb:7:5:9:7 | field | type tracker without call steps | type_tracker.rb:7:5:9:7 | field | @@ -27,8 +27,8 @@ track | type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field | | type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field | | type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | -| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps with content splat position 0 | type_tracker.rb:3:9:3:23 | synthetic splat argument | -| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps with content splat position 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument | +| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps with content element 0 | type_tracker.rb:3:9:3:23 | synthetic splat argument | +| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps with content element 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument | | type_tracker.rb:12:1:16:3 | &block | type tracker without call steps | type_tracker.rb:12:1:16:3 | &block | | type_tracker.rb:12:1:16:3 | m | type tracker without call steps | type_tracker.rb:12:1:16:3 | m | | type_tracker.rb:12:1:16:3 | self in m | type tracker without call steps | type_tracker.rb:12:1:16:3 | self in m | @@ -40,61 +40,56 @@ track | type_tracker.rb:14:5:14:7 | [post] var | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field | | type_tracker.rb:14:5:14:7 | [post] var | type tracker without call steps | type_tracker.rb:14:5:14:7 | [post] var | | type_tracker.rb:14:5:14:13 | call to field= | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= | -| type_tracker.rb:14:5:14:13 | synthetic splat argument | type tracker with call steps | type_tracker.rb:2:5:5:7 | synthetic splat parameter | | type_tracker.rb:14:5:14:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:14:5:14:13 | synthetic splat argument | | type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps | type_tracker.rb:8:9:8:14 | @field | | type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content attribute field | type_tracker.rb:7:5:9:7 | self in field | -| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content splat position 0 | type_tracker.rb:2:5:5:7 | synthetic splat parameter | | type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= | | type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:14:17:14:23 | "hello" | | type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content attribute field | type_tracker.rb:14:5:14:7 | [post] var | -| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content splat position 0 | type_tracker.rb:14:5:14:13 | synthetic splat argument | -| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content splat position 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument | +| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content element 0 | type_tracker.rb:14:5:14:13 | synthetic splat argument | +| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content element 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument | | type_tracker.rb:14:17:14:23 | __synth__0 | type tracker without call steps | type_tracker.rb:14:17:14:23 | __synth__0 | | type_tracker.rb:15:5:15:18 | call to puts | type tracker without call steps | type_tracker.rb:15:5:15:18 | call to puts | | type_tracker.rb:15:5:15:18 | synthetic splat argument | type tracker without call steps | type_tracker.rb:15:5:15:18 | synthetic splat argument | | type_tracker.rb:15:10:15:18 | call to field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field | -| type_tracker.rb:15:10:15:18 | call to field | type tracker without call steps with content splat position 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument | +| type_tracker.rb:15:10:15:18 | call to field | type tracker without call steps with content element 0 | type_tracker.rb:15:5:15:18 | synthetic splat argument | | type_tracker.rb:18:1:21:3 | &block | type tracker without call steps | type_tracker.rb:18:1:21:3 | &block | | type_tracker.rb:18:1:21:3 | positional | type tracker without call steps | type_tracker.rb:18:1:21:3 | positional | | type_tracker.rb:18:1:21:3 | self in positional | type tracker without call steps | type_tracker.rb:18:1:21:3 | self in positional | | type_tracker.rb:18:1:21:3 | synthetic splat parameter | type tracker without call steps | type_tracker.rb:18:1:21:3 | synthetic splat parameter | | type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps | type_tracker.rb:18:16:18:17 | p1 | | type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps | type_tracker.rb:18:16:18:17 | p1 | -| type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps with content splat position 0 | type_tracker.rb:19:5:19:11 | synthetic splat argument | +| type_tracker.rb:18:16:18:17 | p1 | type tracker without call steps with content element 0 | type_tracker.rb:19:5:19:11 | synthetic splat argument | | type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps | type_tracker.rb:18:20:18:21 | p2 | | type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps | type_tracker.rb:18:20:18:21 | p2 | -| type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps with content splat position 0 | type_tracker.rb:20:5:20:11 | synthetic splat argument | +| type_tracker.rb:18:20:18:21 | p2 | type tracker without call steps with content element 0 | type_tracker.rb:20:5:20:11 | synthetic splat argument | | type_tracker.rb:19:5:19:11 | call to puts | type tracker without call steps | type_tracker.rb:19:5:19:11 | call to puts | | type_tracker.rb:19:5:19:11 | synthetic splat argument | type tracker without call steps | type_tracker.rb:19:5:19:11 | synthetic splat argument | | type_tracker.rb:20:5:20:11 | call to puts | type tracker without call steps | type_tracker.rb:20:5:20:11 | call to puts | | type_tracker.rb:20:5:20:11 | call to puts | type tracker without call steps | type_tracker.rb:23:1:23:16 | call to positional | | type_tracker.rb:20:5:20:11 | synthetic splat argument | type tracker without call steps | type_tracker.rb:20:5:20:11 | synthetic splat argument | | type_tracker.rb:23:1:23:16 | call to positional | type tracker without call steps | type_tracker.rb:23:1:23:16 | call to positional | -| type_tracker.rb:23:1:23:16 | synthetic splat argument | type tracker with call steps | type_tracker.rb:18:1:21:3 | synthetic splat parameter | | type_tracker.rb:23:1:23:16 | synthetic splat argument | type tracker without call steps | type_tracker.rb:23:1:23:16 | synthetic splat argument | | type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps | type_tracker.rb:18:16:18:17 | p1 | -| type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps with content splat position 0 | type_tracker.rb:18:1:21:3 | synthetic splat parameter | -| type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps with content splat position 0 | type_tracker.rb:19:5:19:11 | synthetic splat argument | +| type_tracker.rb:23:12:23:12 | 1 | type tracker with call steps with content element 0 | type_tracker.rb:19:5:19:11 | synthetic splat argument | | type_tracker.rb:23:12:23:12 | 1 | type tracker without call steps | type_tracker.rb:23:12:23:12 | 1 | -| type_tracker.rb:23:12:23:12 | 1 | type tracker without call steps with content splat position 0 | type_tracker.rb:23:1:23:16 | synthetic splat argument | +| type_tracker.rb:23:12:23:12 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:23:1:23:16 | synthetic splat argument | | type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps | type_tracker.rb:18:20:18:21 | p2 | -| type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps with content splat position 0 | type_tracker.rb:20:5:20:11 | synthetic splat argument | -| type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps with content splat position 1 | type_tracker.rb:18:1:21:3 | synthetic splat parameter | +| type_tracker.rb:23:15:23:15 | 2 | type tracker with call steps with content element 0 | type_tracker.rb:20:5:20:11 | synthetic splat argument | | type_tracker.rb:23:15:23:15 | 2 | type tracker without call steps | type_tracker.rb:23:15:23:15 | 2 | -| type_tracker.rb:23:15:23:15 | 2 | type tracker without call steps with content splat position 1 | type_tracker.rb:23:1:23:16 | synthetic splat argument | +| type_tracker.rb:23:15:23:15 | 2 | type tracker without call steps with content element 1 | type_tracker.rb:23:1:23:16 | synthetic splat argument | | type_tracker.rb:25:1:28:3 | &block | type tracker without call steps | type_tracker.rb:25:1:28:3 | &block | | type_tracker.rb:25:1:28:3 | keyword | type tracker without call steps | type_tracker.rb:25:1:28:3 | keyword | | type_tracker.rb:25:1:28:3 | self in keyword | type tracker without call steps | type_tracker.rb:25:1:28:3 | self in keyword | | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | type tracker without call steps | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps | type_tracker.rb:25:13:25:14 | p1 | -| type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps with content splat position 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | +| type_tracker.rb:25:13:25:14 | p1 | type tracker without call steps with content element 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | | type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps | type_tracker.rb:25:18:25:19 | p2 | -| type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps with content splat position 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | +| type_tracker.rb:25:18:25:19 | p2 | type tracker without call steps with content element 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | | type_tracker.rb:26:5:26:11 | call to puts | type tracker without call steps | type_tracker.rb:26:5:26:11 | call to puts | | type_tracker.rb:26:5:26:11 | synthetic splat argument | type tracker without call steps | type_tracker.rb:26:5:26:11 | synthetic splat argument | | type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:27:5:27:11 | call to puts | @@ -108,15 +103,15 @@ track | type_tracker.rb:30:9:30:10 | :p1 | type tracker without call steps | type_tracker.rb:30:9:30:10 | :p1 | | type_tracker.rb:30:9:30:13 | Pair | type tracker without call steps | type_tracker.rb:30:9:30:13 | Pair | | type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | +| type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content element 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | | type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content hash-splat position :p1 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | -| type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content splat position 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | | type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps | type_tracker.rb:30:13:30:13 | 3 | | type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps with content hash-splat position :p1 | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | | type_tracker.rb:30:16:30:17 | :p2 | type tracker without call steps | type_tracker.rb:30:16:30:17 | :p2 | | type_tracker.rb:30:16:30:20 | Pair | type tracker without call steps | type_tracker.rb:30:16:30:20 | Pair | | type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | +| type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content element 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | | type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content hash-splat position :p2 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | -| type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content splat position 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | | type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps | type_tracker.rb:30:20:30:20 | 4 | | type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps with content hash-splat position :p2 | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | | type_tracker.rb:31:1:31:21 | call to keyword | type tracker without call steps | type_tracker.rb:31:1:31:21 | call to keyword | @@ -125,15 +120,15 @@ track | type_tracker.rb:31:9:31:10 | :p2 | type tracker without call steps | type_tracker.rb:31:9:31:10 | :p2 | | type_tracker.rb:31:9:31:13 | Pair | type tracker without call steps | type_tracker.rb:31:9:31:13 | Pair | | type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | +| type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content element 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | | type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content hash-splat position :p2 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | -| type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content splat position 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | | type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps | type_tracker.rb:31:13:31:13 | 5 | | type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps with content hash-splat position :p2 | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | | type_tracker.rb:31:16:31:17 | :p1 | type tracker without call steps | type_tracker.rb:31:16:31:17 | :p1 | | type_tracker.rb:31:16:31:20 | Pair | type tracker without call steps | type_tracker.rb:31:16:31:20 | Pair | | type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | +| type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content element 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | | type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content hash-splat position :p1 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | -| type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content splat position 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | | type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps | type_tracker.rb:31:20:31:20 | 6 | | type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps with content hash-splat position :p1 | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | | type_tracker.rb:32:1:32:27 | call to keyword | type tracker without call steps | type_tracker.rb:32:1:32:27 | call to keyword | @@ -142,15 +137,15 @@ track | type_tracker.rb:32:9:32:11 | :p2 | type tracker without call steps | type_tracker.rb:32:9:32:11 | :p2 | | type_tracker.rb:32:9:32:16 | Pair | type tracker without call steps | type_tracker.rb:32:9:32:16 | Pair | | type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | +| type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content element 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | | type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content hash-splat position :p2 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | -| type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content splat position 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | | type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps | type_tracker.rb:32:16:32:16 | 7 | | type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps with content hash-splat position :p2 | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | | type_tracker.rb:32:19:32:21 | :p1 | type tracker without call steps | type_tracker.rb:32:19:32:21 | :p1 | | type_tracker.rb:32:19:32:26 | Pair | type tracker without call steps | type_tracker.rb:32:19:32:26 | Pair | | type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | +| type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content element 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | | type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content hash-splat position :p1 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | -| type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content splat position 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | | type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps | type_tracker.rb:32:26:32:26 | 8 | | type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps with content hash-splat position :p1 | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | | type_tracker.rb:34:1:53:3 | &block | type tracker without call steps | type_tracker.rb:34:1:53:3 | &block | @@ -169,18 +164,18 @@ track | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 | type_tracker.rb:35:11:35:15 | synthetic splat argument | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:43:5:43:10 | [post] array2 | | type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 0 or unknown | type_tracker.rb:47:5:47:10 | [post] array3 | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content splat position 1 | type_tracker.rb:39:5:39:12 | synthetic splat argument | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content splat position 1 | type_tracker.rb:43:5:43:13 | synthetic splat argument | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content splat position 1 | type_tracker.rb:47:5:47:13 | synthetic splat argument | -| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content splat position 1 | type_tracker.rb:51:5:51:13 | synthetic splat argument | +| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 1 | type_tracker.rb:39:5:39:12 | synthetic splat argument | +| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 1 | type_tracker.rb:43:5:43:13 | synthetic splat argument | +| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 1 | type_tracker.rb:47:5:47:13 | synthetic splat argument | +| type_tracker.rb:34:18:34:20 | obj | type tracker without call steps with content element 1 | type_tracker.rb:51:5:51:13 | synthetic splat argument | | type_tracker.rb:34:23:34:23 | y | type tracker without call steps | type_tracker.rb:34:23:34:23 | y | | type_tracker.rb:34:23:34:23 | y | type tracker without call steps | type_tracker.rb:34:23:34:23 | y | -| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content splat position 0 | type_tracker.rb:39:5:39:12 | synthetic splat argument | -| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content splat position 0 | type_tracker.rb:44:5:44:13 | synthetic splat argument | -| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content splat position 0 | type_tracker.rb:51:5:51:13 | synthetic splat argument | +| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content element 0 | type_tracker.rb:39:5:39:12 | synthetic splat argument | +| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content element 0 | type_tracker.rb:44:5:44:13 | synthetic splat argument | +| type_tracker.rb:34:23:34:23 | y | type tracker without call steps with content element 0 | type_tracker.rb:51:5:51:13 | synthetic splat argument | | type_tracker.rb:34:26:34:26 | z | type tracker without call steps | type_tracker.rb:34:26:34:26 | z | | type_tracker.rb:34:26:34:26 | z | type tracker without call steps | type_tracker.rb:34:26:34:26 | z | -| type_tracker.rb:34:26:34:26 | z | type tracker without call steps with content splat position 0 | type_tracker.rb:52:5:52:13 | synthetic splat argument | +| type_tracker.rb:34:26:34:26 | z | type tracker without call steps with content element 0 | type_tracker.rb:52:5:52:13 | synthetic splat argument | | type_tracker.rb:35:5:35:7 | tmp | type tracker without call steps | type_tracker.rb:35:5:35:7 | tmp | | type_tracker.rb:35:11:35:15 | Array | type tracker without call steps | type_tracker.rb:35:11:35:15 | Array | | type_tracker.rb:35:11:35:15 | call to [] | type tracker without call steps | type_tracker.rb:35:11:35:15 | call to [] | @@ -189,7 +184,7 @@ track | type_tracker.rb:36:5:36:10 | ...[...] | type tracker without call steps | type_tracker.rb:36:5:36:10 | ...[...] | | type_tracker.rb:36:5:36:10 | synthetic splat argument | type tracker without call steps | type_tracker.rb:36:5:36:10 | synthetic splat argument | | type_tracker.rb:36:9:36:9 | 0 | type tracker without call steps | type_tracker.rb:36:9:36:9 | 0 | -| type_tracker.rb:36:9:36:9 | 0 | type tracker without call steps with content splat position 0 | type_tracker.rb:36:5:36:10 | synthetic splat argument | +| type_tracker.rb:36:9:36:9 | 0 | type tracker without call steps with content element 0 | type_tracker.rb:36:5:36:10 | synthetic splat argument | | type_tracker.rb:38:5:38:9 | array | type tracker without call steps | type_tracker.rb:38:5:38:9 | array | | type_tracker.rb:38:13:38:25 | Array | type tracker without call steps | type_tracker.rb:38:13:38:25 | Array | | type_tracker.rb:38:13:38:25 | call to [] | type tracker without call steps | type_tracker.rb:38:13:38:25 | call to [] | @@ -221,7 +216,7 @@ track | type_tracker.rb:40:5:40:12 | ...[...] | type tracker without call steps | type_tracker.rb:40:5:40:12 | ...[...] | | type_tracker.rb:40:5:40:12 | synthetic splat argument | type tracker without call steps | type_tracker.rb:40:5:40:12 | synthetic splat argument | | type_tracker.rb:40:11:40:11 | 0 | type tracker without call steps | type_tracker.rb:40:11:40:11 | 0 | -| type_tracker.rb:40:11:40:11 | 0 | type tracker without call steps with content splat position 0 | type_tracker.rb:40:5:40:12 | synthetic splat argument | +| type_tracker.rb:40:11:40:11 | 0 | type tracker without call steps with content element 0 | type_tracker.rb:40:5:40:12 | synthetic splat argument | | type_tracker.rb:42:5:42:10 | array2 | type tracker without call steps | type_tracker.rb:42:5:42:10 | array2 | | type_tracker.rb:42:14:42:26 | Array | type tracker without call steps | type_tracker.rb:42:14:42:26 | Array | | type_tracker.rb:42:14:42:26 | call to [] | type tracker without call steps | type_tracker.rb:42:14:42:26 | call to [] | @@ -263,7 +258,7 @@ track | type_tracker.rb:43:5:43:13 | call to []= | type tracker without call steps | type_tracker.rb:43:5:43:13 | call to []= | | type_tracker.rb:43:5:43:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:43:5:43:13 | synthetic splat argument | | type_tracker.rb:43:12:43:12 | 0 | type tracker without call steps | type_tracker.rb:43:12:43:12 | 0 | -| type_tracker.rb:43:12:43:12 | 0 | type tracker without call steps with content splat position 0 | type_tracker.rb:43:5:43:13 | synthetic splat argument | +| type_tracker.rb:43:12:43:12 | 0 | type tracker without call steps with content element 0 | type_tracker.rb:43:5:43:13 | synthetic splat argument | | type_tracker.rb:43:17:43:19 | __synth__0 | type tracker without call steps | type_tracker.rb:43:17:43:19 | __synth__0 | | type_tracker.rb:44:5:44:13 | ...[...] | type tracker without call steps | type_tracker.rb:44:5:44:13 | ...[...] | | type_tracker.rb:44:5:44:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:44:5:44:13 | synthetic splat argument | @@ -303,12 +298,12 @@ track | type_tracker.rb:47:5:47:13 | call to []= | type tracker without call steps | type_tracker.rb:47:5:47:13 | call to []= | | type_tracker.rb:47:5:47:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:47:5:47:13 | synthetic splat argument | | type_tracker.rb:47:12:47:12 | 0 | type tracker without call steps | type_tracker.rb:47:12:47:12 | 0 | -| type_tracker.rb:47:12:47:12 | 0 | type tracker without call steps with content splat position 0 | type_tracker.rb:47:5:47:13 | synthetic splat argument | +| type_tracker.rb:47:12:47:12 | 0 | type tracker without call steps with content element 0 | type_tracker.rb:47:5:47:13 | synthetic splat argument | | type_tracker.rb:47:17:47:19 | __synth__0 | type tracker without call steps | type_tracker.rb:47:17:47:19 | __synth__0 | | type_tracker.rb:48:5:48:13 | ...[...] | type tracker without call steps | type_tracker.rb:48:5:48:13 | ...[...] | | type_tracker.rb:48:5:48:13 | synthetic splat argument | type tracker without call steps | type_tracker.rb:48:5:48:13 | synthetic splat argument | | type_tracker.rb:48:12:48:12 | 1 | type tracker without call steps | type_tracker.rb:48:12:48:12 | 1 | -| type_tracker.rb:48:12:48:12 | 1 | type tracker without call steps with content splat position 0 | type_tracker.rb:48:5:48:13 | synthetic splat argument | +| type_tracker.rb:48:12:48:12 | 1 | type tracker without call steps with content element 0 | type_tracker.rb:48:5:48:13 | synthetic splat argument | | type_tracker.rb:50:5:50:10 | array4 | type tracker without call steps | type_tracker.rb:50:5:50:10 | array4 | | type_tracker.rb:50:14:50:26 | Array | type tracker without call steps | type_tracker.rb:50:14:50:26 | Array | | type_tracker.rb:50:14:50:26 | call to [] | type tracker without call steps | type_tracker.rb:50:14:50:26 | call to [] | @@ -419,7 +414,6 @@ trackEnd | type_tracker.rb:14:5:14:7 | [post] var | type_tracker.rb:14:5:14:7 | [post] var | | type_tracker.rb:14:5:14:7 | [post] var | type_tracker.rb:15:10:15:12 | var | | type_tracker.rb:14:5:14:13 | call to field= | type_tracker.rb:14:5:14:13 | call to field= | -| type_tracker.rb:14:5:14:13 | synthetic splat argument | type_tracker.rb:2:5:5:7 | synthetic splat parameter | | type_tracker.rb:14:5:14:13 | synthetic splat argument | type_tracker.rb:14:5:14:13 | synthetic splat argument | | type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:2:16:2:18 | val | | type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:2:16:2:18 | val | @@ -458,7 +452,6 @@ trackEnd | type_tracker.rb:20:5:20:11 | call to puts | type_tracker.rb:23:1:23:16 | call to positional | | type_tracker.rb:20:5:20:11 | synthetic splat argument | type_tracker.rb:20:5:20:11 | synthetic splat argument | | type_tracker.rb:23:1:23:16 | call to positional | type_tracker.rb:23:1:23:16 | call to positional | -| type_tracker.rb:23:1:23:16 | synthetic splat argument | type_tracker.rb:18:1:21:3 | synthetic splat parameter | | type_tracker.rb:23:1:23:16 | synthetic splat argument | type_tracker.rb:23:1:23:16 | synthetic splat argument | | type_tracker.rb:23:12:23:12 | 1 | type_tracker.rb:18:16:18:17 | p1 | | type_tracker.rb:23:12:23:12 | 1 | type_tracker.rb:18:16:18:17 | p1 | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.expected b/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.expected index 77c97b234d9..f443f766986 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.expected +++ b/ruby/ql/test/library-tests/frameworks/action_controller/params-flow.expected @@ -67,21 +67,21 @@ edges | params_flow.rb:107:10:107:33 | call to values_at [element 0] | params_flow.rb:107:10:107:33 | call to values_at | provenance | | | params_flow.rb:107:10:107:33 | call to values_at [element 1] | params_flow.rb:107:10:107:33 | call to values_at | provenance | | | params_flow.rb:111:10:111:15 | call to params | params_flow.rb:111:10:111:29 | call to merge | provenance | | -| params_flow.rb:112:10:112:29 | call to merge [splat position 0] | params_flow.rb:112:10:112:29 | call to merge | provenance | | +| params_flow.rb:112:10:112:29 | call to merge [element 0] | params_flow.rb:112:10:112:29 | call to merge | provenance | | | params_flow.rb:112:23:112:28 | call to params | params_flow.rb:112:10:112:29 | call to merge | provenance | | -| params_flow.rb:112:23:112:28 | call to params | params_flow.rb:112:10:112:29 | call to merge [splat position 0] | provenance | | +| params_flow.rb:112:23:112:28 | call to params | params_flow.rb:112:10:112:29 | call to merge [element 0] | provenance | | | params_flow.rb:116:10:116:15 | call to params | params_flow.rb:116:10:116:37 | call to reverse_merge | provenance | | | params_flow.rb:117:31:117:36 | call to params | params_flow.rb:117:10:117:37 | call to reverse_merge | provenance | | | params_flow.rb:121:10:121:15 | call to params | params_flow.rb:121:10:121:43 | call to with_defaults | provenance | | | params_flow.rb:122:31:122:36 | call to params | params_flow.rb:122:10:122:37 | call to with_defaults | provenance | | | params_flow.rb:126:10:126:15 | call to params | params_flow.rb:126:10:126:30 | call to merge! | provenance | | -| params_flow.rb:127:10:127:30 | call to merge! [splat position 0] | params_flow.rb:127:10:127:30 | call to merge! | provenance | | +| params_flow.rb:127:10:127:30 | call to merge! [element 0] | params_flow.rb:127:10:127:30 | call to merge! | provenance | | | params_flow.rb:127:24:127:29 | call to params | params_flow.rb:127:10:127:30 | call to merge! | provenance | | -| params_flow.rb:127:24:127:29 | call to params | params_flow.rb:127:10:127:30 | call to merge! [splat position 0] | provenance | | +| params_flow.rb:127:24:127:29 | call to params | params_flow.rb:127:10:127:30 | call to merge! [element 0] | provenance | | | params_flow.rb:130:5:130:5 | [post] p | params_flow.rb:131:10:131:10 | p | provenance | | -| params_flow.rb:130:5:130:5 | [post] p [splat position 0] | params_flow.rb:131:10:131:10 | p | provenance | | +| params_flow.rb:130:5:130:5 | [post] p [element 0] | params_flow.rb:131:10:131:10 | p | provenance | | | params_flow.rb:130:14:130:19 | call to params | params_flow.rb:130:5:130:5 | [post] p | provenance | | -| params_flow.rb:130:14:130:19 | call to params | params_flow.rb:130:5:130:5 | [post] p [splat position 0] | provenance | | +| params_flow.rb:130:14:130:19 | call to params | params_flow.rb:130:5:130:5 | [post] p [element 0] | provenance | | | params_flow.rb:135:10:135:15 | call to params | params_flow.rb:135:10:135:38 | call to reverse_merge! | provenance | | | params_flow.rb:136:32:136:37 | call to params | params_flow.rb:136:10:136:38 | call to reverse_merge! | provenance | | | params_flow.rb:139:5:139:5 | [post] p | params_flow.rb:140:10:140:10 | p | provenance | | @@ -213,7 +213,7 @@ nodes | params_flow.rb:111:10:111:15 | call to params | semmle.label | call to params | | params_flow.rb:111:10:111:29 | call to merge | semmle.label | call to merge | | params_flow.rb:112:10:112:29 | call to merge | semmle.label | call to merge | -| params_flow.rb:112:10:112:29 | call to merge [splat position 0] | semmle.label | call to merge [splat position 0] | +| params_flow.rb:112:10:112:29 | call to merge [element 0] | semmle.label | call to merge [element 0] | | params_flow.rb:112:23:112:28 | call to params | semmle.label | call to params | | params_flow.rb:116:10:116:15 | call to params | semmle.label | call to params | | params_flow.rb:116:10:116:37 | call to reverse_merge | semmle.label | call to reverse_merge | @@ -226,10 +226,10 @@ nodes | params_flow.rb:126:10:126:15 | call to params | semmle.label | call to params | | params_flow.rb:126:10:126:30 | call to merge! | semmle.label | call to merge! | | params_flow.rb:127:10:127:30 | call to merge! | semmle.label | call to merge! | -| params_flow.rb:127:10:127:30 | call to merge! [splat position 0] | semmle.label | call to merge! [splat position 0] | +| params_flow.rb:127:10:127:30 | call to merge! [element 0] | semmle.label | call to merge! [element 0] | | params_flow.rb:127:24:127:29 | call to params | semmle.label | call to params | | params_flow.rb:130:5:130:5 | [post] p | semmle.label | [post] p | -| params_flow.rb:130:5:130:5 | [post] p [splat position 0] | semmle.label | [post] p [splat position 0] | +| params_flow.rb:130:5:130:5 | [post] p [element 0] | semmle.label | [post] p [element 0] | | params_flow.rb:130:14:130:19 | call to params | semmle.label | call to params | | params_flow.rb:131:10:131:10 | p | semmle.label | p | | params_flow.rb:135:10:135:15 | call to params | semmle.label | call to params | From 20dc2428300c0f3c2bd35680438bc582b7e02aee Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 14 Aug 2024 14:01:13 +0200 Subject: [PATCH 033/404] Ruby: Rework hash splat argument/parameter matching --- .../dataflow/internal/DataFlowDispatch.qll | 7 +- .../dataflow/internal/DataFlowPrivate.qll | 53 +----- .../ruby/dataflow/internal/DataFlowPublic.qll | 5 +- .../VerifyApiGraphExpectations.expected | 2 +- .../flow-summaries/semantics.expected | 24 +-- .../dataflow/params/TypeTracker.expected | 169 ++++++------------ .../dataflow/params/params-flow.expected | 12 +- .../type-tracker/TypeTracker.expected | 24 +-- 8 files changed, 88 insertions(+), 208 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index 8af047e8326..97c0e24fa5b 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -1538,9 +1538,14 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { or exists(string name | ppos.isKeyword(name) and apos.isKeyword(name)) or - (ppos.isHashSplat() or ppos.isSynthHashSplat()) and + ppos.isHashSplat() and (apos.isHashSplat() or apos.isSynthHashSplat()) or + // no case for `apos.isSynthHashSplat() and ppos.isSynthHashSplat()`, since + // direct keyword matching is possible + ppos.isSynthHashSplat() and + apos.isHashSplat() + or exists(int pos, boolean hasActualSplatParam, boolean hasActualSplatArg | ( ppos.isSplat(pos) and diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 5ec24c19901..620a9fb5cab 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -662,7 +662,7 @@ private module Cached { ) } or deprecated TSplatContent(int i, Boolean shifted) { i in [0 .. 10] } or - THashSplatContent(ConstantValue::ConstantSymbolValue cv) or + deprecated THashSplatContent(ConstantValue::ConstantSymbolValue cv) or TCapturedVariableContent(VariableCapture::CapturedVariable v) or // Only used by type-tracking TAttributeName(string name) { name = any(SetterMethodCall c).getTargetName() } @@ -686,24 +686,16 @@ private module Cached { TUnknownElementContentApprox() or TKnownIntegerElementContentApprox() or TKnownElementContentApprox(string approx) { approx = approxKnownElementIndex(_) } or - THashSplatContentApprox(string approx) { approx = approxKnownElementIndex(_) } or TNonElementContentApprox(Content c) { not c instanceof Content::ElementContent } or TCapturedVariableContentApprox(VariableCapture::CapturedVariable v) cached newtype TDataFlowType = TLambdaDataFlowType(Callable c) { c = any(LambdaSelfReferenceNode n).getCallable() } or - // In order to reduce the set of cons-candidates, we annotate all implicit (hash) splat - // creations with the name of the method that they are passed into. This includes - // array/hash literals as well (where the name is simply `[]`), because of how they - // are modeled (see `Array.qll` and `Hash.qll`). - TSynthHashSplatArgumentType(string methodName) { - methodName = any(SynthHashSplatArgumentNode n).getMethodName() - } or TUnknownDataFlowType() } -class TElementContent = TKnownElementContent or TUnknownElementContent or THashSplatContent; +class TElementContent = TKnownElementContent or TUnknownElementContent; import Cached @@ -1118,18 +1110,6 @@ private module ParameterNodes { * * by adding read steps out of the synthesized parameter node to the relevant * keyword parameters. - * - * In order to avoid redundancy (and improve performance) in cases like - * - * ```rb - * foo(p1: taint(1), p2: taint(2)) - * ``` - * - * where direct keyword matching is possible, we use a special `HashSplatContent` - * (instead of reusing `KnownElementContent`) when we construct a synthesized hash - * splat argument (`SynthHashSplatArgumentNode`) at the call site, and then only - * add read steps out of this node for actual hash-splat arguments (which will use - * a normal `KnownElementContent`). */ class SynthHashSplatParameterNode extends ParameterNodeImpl, TSynthHashSplatParameterNode { private DataFlowCallable callable; @@ -1436,24 +1416,7 @@ module ArgumentNodes { not cv.isSymbol(_) ) | - if call instanceof CfgNodes::ExprNodes::HashLiteralCfgNode - then - /* - * Needed for cases like - * - * ```rb - * hash = { a: taint, b: safe } - * - * def foo(a:, b:) - * sink(a) - * end - * - * foo(**hash) - * ``` - */ - - c.isSingleton(Content::getElementContent(cv)) - else c.isSingleton(THashSplatContent(cv)) + c.isSingleton(Content::getElementContent(cv)) ) } @@ -1938,11 +1901,8 @@ DataFlowType getNodeType(Node n) { result = TLambdaDataFlowType(c) ) or - result = TSynthHashSplatArgumentType(n.(SynthHashSplatArgumentNode).getMethodName()) - or not n instanceof LambdaSelfReferenceNode and not mustHaveLambdaType(n, _) and - not n instanceof SynthHashSplatArgumentNode and result = TUnknownDataFlowType() } @@ -2168,11 +2128,6 @@ class ContentApprox extends TContentApprox { result = "approximated element " + approx ) or - exists(string s | - this = THashSplatContentApprox(s) and - result = "approximated hash-splat position " + s - ) - or exists(Content c | this = TNonElementContentApprox(c) and result = c.toString() @@ -2212,8 +2167,6 @@ ContentApprox getContentApprox(Content c) { result = TKnownElementContentApprox(approxKnownElementIndex(c.(Content::KnownElementContent).getIndex())) or - result = THashSplatContentApprox(approxKnownElementIndex(c.(Content::HashSplatContent).getKey())) - or result = TNonElementContentApprox(c) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll index 825c440c9a9..ee3105c3be7 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll @@ -629,7 +629,7 @@ module Content { * * we have an implicit hash-splat argument containing `{:a => 1, :b => 2, :c => 3}`. */ - class HashSplatContent extends ElementContent, THashSplatContent { + deprecated class HashSplatContent extends Content, THashSplatContent { private ConstantValue::ConstantSymbolValue cv; HashSplatContent() { this = THashSplatContent(cv) } @@ -797,7 +797,6 @@ class ContentSet extends TContentSet { private Content getAnElementReadContent() { exists(Content::KnownElementContent c | this.isKnownOrUnknownElement(c) | result = c or - result = THashSplatContent(c.getIndex()) or result = TUnknownElementContent() ) or @@ -815,8 +814,6 @@ class ContentSet extends TContentSet { | type = result.(Content::KnownElementContent).getIndex().getValueType() or - type = result.(Content::HashSplatContent).getKey().getValueType() - or includeUnknown = true and result = TUnknownElementContent() ) diff --git a/ruby/ql/test/library-tests/dataflow/api-graphs/VerifyApiGraphExpectations.expected b/ruby/ql/test/library-tests/dataflow/api-graphs/VerifyApiGraphExpectations.expected index 48de9172b36..8ec8033d086 100644 --- a/ruby/ql/test/library-tests/dataflow/api-graphs/VerifyApiGraphExpectations.expected +++ b/ruby/ql/test/library-tests/dataflow/api-graphs/VerifyApiGraphExpectations.expected @@ -1,2 +1,2 @@ -failures testFailures +failures diff --git a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected index 9f3e900d25d..63f33ab5b55 100644 --- a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected +++ b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected @@ -144,14 +144,14 @@ edges | semantics.rb:108:5:108:5 | b | semantics.rb:110:27:110:27 | b | provenance | | | semantics.rb:108:9:108:18 | call to source | semantics.rb:108:5:108:5 | b | provenance | | | semantics.rb:108:9:108:18 | call to source | semantics.rb:108:5:108:5 | b | provenance | | -| semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | semantics.rb:109:10:109:34 | ...[...] | provenance | | -| semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | semantics.rb:109:10:109:34 | ...[...] | provenance | | -| semantics.rb:109:19:109:19 | a | semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | provenance | | -| semantics.rb:109:19:109:19 | a | semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | provenance | | -| semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | semantics.rb:110:10:110:34 | ...[...] | provenance | | -| semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | semantics.rb:110:10:110:34 | ...[...] | provenance | | -| semantics.rb:110:27:110:27 | b | semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | provenance | | -| semantics.rb:110:27:110:27 | b | semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | provenance | | +| semantics.rb:109:10:109:28 | call to s15 [element :foo] | semantics.rb:109:10:109:34 | ...[...] | provenance | | +| semantics.rb:109:10:109:28 | call to s15 [element :foo] | semantics.rb:109:10:109:34 | ...[...] | provenance | | +| semantics.rb:109:19:109:19 | a | semantics.rb:109:10:109:28 | call to s15 [element :foo] | provenance | | +| semantics.rb:109:19:109:19 | a | semantics.rb:109:10:109:28 | call to s15 [element :foo] | provenance | | +| semantics.rb:110:10:110:28 | call to s15 [element :bar] | semantics.rb:110:10:110:34 | ...[...] | provenance | | +| semantics.rb:110:10:110:28 | call to s15 [element :bar] | semantics.rb:110:10:110:34 | ...[...] | provenance | | +| semantics.rb:110:27:110:27 | b | semantics.rb:110:10:110:28 | call to s15 [element :bar] | provenance | | +| semantics.rb:110:27:110:27 | b | semantics.rb:110:10:110:28 | call to s15 [element :bar] | provenance | | | semantics.rb:114:5:114:5 | a | semantics.rb:116:14:116:14 | a | provenance | | | semantics.rb:114:5:114:5 | a | semantics.rb:116:14:116:14 | a | provenance | | | semantics.rb:114:5:114:5 | a | semantics.rb:119:17:119:17 | a | provenance | | @@ -1269,14 +1269,14 @@ nodes | semantics.rb:108:5:108:5 | b | semmle.label | b | | semantics.rb:108:9:108:18 | call to source | semmle.label | call to source | | semantics.rb:108:9:108:18 | call to source | semmle.label | call to source | -| semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | semmle.label | call to s15 [hash-splat position :foo] | -| semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | semmle.label | call to s15 [hash-splat position :foo] | +| semantics.rb:109:10:109:28 | call to s15 [element :foo] | semmle.label | call to s15 [element :foo] | +| semantics.rb:109:10:109:28 | call to s15 [element :foo] | semmle.label | call to s15 [element :foo] | | semantics.rb:109:10:109:34 | ...[...] | semmle.label | ...[...] | | semantics.rb:109:10:109:34 | ...[...] | semmle.label | ...[...] | | semantics.rb:109:19:109:19 | a | semmle.label | a | | semantics.rb:109:19:109:19 | a | semmle.label | a | -| semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | semmle.label | call to s15 [hash-splat position :bar] | -| semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | semmle.label | call to s15 [hash-splat position :bar] | +| semantics.rb:110:10:110:28 | call to s15 [element :bar] | semmle.label | call to s15 [element :bar] | +| semantics.rb:110:10:110:28 | call to s15 [element :bar] | semmle.label | call to s15 [element :bar] | | semantics.rb:110:10:110:34 | ...[...] | semmle.label | ...[...] | | semantics.rb:110:10:110:34 | ...[...] | semmle.label | ...[...] | | semantics.rb:110:27:110:27 | b | semmle.label | b | diff --git a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected index 90b41808613..25e4a33a46b 100644 --- a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected +++ b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected @@ -134,17 +134,6 @@ track | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element :p2 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element :p3 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element :p3 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :c | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:17:25:24 | **kwargs | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:139:25:139:32 | **kwargs | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:1:11:1:11 | x | type tracker without call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:1:11:1:11 | x | type tracker without call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:1:11:1:11 | x | type tracker without call steps | params_flow.rb:14:12:14:19 | call to taint | @@ -362,38 +351,38 @@ track | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 4 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 4 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element 5 | params_flow.rb:94:1:94:48 | synthetic splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :c | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:37:8:37:44 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:37:8:37:44 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:38:8:38:13 | ** ... | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:40:8:40:26 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:40:8:40:26 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p1 | params_flow.rb:41:24:41:29 | ** ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:37:8:37:44 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:37:8:37:44 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:38:8:38:13 | ** ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:143:10:143:34 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:143:10:143:34 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:145:21:145:28 | ** ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:157:10:157:34 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:157:10:157:34 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:159:19:159:26 | ** ... | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p2 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | +| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p3 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p3 | params_flow.rb:34:8:34:32 | call to [] | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p3 | params_flow.rb:34:8:34:32 | synthetic hash-splat argument | | params_flow.rb:1:11:1:11 | x | type tracker without call steps with content element :p3 | params_flow.rb:35:23:35:28 | ** ... | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :c | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker without call steps with content hash-splat position :p3 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:5:1:7:3 | &block | type tracker without call steps | params_flow.rb:5:1:7:3 | &block | | params_flow.rb:5:1:7:3 | self in sink | type tracker without call steps | params_flow.rb:5:1:7:3 | self in sink | | params_flow.rb:5:1:7:3 | sink | type tracker without call steps | params_flow.rb:5:1:7:3 | sink | @@ -569,7 +558,6 @@ track | params_flow.rb:18:5:18:11 | call to sink | type tracker without call steps | params_flow.rb:41:1:41:30 | call to keyword | | params_flow.rb:18:5:18:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:21:1:21:35 | call to keyword | type tracker without call steps | params_flow.rb:21:1:21:35 | call to keyword | -| params_flow.rb:21:1:21:35 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | | params_flow.rb:21:9:21:10 | :p1 | type tracker without call steps | params_flow.rb:21:9:21:10 | :p1 | | params_flow.rb:21:9:21:20 | Pair | type tracker without call steps | params_flow.rb:21:9:21:20 | Pair | @@ -577,42 +565,37 @@ track | params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | -| params_flow.rb:21:13:21:20 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:21:13:21:20 | call to taint | type tracker without call steps | params_flow.rb:21:13:21:20 | call to taint | -| params_flow.rb:21:13:21:20 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | +| params_flow.rb:21:13:21:20 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | | params_flow.rb:21:13:21:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:21:13:21:20 | synthetic splat argument | | params_flow.rb:21:19:21:19 | 3 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:21:19:21:19 | 3 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:21:19:21:19 | 3 | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | -| params_flow.rb:21:19:21:19 | 3 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:21:19:21:19 | 3 | type tracker without call steps | params_flow.rb:21:13:21:20 | call to taint | | params_flow.rb:21:19:21:19 | 3 | type tracker without call steps | params_flow.rb:21:19:21:19 | 3 | | params_flow.rb:21:19:21:19 | 3 | type tracker without call steps with content element 0 | params_flow.rb:21:13:21:20 | synthetic splat argument | -| params_flow.rb:21:19:21:19 | 3 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | +| params_flow.rb:21:19:21:19 | 3 | type tracker without call steps with content element :p1 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | | params_flow.rb:21:23:21:24 | :p2 | type tracker without call steps | params_flow.rb:21:23:21:24 | :p2 | | params_flow.rb:21:23:21:34 | Pair | type tracker without call steps | params_flow.rb:21:23:21:34 | Pair | | params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | -| params_flow.rb:21:27:21:34 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:21:27:21:34 | call to taint | type tracker without call steps | params_flow.rb:21:27:21:34 | call to taint | -| params_flow.rb:21:27:21:34 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | +| params_flow.rb:21:27:21:34 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | | params_flow.rb:21:27:21:34 | synthetic splat argument | type tracker without call steps | params_flow.rb:21:27:21:34 | synthetic splat argument | | params_flow.rb:21:33:21:33 | 4 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:21:33:21:33 | 4 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:21:33:21:33 | 4 | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | -| params_flow.rb:21:33:21:33 | 4 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:21:33:21:33 | 4 | type tracker without call steps | params_flow.rb:21:27:21:34 | call to taint | | params_flow.rb:21:33:21:33 | 4 | type tracker without call steps | params_flow.rb:21:33:21:33 | 4 | | params_flow.rb:21:33:21:33 | 4 | type tracker without call steps with content element 0 | params_flow.rb:21:27:21:34 | synthetic splat argument | -| params_flow.rb:21:33:21:33 | 4 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | +| params_flow.rb:21:33:21:33 | 4 | type tracker without call steps with content element :p2 | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | | params_flow.rb:22:1:22:35 | call to keyword | type tracker without call steps | params_flow.rb:22:1:22:35 | call to keyword | -| params_flow.rb:22:1:22:35 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | | params_flow.rb:22:9:22:10 | :p2 | type tracker without call steps | params_flow.rb:22:9:22:10 | :p2 | | params_flow.rb:22:9:22:20 | Pair | type tracker without call steps | params_flow.rb:22:9:22:20 | Pair | @@ -620,42 +603,37 @@ track | params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | -| params_flow.rb:22:13:22:20 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:22:13:22:20 | call to taint | type tracker without call steps | params_flow.rb:22:13:22:20 | call to taint | -| params_flow.rb:22:13:22:20 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | +| params_flow.rb:22:13:22:20 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | | params_flow.rb:22:13:22:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:22:13:22:20 | synthetic splat argument | | params_flow.rb:22:19:22:19 | 5 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:22:19:22:19 | 5 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:22:19:22:19 | 5 | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | -| params_flow.rb:22:19:22:19 | 5 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:22:19:22:19 | 5 | type tracker without call steps | params_flow.rb:22:13:22:20 | call to taint | | params_flow.rb:22:19:22:19 | 5 | type tracker without call steps | params_flow.rb:22:19:22:19 | 5 | | params_flow.rb:22:19:22:19 | 5 | type tracker without call steps with content element 0 | params_flow.rb:22:13:22:20 | synthetic splat argument | -| params_flow.rb:22:19:22:19 | 5 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | +| params_flow.rb:22:19:22:19 | 5 | type tracker without call steps with content element :p2 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | | params_flow.rb:22:23:22:24 | :p1 | type tracker without call steps | params_flow.rb:22:23:22:24 | :p1 | | params_flow.rb:22:23:22:34 | Pair | type tracker without call steps | params_flow.rb:22:23:22:34 | Pair | | params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | -| params_flow.rb:22:27:22:34 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:22:27:22:34 | call to taint | type tracker without call steps | params_flow.rb:22:27:22:34 | call to taint | -| params_flow.rb:22:27:22:34 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | +| params_flow.rb:22:27:22:34 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | | params_flow.rb:22:27:22:34 | synthetic splat argument | type tracker without call steps | params_flow.rb:22:27:22:34 | synthetic splat argument | | params_flow.rb:22:33:22:33 | 6 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:22:33:22:33 | 6 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:22:33:22:33 | 6 | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | -| params_flow.rb:22:33:22:33 | 6 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:22:33:22:33 | 6 | type tracker without call steps | params_flow.rb:22:27:22:34 | call to taint | | params_flow.rb:22:33:22:33 | 6 | type tracker without call steps | params_flow.rb:22:33:22:33 | 6 | | params_flow.rb:22:33:22:33 | 6 | type tracker without call steps with content element 0 | params_flow.rb:22:27:22:34 | synthetic splat argument | -| params_flow.rb:22:33:22:33 | 6 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | +| params_flow.rb:22:33:22:33 | 6 | type tracker without call steps with content element :p1 | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | | params_flow.rb:23:1:23:41 | call to keyword | type tracker without call steps | params_flow.rb:23:1:23:41 | call to keyword | -| params_flow.rb:23:1:23:41 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | | params_flow.rb:23:9:23:11 | :p2 | type tracker without call steps | params_flow.rb:23:9:23:11 | :p2 | | params_flow.rb:23:9:23:23 | Pair | type tracker without call steps | params_flow.rb:23:9:23:23 | Pair | @@ -663,40 +641,36 @@ track | params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | -| params_flow.rb:23:16:23:23 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:23:16:23:23 | call to taint | type tracker without call steps | params_flow.rb:23:16:23:23 | call to taint | -| params_flow.rb:23:16:23:23 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | +| params_flow.rb:23:16:23:23 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | | params_flow.rb:23:16:23:23 | synthetic splat argument | type tracker without call steps | params_flow.rb:23:16:23:23 | synthetic splat argument | | params_flow.rb:23:22:23:22 | 7 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:23:22:23:22 | 7 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:23:22:23:22 | 7 | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | -| params_flow.rb:23:22:23:22 | 7 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:23:22:23:22 | 7 | type tracker without call steps | params_flow.rb:23:16:23:23 | call to taint | | params_flow.rb:23:22:23:22 | 7 | type tracker without call steps | params_flow.rb:23:22:23:22 | 7 | | params_flow.rb:23:22:23:22 | 7 | type tracker without call steps with content element 0 | params_flow.rb:23:16:23:23 | synthetic splat argument | -| params_flow.rb:23:22:23:22 | 7 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | +| params_flow.rb:23:22:23:22 | 7 | type tracker without call steps with content element :p2 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | | params_flow.rb:23:26:23:28 | :p1 | type tracker without call steps | params_flow.rb:23:26:23:28 | :p1 | | params_flow.rb:23:26:23:40 | Pair | type tracker without call steps | params_flow.rb:23:26:23:40 | Pair | | params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | -| params_flow.rb:23:33:23:40 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:23:33:23:40 | call to taint | type tracker without call steps | params_flow.rb:23:33:23:40 | call to taint | -| params_flow.rb:23:33:23:40 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | +| params_flow.rb:23:33:23:40 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | | params_flow.rb:23:33:23:40 | synthetic splat argument | type tracker without call steps | params_flow.rb:23:33:23:40 | synthetic splat argument | | params_flow.rb:23:39:23:39 | 8 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:23:39:23:39 | 8 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:23:39:23:39 | 8 | type tracker with call steps | params_flow.rb:16:13:16:14 | p1 | | params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content element 0 | params_flow.rb:17:5:17:11 | synthetic splat argument | -| params_flow.rb:23:39:23:39 | 8 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:23:39:23:39 | 8 | type tracker without call steps | params_flow.rb:23:33:23:40 | call to taint | | params_flow.rb:23:39:23:39 | 8 | type tracker without call steps | params_flow.rb:23:39:23:39 | 8 | | params_flow.rb:23:39:23:39 | 8 | type tracker without call steps with content element 0 | params_flow.rb:23:33:23:40 | synthetic splat argument | -| params_flow.rb:23:39:23:39 | 8 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | +| params_flow.rb:23:39:23:39 | 8 | type tracker without call steps with content element :p1 | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | | params_flow.rb:25:1:31:3 | &block | type tracker without call steps | params_flow.rb:25:1:31:3 | &block | | params_flow.rb:25:1:31:3 | kwargs | type tracker without call steps | params_flow.rb:25:1:31:3 | kwargs | | params_flow.rb:25:1:31:3 | self in kwargs | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | @@ -751,7 +725,6 @@ track | params_flow.rb:30:18:30:20 | :p4 | type tracker without call steps | params_flow.rb:30:18:30:20 | :p4 | | params_flow.rb:30:18:30:20 | :p4 | type tracker without call steps with content element 0 | params_flow.rb:30:11:30:21 | synthetic splat argument | | params_flow.rb:33:1:33:58 | call to kwargs | type tracker without call steps | params_flow.rb:33:1:33:58 | call to kwargs | -| params_flow.rb:33:1:33:58 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:33:8:33:9 | :p1 | type tracker without call steps | params_flow.rb:33:8:33:9 | :p1 | @@ -762,10 +735,9 @@ track | params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | | params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | -| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:17:25:24 | **kwargs | +| params_flow.rb:33:12:33:19 | call to taint | type tracker with call steps with content element :p1 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:33:12:33:19 | call to taint | type tracker without call steps | params_flow.rb:33:12:33:19 | call to taint | -| params_flow.rb:33:12:33:19 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | +| params_flow.rb:33:12:33:19 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:33:12:33:19 | synthetic splat argument | type tracker without call steps | params_flow.rb:33:12:33:19 | synthetic splat argument | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | @@ -774,66 +746,60 @@ track | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | | params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | -| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:17:25:24 | **kwargs | +| params_flow.rb:33:18:33:18 | 9 | type tracker with call steps with content element :p1 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:33:18:33:18 | 9 | type tracker without call steps | params_flow.rb:33:12:33:19 | call to taint | | params_flow.rb:33:18:33:18 | 9 | type tracker without call steps | params_flow.rb:33:18:33:18 | 9 | | params_flow.rb:33:18:33:18 | 9 | type tracker without call steps with content element 0 | params_flow.rb:33:12:33:19 | synthetic splat argument | -| params_flow.rb:33:18:33:18 | 9 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | +| params_flow.rb:33:18:33:18 | 9 | type tracker without call steps with content element :p1 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:33:22:33:23 | :p2 | type tracker without call steps | params_flow.rb:33:22:33:23 | :p2 | | params_flow.rb:33:22:33:34 | Pair | type tracker without call steps | params_flow.rb:33:22:33:34 | Pair | | params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps | params_flow.rb:28:11:28:21 | ...[...] | | params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | -| params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:17:25:24 | **kwargs | +| params_flow.rb:33:26:33:34 | call to taint | type tracker with call steps with content element :p2 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:33:26:33:34 | call to taint | type tracker without call steps | params_flow.rb:33:26:33:34 | call to taint | -| params_flow.rb:33:26:33:34 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | +| params_flow.rb:33:26:33:34 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:33:26:33:34 | synthetic splat argument | type tracker without call steps | params_flow.rb:33:26:33:34 | synthetic splat argument | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps | params_flow.rb:28:11:28:21 | ...[...] | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content element 0 | params_flow.rb:28:5:28:22 | synthetic splat argument | -| params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:25:17:25:24 | **kwargs | +| params_flow.rb:33:32:33:33 | 10 | type tracker with call steps with content element :p2 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:33:32:33:33 | 10 | type tracker without call steps | params_flow.rb:33:26:33:34 | call to taint | | params_flow.rb:33:32:33:33 | 10 | type tracker without call steps | params_flow.rb:33:32:33:33 | 10 | | params_flow.rb:33:32:33:33 | 10 | type tracker without call steps with content element 0 | params_flow.rb:33:26:33:34 | synthetic splat argument | -| params_flow.rb:33:32:33:33 | 10 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | +| params_flow.rb:33:32:33:33 | 10 | type tracker without call steps with content element :p2 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:33:37:33:38 | :p3 | type tracker without call steps | params_flow.rb:33:37:33:38 | :p3 | | params_flow.rb:33:37:33:49 | Pair | type tracker without call steps | params_flow.rb:33:37:33:49 | Pair | | params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps | params_flow.rb:29:11:29:21 | ...[...] | | params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | -| params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:17:25:24 | **kwargs | +| params_flow.rb:33:41:33:49 | call to taint | type tracker with call steps with content element :p3 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:33:41:33:49 | call to taint | type tracker without call steps | params_flow.rb:33:41:33:49 | call to taint | -| params_flow.rb:33:41:33:49 | call to taint | type tracker without call steps with content hash-splat position :p3 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | +| params_flow.rb:33:41:33:49 | call to taint | type tracker without call steps with content element :p3 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:33:41:33:49 | synthetic splat argument | type tracker without call steps | params_flow.rb:33:41:33:49 | synthetic splat argument | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps | params_flow.rb:29:11:29:21 | ...[...] | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content element 0 | params_flow.rb:29:5:29:22 | synthetic splat argument | -| params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content hash-splat position :p3 | params_flow.rb:25:17:25:24 | **kwargs | +| params_flow.rb:33:47:33:48 | 11 | type tracker with call steps with content element :p3 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:33:47:33:48 | 11 | type tracker without call steps | params_flow.rb:33:41:33:49 | call to taint | | params_flow.rb:33:47:33:48 | 11 | type tracker without call steps | params_flow.rb:33:47:33:48 | 11 | | params_flow.rb:33:47:33:48 | 11 | type tracker without call steps with content element 0 | params_flow.rb:33:41:33:49 | synthetic splat argument | -| params_flow.rb:33:47:33:48 | 11 | type tracker without call steps with content hash-splat position :p3 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | +| params_flow.rb:33:47:33:48 | 11 | type tracker without call steps with content element :p3 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:33:52:33:53 | :p4 | type tracker without call steps | params_flow.rb:33:52:33:53 | :p4 | | params_flow.rb:33:52:33:57 | Pair | type tracker without call steps | params_flow.rb:33:52:33:57 | Pair | | params_flow.rb:33:56:33:57 | "" | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:33:56:33:57 | "" | type tracker with call steps | params_flow.rb:30:11:30:21 | ...[...] | | params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content element 0 | params_flow.rb:30:5:30:22 | synthetic splat argument | -| params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content hash-splat position :p4 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content hash-splat position :p4 | params_flow.rb:25:17:25:24 | **kwargs | +| params_flow.rb:33:56:33:57 | "" | type tracker with call steps with content element :p4 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:33:56:33:57 | "" | type tracker without call steps | params_flow.rb:33:56:33:57 | "" | -| params_flow.rb:33:56:33:57 | "" | type tracker without call steps with content hash-splat position :p4 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | +| params_flow.rb:33:56:33:57 | "" | type tracker without call steps with content element :p4 | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | | params_flow.rb:34:1:34:4 | args | type tracker without call steps | params_flow.rb:34:1:34:4 | args | | params_flow.rb:34:8:34:32 | Hash | type tracker without call steps | params_flow.rb:34:8:34:32 | Hash | | params_flow.rb:34:8:34:32 | call to [] | type tracker without call steps | params_flow.rb:34:8:34:32 | call to [] | @@ -878,7 +844,6 @@ track | params_flow.rb:34:29:34:30 | "" | type tracker without call steps with content element :p4 | params_flow.rb:34:8:34:32 | synthetic hash-splat argument | | params_flow.rb:34:29:34:30 | "" | type tracker without call steps with content element :p4 | params_flow.rb:35:23:35:28 | ** ... | | params_flow.rb:35:1:35:29 | call to kwargs | type tracker without call steps | params_flow.rb:35:1:35:29 | call to kwargs | -| params_flow.rb:35:1:35:29 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | | params_flow.rb:35:8:35:9 | :p1 | type tracker without call steps | params_flow.rb:35:8:35:9 | :p1 | @@ -889,10 +854,9 @@ track | params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | | params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | -| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:17:25:24 | **kwargs | +| params_flow.rb:35:12:35:20 | call to taint | type tracker with call steps with content element :p1 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:35:12:35:20 | call to taint | type tracker without call steps | params_flow.rb:35:12:35:20 | call to taint | -| params_flow.rb:35:12:35:20 | call to taint | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | +| params_flow.rb:35:12:35:20 | call to taint | type tracker without call steps with content element :p1 | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | | params_flow.rb:35:12:35:20 | synthetic splat argument | type tracker without call steps | params_flow.rb:35:12:35:20 | synthetic splat argument | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | @@ -901,12 +865,11 @@ track | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content element 0 | params_flow.rb:26:5:26:11 | synthetic splat argument | | params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content element 0 | params_flow.rb:27:5:27:22 | synthetic splat argument | -| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | -| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:25:17:25:24 | **kwargs | +| params_flow.rb:35:18:35:19 | 13 | type tracker with call steps with content element :p1 | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:35:18:35:19 | 13 | type tracker without call steps | params_flow.rb:35:12:35:20 | call to taint | | params_flow.rb:35:18:35:19 | 13 | type tracker without call steps | params_flow.rb:35:18:35:19 | 13 | | params_flow.rb:35:18:35:19 | 13 | type tracker without call steps with content element 0 | params_flow.rb:35:12:35:20 | synthetic splat argument | -| params_flow.rb:35:18:35:19 | 13 | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | +| params_flow.rb:35:18:35:19 | 13 | type tracker without call steps with content element :p1 | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | | params_flow.rb:35:23:35:28 | ** ... | type tracker with call steps | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:35:23:35:28 | ** ... | type tracker with call steps | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:35:23:35:28 | ** ... | type tracker without call steps | params_flow.rb:35:23:35:28 | ** ... | @@ -1005,7 +968,6 @@ track | params_flow.rb:40:22:40:23 | 16 | type tracker without call steps with content element :p1 | params_flow.rb:40:8:40:26 | synthetic hash-splat argument | | params_flow.rb:40:22:40:23 | 16 | type tracker without call steps with content element :p1 | params_flow.rb:41:24:41:29 | ** ... | | params_flow.rb:41:1:41:30 | call to keyword | type tracker without call steps | params_flow.rb:41:1:41:30 | call to keyword | -| params_flow.rb:41:1:41:30 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | | params_flow.rb:41:9:41:10 | :p2 | type tracker without call steps | params_flow.rb:41:9:41:10 | :p2 | | params_flow.rb:41:9:41:21 | Pair | type tracker without call steps | params_flow.rb:41:9:41:21 | Pair | @@ -1013,20 +975,18 @@ track | params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | -| params_flow.rb:41:13:41:21 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:41:13:41:21 | call to taint | type tracker without call steps | params_flow.rb:41:13:41:21 | call to taint | -| params_flow.rb:41:13:41:21 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | +| params_flow.rb:41:13:41:21 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | | params_flow.rb:41:13:41:21 | synthetic splat argument | type tracker without call steps | params_flow.rb:41:13:41:21 | synthetic splat argument | | params_flow.rb:41:19:41:20 | 17 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:41:19:41:20 | 17 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:41:19:41:20 | 17 | type tracker with call steps | params_flow.rb:16:18:16:19 | p2 | | params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content element 0 | params_flow.rb:18:5:18:11 | synthetic splat argument | -| params_flow.rb:41:19:41:20 | 17 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:41:19:41:20 | 17 | type tracker without call steps | params_flow.rb:41:13:41:21 | call to taint | | params_flow.rb:41:19:41:20 | 17 | type tracker without call steps | params_flow.rb:41:19:41:20 | 17 | | params_flow.rb:41:19:41:20 | 17 | type tracker without call steps with content element 0 | params_flow.rb:41:13:41:21 | synthetic splat argument | -| params_flow.rb:41:19:41:20 | 17 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | +| params_flow.rb:41:19:41:20 | 17 | type tracker without call steps with content element :p2 | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | | params_flow.rb:41:24:41:29 | ** ... | type tracker with call steps | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:41:24:41:29 | ** ... | type tracker without call steps | params_flow.rb:41:24:41:29 | ** ... | | params_flow.rb:43:1:43:4 | args | type tracker without call steps | params_flow.rb:43:1:43:4 | args | @@ -2208,7 +2168,6 @@ track | params_flow.rb:111:5:111:10 | call to sink | type tracker without call steps | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | | params_flow.rb:111:5:111:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | type tracker without call steps | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | -| params_flow.rb:114:1:114:67 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | | params_flow.rb:114:1:114:67 | synthetic splat argument | type tracker with call steps | params_flow.rb:108:1:112:3 | synthetic splat parameter | | params_flow.rb:114:1:114:67 | synthetic splat argument | type tracker without call steps | params_flow.rb:114:1:114:67 | synthetic splat argument | @@ -2256,20 +2215,18 @@ track | params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps | params_flow.rb:108:44:108:44 | c | | params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | -| params_flow.rb:114:58:114:66 | call to taint | type tracker with call steps with content hash-splat position :c | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | | params_flow.rb:114:58:114:66 | call to taint | type tracker without call steps | params_flow.rb:114:58:114:66 | call to taint | -| params_flow.rb:114:58:114:66 | call to taint | type tracker without call steps with content hash-splat position :c | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | +| params_flow.rb:114:58:114:66 | call to taint | type tracker without call steps with content element :c | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | | params_flow.rb:114:58:114:66 | synthetic splat argument | type tracker without call steps | params_flow.rb:114:58:114:66 | synthetic splat argument | | params_flow.rb:114:64:114:65 | 60 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:114:64:114:65 | 60 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:114:64:114:65 | 60 | type tracker with call steps | params_flow.rb:108:44:108:44 | c | | params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content element 0 | params_flow.rb:111:5:111:10 | synthetic splat argument | -| params_flow.rb:114:64:114:65 | 60 | type tracker with call steps with content hash-splat position :c | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | | params_flow.rb:114:64:114:65 | 60 | type tracker without call steps | params_flow.rb:114:58:114:66 | call to taint | | params_flow.rb:114:64:114:65 | 60 | type tracker without call steps | params_flow.rb:114:64:114:65 | 60 | | params_flow.rb:114:64:114:65 | 60 | type tracker without call steps with content element 0 | params_flow.rb:114:58:114:66 | synthetic splat argument | -| params_flow.rb:114:64:114:65 | 60 | type tracker without call steps with content hash-splat position :c | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | +| params_flow.rb:114:64:114:65 | 60 | type tracker without call steps with content element :c | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | | params_flow.rb:116:1:116:1 | x | type tracker without call steps | params_flow.rb:116:1:116:1 | x | | params_flow.rb:116:5:116:6 | Array | type tracker without call steps | params_flow.rb:116:5:116:6 | Array | | params_flow.rb:116:5:116:6 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | @@ -2699,9 +2656,9 @@ track | params_flow.rb:148:1:148:2 | p1 | type tracker without call steps | params_flow.rb:148:1:148:2 | p1 | | params_flow.rb:148:6:148:7 | Array | type tracker without call steps | params_flow.rb:148:6:148:7 | Array | | params_flow.rb:148:6:148:7 | call to [] | type tracker with call steps | params_flow.rb:140:5:140:15 | ...[...] | -| params_flow.rb:148:6:148:7 | call to [] | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:139:25:139:32 | **kwargs | +| params_flow.rb:148:6:148:7 | call to [] | type tracker with call steps with content element :p1 | params_flow.rb:139:25:139:32 | **kwargs | | params_flow.rb:148:6:148:7 | call to [] | type tracker without call steps | params_flow.rb:148:6:148:7 | call to [] | -| params_flow.rb:148:6:148:7 | call to [] | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | +| params_flow.rb:148:6:148:7 | call to [] | type tracker without call steps with content element :p1 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | | params_flow.rb:149:1:149:11 | call to sink | type tracker without call steps | params_flow.rb:149:1:149:11 | call to sink | | params_flow.rb:149:1:149:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:149:1:149:11 | synthetic splat argument | | params_flow.rb:149:6:149:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | @@ -2722,20 +2679,20 @@ track | params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:15 | [post] ...[...] | | params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:38 | call to insert | | params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | -| params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:139:25:139:32 | **kwargs | +| params_flow.rb:150:33:150:41 | call to taint | type tracker with call steps with content element :p2 | params_flow.rb:139:25:139:32 | **kwargs | | params_flow.rb:150:33:150:41 | call to taint | type tracker without call steps | params_flow.rb:150:33:150:41 | call to taint | -| params_flow.rb:150:33:150:41 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | +| params_flow.rb:150:33:150:41 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | | params_flow.rb:150:33:150:41 | synthetic splat argument | type tracker without call steps | params_flow.rb:150:33:150:41 | synthetic splat argument | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps | params_flow.rb:140:27:140:37 | ...[...] | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:15 | [post] ...[...] | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content element 0 or unknown | params_flow.rb:140:5:140:38 | call to insert | | params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content element 1 | params_flow.rb:140:5:140:38 | synthetic splat argument | -| params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:139:25:139:32 | **kwargs | +| params_flow.rb:150:39:150:40 | 73 | type tracker with call steps with content element :p2 | params_flow.rb:139:25:139:32 | **kwargs | | params_flow.rb:150:39:150:40 | 73 | type tracker without call steps | params_flow.rb:150:33:150:41 | call to taint | | params_flow.rb:150:39:150:40 | 73 | type tracker without call steps | params_flow.rb:150:39:150:40 | 73 | | params_flow.rb:150:39:150:40 | 73 | type tracker without call steps with content element 0 | params_flow.rb:150:33:150:41 | synthetic splat argument | -| params_flow.rb:150:39:150:40 | 73 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | +| params_flow.rb:150:39:150:40 | 73 | type tracker without call steps with content element :p2 | params_flow.rb:150:1:150:42 | synthetic hash-splat argument | | params_flow.rb:151:1:151:11 | call to sink | type tracker without call steps | params_flow.rb:151:1:151:11 | call to sink | | params_flow.rb:151:1:151:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:151:1:151:11 | synthetic splat argument | | params_flow.rb:151:6:151:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | @@ -2837,9 +2794,8 @@ track | params_flow.rb:162:1:162:2 | p1 | type tracker without call steps | params_flow.rb:162:1:162:2 | p1 | | params_flow.rb:162:6:162:7 | Array | type tracker without call steps | params_flow.rb:162:6:162:7 | Array | | params_flow.rb:162:6:162:7 | call to [] | type tracker with call steps | params_flow.rb:153:23:153:24 | p1 | -| params_flow.rb:162:6:162:7 | call to [] | type tracker with call steps with content hash-splat position :p1 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:162:6:162:7 | call to [] | type tracker without call steps | params_flow.rb:162:6:162:7 | call to [] | -| params_flow.rb:162:6:162:7 | call to [] | type tracker without call steps with content hash-splat position :p1 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | +| params_flow.rb:162:6:162:7 | call to [] | type tracker without call steps with content element :p1 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | | params_flow.rb:163:1:163:11 | call to sink | type tracker without call steps | params_flow.rb:163:1:163:11 | call to sink | | params_flow.rb:163:1:163:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:163:1:163:11 | synthetic splat argument | | params_flow.rb:163:6:163:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | @@ -2850,7 +2806,6 @@ track | params_flow.rb:163:9:163:9 | 0 | type tracker without call steps | params_flow.rb:163:9:163:9 | 0 | | params_flow.rb:163:9:163:9 | 0 | type tracker without call steps with content element 0 | params_flow.rb:163:6:163:10 | synthetic splat argument | | params_flow.rb:164:1:164:40 | call to keywordSideEffect | type tracker without call steps | params_flow.rb:164:1:164:40 | call to keywordSideEffect | -| params_flow.rb:164:1:164:40 | synthetic hash-splat argument | type tracker with call steps | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | type tracker without call steps | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | | params_flow.rb:164:19:164:20 | :p1 | type tracker without call steps | params_flow.rb:164:19:164:20 | :p1 | | params_flow.rb:164:19:164:24 | Pair | type tracker without call steps | params_flow.rb:164:19:164:24 | Pair | @@ -2860,20 +2815,18 @@ track | params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:6 | [post] p1 | | params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:20 | call to insert | | params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | -| params_flow.rb:164:31:164:39 | call to taint | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:164:31:164:39 | call to taint | type tracker without call steps | params_flow.rb:164:31:164:39 | call to taint | -| params_flow.rb:164:31:164:39 | call to taint | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | +| params_flow.rb:164:31:164:39 | call to taint | type tracker without call steps with content element :p2 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | | params_flow.rb:164:31:164:39 | synthetic splat argument | type tracker without call steps | params_flow.rb:164:31:164:39 | synthetic splat argument | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps | params_flow.rb:153:28:153:29 | p2 | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:6 | [post] p1 | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content element 0 or unknown | params_flow.rb:154:5:154:20 | call to insert | | params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content element 1 | params_flow.rb:154:5:154:20 | synthetic splat argument | -| params_flow.rb:164:37:164:38 | 75 | type tracker with call steps with content hash-splat position :p2 | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:164:37:164:38 | 75 | type tracker without call steps | params_flow.rb:164:31:164:39 | call to taint | | params_flow.rb:164:37:164:38 | 75 | type tracker without call steps | params_flow.rb:164:37:164:38 | 75 | | params_flow.rb:164:37:164:38 | 75 | type tracker without call steps with content element 0 | params_flow.rb:164:31:164:39 | synthetic splat argument | -| params_flow.rb:164:37:164:38 | 75 | type tracker without call steps with content hash-splat position :p2 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | +| params_flow.rb:164:37:164:38 | 75 | type tracker without call steps with content element :p2 | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | | params_flow.rb:165:1:165:11 | call to sink | type tracker without call steps | params_flow.rb:165:1:165:11 | call to sink | | params_flow.rb:165:1:165:11 | synthetic splat argument | type tracker without call steps | params_flow.rb:165:1:165:11 | synthetic splat argument | | params_flow.rb:165:6:165:10 | ...[...] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | @@ -3841,7 +3794,6 @@ trackEnd | params_flow.rb:18:5:18:11 | call to sink | params_flow.rb:41:1:41:30 | call to keyword | | params_flow.rb:18:5:18:11 | synthetic splat argument | params_flow.rb:18:5:18:11 | synthetic splat argument | | params_flow.rb:21:1:21:35 | call to keyword | params_flow.rb:21:1:21:35 | call to keyword | -| params_flow.rb:21:1:21:35 | synthetic hash-splat argument | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | params_flow.rb:21:1:21:35 | synthetic hash-splat argument | | params_flow.rb:21:9:21:10 | :p1 | params_flow.rb:21:9:21:10 | :p1 | | params_flow.rb:21:9:21:20 | Pair | params_flow.rb:21:9:21:20 | Pair | @@ -3886,7 +3838,6 @@ trackEnd | params_flow.rb:21:33:21:33 | 4 | params_flow.rb:21:27:21:34 | call to taint | | params_flow.rb:21:33:21:33 | 4 | params_flow.rb:21:33:21:33 | 4 | | params_flow.rb:22:1:22:35 | call to keyword | params_flow.rb:22:1:22:35 | call to keyword | -| params_flow.rb:22:1:22:35 | synthetic hash-splat argument | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | params_flow.rb:22:1:22:35 | synthetic hash-splat argument | | params_flow.rb:22:9:22:10 | :p2 | params_flow.rb:22:9:22:10 | :p2 | | params_flow.rb:22:9:22:20 | Pair | params_flow.rb:22:9:22:20 | Pair | @@ -3931,7 +3882,6 @@ trackEnd | params_flow.rb:22:33:22:33 | 6 | params_flow.rb:22:27:22:34 | call to taint | | params_flow.rb:22:33:22:33 | 6 | params_flow.rb:22:33:22:33 | 6 | | params_flow.rb:23:1:23:41 | call to keyword | params_flow.rb:23:1:23:41 | call to keyword | -| params_flow.rb:23:1:23:41 | synthetic hash-splat argument | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | params_flow.rb:23:1:23:41 | synthetic hash-splat argument | | params_flow.rb:23:9:23:11 | :p2 | params_flow.rb:23:9:23:11 | :p2 | | params_flow.rb:23:9:23:23 | Pair | params_flow.rb:23:9:23:23 | Pair | @@ -4044,7 +3994,6 @@ trackEnd | params_flow.rb:30:11:30:21 | synthetic splat argument | params_flow.rb:30:11:30:21 | synthetic splat argument | | params_flow.rb:30:18:30:20 | :p4 | params_flow.rb:30:18:30:20 | :p4 | | params_flow.rb:33:1:33:58 | call to kwargs | params_flow.rb:33:1:33:58 | call to kwargs | -| params_flow.rb:33:1:33:58 | synthetic hash-splat argument | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | params_flow.rb:25:19:25:24 | kwargs | | params_flow.rb:33:1:33:58 | synthetic hash-splat argument | params_flow.rb:27:11:27:16 | kwargs | @@ -4162,7 +4111,6 @@ trackEnd | params_flow.rb:34:29:34:30 | "" | params_flow.rb:30:11:30:21 | ...[...] | | params_flow.rb:34:29:34:30 | "" | params_flow.rb:34:29:34:30 | "" | | params_flow.rb:35:1:35:29 | call to kwargs | params_flow.rb:35:1:35:29 | call to kwargs | -| params_flow.rb:35:1:35:29 | synthetic hash-splat argument | params_flow.rb:25:1:31:3 | synthetic hash-splat parameter | | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | params_flow.rb:25:17:25:24 | **kwargs | | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | params_flow.rb:25:19:25:24 | kwargs | | params_flow.rb:35:1:35:29 | synthetic hash-splat argument | params_flow.rb:27:11:27:16 | kwargs | @@ -4300,7 +4248,6 @@ trackEnd | params_flow.rb:40:22:40:23 | 16 | params_flow.rb:40:16:40:24 | call to taint | | params_flow.rb:40:22:40:23 | 16 | params_flow.rb:40:22:40:23 | 16 | | params_flow.rb:41:1:41:30 | call to keyword | params_flow.rb:41:1:41:30 | call to keyword | -| params_flow.rb:41:1:41:30 | synthetic hash-splat argument | params_flow.rb:16:1:19:3 | synthetic hash-splat parameter | | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | params_flow.rb:41:1:41:30 | synthetic hash-splat argument | | params_flow.rb:41:9:41:10 | :p2 | params_flow.rb:41:9:41:10 | :p2 | | params_flow.rb:41:9:41:21 | Pair | params_flow.rb:41:9:41:21 | Pair | @@ -5498,7 +5445,6 @@ trackEnd | params_flow.rb:111:5:111:10 | call to sink | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | | params_flow.rb:111:5:111:10 | synthetic splat argument | params_flow.rb:111:5:111:10 | synthetic splat argument | | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | params_flow.rb:114:1:114:67 | call to splat_followed_by_keyword_param | -| params_flow.rb:114:1:114:67 | synthetic hash-splat argument | params_flow.rb:108:1:112:3 | synthetic hash-splat parameter | | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | params_flow.rb:114:1:114:67 | synthetic hash-splat argument | | params_flow.rb:114:1:114:67 | synthetic splat argument | params_flow.rb:108:1:112:3 | synthetic splat parameter | | params_flow.rb:114:1:114:67 | synthetic splat argument | params_flow.rb:114:1:114:67 | synthetic splat argument | @@ -6111,7 +6057,6 @@ trackEnd | params_flow.rb:163:6:163:10 | synthetic splat argument | params_flow.rb:163:6:163:10 | synthetic splat argument | | params_flow.rb:163:9:163:9 | 0 | params_flow.rb:163:9:163:9 | 0 | | params_flow.rb:164:1:164:40 | call to keywordSideEffect | params_flow.rb:164:1:164:40 | call to keywordSideEffect | -| params_flow.rb:164:1:164:40 | synthetic hash-splat argument | params_flow.rb:153:1:155:3 | synthetic hash-splat parameter | | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | params_flow.rb:164:1:164:40 | synthetic hash-splat argument | | params_flow.rb:164:19:164:20 | :p1 | params_flow.rb:164:19:164:20 | :p1 | | params_flow.rb:164:19:164:24 | Pair | params_flow.rb:164:19:164:24 | Pair | diff --git a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected index 4b079e0ebbb..0484c2f1e27 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected @@ -15,17 +15,13 @@ edges | params_flow.rb:25:12:25:13 | p1 | params_flow.rb:26:10:26:11 | p1 | provenance | | | params_flow.rb:25:17:25:24 | **kwargs [element :p2] | params_flow.rb:28:11:28:16 | kwargs [element :p2] | provenance | | | params_flow.rb:25:17:25:24 | **kwargs [element :p3] | params_flow.rb:29:11:29:16 | kwargs [element :p3] | provenance | | -| params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p2] | params_flow.rb:28:11:28:16 | kwargs [hash-splat position :p2] | provenance | | -| params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p3] | params_flow.rb:29:11:29:16 | kwargs [hash-splat position :p3] | provenance | | | params_flow.rb:28:11:28:16 | kwargs [element :p2] | params_flow.rb:28:11:28:21 | ...[...] | provenance | | -| params_flow.rb:28:11:28:16 | kwargs [hash-splat position :p2] | params_flow.rb:28:11:28:21 | ...[...] | provenance | | | params_flow.rb:28:11:28:21 | ...[...] | params_flow.rb:28:10:28:22 | ( ... ) | provenance | | | params_flow.rb:29:11:29:16 | kwargs [element :p3] | params_flow.rb:29:11:29:21 | ...[...] | provenance | | -| params_flow.rb:29:11:29:16 | kwargs [hash-splat position :p3] | params_flow.rb:29:11:29:21 | ...[...] | provenance | | | params_flow.rb:29:11:29:21 | ...[...] | params_flow.rb:29:10:29:22 | ( ... ) | provenance | | | params_flow.rb:33:12:33:19 | call to taint | params_flow.rb:25:12:25:13 | p1 | provenance | | -| params_flow.rb:33:26:33:34 | call to taint | params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p2] | provenance | | -| params_flow.rb:33:41:33:49 | call to taint | params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p3] | provenance | | +| params_flow.rb:33:26:33:34 | call to taint | params_flow.rb:25:17:25:24 | **kwargs [element :p2] | provenance | | +| params_flow.rb:33:41:33:49 | call to taint | params_flow.rb:25:17:25:24 | **kwargs [element :p3] | provenance | | | params_flow.rb:34:1:34:4 | args [element :p3] | params_flow.rb:35:25:35:28 | args [element :p3] | provenance | | | params_flow.rb:34:8:34:32 | call to [] [element :p3] | params_flow.rb:34:1:34:4 | args [element :p3] | provenance | | | params_flow.rb:34:14:34:22 | call to taint | params_flow.rb:34:8:34:32 | call to [] [element :p3] | provenance | | @@ -206,16 +202,12 @@ nodes | params_flow.rb:25:12:25:13 | p1 | semmle.label | p1 | | params_flow.rb:25:17:25:24 | **kwargs [element :p2] | semmle.label | **kwargs [element :p2] | | params_flow.rb:25:17:25:24 | **kwargs [element :p3] | semmle.label | **kwargs [element :p3] | -| params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p2] | semmle.label | **kwargs [hash-splat position :p2] | -| params_flow.rb:25:17:25:24 | **kwargs [hash-splat position :p3] | semmle.label | **kwargs [hash-splat position :p3] | | params_flow.rb:26:10:26:11 | p1 | semmle.label | p1 | | params_flow.rb:28:10:28:22 | ( ... ) | semmle.label | ( ... ) | | params_flow.rb:28:11:28:16 | kwargs [element :p2] | semmle.label | kwargs [element :p2] | -| params_flow.rb:28:11:28:16 | kwargs [hash-splat position :p2] | semmle.label | kwargs [hash-splat position :p2] | | params_flow.rb:28:11:28:21 | ...[...] | semmle.label | ...[...] | | params_flow.rb:29:10:29:22 | ( ... ) | semmle.label | ( ... ) | | params_flow.rb:29:11:29:16 | kwargs [element :p3] | semmle.label | kwargs [element :p3] | -| params_flow.rb:29:11:29:16 | kwargs [hash-splat position :p3] | semmle.label | kwargs [hash-splat position :p3] | | params_flow.rb:29:11:29:21 | ...[...] | semmle.label | ...[...] | | params_flow.rb:33:12:33:19 | call to taint | semmle.label | call to taint | | params_flow.rb:33:26:33:34 | call to taint | semmle.label | call to taint | diff --git a/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected b/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected index f0199572d78..7b308c6816c 100644 --- a/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected +++ b/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected @@ -98,56 +98,47 @@ track | type_tracker.rb:27:5:27:11 | call to puts | type tracker without call steps | type_tracker.rb:32:1:32:27 | call to keyword | | type_tracker.rb:27:5:27:11 | synthetic splat argument | type tracker without call steps | type_tracker.rb:27:5:27:11 | synthetic splat argument | | type_tracker.rb:30:1:30:21 | call to keyword | type tracker without call steps | type_tracker.rb:30:1:30:21 | call to keyword | -| type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | type tracker with call steps | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | type tracker without call steps | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | | type_tracker.rb:30:9:30:10 | :p1 | type tracker without call steps | type_tracker.rb:30:9:30:10 | :p1 | | type_tracker.rb:30:9:30:13 | Pair | type tracker without call steps | type_tracker.rb:30:9:30:13 | Pair | | type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content element 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | -| type_tracker.rb:30:13:30:13 | 3 | type tracker with call steps with content hash-splat position :p1 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps | type_tracker.rb:30:13:30:13 | 3 | -| type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps with content hash-splat position :p1 | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | +| type_tracker.rb:30:13:30:13 | 3 | type tracker without call steps with content element :p1 | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | | type_tracker.rb:30:16:30:17 | :p2 | type tracker without call steps | type_tracker.rb:30:16:30:17 | :p2 | | type_tracker.rb:30:16:30:20 | Pair | type tracker without call steps | type_tracker.rb:30:16:30:20 | Pair | | type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content element 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | -| type_tracker.rb:30:20:30:20 | 4 | type tracker with call steps with content hash-splat position :p2 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps | type_tracker.rb:30:20:30:20 | 4 | -| type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps with content hash-splat position :p2 | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | +| type_tracker.rb:30:20:30:20 | 4 | type tracker without call steps with content element :p2 | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | | type_tracker.rb:31:1:31:21 | call to keyword | type tracker without call steps | type_tracker.rb:31:1:31:21 | call to keyword | -| type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | type tracker with call steps | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | type tracker without call steps | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | | type_tracker.rb:31:9:31:10 | :p2 | type tracker without call steps | type_tracker.rb:31:9:31:10 | :p2 | | type_tracker.rb:31:9:31:13 | Pair | type tracker without call steps | type_tracker.rb:31:9:31:13 | Pair | | type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content element 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | -| type_tracker.rb:31:13:31:13 | 5 | type tracker with call steps with content hash-splat position :p2 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps | type_tracker.rb:31:13:31:13 | 5 | -| type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps with content hash-splat position :p2 | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | +| type_tracker.rb:31:13:31:13 | 5 | type tracker without call steps with content element :p2 | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | | type_tracker.rb:31:16:31:17 | :p1 | type tracker without call steps | type_tracker.rb:31:16:31:17 | :p1 | | type_tracker.rb:31:16:31:20 | Pair | type tracker without call steps | type_tracker.rb:31:16:31:20 | Pair | | type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content element 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | -| type_tracker.rb:31:20:31:20 | 6 | type tracker with call steps with content hash-splat position :p1 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps | type_tracker.rb:31:20:31:20 | 6 | -| type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps with content hash-splat position :p1 | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | +| type_tracker.rb:31:20:31:20 | 6 | type tracker without call steps with content element :p1 | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | | type_tracker.rb:32:1:32:27 | call to keyword | type tracker without call steps | type_tracker.rb:32:1:32:27 | call to keyword | -| type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | type tracker with call steps | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | type tracker without call steps | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | | type_tracker.rb:32:9:32:11 | :p2 | type tracker without call steps | type_tracker.rb:32:9:32:11 | :p2 | | type_tracker.rb:32:9:32:16 | Pair | type tracker without call steps | type_tracker.rb:32:9:32:16 | Pair | | type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps | type_tracker.rb:25:18:25:19 | p2 | | type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content element 0 | type_tracker.rb:27:5:27:11 | synthetic splat argument | -| type_tracker.rb:32:16:32:16 | 7 | type tracker with call steps with content hash-splat position :p2 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps | type_tracker.rb:32:16:32:16 | 7 | -| type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps with content hash-splat position :p2 | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | +| type_tracker.rb:32:16:32:16 | 7 | type tracker without call steps with content element :p2 | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | | type_tracker.rb:32:19:32:21 | :p1 | type tracker without call steps | type_tracker.rb:32:19:32:21 | :p1 | | type_tracker.rb:32:19:32:26 | Pair | type tracker without call steps | type_tracker.rb:32:19:32:26 | Pair | | type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps | type_tracker.rb:25:13:25:14 | p1 | | type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content element 0 | type_tracker.rb:26:5:26:11 | synthetic splat argument | -| type_tracker.rb:32:26:32:26 | 8 | type tracker with call steps with content hash-splat position :p1 | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps | type_tracker.rb:32:26:32:26 | 8 | -| type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps with content hash-splat position :p1 | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | +| type_tracker.rb:32:26:32:26 | 8 | type tracker without call steps with content element :p1 | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | | type_tracker.rb:34:1:53:3 | &block | type tracker without call steps | type_tracker.rb:34:1:53:3 | &block | | type_tracker.rb:34:1:53:3 | self in throughArray | type tracker without call steps | type_tracker.rb:34:1:53:3 | self in throughArray | | type_tracker.rb:34:1:53:3 | synthetic splat parameter | type tracker without call steps | type_tracker.rb:34:1:53:3 | synthetic splat parameter | @@ -484,7 +475,6 @@ trackEnd | type_tracker.rb:27:5:27:11 | call to puts | type_tracker.rb:32:1:32:27 | call to keyword | | type_tracker.rb:27:5:27:11 | synthetic splat argument | type_tracker.rb:27:5:27:11 | synthetic splat argument | | type_tracker.rb:30:1:30:21 | call to keyword | type_tracker.rb:30:1:30:21 | call to keyword | -| type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | type_tracker.rb:30:1:30:21 | synthetic hash-splat argument | | type_tracker.rb:30:9:30:10 | :p1 | type_tracker.rb:30:9:30:10 | :p1 | | type_tracker.rb:30:9:30:13 | Pair | type_tracker.rb:30:9:30:13 | Pair | @@ -499,7 +489,6 @@ trackEnd | type_tracker.rb:30:20:30:20 | 4 | type_tracker.rb:27:10:27:11 | p2 | | type_tracker.rb:30:20:30:20 | 4 | type_tracker.rb:30:20:30:20 | 4 | | type_tracker.rb:31:1:31:21 | call to keyword | type_tracker.rb:31:1:31:21 | call to keyword | -| type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | type_tracker.rb:31:1:31:21 | synthetic hash-splat argument | | type_tracker.rb:31:9:31:10 | :p2 | type_tracker.rb:31:9:31:10 | :p2 | | type_tracker.rb:31:9:31:13 | Pair | type_tracker.rb:31:9:31:13 | Pair | @@ -514,7 +503,6 @@ trackEnd | type_tracker.rb:31:20:31:20 | 6 | type_tracker.rb:26:10:26:11 | p1 | | type_tracker.rb:31:20:31:20 | 6 | type_tracker.rb:31:20:31:20 | 6 | | type_tracker.rb:32:1:32:27 | call to keyword | type_tracker.rb:32:1:32:27 | call to keyword | -| type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | type_tracker.rb:25:1:28:3 | synthetic hash-splat parameter | | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | type_tracker.rb:32:1:32:27 | synthetic hash-splat argument | | type_tracker.rb:32:9:32:11 | :p2 | type_tracker.rb:32:9:32:11 | :p2 | | type_tracker.rb:32:9:32:16 | Pair | type_tracker.rb:32:9:32:16 | Pair | From c4b0f818837ed81bbbd87760f2a0e2ac21f1a655 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 20 Aug 2024 14:19:29 +0200 Subject: [PATCH 034/404] Ruby: Prevent positional matching when preceded by a splat --- .../dataflow/internal/DataFlowPrivate.qll | 21 +- .../dataflow/params/TypeTracker.expected | 195 ------------------ .../dataflow/params/params-flow.expected | 30 --- .../dataflow/params/params_flow.rb | 12 +- 4 files changed, 22 insertions(+), 236 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 620a9fb5cab..1cfb3b0f395 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -195,7 +195,9 @@ private class Argument extends CfgNodes::ExprCfgNode { not this.getExpr().(Pair).getKey().getConstantValue().isSymbol(_) and not this.getExpr() instanceof HashSplatExpr and not this.getExpr() instanceof SplatExpr and - arg.isPositional(i) + arg.isPositional(i) and + // There are no splat arguments before the positional argument + not splatArgumentAt(call, any(int j | j < i)) ) or exists(CfgNodes::ExprNodes::PairCfgNode p | @@ -217,7 +219,9 @@ private class Argument extends CfgNodes::ExprCfgNode { exists(int pos | this = call.getArgument(pos) and this.getExpr() instanceof SplatExpr and - arg.isSplat(pos) + arg.isSplat(pos) and + // There are no earlier splat arguments + not splatArgumentAt(call, any(int j | j < pos)) ) or this = call.getAnArgument() and @@ -432,7 +436,7 @@ private predicate splatParameterAt(Callable c, int pos) { } private predicate splatArgumentAt(CfgNodes::ExprNodes::CallCfgNode c, int pos) { - exists(Argument arg, ArgumentPosition apos | arg.isArgumentOf(c, apos) and apos.isSplat(pos)) + c.getArgument(pos).getExpr() instanceof SplatExpr } /** A collection of cached types and predicates to be evaluated in the same stage. */ @@ -920,7 +924,12 @@ private module ParameterNodes { override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { exists(Callable callable | callable = c.asCfgScope() | - exists(int i | pos.isPositional(i) and callable.getParameter(i) = parameter | + exists(int i | + pos.isPositional(i) and + callable.getParameter(i) = parameter and + // There are no splat parameters before the positional parameter + not splatParameterAt(callable, any(int m | m < i)) + | parameter instanceof SimpleParameter or parameter instanceof OptionalParameter @@ -939,7 +948,9 @@ private module ParameterNodes { parameter = callable.getParameter(n).(SplatParameter) and pos.isSplat(n) and // There are no positional parameters after the splat - not exists(SimpleParameter p, int m | m > n | p = callable.getParameter(m)) + not exists(SimpleParameter p, int m | m > n | p = callable.getParameter(m)) and + // There are no earlier splat parameters + not splatParameterAt(callable, any(int m | m < n)) ) or parameter = callable.getAParameter().(BlockParameter) and diff --git a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected index 25e4a33a46b..4ebb2d50537 100644 --- a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected +++ b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected @@ -36,8 +36,6 @@ track | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:65:10:65:13 | ...[...] | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:69:14:69:14 | x | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:69:27:69:27 | r | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:83:14:83:14 | t | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:83:17:83:17 | u | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:83:20:83:20 | v | @@ -45,7 +43,6 @@ track | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:83:26:83:26 | x | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:83:29:83:29 | y | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:98:19:98:19 | a | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:98:31:98:31 | b | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:108:37:108:37 | a | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:108:44:108:44 | c | | params_flow.rb:1:11:1:11 | x | type tracker with call steps | params_flow.rb:110:10:110:13 | ...[...] | @@ -74,8 +71,6 @@ track | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:84:5:84:10 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | @@ -85,7 +80,6 @@ track | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | -| params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:108:1:112:3 | synthetic splat parameter | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:108:40:108:41 | *b | | params_flow.rb:1:11:1:11 | x | type tracker with call steps with content element 0 | params_flow.rb:109:5:109:10 | synthetic splat argument | @@ -1475,37 +1469,21 @@ track | params_flow.rb:78:38:78:39 | 29 | type tracker without call steps | params_flow.rb:78:38:78:39 | 29 | | params_flow.rb:78:38:78:39 | 29 | type tracker without call steps with content element 0 | params_flow.rb:78:32:78:40 | synthetic splat argument | | params_flow.rb:78:38:78:39 | 29 | type tracker without call steps with content element 2 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | | params_flow.rb:78:43:78:51 | call to taint | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:43:78:51 | call to taint | type tracker without call steps | params_flow.rb:78:43:78:51 | call to taint | | params_flow.rb:78:43:78:51 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:43:78:51 | synthetic splat argument | type tracker without call steps | params_flow.rb:78:43:78:51 | synthetic splat argument | | params_flow.rb:78:49:78:50 | 30 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | | params_flow.rb:78:49:78:50 | 30 | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:49:78:50 | 30 | type tracker without call steps | params_flow.rb:78:43:78:51 | call to taint | | params_flow.rb:78:49:78:50 | 30 | type tracker without call steps | params_flow.rb:78:49:78:50 | 30 | | params_flow.rb:78:49:78:50 | 30 | type tracker without call steps with content element 0 | params_flow.rb:78:43:78:51 | synthetic splat argument | | params_flow.rb:78:49:78:50 | 30 | type tracker without call steps with content element 3 | params_flow.rb:78:1:78:63 | synthetic splat argument | -| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:78:54:78:62 | call to taint | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:54:78:62 | call to taint | type tracker without call steps | params_flow.rb:78:54:78:62 | call to taint | | params_flow.rb:78:54:78:62 | call to taint | type tracker without call steps with content element 4 | params_flow.rb:78:1:78:63 | synthetic splat argument | | params_flow.rb:78:54:78:62 | synthetic splat argument | type tracker without call steps | params_flow.rb:78:54:78:62 | synthetic splat argument | | params_flow.rb:78:60:78:61 | 31 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:78:60:78:61 | 31 | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:78:60:78:61 | 31 | type tracker without call steps | params_flow.rb:78:54:78:62 | call to taint | | params_flow.rb:78:60:78:61 | 31 | type tracker without call steps | params_flow.rb:78:60:78:61 | 31 | @@ -1841,17 +1819,9 @@ track | params_flow.rb:94:27:94:28 | 39 | type tracker without call steps with content element 0 | params_flow.rb:94:21:94:29 | synthetic splat argument | | params_flow.rb:94:27:94:28 | 39 | type tracker without call steps with content element 1 | params_flow.rb:94:1:94:48 | synthetic splat argument | | params_flow.rb:94:32:94:36 | * ... | type tracker without call steps | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:94:39:94:47 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | | params_flow.rb:94:39:94:47 | call to taint | type tracker without call steps | params_flow.rb:94:39:94:47 | call to taint | | params_flow.rb:94:39:94:47 | synthetic splat argument | type tracker without call steps | params_flow.rb:94:39:94:47 | synthetic splat argument | | params_flow.rb:94:45:94:46 | 44 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:94:45:94:46 | 44 | type tracker with call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | | params_flow.rb:94:45:94:46 | 44 | type tracker without call steps | params_flow.rb:94:39:94:47 | call to taint | | params_flow.rb:94:45:94:46 | 44 | type tracker without call steps | params_flow.rb:94:45:94:46 | 44 | | params_flow.rb:94:45:94:46 | 44 | type tracker without call steps with content element 0 | params_flow.rb:94:39:94:47 | synthetic splat argument | @@ -1953,31 +1923,15 @@ track | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content element 2 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content element 2 | params_flow.rb:96:33:96:65 | synthetic splat argument | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content element 4 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:68:96:76 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | | params_flow.rb:96:68:96:76 | call to taint | type tracker without call steps | params_flow.rb:96:68:96:76 | call to taint | | params_flow.rb:96:68:96:76 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:68:96:76 | synthetic splat argument | | params_flow.rb:96:74:96:75 | 50 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:74:96:75 | 50 | type tracker with call steps with content element 0 | params_flow.rb:74:5:74:10 | synthetic splat argument | | params_flow.rb:96:74:96:75 | 50 | type tracker without call steps | params_flow.rb:96:68:96:76 | call to taint | | params_flow.rb:96:74:96:75 | 50 | type tracker without call steps | params_flow.rb:96:74:96:75 | 50 | | params_flow.rb:96:74:96:75 | 50 | type tracker without call steps with content element 0 | params_flow.rb:96:68:96:76 | synthetic splat argument | -| params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:79:96:87 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:96:79:96:87 | call to taint | type tracker without call steps | params_flow.rb:96:79:96:87 | call to taint | | params_flow.rb:96:79:96:87 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:79:96:87 | synthetic splat argument | | params_flow.rb:96:85:96:86 | 51 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:85:96:86 | 51 | type tracker with call steps with content element 0 | params_flow.rb:75:5:75:10 | synthetic splat argument | | params_flow.rb:96:85:96:86 | 51 | type tracker without call steps | params_flow.rb:96:79:96:87 | call to taint | | params_flow.rb:96:85:96:86 | 51 | type tracker without call steps | params_flow.rb:96:85:96:86 | 51 | | params_flow.rb:96:85:96:86 | 51 | type tracker without call steps with content element 0 | params_flow.rb:96:79:96:87 | synthetic splat argument | @@ -2117,19 +2071,11 @@ track | params_flow.rb:106:32:106:33 | 56 | type tracker without call steps | params_flow.rb:106:32:106:33 | 56 | | params_flow.rb:106:32:106:33 | 56 | type tracker without call steps with content element 0 | params_flow.rb:106:26:106:34 | synthetic splat argument | | params_flow.rb:106:32:106:33 | 56 | type tracker without call steps with content element 1 | params_flow.rb:106:1:106:46 | synthetic splat argument | -| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | | params_flow.rb:106:37:106:45 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:106:37:106:45 | call to taint | type tracker without call steps | params_flow.rb:106:37:106:45 | call to taint | | params_flow.rb:106:37:106:45 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:106:1:106:46 | synthetic splat argument | | params_flow.rb:106:37:106:45 | synthetic splat argument | type tracker without call steps | params_flow.rb:106:37:106:45 | synthetic splat argument | | params_flow.rb:106:43:106:44 | 57 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content element 0 | params_flow.rb:102:5:102:10 | synthetic splat argument | | params_flow.rb:106:43:106:44 | 57 | type tracker with call steps with content element 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:106:43:106:44 | 57 | type tracker without call steps | params_flow.rb:106:37:106:45 | call to taint | | params_flow.rb:106:43:106:44 | 57 | type tracker without call steps | params_flow.rb:106:43:106:44 | 57 | @@ -2448,39 +2394,15 @@ track | params_flow.rb:131:1:131:46 | call to pos_many | type tracker without call steps | params_flow.rb:131:1:131:46 | call to pos_many | | params_flow.rb:131:10:131:14 | * ... | type tracker with call steps | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:131:10:131:14 | * ... | type tracker without call steps | params_flow.rb:131:10:131:14 | * ... | -| params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:17:131:25 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:131:17:131:25 | call to taint | type tracker without call steps | params_flow.rb:131:17:131:25 | call to taint | | params_flow.rb:131:17:131:25 | synthetic splat argument | type tracker without call steps | params_flow.rb:131:17:131:25 | synthetic splat argument | | params_flow.rb:131:23:131:24 | 68 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:23:131:24 | 68 | type tracker with call steps with content element 0 | params_flow.rb:85:5:85:10 | synthetic splat argument | | params_flow.rb:131:23:131:24 | 68 | type tracker without call steps | params_flow.rb:131:17:131:25 | call to taint | | params_flow.rb:131:23:131:24 | 68 | type tracker without call steps | params_flow.rb:131:23:131:24 | 68 | | params_flow.rb:131:23:131:24 | 68 | type tracker without call steps with content element 0 | params_flow.rb:131:17:131:25 | synthetic splat argument | -| params_flow.rb:131:28:131:30 | nil | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:28:131:30 | nil | type tracker with call steps | params_flow.rb:83:20:83:20 | v | -| params_flow.rb:131:28:131:30 | nil | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:28:131:30 | nil | type tracker with call steps with content element 0 | params_flow.rb:86:5:86:10 | synthetic splat argument | | params_flow.rb:131:28:131:30 | nil | type tracker without call steps | params_flow.rb:131:28:131:30 | nil | -| params_flow.rb:131:33:131:35 | nil | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:33:131:35 | nil | type tracker with call steps | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:131:33:131:35 | nil | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:33:131:35 | nil | type tracker with call steps with content element 0 | params_flow.rb:87:5:87:10 | synthetic splat argument | | params_flow.rb:131:33:131:35 | nil | type tracker without call steps | params_flow.rb:131:33:131:35 | nil | -| params_flow.rb:131:38:131:40 | nil | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:38:131:40 | nil | type tracker with call steps | params_flow.rb:83:26:83:26 | x | -| params_flow.rb:131:38:131:40 | nil | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:38:131:40 | nil | type tracker with call steps with content element 0 | params_flow.rb:88:5:88:10 | synthetic splat argument | | params_flow.rb:131:38:131:40 | nil | type tracker without call steps | params_flow.rb:131:38:131:40 | nil | -| params_flow.rb:131:43:131:45 | nil | type tracker with call steps | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:43:131:45 | nil | type tracker with call steps | params_flow.rb:83:29:83:29 | y | -| params_flow.rb:131:43:131:45 | nil | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:131:43:131:45 | nil | type tracker with call steps with content element 0 | params_flow.rb:89:5:89:10 | synthetic splat argument | | params_flow.rb:131:43:131:45 | nil | type tracker without call steps | params_flow.rb:131:43:131:45 | nil | | params_flow.rb:133:1:135:3 | &block | type tracker without call steps | params_flow.rb:133:1:135:3 | &block | | params_flow.rb:133:1:135:3 | self in splatall | type tracker with call steps | params_flow.rb:5:1:7:3 | self in sink | @@ -3482,14 +3404,8 @@ trackEnd | params_flow.rb:1:11:1:11 | x | params_flow.rb:69:14:69:14 | x | | params_flow.rb:1:11:1:11 | x | params_flow.rb:69:17:69:17 | y | | params_flow.rb:1:11:1:11 | x | params_flow.rb:69:17:69:17 | y | -| params_flow.rb:1:11:1:11 | x | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:1:11:1:11 | x | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:1:11:1:11 | x | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:1:11:1:11 | x | params_flow.rb:69:27:69:27 | r | | params_flow.rb:1:11:1:11 | x | params_flow.rb:70:10:70:10 | x | | params_flow.rb:1:11:1:11 | x | params_flow.rb:71:10:71:10 | y | -| params_flow.rb:1:11:1:11 | x | params_flow.rb:74:10:74:10 | w | -| params_flow.rb:1:11:1:11 | x | params_flow.rb:75:10:75:10 | r | | params_flow.rb:1:11:1:11 | x | params_flow.rb:78:10:78:18 | call to taint | | params_flow.rb:1:11:1:11 | x | params_flow.rb:78:21:78:29 | call to taint | | params_flow.rb:1:11:1:11 | x | params_flow.rb:78:32:78:40 | call to taint | @@ -3535,10 +3451,7 @@ trackEnd | params_flow.rb:1:11:1:11 | x | params_flow.rb:96:79:96:87 | call to taint | | params_flow.rb:1:11:1:11 | x | params_flow.rb:98:19:98:19 | a | | params_flow.rb:1:11:1:11 | x | params_flow.rb:98:19:98:19 | a | -| params_flow.rb:1:11:1:11 | x | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:1:11:1:11 | x | params_flow.rb:98:31:98:31 | b | | params_flow.rb:1:11:1:11 | x | params_flow.rb:99:10:99:10 | a | -| params_flow.rb:1:11:1:11 | x | params_flow.rb:102:10:102:10 | b | | params_flow.rb:1:11:1:11 | x | params_flow.rb:105:15:105:23 | call to taint | | params_flow.rb:1:11:1:11 | x | params_flow.rb:105:28:105:36 | call to taint | | params_flow.rb:1:11:1:11 | x | params_flow.rb:105:39:105:47 | call to taint | @@ -4783,42 +4696,18 @@ trackEnd | params_flow.rb:78:38:78:39 | 29 | params_flow.rb:2:5:2:5 | x | | params_flow.rb:78:38:78:39 | 29 | params_flow.rb:78:32:78:40 | call to taint | | params_flow.rb:78:38:78:39 | 29 | params_flow.rb:78:38:78:39 | 29 | -| params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:74:10:74:10 | w | | params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:78:43:78:51 | call to taint | | params_flow.rb:78:43:78:51 | synthetic splat argument | params_flow.rb:78:43:78:51 | synthetic splat argument | | params_flow.rb:78:49:78:50 | 30 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:49:78:50 | 30 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:49:78:50 | 30 | params_flow.rb:2:5:2:5 | x | -| params_flow.rb:78:49:78:50 | 30 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:49:78:50 | 30 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:49:78:50 | 30 | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:78:49:78:50 | 30 | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:78:49:78:50 | 30 | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:78:49:78:50 | 30 | params_flow.rb:74:10:74:10 | w | | params_flow.rb:78:49:78:50 | 30 | params_flow.rb:78:43:78:51 | call to taint | | params_flow.rb:78:49:78:50 | 30 | params_flow.rb:78:49:78:50 | 30 | -| params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:75:10:75:10 | r | | params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:78:54:78:62 | call to taint | | params_flow.rb:78:54:78:62 | synthetic splat argument | params_flow.rb:78:54:78:62 | synthetic splat argument | | params_flow.rb:78:60:78:61 | 31 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:60:78:61 | 31 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:78:60:78:61 | 31 | params_flow.rb:2:5:2:5 | x | -| params_flow.rb:78:60:78:61 | 31 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:60:78:61 | 31 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:78:60:78:61 | 31 | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:78:60:78:61 | 31 | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:78:60:78:61 | 31 | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:78:60:78:61 | 31 | params_flow.rb:75:10:75:10 | r | | params_flow.rb:78:60:78:61 | 31 | params_flow.rb:78:54:78:62 | call to taint | | params_flow.rb:78:60:78:61 | 31 | params_flow.rb:78:60:78:61 | 31 | | params_flow.rb:80:1:80:4 | args | params_flow.rb:80:1:80:4 | args | @@ -5135,23 +5024,11 @@ trackEnd | params_flow.rb:94:27:94:28 | 39 | params_flow.rb:94:21:94:29 | call to taint | | params_flow.rb:94:27:94:28 | 39 | params_flow.rb:94:27:94:28 | 39 | | params_flow.rb:94:32:94:36 | * ... | params_flow.rb:94:32:94:36 | * ... | -| params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:87:10:87:10 | w | | params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:94:39:94:47 | call to taint | | params_flow.rb:94:39:94:47 | synthetic splat argument | params_flow.rb:94:39:94:47 | synthetic splat argument | | params_flow.rb:94:45:94:46 | 44 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:94:45:94:46 | 44 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:94:45:94:46 | 44 | params_flow.rb:2:5:2:5 | x | -| params_flow.rb:94:45:94:46 | 44 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:94:45:94:46 | 44 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:94:45:94:46 | 44 | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:94:45:94:46 | 44 | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:94:45:94:46 | 44 | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:94:45:94:46 | 44 | params_flow.rb:87:10:87:10 | w | | params_flow.rb:94:45:94:46 | 44 | params_flow.rb:94:39:94:47 | call to taint | | params_flow.rb:94:45:94:46 | 44 | params_flow.rb:94:45:94:46 | 44 | | params_flow.rb:96:1:96:88 | call to splatmid | params_flow.rb:96:1:96:88 | call to splatmid | @@ -5221,42 +5098,18 @@ trackEnd | params_flow.rb:96:62:96:63 | 49 | params_flow.rb:2:5:2:5 | x | | params_flow.rb:96:62:96:63 | 49 | params_flow.rb:96:56:96:64 | call to taint | | params_flow.rb:96:62:96:63 | 49 | params_flow.rb:96:62:96:63 | 49 | -| params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:74:10:74:10 | w | | params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:96:68:96:76 | call to taint | | params_flow.rb:96:68:96:76 | synthetic splat argument | params_flow.rb:96:68:96:76 | synthetic splat argument | | params_flow.rb:96:74:96:75 | 50 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:74:96:75 | 50 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:74:96:75 | 50 | params_flow.rb:2:5:2:5 | x | -| params_flow.rb:96:74:96:75 | 50 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:74:96:75 | 50 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:74:96:75 | 50 | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:96:74:96:75 | 50 | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:96:74:96:75 | 50 | params_flow.rb:69:24:69:24 | w | -| params_flow.rb:96:74:96:75 | 50 | params_flow.rb:74:10:74:10 | w | | params_flow.rb:96:74:96:75 | 50 | params_flow.rb:96:68:96:76 | call to taint | | params_flow.rb:96:74:96:75 | 50 | params_flow.rb:96:74:96:75 | 50 | -| params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:75:10:75:10 | r | | params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:96:79:96:87 | call to taint | | params_flow.rb:96:79:96:87 | synthetic splat argument | params_flow.rb:96:79:96:87 | synthetic splat argument | | params_flow.rb:96:85:96:86 | 51 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:85:96:86 | 51 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:96:85:96:86 | 51 | params_flow.rb:2:5:2:5 | x | -| params_flow.rb:96:85:96:86 | 51 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:85:96:86 | 51 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:96:85:96:86 | 51 | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:96:85:96:86 | 51 | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:96:85:96:86 | 51 | params_flow.rb:69:27:69:27 | r | -| params_flow.rb:96:85:96:86 | 51 | params_flow.rb:75:10:75:10 | r | | params_flow.rb:96:85:96:86 | 51 | params_flow.rb:96:79:96:87 | call to taint | | params_flow.rb:96:85:96:86 | 51 | params_flow.rb:96:85:96:86 | 51 | | params_flow.rb:98:1:103:3 | &block | params_flow.rb:98:1:103:3 | &block | @@ -5382,23 +5235,11 @@ trackEnd | params_flow.rb:106:32:106:33 | 56 | params_flow.rb:2:5:2:5 | x | | params_flow.rb:106:32:106:33 | 56 | params_flow.rb:106:26:106:34 | call to taint | | params_flow.rb:106:32:106:33 | 56 | params_flow.rb:106:32:106:33 | 56 | -| params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:102:10:102:10 | b | | params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:106:37:106:45 | call to taint | | params_flow.rb:106:37:106:45 | synthetic splat argument | params_flow.rb:106:37:106:45 | synthetic splat argument | | params_flow.rb:106:43:106:44 | 57 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:106:43:106:44 | 57 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:106:43:106:44 | 57 | params_flow.rb:2:5:2:5 | x | -| params_flow.rb:106:43:106:44 | 57 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:106:43:106:44 | 57 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:106:43:106:44 | 57 | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:106:43:106:44 | 57 | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:106:43:106:44 | 57 | params_flow.rb:98:31:98:31 | b | -| params_flow.rb:106:43:106:44 | 57 | params_flow.rb:102:10:102:10 | b | | params_flow.rb:106:43:106:44 | 57 | params_flow.rb:106:37:106:45 | call to taint | | params_flow.rb:106:43:106:44 | 57 | params_flow.rb:106:43:106:44 | 57 | | params_flow.rb:108:1:112:3 | &block | params_flow.rb:108:1:112:3 | &block | @@ -5724,52 +5565,16 @@ trackEnd | params_flow.rb:131:1:131:46 | call to pos_many | params_flow.rb:131:1:131:46 | call to pos_many | | params_flow.rb:131:10:131:14 | * ... | params_flow.rb:83:1:91:3 | synthetic splat parameter | | params_flow.rb:131:10:131:14 | * ... | params_flow.rb:131:10:131:14 | * ... | -| params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:85:10:85:10 | u | | params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:131:17:131:25 | call to taint | | params_flow.rb:131:17:131:25 | synthetic splat argument | params_flow.rb:131:17:131:25 | synthetic splat argument | | params_flow.rb:131:23:131:24 | 68 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:131:23:131:24 | 68 | params_flow.rb:1:11:1:11 | x | | params_flow.rb:131:23:131:24 | 68 | params_flow.rb:2:5:2:5 | x | -| params_flow.rb:131:23:131:24 | 68 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:23:131:24 | 68 | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:23:131:24 | 68 | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:131:23:131:24 | 68 | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:131:23:131:24 | 68 | params_flow.rb:83:17:83:17 | u | -| params_flow.rb:131:23:131:24 | 68 | params_flow.rb:85:10:85:10 | u | | params_flow.rb:131:23:131:24 | 68 | params_flow.rb:131:17:131:25 | call to taint | | params_flow.rb:131:23:131:24 | 68 | params_flow.rb:131:23:131:24 | 68 | -| params_flow.rb:131:28:131:30 | nil | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:28:131:30 | nil | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:28:131:30 | nil | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:131:28:131:30 | nil | params_flow.rb:83:20:83:20 | v | -| params_flow.rb:131:28:131:30 | nil | params_flow.rb:83:20:83:20 | v | -| params_flow.rb:131:28:131:30 | nil | params_flow.rb:86:10:86:10 | v | | params_flow.rb:131:28:131:30 | nil | params_flow.rb:131:28:131:30 | nil | -| params_flow.rb:131:33:131:35 | nil | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:33:131:35 | nil | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:33:131:35 | nil | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:131:33:131:35 | nil | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:131:33:131:35 | nil | params_flow.rb:83:23:83:23 | w | -| params_flow.rb:131:33:131:35 | nil | params_flow.rb:87:10:87:10 | w | | params_flow.rb:131:33:131:35 | nil | params_flow.rb:131:33:131:35 | nil | -| params_flow.rb:131:38:131:40 | nil | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:38:131:40 | nil | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:38:131:40 | nil | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:131:38:131:40 | nil | params_flow.rb:83:26:83:26 | x | -| params_flow.rb:131:38:131:40 | nil | params_flow.rb:83:26:83:26 | x | -| params_flow.rb:131:38:131:40 | nil | params_flow.rb:88:10:88:10 | x | | params_flow.rb:131:38:131:40 | nil | params_flow.rb:131:38:131:40 | nil | -| params_flow.rb:131:43:131:45 | nil | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:43:131:45 | nil | params_flow.rb:5:10:5:10 | x | -| params_flow.rb:131:43:131:45 | nil | params_flow.rb:6:10:6:10 | x | -| params_flow.rb:131:43:131:45 | nil | params_flow.rb:83:29:83:29 | y | -| params_flow.rb:131:43:131:45 | nil | params_flow.rb:83:29:83:29 | y | -| params_flow.rb:131:43:131:45 | nil | params_flow.rb:89:10:89:10 | y | | params_flow.rb:131:43:131:45 | nil | params_flow.rb:131:43:131:45 | nil | | params_flow.rb:133:1:135:3 | &block | params_flow.rb:133:1:135:3 | &block | | params_flow.rb:133:1:135:3 | self in splatall | params_flow.rb:5:1:7:3 | self (sink) | diff --git a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected index 0484c2f1e27..f665080a329 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected @@ -90,12 +90,8 @@ edges | params_flow.rb:67:13:67:16 | args | params_flow.rb:67:12:67:16 | * ... [element 0] | provenance | | | params_flow.rb:69:14:69:14 | x | params_flow.rb:70:10:70:10 | x | provenance | | | params_flow.rb:69:17:69:17 | y | params_flow.rb:71:10:71:10 | y | provenance | | -| params_flow.rb:69:24:69:24 | w | params_flow.rb:74:10:74:10 | w | provenance | | -| params_flow.rb:69:27:69:27 | r | params_flow.rb:75:10:75:10 | r | provenance | | | params_flow.rb:78:10:78:18 | call to taint | params_flow.rb:69:14:69:14 | x | provenance | | | params_flow.rb:78:21:78:29 | call to taint | params_flow.rb:69:17:69:17 | y | provenance | | -| params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:69:24:69:24 | w | provenance | | -| params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:69:27:69:27 | r | provenance | | | params_flow.rb:80:1:80:4 | args [element 0] | params_flow.rb:81:22:81:25 | args [element 0] | provenance | | | params_flow.rb:80:8:80:51 | call to [] [element 0] | params_flow.rb:80:1:80:4 | args [element 0] | provenance | | | params_flow.rb:80:9:80:17 | call to taint | params_flow.rb:80:8:80:51 | call to [] [element 0] | provenance | | @@ -130,16 +126,11 @@ edges | params_flow.rb:94:33:94:36 | args [element 1] | params_flow.rb:94:32:94:36 | * ... [element 1] | provenance | | | params_flow.rb:94:33:94:36 | args [element 2] | params_flow.rb:94:32:94:36 | * ... [element 2] | provenance | | | params_flow.rb:94:33:94:36 | args [element 3] | params_flow.rb:94:32:94:36 | * ... [element 3] | provenance | | -| params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:83:23:83:23 | w | provenance | | | params_flow.rb:96:10:96:18 | call to taint | params_flow.rb:69:14:69:14 | x | provenance | | | params_flow.rb:96:21:96:29 | call to taint | params_flow.rb:69:17:69:17 | y | provenance | | -| params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:69:24:69:24 | w | provenance | | -| params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:69:27:69:27 | r | provenance | | | params_flow.rb:98:19:98:19 | a | params_flow.rb:99:10:99:10 | a | provenance | | -| params_flow.rb:98:31:98:31 | b | params_flow.rb:102:10:102:10 | b | provenance | | | params_flow.rb:105:15:105:23 | call to taint | params_flow.rb:98:19:98:19 | a | provenance | | | params_flow.rb:106:15:106:23 | call to taint | params_flow.rb:98:19:98:19 | a | provenance | | -| params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:98:31:98:31 | b | provenance | | | params_flow.rb:108:37:108:37 | a | params_flow.rb:109:10:109:10 | a | provenance | | | params_flow.rb:108:40:108:41 | *b [element 0] | params_flow.rb:110:10:110:10 | b [element 0] | provenance | | | params_flow.rb:108:44:108:44 | c | params_flow.rb:111:10:111:10 | c | provenance | | @@ -162,7 +153,6 @@ edges | params_flow.rb:131:10:131:14 | * ... [element 1] | params_flow.rb:83:17:83:17 | u | provenance | | | params_flow.rb:131:11:131:14 | args [element 0] | params_flow.rb:131:10:131:14 | * ... [element 0] | provenance | | | params_flow.rb:131:11:131:14 | args [element 1] | params_flow.rb:131:10:131:14 | * ... [element 1] | provenance | | -| params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:83:17:83:17 | u | provenance | | | params_flow.rb:133:14:133:18 | *args [element 1] | params_flow.rb:134:10:134:13 | args [element 1] | provenance | | | params_flow.rb:134:10:134:13 | args [element 1] | params_flow.rb:134:10:134:16 | ...[...] | provenance | | | params_flow.rb:137:10:137:43 | * ... [element 1] | params_flow.rb:133:14:133:18 | *args [element 1] | provenance | | @@ -283,16 +273,10 @@ nodes | params_flow.rb:67:13:67:16 | args | semmle.label | args | | params_flow.rb:69:14:69:14 | x | semmle.label | x | | params_flow.rb:69:17:69:17 | y | semmle.label | y | -| params_flow.rb:69:24:69:24 | w | semmle.label | w | -| params_flow.rb:69:27:69:27 | r | semmle.label | r | | params_flow.rb:70:10:70:10 | x | semmle.label | x | | params_flow.rb:71:10:71:10 | y | semmle.label | y | -| params_flow.rb:74:10:74:10 | w | semmle.label | w | -| params_flow.rb:75:10:75:10 | r | semmle.label | r | | params_flow.rb:78:10:78:18 | call to taint | semmle.label | call to taint | | params_flow.rb:78:21:78:29 | call to taint | semmle.label | call to taint | -| params_flow.rb:78:43:78:51 | call to taint | semmle.label | call to taint | -| params_flow.rb:78:54:78:62 | call to taint | semmle.label | call to taint | | params_flow.rb:80:1:80:4 | args [element 0] | semmle.label | args [element 0] | | params_flow.rb:80:8:80:51 | call to [] [element 0] | semmle.label | call to [] [element 0] | | params_flow.rb:80:9:80:17 | call to taint | semmle.label | call to taint | @@ -333,18 +317,12 @@ nodes | params_flow.rb:94:33:94:36 | args [element 1] | semmle.label | args [element 1] | | params_flow.rb:94:33:94:36 | args [element 2] | semmle.label | args [element 2] | | params_flow.rb:94:33:94:36 | args [element 3] | semmle.label | args [element 3] | -| params_flow.rb:94:39:94:47 | call to taint | semmle.label | call to taint | | params_flow.rb:96:10:96:18 | call to taint | semmle.label | call to taint | | params_flow.rb:96:21:96:29 | call to taint | semmle.label | call to taint | -| params_flow.rb:96:68:96:76 | call to taint | semmle.label | call to taint | -| params_flow.rb:96:79:96:87 | call to taint | semmle.label | call to taint | | params_flow.rb:98:19:98:19 | a | semmle.label | a | -| params_flow.rb:98:31:98:31 | b | semmle.label | b | | params_flow.rb:99:10:99:10 | a | semmle.label | a | -| params_flow.rb:102:10:102:10 | b | semmle.label | b | | params_flow.rb:105:15:105:23 | call to taint | semmle.label | call to taint | | params_flow.rb:106:15:106:23 | call to taint | semmle.label | call to taint | -| params_flow.rb:106:37:106:45 | call to taint | semmle.label | call to taint | | params_flow.rb:108:37:108:37 | a | semmle.label | a | | params_flow.rb:108:40:108:41 | *b [element 0] | semmle.label | *b [element 0] | | params_flow.rb:108:44:108:44 | c | semmle.label | c | @@ -369,7 +347,6 @@ nodes | params_flow.rb:131:10:131:14 | * ... [element 1] | semmle.label | * ... [element 1] | | params_flow.rb:131:11:131:14 | args [element 0] | semmle.label | args [element 0] | | params_flow.rb:131:11:131:14 | args [element 1] | semmle.label | args [element 1] | -| params_flow.rb:131:17:131:25 | call to taint | semmle.label | call to taint | | params_flow.rb:133:14:133:18 | *args [element 1] | semmle.label | *args [element 1] | | params_flow.rb:134:10:134:13 | args [element 1] | semmle.label | args [element 1] | | params_flow.rb:134:10:134:16 | ...[...] | semmle.label | ...[...] | @@ -433,23 +410,16 @@ testFailures | params_flow.rb:71:10:71:10 | y | params_flow.rb:78:21:78:29 | call to taint | params_flow.rb:71:10:71:10 | y | $@ | params_flow.rb:78:21:78:29 | call to taint | call to taint | | params_flow.rb:71:10:71:10 | y | params_flow.rb:80:9:80:17 | call to taint | params_flow.rb:71:10:71:10 | y | $@ | params_flow.rb:80:9:80:17 | call to taint | call to taint | | params_flow.rb:71:10:71:10 | y | params_flow.rb:96:21:96:29 | call to taint | params_flow.rb:71:10:71:10 | y | $@ | params_flow.rb:96:21:96:29 | call to taint | call to taint | -| params_flow.rb:74:10:74:10 | w | params_flow.rb:78:43:78:51 | call to taint | params_flow.rb:74:10:74:10 | w | $@ | params_flow.rb:78:43:78:51 | call to taint | call to taint | -| params_flow.rb:74:10:74:10 | w | params_flow.rb:96:68:96:76 | call to taint | params_flow.rb:74:10:74:10 | w | $@ | params_flow.rb:96:68:96:76 | call to taint | call to taint | -| params_flow.rb:75:10:75:10 | r | params_flow.rb:78:54:78:62 | call to taint | params_flow.rb:75:10:75:10 | r | $@ | params_flow.rb:78:54:78:62 | call to taint | call to taint | -| params_flow.rb:75:10:75:10 | r | params_flow.rb:96:79:96:87 | call to taint | params_flow.rb:75:10:75:10 | r | $@ | params_flow.rb:96:79:96:87 | call to taint | call to taint | | params_flow.rb:84:10:84:10 | t | params_flow.rb:94:10:94:18 | call to taint | params_flow.rb:84:10:84:10 | t | $@ | params_flow.rb:94:10:94:18 | call to taint | call to taint | | params_flow.rb:84:10:84:10 | t | params_flow.rb:130:9:130:17 | call to taint | params_flow.rb:84:10:84:10 | t | $@ | params_flow.rb:130:9:130:17 | call to taint | call to taint | | params_flow.rb:85:10:85:10 | u | params_flow.rb:94:21:94:29 | call to taint | params_flow.rb:85:10:85:10 | u | $@ | params_flow.rb:94:21:94:29 | call to taint | call to taint | | params_flow.rb:85:10:85:10 | u | params_flow.rb:130:20:130:28 | call to taint | params_flow.rb:85:10:85:10 | u | $@ | params_flow.rb:130:20:130:28 | call to taint | call to taint | -| params_flow.rb:85:10:85:10 | u | params_flow.rb:131:17:131:25 | call to taint | params_flow.rb:85:10:85:10 | u | $@ | params_flow.rb:131:17:131:25 | call to taint | call to taint | | params_flow.rb:86:10:86:10 | v | params_flow.rb:93:9:93:17 | call to taint | params_flow.rb:86:10:86:10 | v | $@ | params_flow.rb:93:9:93:17 | call to taint | call to taint | | params_flow.rb:87:10:87:10 | w | params_flow.rb:93:20:93:28 | call to taint | params_flow.rb:87:10:87:10 | w | $@ | params_flow.rb:93:20:93:28 | call to taint | call to taint | -| params_flow.rb:87:10:87:10 | w | params_flow.rb:94:39:94:47 | call to taint | params_flow.rb:87:10:87:10 | w | $@ | params_flow.rb:94:39:94:47 | call to taint | call to taint | | params_flow.rb:88:10:88:10 | x | params_flow.rb:93:31:93:39 | call to taint | params_flow.rb:88:10:88:10 | x | $@ | params_flow.rb:93:31:93:39 | call to taint | call to taint | | params_flow.rb:89:10:89:10 | y | params_flow.rb:93:42:93:50 | call to taint | params_flow.rb:89:10:89:10 | y | $@ | params_flow.rb:93:42:93:50 | call to taint | call to taint | | params_flow.rb:99:10:99:10 | a | params_flow.rb:105:15:105:23 | call to taint | params_flow.rb:99:10:99:10 | a | $@ | params_flow.rb:105:15:105:23 | call to taint | call to taint | | params_flow.rb:99:10:99:10 | a | params_flow.rb:106:15:106:23 | call to taint | params_flow.rb:99:10:99:10 | a | $@ | params_flow.rb:106:15:106:23 | call to taint | call to taint | -| params_flow.rb:102:10:102:10 | b | params_flow.rb:106:37:106:45 | call to taint | params_flow.rb:102:10:102:10 | b | $@ | params_flow.rb:106:37:106:45 | call to taint | call to taint | | params_flow.rb:109:10:109:10 | a | params_flow.rb:114:33:114:41 | call to taint | params_flow.rb:109:10:109:10 | a | $@ | params_flow.rb:114:33:114:41 | call to taint | call to taint | | params_flow.rb:110:10:110:13 | ...[...] | params_flow.rb:114:44:114:52 | call to taint | params_flow.rb:110:10:110:13 | ...[...] | $@ | params_flow.rb:114:44:114:52 | call to taint | call to taint | | params_flow.rb:111:10:111:10 | c | params_flow.rb:114:58:114:66 | call to taint | params_flow.rb:111:10:111:10 | c | $@ | params_flow.rb:114:58:114:66 | call to taint | call to taint | diff --git a/ruby/ql/test/library-tests/dataflow/params/params_flow.rb b/ruby/ql/test/library-tests/dataflow/params/params_flow.rb index 34599eb35a9..65b663a7c4e 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params_flow.rb +++ b/ruby/ql/test/library-tests/dataflow/params/params_flow.rb @@ -69,10 +69,10 @@ splatstuff(*args) def splatmid(x, y, *z, w, r) sink x # $ hasValueFlow=27 $ hasValueFlow=32 $ hasValueFlow=45 sink y # $ hasValueFlow=28 $ hasValueFlow=46 $ hasValueFlow=33 - sink z[0] # MISSING: $ hasValueFlow=47 $ hasValueFlow=29 $ hasValueFlow=34 + sink z[0] # $ MISSING: hasValueFlow=47 $ hasValueFlow=29 $ hasValueFlow=34 sink z[1] # $ MISSING: hasValueFlow=48 $ hasValueFlow=35 - sink w # $ hasValueFlow=30 $ hasValueFlow=50 $ MISSING: hasValueFlow=36 - sink r # $ hasValueFlow=31 $ hasValueFlow=51 $ MISSING: hasValueFlow=37 + sink w # $ MISSING: hasValueFlow=30 $ hasValueFlow=50 $ hasValueFlow=36 + sink r # $ MISSING: hasValueFlow=31 $ hasValueFlow=51 $ hasValueFlow=37 end splatmid(taint(27), taint(28), taint(29), taint(30), taint(31)) @@ -82,9 +82,9 @@ splatmid(taint(32), *args, taint(37)) def pos_many(t, u, v, w, x, y, z) sink t # $ hasValueFlow=38 $ hasValueFlow=66 - sink u # $ hasValueFlow=39 $ hasValueFlow=67 $ SPURIOUS: hasValueFlow=68 + sink u # $ hasValueFlow=39 $ hasValueFlow=67 sink v # $ hasValueFlow=40 - sink w # $ hasValueFlow=41 $ SPURIOUS: hasValueFlow=44 + sink w # $ hasValueFlow=41 sink x # $ hasValueFlow=42 sink y # $ hasValueFlow=43 sink z # $ MISSING: hasValueFlow=44 @@ -99,7 +99,7 @@ def splatmidsmall(a, *splats, b) sink a # $ hasValueFlow=52 $ hasValueFlow=55 sink splats[0] # $ MISSING: hasValueFlow=53 sink splats[1] - sink b # $ hasValueFlow=57 $ MISSING: hasValueFlow=54 + sink b # $ MISSING: hasValueFlow=57 $ hasValueFlow=54 end splatmidsmall(taint(52), *[taint(53), taint(54)]) From d15e1b5598841c7d710abc67a3c170076b3869bc Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 20 Aug 2024 15:05:49 +0200 Subject: [PATCH 035/404] Ruby: Prevent synthetic splat matching for actual splats at same positions --- .../dataflow/internal/DataFlowDispatch.qll | 81 ++++++++++--------- .../dataflow/internal/DataFlowPrivate.qll | 22 ++--- .../dataflow/params/TypeTracker.expected | 34 -------- 3 files changed, 53 insertions(+), 84 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index 97c0e24fa5b..268c289259e 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -563,7 +563,11 @@ private module Cached { THashSplatArgumentPosition() or TSynthHashSplatArgumentPosition() or TSplatArgumentPosition(int pos) { exists(Call c | c.getArgument(pos) instanceof SplatExpr) } or - TSynthSplatArgumentPosition(Boolean hasActualSplat) or + TSynthSplatArgumentPosition(int actualSplatPos) { + actualSplatPos = -1 // represents no actual splat + or + exists(Call c | c.getArgument(actualSplatPos) instanceof SplatExpr) + } or TAnyArgumentPosition() or TAnyKeywordArgumentPosition() @@ -594,7 +598,11 @@ private module Cached { or exists(Parameter p | p.getPosition() = pos and p instanceof SplatParameter) } or - TSynthSplatParameterPosition(Boolean hasActualSplat) or + TSynthSplatParameterPosition(int actualSplatPos) { + actualSplatPos = -1 // represents no actual splat + or + exists(Callable c | c.getParameter(actualSplatPos) instanceof SplatParameter) + } or TAnyParameterPosition() or TAnyKeywordParameterPosition() } @@ -1386,12 +1394,11 @@ class ParameterPosition extends TParameterPosition { /** * Holds if this position represents a synthetic splat parameter. * - * `hasActualSplat` indicates whether the method that the parameter belongs - * to also has an actual splat parameter. + * `actualSplatPos` indicates the position of the (unique) actual splat + * parameter belonging to the same method, with `-1` representing no actual + * splat parameter. */ - predicate isSynthSplat(boolean hasActualSplat) { - this = TSynthSplatParameterPosition(hasActualSplat) - } + predicate isSynthSplat(int actualSplatPos) { this = TSynthSplatParameterPosition(actualSplatPos) } /** * Holds if this position represents any parameter, except `self` parameters. This @@ -1426,10 +1433,10 @@ class ParameterPosition extends TParameterPosition { or exists(int pos | this.isSplat(pos) and result = "* (position " + pos + ")") or - exists(boolean hasActualSplat, string suffix | - this.isSynthSplat(hasActualSplat) and + exists(int actualSplatPos, string suffix | + this.isSynthSplat(actualSplatPos) and result = "synthetic *" + suffix and - if hasActualSplat = true then suffix = " (with actual)" else suffix = "" + if actualSplatPos = -1 then suffix = "" else suffix = " (actual at " + actualSplatPos + ")" ) } } @@ -1472,12 +1479,11 @@ class ArgumentPosition extends TArgumentPosition { /** * Holds if this position represents a synthetic splat argument. * - * `hasActualSplat` indicates whether the call that the argument belongs - * to also has an actual splat argument. + * `actualSplatPos` indicates the position of the (unique) actual splat + * argument belonging to the same call, with `-1` representing no actual + * splat argument. */ - predicate isSynthSplat(boolean hasActualSplat) { - this = TSynthSplatArgumentPosition(hasActualSplat) - } + predicate isSynthSplat(int actualSplatPos) { this = TSynthSplatArgumentPosition(actualSplatPos) } /** Gets a textual representation of this position. */ string toString() { @@ -1501,10 +1507,10 @@ class ArgumentPosition extends TArgumentPosition { or exists(int pos | this.isSplat(pos) and result = "* (position " + pos + ")") or - exists(boolean hasActualSplat, string suffix | - this.isSynthSplat(hasActualSplat) and + exists(int actualSplatPos, string suffix | + this.isSynthSplat(actualSplatPos) and result = "synthetic *" + suffix and - if hasActualSplat = true then suffix = " (with actual)" else suffix = "" + if actualSplatPos = -1 then suffix = "" else suffix = " (actual at " + actualSplatPos + ")" ) } } @@ -1538,35 +1544,30 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { or exists(string name | ppos.isKeyword(name) and apos.isKeyword(name)) or - ppos.isHashSplat() and - (apos.isHashSplat() or apos.isSynthHashSplat()) + (ppos.isHashSplat() or ppos.isSynthHashSplat()) and + (apos.isHashSplat() or apos.isSynthHashSplat()) and + // prevent synthetic hash-splat parameters from matching synthetic hash-splat + // arguments when direct keyword matching is possible + not (ppos.isSynthHashSplat() and apos.isSynthHashSplat()) or - // no case for `apos.isSynthHashSplat() and ppos.isSynthHashSplat()`, since - // direct keyword matching is possible - ppos.isSynthHashSplat() and - apos.isHashSplat() - or - exists(int pos, boolean hasActualSplatParam, boolean hasActualSplatArg | + exists(int pos | ( - ppos.isSplat(pos) and - hasActualSplatParam = true // allow matching with synthetic splat argument + ppos.isSplat(pos) or - ppos.isSynthSplat(hasActualSplatParam) and - pos = 0 and - // prevent synthetic splat parameters from matching synthetic splat arguments - // when direct positional matching is possible - ( - hasActualSplatParam = true - or - hasActualSplatArg = true - ) + ppos.isSynthSplat(_) and + pos = 0 ) and ( - apos.isSplat(pos) and - hasActualSplatArg = true // allow matching with synthetic splat parameter + apos.isSplat(pos) or - apos.isSynthSplat(hasActualSplatArg) and pos = 0 + apos.isSynthSplat(_) and pos = 0 ) + ) and + // prevent synthetic splat parameters from matching synthetic splat arguments + // when direct positional matching is possible + not exists(int actualSplatPos | + ppos.isSynthSplat(actualSplatPos) and + apos.isSynthSplat(actualSplatPos) ) or ppos.isAny() and argumentPositionIsNotSelf(apos) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 1cfb3b0f395..78f0491ff13 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -1204,11 +1204,11 @@ private module ParameterNodes { final override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { c = callable and - exists(boolean hasActualSplat | - pos.isSynthSplat(hasActualSplat) and - if exists(TSynthSplatParameterShiftNode(c, _, _)) - then hasActualSplat = true - else hasActualSplat = false + exists(int actualSplat | pos.isSynthSplat(actualSplat) | + exists(TSynthSplatParameterShiftNode(c, actualSplat, _)) + or + not exists(TSynthSplatParameterShiftNode(c, _, _)) and + actualSplat = -1 ) } @@ -1488,11 +1488,13 @@ module ArgumentNodes { override predicate sourceArgumentOf(CfgNodes::ExprNodes::CallCfgNode call, ArgumentPosition pos) { call = call_ and - exists(boolean hasActualSplat | - pos.isSynthSplat(hasActualSplat) and - if any(SynthSplatArgumentShiftNode shift).storeInto(this, _) - then hasActualSplat = true - else hasActualSplat = false + exists(int actualSplat | pos.isSynthSplat(actualSplat) | + any(SynthSplatArgumentShiftNode shift | + shift = TSynthSplatArgumentShiftNode(_, actualSplat, _) + ).storeInto(this, _) + or + not any(SynthSplatArgumentShiftNode shift).storeInto(this, _) and + actualSplat = -1 ) } diff --git a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected index 4ebb2d50537..23d66c80ad2 100644 --- a/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected +++ b/ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected @@ -1193,20 +1193,16 @@ track | params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | | params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | | params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 0 or unknown | params_flow.rb:49:17:49:24 | *posargs | -| params_flow.rb:57:8:57:18 | call to [] | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:57:8:57:18 | call to [] | type tracker without call steps | params_flow.rb:57:8:57:18 | call to [] | | params_flow.rb:57:8:57:18 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:58:20:58:24 | * ... | | params_flow.rb:57:8:57:18 | call to [] | type tracker without call steps with content element 1 | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps | params_flow.rb:51:11:51:20 | ...[...] | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 0 or unknown | params_flow.rb:49:17:49:24 | *posargs | -| params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:57:8:57:18 | call to [] | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker without call steps | params_flow.rb:57:8:57:18 | synthetic splat argument | | params_flow.rb:57:8:57:18 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:58:20:58:24 | * ... | @@ -1216,7 +1212,6 @@ track | params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | | params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | -| params_flow.rb:57:9:57:17 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:57:9:57:17 | call to taint | type tracker without call steps | params_flow.rb:57:9:57:17 | call to taint | | params_flow.rb:57:9:57:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:57:8:57:18 | call to [] | | params_flow.rb:57:9:57:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:57:8:57:18 | synthetic splat argument | @@ -1229,7 +1224,6 @@ track | params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content element 0 | params_flow.rb:49:17:49:24 | *posargs | | params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content element 0 | params_flow.rb:51:5:51:21 | synthetic splat argument | -| params_flow.rb:57:15:57:16 | 22 | type tracker with call steps with content element 1 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps | params_flow.rb:57:9:57:17 | call to taint | | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps | params_flow.rb:57:15:57:16 | 22 | | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content element 0 | params_flow.rb:57:8:57:18 | call to [] | @@ -1238,12 +1232,10 @@ track | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content element 0 | params_flow.rb:58:20:58:24 | * ... | | params_flow.rb:57:15:57:16 | 22 | type tracker without call steps with content element 1 | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:58:1:58:25 | call to posargs | type tracker without call steps | params_flow.rb:58:1:58:25 | call to posargs | -| params_flow.rb:58:1:58:25 | synthetic splat argument | type tracker with call steps | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:58:1:58:25 | synthetic splat argument | type tracker without call steps | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | | params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:58:9:58:17 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:58:9:58:17 | call to taint | type tracker without call steps | params_flow.rb:58:9:58:17 | call to taint | | params_flow.rb:58:9:58:17 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:58:1:58:25 | synthetic splat argument | @@ -1252,7 +1244,6 @@ track | params_flow.rb:58:15:58:16 | 23 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:58:15:58:16 | 23 | type tracker with call steps | params_flow.rb:49:13:49:14 | p1 | | params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content element 0 | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:58:15:58:16 | 23 | type tracker with call steps with content element 0 | params_flow.rb:50:5:50:11 | synthetic splat argument | | params_flow.rb:58:15:58:16 | 23 | type tracker without call steps | params_flow.rb:58:9:58:17 | call to taint | | params_flow.rb:58:15:58:16 | 23 | type tracker without call steps | params_flow.rb:58:15:58:16 | 23 | @@ -1826,12 +1817,10 @@ track | params_flow.rb:94:45:94:46 | 44 | type tracker without call steps | params_flow.rb:94:45:94:46 | 44 | | params_flow.rb:94:45:94:46 | 44 | type tracker without call steps with content element 0 | params_flow.rb:94:39:94:47 | synthetic splat argument | | params_flow.rb:96:1:96:88 | call to splatmid | type tracker without call steps | params_flow.rb:96:1:96:88 | call to splatmid | -| params_flow.rb:96:1:96:88 | synthetic splat argument | type tracker with call steps | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:1:96:88 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps | params_flow.rb:69:14:69:14 | x | | params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:10:96:18 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:96:10:96:18 | call to taint | type tracker without call steps | params_flow.rb:96:10:96:18 | call to taint | | params_flow.rb:96:10:96:18 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:96:1:96:88 | synthetic splat argument | @@ -1840,7 +1829,6 @@ track | params_flow.rb:96:16:96:17 | 45 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:16:96:17 | 45 | type tracker with call steps | params_flow.rb:69:14:69:14 | x | | params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content element 0 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:16:96:17 | 45 | type tracker with call steps with content element 0 | params_flow.rb:70:5:70:10 | synthetic splat argument | | params_flow.rb:96:16:96:17 | 45 | type tracker without call steps | params_flow.rb:96:10:96:18 | call to taint | | params_flow.rb:96:16:96:17 | 45 | type tracker without call steps | params_flow.rb:96:16:96:17 | 45 | @@ -1850,7 +1838,6 @@ track | params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps | params_flow.rb:69:17:69:17 | y | | params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:96:21:96:29 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:21:96:29 | call to taint | type tracker without call steps | params_flow.rb:96:21:96:29 | call to taint | | params_flow.rb:96:21:96:29 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:21:96:29 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:21:96:29 | synthetic splat argument | @@ -1859,23 +1846,19 @@ track | params_flow.rb:96:27:96:28 | 46 | type tracker with call steps | params_flow.rb:69:17:69:17 | y | | params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | | params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content element 0 | params_flow.rb:71:5:71:10 | synthetic splat argument | -| params_flow.rb:96:27:96:28 | 46 | type tracker with call steps with content element 1 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:27:96:28 | 46 | type tracker without call steps | params_flow.rb:96:21:96:29 | call to taint | | params_flow.rb:96:27:96:28 | 46 | type tracker without call steps | params_flow.rb:96:27:96:28 | 46 | | params_flow.rb:96:27:96:28 | 46 | type tracker without call steps with content element 0 | params_flow.rb:96:21:96:29 | synthetic splat argument | | params_flow.rb:96:27:96:28 | 46 | type tracker without call steps with content element 1 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:32:96:65 | * ... | type tracker without call steps | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:33:96:65 | Array | type tracker without call steps | params_flow.rb:96:33:96:65 | Array | -| params_flow.rb:96:33:96:65 | call to [] | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:33:96:65 | call to [] | type tracker without call steps | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:33:96:65 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:33:96:65 | call to [] | type tracker without call steps with content element 2 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:33:96:65 | synthetic splat argument | | params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:33:96:65 | synthetic splat argument | type tracker without call steps with content element 2 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:34:96:42 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps | params_flow.rb:96:34:96:42 | call to taint | | params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:96:33:96:65 | call to [] | @@ -1883,7 +1866,6 @@ track | params_flow.rb:96:34:96:42 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:34:96:42 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:34:96:42 | synthetic splat argument | | params_flow.rb:96:40:96:41 | 47 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:96:40:96:41 | 47 | type tracker with call steps with content element 2 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps | params_flow.rb:96:34:96:42 | call to taint | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps | params_flow.rb:96:40:96:41 | 47 | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content element 0 | params_flow.rb:96:32:96:65 | * ... | @@ -1891,7 +1873,6 @@ track | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content element 0 | params_flow.rb:96:33:96:65 | synthetic splat argument | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content element 0 | params_flow.rb:96:34:96:42 | synthetic splat argument | | params_flow.rb:96:40:96:41 | 47 | type tracker without call steps with content element 2 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:45:96:53 | call to taint | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps | params_flow.rb:96:45:96:53 | call to taint | | params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:96:33:96:65 | call to [] | @@ -1899,7 +1880,6 @@ track | params_flow.rb:96:45:96:53 | call to taint | type tracker without call steps with content element 3 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:45:96:53 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:45:96:53 | synthetic splat argument | | params_flow.rb:96:51:96:52 | 48 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:96:51:96:52 | 48 | type tracker with call steps with content element 3 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps | params_flow.rb:96:45:96:53 | call to taint | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps | params_flow.rb:96:51:96:52 | 48 | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content element 0 | params_flow.rb:96:45:96:53 | synthetic splat argument | @@ -1907,7 +1887,6 @@ track | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content element 1 | params_flow.rb:96:33:96:65 | call to [] | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content element 1 | params_flow.rb:96:33:96:65 | synthetic splat argument | | params_flow.rb:96:51:96:52 | 48 | type tracker without call steps with content element 3 | params_flow.rb:96:1:96:88 | synthetic splat argument | -| params_flow.rb:96:56:96:64 | call to taint | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps | params_flow.rb:96:56:96:64 | call to taint | | params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:96:32:96:65 | * ... | | params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:96:33:96:65 | call to [] | @@ -1915,7 +1894,6 @@ track | params_flow.rb:96:56:96:64 | call to taint | type tracker without call steps with content element 4 | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:56:96:64 | synthetic splat argument | type tracker without call steps | params_flow.rb:96:56:96:64 | synthetic splat argument | | params_flow.rb:96:62:96:63 | 49 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:96:62:96:63 | 49 | type tracker with call steps with content element 4 | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps | params_flow.rb:96:56:96:64 | call to taint | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps | params_flow.rb:96:62:96:63 | 49 | | params_flow.rb:96:62:96:63 | 49 | type tracker without call steps with content element 0 | params_flow.rb:96:56:96:64 | synthetic splat argument | @@ -1977,12 +1955,10 @@ track | params_flow.rb:102:5:102:10 | call to sink | type tracker without call steps | params_flow.rb:106:1:106:46 | call to splatmidsmall | | params_flow.rb:102:5:102:10 | synthetic splat argument | type tracker without call steps | params_flow.rb:102:5:102:10 | synthetic splat argument | | params_flow.rb:105:1:105:49 | call to splatmidsmall | type tracker without call steps | params_flow.rb:105:1:105:49 | call to splatmidsmall | -| params_flow.rb:105:1:105:49 | synthetic splat argument | type tracker with call steps | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:1:105:49 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps | params_flow.rb:98:19:98:19 | a | | params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:15:105:23 | call to taint | type tracker with call steps with content element 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | | params_flow.rb:105:15:105:23 | call to taint | type tracker without call steps | params_flow.rb:105:15:105:23 | call to taint | | params_flow.rb:105:15:105:23 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:105:1:105:49 | synthetic splat argument | @@ -1991,7 +1967,6 @@ track | params_flow.rb:105:21:105:22 | 52 | type tracker with call steps | params_flow.rb:5:10:5:10 | x | | params_flow.rb:105:21:105:22 | 52 | type tracker with call steps | params_flow.rb:98:19:98:19 | a | | params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content element 0 | params_flow.rb:6:5:6:10 | synthetic splat argument | -| params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content element 0 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:21:105:22 | 52 | type tracker with call steps with content element 0 | params_flow.rb:99:5:99:10 | synthetic splat argument | | params_flow.rb:105:21:105:22 | 52 | type tracker without call steps | params_flow.rb:105:15:105:23 | call to taint | | params_flow.rb:105:21:105:22 | 52 | type tracker without call steps | params_flow.rb:105:21:105:22 | 52 | @@ -1999,16 +1974,13 @@ track | params_flow.rb:105:21:105:22 | 52 | type tracker without call steps with content element 0 | params_flow.rb:105:15:105:23 | synthetic splat argument | | params_flow.rb:105:26:105:48 | * ... | type tracker without call steps | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:27:105:48 | Array | type tracker without call steps | params_flow.rb:105:27:105:48 | Array | -| params_flow.rb:105:27:105:48 | call to [] | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:27:105:48 | call to [] | type tracker without call steps | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:105:27:105:48 | call to [] | type tracker without call steps with content element 0 or unknown | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:27:105:48 | call to [] | type tracker without call steps with content element 1 | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:27:105:48 | call to [] | | params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:27:105:48 | synthetic splat argument | | params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker without call steps with content element 0 or unknown | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:27:105:48 | synthetic splat argument | type tracker without call steps with content element 1 | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:28:105:36 | call to taint | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps | params_flow.rb:105:28:105:36 | call to taint | | params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps with content element 0 | params_flow.rb:105:27:105:48 | call to [] | @@ -2016,7 +1988,6 @@ track | params_flow.rb:105:28:105:36 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:105:28:105:36 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:28:105:36 | synthetic splat argument | | params_flow.rb:105:34:105:35 | 53 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:105:34:105:35 | 53 | type tracker with call steps with content element 1 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps | params_flow.rb:105:28:105:36 | call to taint | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps | params_flow.rb:105:34:105:35 | 53 | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content element 0 | params_flow.rb:105:26:105:48 | * ... | @@ -2024,7 +1995,6 @@ track | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content element 0 | params_flow.rb:105:27:105:48 | synthetic splat argument | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content element 0 | params_flow.rb:105:28:105:36 | synthetic splat argument | | params_flow.rb:105:34:105:35 | 53 | type tracker without call steps with content element 1 | params_flow.rb:105:1:105:49 | synthetic splat argument | -| params_flow.rb:105:39:105:47 | call to taint | type tracker with call steps with content element 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps | params_flow.rb:105:39:105:47 | call to taint | | params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:105:26:105:48 | * ... | | params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps with content element 1 | params_flow.rb:105:27:105:48 | call to [] | @@ -2032,7 +2002,6 @@ track | params_flow.rb:105:39:105:47 | call to taint | type tracker without call steps with content element 2 | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:105:39:105:47 | synthetic splat argument | type tracker without call steps | params_flow.rb:105:39:105:47 | synthetic splat argument | | params_flow.rb:105:45:105:46 | 54 | type tracker with call steps | params_flow.rb:1:11:1:11 | x | -| params_flow.rb:105:45:105:46 | 54 | type tracker with call steps with content element 2 | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:45:105:46 | 54 | type tracker without call steps | params_flow.rb:105:39:105:47 | call to taint | | params_flow.rb:105:45:105:46 | 54 | type tracker without call steps | params_flow.rb:105:45:105:46 | 54 | | params_flow.rb:105:45:105:46 | 54 | type tracker without call steps with content element 0 | params_flow.rb:105:39:105:47 | synthetic splat argument | @@ -4438,7 +4407,6 @@ trackEnd | params_flow.rb:57:15:57:16 | 22 | params_flow.rb:57:9:57:17 | call to taint | | params_flow.rb:57:15:57:16 | 22 | params_flow.rb:57:15:57:16 | 22 | | params_flow.rb:58:1:58:25 | call to posargs | params_flow.rb:58:1:58:25 | call to posargs | -| params_flow.rb:58:1:58:25 | synthetic splat argument | params_flow.rb:49:1:53:3 | synthetic splat parameter | | params_flow.rb:58:1:58:25 | synthetic splat argument | params_flow.rb:58:1:58:25 | synthetic splat argument | | params_flow.rb:58:9:58:17 | call to taint | params_flow.rb:5:10:5:10 | x | | params_flow.rb:58:9:58:17 | call to taint | params_flow.rb:5:10:5:10 | x | @@ -5032,7 +5000,6 @@ trackEnd | params_flow.rb:94:45:94:46 | 44 | params_flow.rb:94:39:94:47 | call to taint | | params_flow.rb:94:45:94:46 | 44 | params_flow.rb:94:45:94:46 | 44 | | params_flow.rb:96:1:96:88 | call to splatmid | params_flow.rb:96:1:96:88 | call to splatmid | -| params_flow.rb:96:1:96:88 | synthetic splat argument | params_flow.rb:69:1:76:3 | synthetic splat parameter | | params_flow.rb:96:1:96:88 | synthetic splat argument | params_flow.rb:96:1:96:88 | synthetic splat argument | | params_flow.rb:96:10:96:18 | call to taint | params_flow.rb:5:10:5:10 | x | | params_flow.rb:96:10:96:18 | call to taint | params_flow.rb:5:10:5:10 | x | @@ -5166,7 +5133,6 @@ trackEnd | params_flow.rb:102:5:102:10 | call to sink | params_flow.rb:106:1:106:46 | call to splatmidsmall | | params_flow.rb:102:5:102:10 | synthetic splat argument | params_flow.rb:102:5:102:10 | synthetic splat argument | | params_flow.rb:105:1:105:49 | call to splatmidsmall | params_flow.rb:105:1:105:49 | call to splatmidsmall | -| params_flow.rb:105:1:105:49 | synthetic splat argument | params_flow.rb:98:1:103:3 | synthetic splat parameter | | params_flow.rb:105:1:105:49 | synthetic splat argument | params_flow.rb:105:1:105:49 | synthetic splat argument | | params_flow.rb:105:15:105:23 | call to taint | params_flow.rb:5:10:5:10 | x | | params_flow.rb:105:15:105:23 | call to taint | params_flow.rb:5:10:5:10 | x | From fd311d5143de10e8f1f7611b8a68454721beb7f4 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 16 Aug 2024 16:09:55 +0200 Subject: [PATCH 036/404] Java: Add some summary debugging queries. --- .../debug/CaptureSummaryModelsPartialPath.ql | 28 +++++++++++++++++++ .../debug/CaptureSummaryModelsPath.ql | 25 +++++++++++++++++ .../src/utils/modelgenerator/debug/README.md | 1 + .../modelgenerator/internal/CaptureModels.qll | 23 ++++++++++----- 4 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql create mode 100644 java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql create mode 100644 java/ql/src/utils/modelgenerator/debug/README.md diff --git a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql new file mode 100644 index 00000000000..2b8a6e220f8 --- /dev/null +++ b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql @@ -0,0 +1,28 @@ +/** + * @name Capture Summary Models Partial Path + * @description Capture Summary Models Partial Path + * @kind path-problem + * @precision low + * @id java/utils/modelgenerator/summary-models-partial-path + * @severity info + * @tags modelgenerator + */ + +import java +import semmle.code.java.dataflow.DataFlow +import utils.modelgenerator.internal.CaptureModels +import PartialFlow::PartialPathGraph + +int explorationLimit() { result = 3 } + +module PartialFlow = PropagateFlow::FlowExplorationFwd; + +from + PartialFlow::PartialPathNode source, PartialFlow::PartialPathNode sink, + DataFlowSummaryTargetApi api, DataFlow::ParameterNode p +where + PartialFlow::partialFlow(source, sink, _) and + p = source.getNode() and + p.asParameter() = api.getParameter(0) +select sink.getNode(), source, sink, "There is flow from a $@ to $@.", source.getNode(), + "parameter", sink.getNode(), "intermediate value" diff --git a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql new file mode 100644 index 00000000000..88d45dc1f5b --- /dev/null +++ b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql @@ -0,0 +1,25 @@ +/** + * @name Capture Summary Models Path + * @description Capture Summary Models Path + * @kind path-problem + * @precision low + * @id java/utils/modelgenerator/summary-models-path + * @severity warning + * @tags modelgenerator + */ + +import java +import semmle.code.java.dataflow.DataFlow +import utils.modelgenerator.internal.CaptureModels +import PropagateFlow::PathGraph + +from + PropagateFlow::PathNode source, PropagateFlow::PathNode sink, DataFlowSummaryTargetApi api, + DataFlow::Node p, DataFlow::Node returnNodeExt +where + PropagateFlow::flowPath(source, sink) and + p = source.getNode() and + returnNodeExt = sink.getNode() and + exists(captureThroughFlow0(api, p, returnNodeExt)) +select sink.getNode(), source, sink, "There is flow from $@ to the $@.", source.getNode(), + "parameter", sink.getNode(), "return value" diff --git a/java/ql/src/utils/modelgenerator/debug/README.md b/java/ql/src/utils/modelgenerator/debug/README.md new file mode 100644 index 00000000000..8d01e511882 --- /dev/null +++ b/java/ql/src/utils/modelgenerator/debug/README.md @@ -0,0 +1 @@ +The queries in this directory are purely used for model generator debugging purposes in VS Code. diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll index b8bc01f0800..ae8c2cad891 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -196,14 +196,13 @@ module PropagateFlowConfig implements DataFlow::StateConfigSig { } } -private module PropagateFlow = TaintTracking::GlobalWithState; +module PropagateFlow = TaintTracking::GlobalWithState; -/** - * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. - */ -string captureThroughFlow(DataFlowSummaryTargetApi api) { - exists(DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt, string input, string output | - PropagateFlow::flow(p, returnNodeExt) and +string captureThroughFlow0( + DataFlowSummaryTargetApi api, DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt +) { + exists(string input, string output | + p.getEnclosingCallable() = api and returnNodeExt.(DataFlow::Node).getEnclosingCallable() = api and input = parameterNodeAsInput(p) and output = returnNodeExt.getOutput() and @@ -212,6 +211,16 @@ string captureThroughFlow(DataFlowSummaryTargetApi api) { ) } +/** + * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. + */ +string captureThroughFlow(DataFlowSummaryTargetApi api) { + exists(DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt | + PropagateFlow::flow(p, returnNodeExt) and + result = captureThroughFlow0(api, p, returnNodeExt) + ) +} + /** * A dataflow configuration used for finding new sources. * The sources are the already known existing sources and the sinks are the API return nodes. From 6ea01b81bbdd865a092130b397da0366e9b6cf98 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 20 Aug 2024 16:23:22 +0200 Subject: [PATCH 037/404] C#: Add some summary debugging queries. --- .../debug/CaptureSummaryModelsPartialPath.ql | 27 +++++++++++++++++++ .../debug/CaptureSummaryModelsPath.ql | 24 +++++++++++++++++ .../src/utils/modelgenerator/debug/README.md | 1 + .../modelgenerator/internal/CaptureModels.qll | 23 +++++++++++----- 4 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql create mode 100644 csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql create mode 100644 csharp/ql/src/utils/modelgenerator/debug/README.md diff --git a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql new file mode 100644 index 00000000000..614fb7630b4 --- /dev/null +++ b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql @@ -0,0 +1,27 @@ +/** + * @name Capture Summary Models Partial Path + * @description Capture Summary Models Partial Path + * @kind path-problem + * @precision low + * @id csharp/utils/modelgenerator/summary-models-partial-path + * @severity info + * @tags modelgenerator + */ + +import csharp +import utils.modelgenerator.internal.CaptureModels +import PartialFlow::PartialPathGraph + +int explorationLimit() { result = 3 } + +module PartialFlow = PropagateFlow::FlowExplorationFwd; + +from + PartialFlow::PartialPathNode source, PartialFlow::PartialPathNode sink, + DataFlowSummaryTargetApi api, DataFlow::ParameterNode p +where + PartialFlow::partialFlow(source, sink, _) and + p = source.getNode() and + p.asParameter() = api.getParameter(0) +select sink.getNode(), source, sink, "There is flow from a $@ to $@.", source.getNode(), + "parameter", sink.getNode(), "intermediate value" diff --git a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql new file mode 100644 index 00000000000..7be5a1fc00e --- /dev/null +++ b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPath.ql @@ -0,0 +1,24 @@ +/** + * @name Capture Summary Models Path + * @description Capture Summary Models Path + * @kind path-problem + * @precision low + * @id csharp/utils/modelgenerator/summary-models-path + * @severity warning + * @tags modelgenerator + */ + +import csharp +import utils.modelgenerator.internal.CaptureModels +import PropagateFlow::PathGraph + +from + PropagateFlow::PathNode source, PropagateFlow::PathNode sink, DataFlowSummaryTargetApi api, + DataFlow::Node p, DataFlow::Node returnNodeExt +where + PropagateFlow::flowPath(source, sink) and + p = source.getNode() and + returnNodeExt = sink.getNode() and + exists(captureThroughFlow0(api, p, returnNodeExt)) +select sink.getNode(), source, sink, "There is flow from $@ to the $@.", source.getNode(), + "parameter", sink.getNode(), "return value" diff --git a/csharp/ql/src/utils/modelgenerator/debug/README.md b/csharp/ql/src/utils/modelgenerator/debug/README.md new file mode 100644 index 00000000000..8d01e511882 --- /dev/null +++ b/csharp/ql/src/utils/modelgenerator/debug/README.md @@ -0,0 +1 @@ +The queries in this directory are purely used for model generator debugging purposes in VS Code. diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll index b8bc01f0800..ae8c2cad891 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -196,14 +196,13 @@ module PropagateFlowConfig implements DataFlow::StateConfigSig { } } -private module PropagateFlow = TaintTracking::GlobalWithState; +module PropagateFlow = TaintTracking::GlobalWithState; -/** - * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. - */ -string captureThroughFlow(DataFlowSummaryTargetApi api) { - exists(DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt, string input, string output | - PropagateFlow::flow(p, returnNodeExt) and +string captureThroughFlow0( + DataFlowSummaryTargetApi api, DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt +) { + exists(string input, string output | + p.getEnclosingCallable() = api and returnNodeExt.(DataFlow::Node).getEnclosingCallable() = api and input = parameterNodeAsInput(p) and output = returnNodeExt.getOutput() and @@ -212,6 +211,16 @@ string captureThroughFlow(DataFlowSummaryTargetApi api) { ) } +/** + * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. + */ +string captureThroughFlow(DataFlowSummaryTargetApi api) { + exists(DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt | + PropagateFlow::flow(p, returnNodeExt) and + result = captureThroughFlow0(api, p, returnNodeExt) + ) +} + /** * A dataflow configuration used for finding new sources. * The sources are the already known existing sources and the sinks are the API return nodes. From 21366dd5023b588215a9820f541b4c3a3e38700f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 14 Aug 2024 17:57:24 +0100 Subject: [PATCH 038/404] Go / configure-baseline: account for multiple vendor directories and the `CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS` setting Our existing configure-baseline scripts would give the wrong result if a `vendor` directory wasn't at the root of the repository, or if the `CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS` variable was set to `true` indicating the user wants their vendored code scanned. Here I replace the shell scripts that implemented the very simplest behaviour with a small Go program. --- go/BUILD.bazel | 1 + go/codeql-tools/baseline-config-empty.json | 3 -- go/codeql-tools/baseline-config-vendor.json | 5 -- go/codeql-tools/configure-baseline.cmd | 11 +++-- go/codeql-tools/configure-baseline.sh | 6 +-- .../cli/go-configure-baseline/BUILD.bazel | 18 +++++++ .../go-configure-baseline.go | 14 ++++++ go/extractor/configurebaseline/BUILD.bazel | 10 ++++ .../configurebaseline/configurebaseline.go | 48 +++++++++++++++++++ 9 files changed, 98 insertions(+), 18 deletions(-) delete mode 100644 go/codeql-tools/baseline-config-empty.json delete mode 100644 go/codeql-tools/baseline-config-vendor.json create mode 100644 go/extractor/cli/go-configure-baseline/BUILD.bazel create mode 100644 go/extractor/cli/go-configure-baseline/go-configure-baseline.go create mode 100644 go/extractor/configurebaseline/BUILD.bazel create mode 100644 go/extractor/configurebaseline/configurebaseline.go diff --git a/go/BUILD.bazel b/go/BUILD.bazel index 936c86e0ed1..931f061da9e 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -47,6 +47,7 @@ codeql_pkg_files( "//go/extractor/cli/go-autobuilder", "//go/extractor/cli/go-bootstrap", "//go/extractor/cli/go-build-runner", + "//go/extractor/cli/go-configure-baseline", "//go/extractor/cli/go-extractor", "//go/extractor/cli/go-gen-dbscheme", "//go/extractor/cli/go-tokenizer", diff --git a/go/codeql-tools/baseline-config-empty.json b/go/codeql-tools/baseline-config-empty.json deleted file mode 100644 index 568d688fc3f..00000000000 --- a/go/codeql-tools/baseline-config-empty.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "paths-ignore": [] -} \ No newline at end of file diff --git a/go/codeql-tools/baseline-config-vendor.json b/go/codeql-tools/baseline-config-vendor.json deleted file mode 100644 index d2f654073b0..00000000000 --- a/go/codeql-tools/baseline-config-vendor.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "paths-ignore": [ - "vendor/**" - ] -} \ No newline at end of file diff --git a/go/codeql-tools/configure-baseline.cmd b/go/codeql-tools/configure-baseline.cmd index 285c3d66829..03edd525f3e 100644 --- a/go/codeql-tools/configure-baseline.cmd +++ b/go/codeql-tools/configure-baseline.cmd @@ -1,6 +1,7 @@ @echo off -if exist vendor\modules.txt ( - type "%CODEQL_EXTRACTOR_GO_ROOT%\tools\baseline-config-vendor.json" -) else ( - type "%CODEQL_EXTRACTOR_GO_ROOT%\tools\baseline-config-empty.json" -) +SETLOCAL EnableDelayedExpansion + +type NUL && "%CODEQL_EXTRACTOR_GO_ROOT%/tools/%CODEQL_PLATFORM%/go-configure-baseline.exe" +exit /b %ERRORLEVEL% + +ENDLOCAL diff --git a/go/codeql-tools/configure-baseline.sh b/go/codeql-tools/configure-baseline.sh index f426773c3ba..20edf8b4c93 100755 --- a/go/codeql-tools/configure-baseline.sh +++ b/go/codeql-tools/configure-baseline.sh @@ -1,7 +1,3 @@ #!/bin/sh -if [ -f vendor/modules.txt ]; then - cat "$CODEQL_EXTRACTOR_GO_ROOT/tools/baseline-config-vendor.json" -else - cat "$CODEQL_EXTRACTOR_GO_ROOT/tools/baseline-config-empty.json" -fi +"$CODEQL_EXTRACTOR_GO_ROOT/tools/$CODEQL_PLATFORM/go-configure-baseline" diff --git a/go/extractor/cli/go-configure-baseline/BUILD.bazel b/go/extractor/cli/go-configure-baseline/BUILD.bazel new file mode 100644 index 00000000000..df1af64d6a3 --- /dev/null +++ b/go/extractor/cli/go-configure-baseline/BUILD.bazel @@ -0,0 +1,18 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") +load("//go:rules.bzl", "codeql_go_binary") + +go_library( + name = "go-configure-baseline_lib", + srcs = ["go-configure-baseline.go"], + importpath = "github.com/github/codeql-go/extractor/cli/go-configure-baseline", + visibility = ["//visibility:private"], + deps = ["//go/extractor/configurebaseline"], +) + +codeql_go_binary( + name = "go-configure-baseline", + embed = [":go-configure-baseline_lib"], + visibility = ["//visibility:public"], +) diff --git a/go/extractor/cli/go-configure-baseline/go-configure-baseline.go b/go/extractor/cli/go-configure-baseline/go-configure-baseline.go new file mode 100644 index 00000000000..b7f88230267 --- /dev/null +++ b/go/extractor/cli/go-configure-baseline/go-configure-baseline.go @@ -0,0 +1,14 @@ +package main + +import ( + "github.com/github/codeql-go/extractor/configurebaseline" +) + +func main() { + jsonResult, err := configurebaseline.GetConfigBaselineAsJSON(".") + if err != nil { + panic(err) + } else { + println(string(jsonResult)) + } +} diff --git a/go/extractor/configurebaseline/BUILD.bazel b/go/extractor/configurebaseline/BUILD.bazel new file mode 100644 index 00000000000..7c5161683f5 --- /dev/null +++ b/go/extractor/configurebaseline/BUILD.bazel @@ -0,0 +1,10 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "configurebaseline", + srcs = ["configurebaseline.go"], + importpath = "github.com/github/codeql-go/extractor/configurebaseline", + visibility = ["//visibility:public"], +) diff --git a/go/extractor/configurebaseline/configurebaseline.go b/go/extractor/configurebaseline/configurebaseline.go new file mode 100644 index 00000000000..b8bab4eeb95 --- /dev/null +++ b/go/extractor/configurebaseline/configurebaseline.go @@ -0,0 +1,48 @@ +package configurebaseline + +import ( + "encoding/json" + "io/fs" + "os" + "path" + "path/filepath" +) + +func fileExists(path string) bool { + stat, err := os.Stat(path) + return err == nil && stat.Mode().IsRegular() +} + +func isGolangVendorDirectory(dirPath string) bool { + // Call a directory a Golang vendor directory if it contains a modules.txt file. + return path.Base(dirPath) == "vendor" && fileExists(path.Join(dirPath, "modules.txt")) +} + +type PathsIgnoreStruct struct { + PathsIgnore []string `json:"paths-ignore"` +} + +func GetConfigBaselineAsJSON(rootDir string) ([]byte, error) { + vendorDirs := make([]string, 0) + + // If CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS is "true": + if os.Getenv("CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS") == "true" { + // The user wants vendor directories scanned; emit an empty report. + } else { + filepath.WalkDir(rootDir, func(dirPath string, d fs.DirEntry, err error) error { + if err != nil { + // Mask any unreadable paths. + return nil + } + if isGolangVendorDirectory(dirPath) { + vendorDirs = append(vendorDirs, path.Join(dirPath, "**")) + return filepath.SkipDir + } else { + return nil + } + }) + } + + outputStruct := PathsIgnoreStruct{PathsIgnore: vendorDirs} + return json.Marshal(outputStruct) +} From 624d2b83c04928f32e27f585cac8712aaa8f13db Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 19 Aug 2024 17:40:27 +0100 Subject: [PATCH 039/404] Tidy comments --- go/extractor/configurebaseline/configurebaseline.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/extractor/configurebaseline/configurebaseline.go b/go/extractor/configurebaseline/configurebaseline.go index b8bab4eeb95..5ed112c624b 100644 --- a/go/extractor/configurebaseline/configurebaseline.go +++ b/go/extractor/configurebaseline/configurebaseline.go @@ -13,8 +13,9 @@ func fileExists(path string) bool { return err == nil && stat.Mode().IsRegular() } +// Decides if `dirPath` is a vendor directory by testing whether it is called `vendor` +// and contains a `modules.txt` file. func isGolangVendorDirectory(dirPath string) bool { - // Call a directory a Golang vendor directory if it contains a modules.txt file. return path.Base(dirPath) == "vendor" && fileExists(path.Join(dirPath, "modules.txt")) } @@ -25,7 +26,6 @@ type PathsIgnoreStruct struct { func GetConfigBaselineAsJSON(rootDir string) ([]byte, error) { vendorDirs := make([]string, 0) - // If CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS is "true": if os.Getenv("CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS") == "true" { // The user wants vendor directories scanned; emit an empty report. } else { From 5d34dbf2c296db396a7ab84161c5edb21111b00d Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 19 Aug 2024 17:49:48 +0100 Subject: [PATCH 040/404] Remove unnecessary batch script flag --- go/codeql-tools/configure-baseline.cmd | 3 --- 1 file changed, 3 deletions(-) diff --git a/go/codeql-tools/configure-baseline.cmd b/go/codeql-tools/configure-baseline.cmd index 03edd525f3e..47789cfbd3a 100644 --- a/go/codeql-tools/configure-baseline.cmd +++ b/go/codeql-tools/configure-baseline.cmd @@ -1,7 +1,4 @@ @echo off -SETLOCAL EnableDelayedExpansion type NUL && "%CODEQL_EXTRACTOR_GO_ROOT%/tools/%CODEQL_PLATFORM%/go-configure-baseline.exe" exit /b %ERRORLEVEL% - -ENDLOCAL From 22802fd41fea6b854ab54f9afe30e36abd6c9018 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 19 Aug 2024 17:50:53 +0100 Subject: [PATCH 041/404] Improve struct naming --- go/extractor/configurebaseline/configurebaseline.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/extractor/configurebaseline/configurebaseline.go b/go/extractor/configurebaseline/configurebaseline.go index 5ed112c624b..59075b07239 100644 --- a/go/extractor/configurebaseline/configurebaseline.go +++ b/go/extractor/configurebaseline/configurebaseline.go @@ -19,7 +19,7 @@ func isGolangVendorDirectory(dirPath string) bool { return path.Base(dirPath) == "vendor" && fileExists(path.Join(dirPath, "modules.txt")) } -type PathsIgnoreStruct struct { +type BaselineConfig struct { PathsIgnore []string `json:"paths-ignore"` } @@ -43,6 +43,6 @@ func GetConfigBaselineAsJSON(rootDir string) ([]byte, error) { }) } - outputStruct := PathsIgnoreStruct{PathsIgnore: vendorDirs} + outputStruct := BaselineConfig{PathsIgnore: vendorDirs} return json.Marshal(outputStruct) } From f1f6f9b580a11977fa31a3da1992b7fb6f70fd15 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 19 Aug 2024 17:55:42 +0100 Subject: [PATCH 042/404] Share vendor-dir extraction logic between extractor and configure-baseline script --- go/extractor/configurebaseline/configurebaseline.go | 4 +++- go/extractor/extractor.go | 2 +- go/extractor/util/extractvendordirs.go | 9 +++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 go/extractor/util/extractvendordirs.go diff --git a/go/extractor/configurebaseline/configurebaseline.go b/go/extractor/configurebaseline/configurebaseline.go index 59075b07239..e318111fef9 100644 --- a/go/extractor/configurebaseline/configurebaseline.go +++ b/go/extractor/configurebaseline/configurebaseline.go @@ -6,6 +6,8 @@ import ( "os" "path" "path/filepath" + + "github.com/github/codeql-go/extractor/util" ) func fileExists(path string) bool { @@ -26,7 +28,7 @@ type BaselineConfig struct { func GetConfigBaselineAsJSON(rootDir string) ([]byte, error) { vendorDirs := make([]string, 0) - if os.Getenv("CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS") == "true" { + if util.IsVendorDirExtractionEnabled() { // The user wants vendor directories scanned; emit an empty report. } else { filepath.WalkDir(rootDir, func(dirPath string, d fs.DirEntry, err error) error { diff --git a/go/extractor/extractor.go b/go/extractor/extractor.go index df3a43f80cf..4926d8e3e13 100644 --- a/go/extractor/extractor.go +++ b/go/extractor/extractor.go @@ -199,7 +199,7 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error { // If CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS is "true", we extract `vendor` directories; // otherwise (the default) is to exclude them from extraction - includeVendor := os.Getenv("CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS") == "true" + includeVendor := util.IsVendorDirExtractionEnabled() if !includeVendor { excludedDirs = append(excludedDirs, "vendor") } diff --git a/go/extractor/util/extractvendordirs.go b/go/extractor/util/extractvendordirs.go new file mode 100644 index 00000000000..778d5120cf2 --- /dev/null +++ b/go/extractor/util/extractvendordirs.go @@ -0,0 +1,9 @@ +package util + +import ( + "os" +) + +func IsVendorDirExtractionEnabled() bool { + return os.Getenv("CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS") == "true" +} From ea3e5c8a99011495c02e9ae2a8ff0afbc6a02234 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 19 Aug 2024 17:57:12 +0100 Subject: [PATCH 043/404] Clarify comment --- go/extractor/configurebaseline/configurebaseline.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/extractor/configurebaseline/configurebaseline.go b/go/extractor/configurebaseline/configurebaseline.go index e318111fef9..fa8023f24a8 100644 --- a/go/extractor/configurebaseline/configurebaseline.go +++ b/go/extractor/configurebaseline/configurebaseline.go @@ -33,7 +33,8 @@ func GetConfigBaselineAsJSON(rootDir string) ([]byte, error) { } else { filepath.WalkDir(rootDir, func(dirPath string, d fs.DirEntry, err error) error { if err != nil { - // Mask any unreadable paths. + // Ignore any unreadable paths -- if this script can't see it, very likely + // it will not be extracted either. return nil } if isGolangVendorDirectory(dirPath) { From 8b9617cd3810c07a32ec173a1b47747d4f258008 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 20 Aug 2024 15:55:02 +0100 Subject: [PATCH 044/404] Update bazel build files --- go/extractor/configurebaseline/BUILD.bazel | 1 + go/extractor/util/BUILD.bazel | 1 + 2 files changed, 2 insertions(+) diff --git a/go/extractor/configurebaseline/BUILD.bazel b/go/extractor/configurebaseline/BUILD.bazel index 7c5161683f5..b12e89abaf3 100644 --- a/go/extractor/configurebaseline/BUILD.bazel +++ b/go/extractor/configurebaseline/BUILD.bazel @@ -7,4 +7,5 @@ go_library( srcs = ["configurebaseline.go"], importpath = "github.com/github/codeql-go/extractor/configurebaseline", visibility = ["//visibility:public"], + deps = ["//go/extractor/util"], ) diff --git a/go/extractor/util/BUILD.bazel b/go/extractor/util/BUILD.bazel index d0195e05be2..b7a7783aa79 100644 --- a/go/extractor/util/BUILD.bazel +++ b/go/extractor/util/BUILD.bazel @@ -5,6 +5,7 @@ load("@rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "util", srcs = [ + "extractvendordirs.go", "semver.go", "util.go", ], From 15b5bcc67c7028a95e792e00bea91bd163eaa90a Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 20 Aug 2024 17:01:54 +0100 Subject: [PATCH 045/404] Output to stdout, not stderr --- .../cli/go-configure-baseline/go-configure-baseline.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go/extractor/cli/go-configure-baseline/go-configure-baseline.go b/go/extractor/cli/go-configure-baseline/go-configure-baseline.go index b7f88230267..c8159908e0a 100644 --- a/go/extractor/cli/go-configure-baseline/go-configure-baseline.go +++ b/go/extractor/cli/go-configure-baseline/go-configure-baseline.go @@ -1,6 +1,8 @@ package main import ( + "fmt" + "github.com/github/codeql-go/extractor/configurebaseline" ) @@ -9,6 +11,6 @@ func main() { if err != nil { panic(err) } else { - println(string(jsonResult)) + fmt.Println(string(jsonResult)) } } From 3acab640b2b990857f9ecad64a8ee166bc109310 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 20 Aug 2024 17:07:09 +0100 Subject: [PATCH 046/404] Add configure-baseline integration test --- .../go/configure-baseline/src/a/vendor/avendor.go | 1 + .../go/configure-baseline/src/a/vendor/modules.txt | 0 .../go/configure-baseline/src/b/vendor/bvendor.go | 1 + .../go/configure-baseline/src/b/vendor/modules.txt | 0 .../go/configure-baseline/src/c/vendor/cvendor.go | 1 + .../all-platforms/go/configure-baseline/src/root.go | 1 + .../all-platforms/go/configure-baseline/test.py | 9 +++++++++ 7 files changed, 13 insertions(+) create mode 100644 go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/avendor.go create mode 100644 go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/modules.txt create mode 100644 go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/bvendor.go create mode 100644 go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/modules.txt create mode 100644 go/ql/integration-tests/all-platforms/go/configure-baseline/src/c/vendor/cvendor.go create mode 100644 go/ql/integration-tests/all-platforms/go/configure-baseline/src/root.go create mode 100644 go/ql/integration-tests/all-platforms/go/configure-baseline/test.py diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/avendor.go b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/avendor.go new file mode 100644 index 00000000000..6e423a61072 --- /dev/null +++ b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/avendor.go @@ -0,0 +1 @@ +package abc diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/modules.txt b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/modules.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/bvendor.go b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/bvendor.go new file mode 100644 index 00000000000..6e423a61072 --- /dev/null +++ b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/bvendor.go @@ -0,0 +1 @@ +package abc diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/modules.txt b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/modules.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/c/vendor/cvendor.go b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/c/vendor/cvendor.go new file mode 100644 index 00000000000..6e423a61072 --- /dev/null +++ b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/c/vendor/cvendor.go @@ -0,0 +1 @@ +package abc diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/root.go b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/root.go new file mode 100644 index 00000000000..6e423a61072 --- /dev/null +++ b/go/ql/integration-tests/all-platforms/go/configure-baseline/src/root.go @@ -0,0 +1 @@ +package abc diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py b/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py new file mode 100644 index 00000000000..ea414349666 --- /dev/null +++ b/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py @@ -0,0 +1,9 @@ +import os.path +import json + +def test(codeql, go): + codeql.database.init(source_root="src") + baseline_info_path = os.path.join("test-db", "baseline-info.json") + with open(baseline_info_path, "r") as f: + baseline_info = json.load(f) + assert set(baseline_info["languages"]["go"]["files"]) == set(["root.go", os.path.join("c", "vendor", "cvendor.go")]), "Expected root.go and cvendor.go in baseline" From fc301206d1d8deeccfc8bb45cf4334d6bf2b5277 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 20 Aug 2024 17:11:58 +0100 Subject: [PATCH 047/404] Change note --- go/ql/lib/change-notes/2024-08-20-vendor-dirs-baseline.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/lib/change-notes/2024-08-20-vendor-dirs-baseline.md diff --git a/go/ql/lib/change-notes/2024-08-20-vendor-dirs-baseline.md b/go/ql/lib/change-notes/2024-08-20-vendor-dirs-baseline.md new file mode 100644 index 00000000000..cab6b49f3ba --- /dev/null +++ b/go/ql/lib/change-notes/2024-08-20-vendor-dirs-baseline.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Golang vendor directories not at the root of a repository are now correctly excluded from the baseline Go file count. This means code coverage information will be more accurate. From 9bd3f3dee01958294ea45154a3b83a458cb4b6da Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 29 Jul 2024 13:30:45 +0200 Subject: [PATCH 048/404] Dataflow: Rename StagePathNode to StagePathNodeImpl. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 6425574581e..19966185c45 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2536,7 +2536,7 @@ module MakeImpl Lang> { TStagePathNodeSrcGrp() or TStagePathNodeSinkGrp() - class StagePathNode extends TStagePathNode { + class StagePathNodeImpl extends TStagePathNode { abstract string toString(); abstract Location getLocation(); @@ -2553,19 +2553,19 @@ module MakeImpl Lang> { predicate isArbitrarySink() { this instanceof TStagePathNodeSinkGrp } } - class StagePathNodeSrcGrp extends StagePathNode, TStagePathNodeSrcGrp { + class StagePathNodeSrcGrp extends StagePathNodeImpl, TStagePathNodeSrcGrp { override string toString() { result = "" } override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } } - class StagePathNodeSinkGrp extends StagePathNode, TStagePathNodeSinkGrp { + class StagePathNodeSinkGrp extends StagePathNodeImpl, TStagePathNodeSinkGrp { override string toString() { result = "" } override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } } - class StagePathNodeMid extends StagePathNode, TStagePathNodeMid { + class StagePathNodeMid extends StagePathNodeImpl, TStagePathNodeMid { NodeEx node; FlowState state; Cc cc; @@ -2646,14 +2646,14 @@ module MakeImpl Lang> { bindingset[node, state, cc, summaryCtx, argT, argAp, t, ap] pragma[inline_late] - private StagePathNode mkStagePathNode( + private StagePathNodeImpl mkStagePathNode( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap ) { result = TStagePathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) } - private StagePathNode typeStrengthenToStagePathNode( + private StagePathNodeImpl typeStrengthenToStagePathNode( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t0, Ap ap ) { @@ -2665,9 +2665,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThroughStep1( - StagePathNode pn1, StagePathNode pn2, StagePathNode pn3, DataFlowCall call, Cc cc, - FlowState state, CcCall ccc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, - Typ t, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa + StagePathNodeImpl pn1, StagePathNodeImpl pn2, StagePathNodeImpl pn3, DataFlowCall call, + Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, TypOption argT, + ApOption argAp, Typ t, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa ) { exists(FlowState state0, ArgNodeEx arg, ParamNodeEx p, Typ innerArgT, Ap innerArgAp | fwdFlowThroughStep0(call, arg, cc, state, ccc, summaryCtx, argT, argAp, t, ap, apa, @@ -2685,7 +2685,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThroughStep2( - StagePathNode pn1, StagePathNode pn2, StagePathNode pn3, NodeEx node, Cc cc, + StagePathNodeImpl pn1, StagePathNodeImpl pn2, StagePathNodeImpl pn3, NodeEx node, Cc cc, FlowState state, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap ) { @@ -2701,7 +2701,7 @@ module MakeImpl Lang> { } private predicate localStep( - StagePathNode pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, + StagePathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, string label ) { exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | @@ -2732,7 +2732,7 @@ module MakeImpl Lang> { ) } - private predicate localStep(StagePathNode pn1, StagePathNode pn2, string label) { + private predicate localStep(StagePathNodeImpl pn1, StagePathNodeImpl pn2, string label) { exists( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t0, Ap ap @@ -2744,27 +2744,29 @@ module MakeImpl Lang> { summaryStep(pn1, pn2, label) } - private predicate summaryLabel(StagePathNode pn1, StagePathNode pn2, string summaryLabel) { + private predicate summaryLabel( + StagePathNodeImpl pn1, StagePathNodeImpl pn2, string summaryLabel + ) { pn1 = pn2 and summaryLabel = "" and subpaths(_, pn1, _, _) or - exists(StagePathNode mid, string l1, string l2 | + exists(StagePathNodeImpl mid, string l1, string l2 | summaryLabel(pn1, mid, l1) and localStep(mid, pn2, l2) and summaryLabel = mergeLabels(l1, l2) ) } - private predicate summaryStep(StagePathNode arg, StagePathNode out, string label) { - exists(StagePathNode par, StagePathNode ret | + private predicate summaryStep(StagePathNodeImpl arg, StagePathNodeImpl out, string label) { + exists(StagePathNodeImpl par, StagePathNodeImpl ret | subpaths(arg, par, ret, out) and summaryLabel(par, ret, label) ) } private predicate nonLocalStep( - StagePathNode pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, + StagePathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, string label ) { // jump @@ -2823,7 +2825,7 @@ module MakeImpl Lang> { ) } - private predicate nonLocalStep(StagePathNode pn1, StagePathNode pn2, string label) { + private predicate nonLocalStep(StagePathNodeImpl pn1, StagePathNodeImpl pn2, string label) { exists( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t0, Ap ap @@ -2834,7 +2836,8 @@ module MakeImpl Lang> { } query predicate subpaths( - StagePathNode arg, StagePathNode par, StagePathNode ret, StagePathNode out + StagePathNodeImpl arg, StagePathNodeImpl par, StagePathNodeImpl ret, + StagePathNodeImpl out ) { exists( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -2845,7 +2848,7 @@ module MakeImpl Lang> { ) } - query predicate edges(StagePathNode pn1, StagePathNode pn2, string key, string val) { + query predicate edges(StagePathNodeImpl pn1, StagePathNodeImpl pn2, string key, string val) { key = "provenance" and ( localStep(pn1, pn2, val) From bc0ae4cd1e1eec90b2d2dbf3e45be93adc16c2ec Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 20 Aug 2024 11:45:40 +0200 Subject: [PATCH 049/404] Dataflow: Replace StagePathNode.getNode with getNodeEx. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 19966185c45..20b44896533 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2537,13 +2537,12 @@ module MakeImpl Lang> { TStagePathNodeSinkGrp() class StagePathNodeImpl extends TStagePathNode { + abstract NodeEx getNodeEx(); + abstract string toString(); abstract Location getLocation(); - /** Gets the corresponding `Node`, if any. */ - Node getNode() { none() } - predicate isSource() { none() } predicate isSink() { none() } @@ -2557,12 +2556,16 @@ module MakeImpl Lang> { override string toString() { result = "" } override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } + + override NodeEx getNodeEx() { none() } } class StagePathNodeSinkGrp extends StagePathNodeImpl, TStagePathNodeSinkGrp { override string toString() { result = "" } override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } + + override NodeEx getNodeEx() { none() } } class StagePathNodeMid extends StagePathNodeImpl, TStagePathNodeMid { @@ -2579,6 +2582,8 @@ module MakeImpl Lang> { this = TStagePathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) } + override NodeEx getNodeEx() { result = node } + override string toString() { result = node.toString() + " " + cc.toString() + " " + t.toString() + " " + ap.toString() @@ -2586,8 +2591,6 @@ module MakeImpl Lang> { override Location getLocation() { result = node.getLocation() } - override Node getNode() { result = node.asNode() } - override predicate isSource() { sourceNode(node, state) and (if hasSourceCallCtx() then cc = ccSomeCall() else cc = ccNone()) and From bdcc5e7b6725b42630311f8efb20c63c9014550b Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 20 Aug 2024 11:47:59 +0200 Subject: [PATCH 050/404] Dataflow: Refactor getLocation --- shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 20b44896533..147f8671417 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2541,12 +2541,13 @@ module MakeImpl Lang> { abstract string toString(); - abstract Location getLocation(); - predicate isSource() { none() } predicate isSink() { none() } + /** Gets the location of this node. */ + Location getLocation() { result = this.getNodeEx().getLocation() } + predicate isArbitrarySource() { this instanceof TStagePathNodeSrcGrp } predicate isArbitrarySink() { this instanceof TStagePathNodeSinkGrp } @@ -2589,8 +2590,6 @@ module MakeImpl Lang> { node.toString() + " " + cc.toString() + " " + t.toString() + " " + ap.toString() } - override Location getLocation() { result = node.getLocation() } - override predicate isSource() { sourceNode(node, state) and (if hasSourceCallCtx() then cc = ccSomeCall() else cc = ccNone()) and From 81a815c343a4d501bf200e31d27169633cd55f01 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 20 Aug 2024 11:49:50 +0200 Subject: [PATCH 051/404] Dataflow: Add StagePathNode.getState. --- .../dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 147f8671417..8e70f6235fe 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2539,6 +2539,9 @@ module MakeImpl Lang> { class StagePathNodeImpl extends TStagePathNode { abstract NodeEx getNodeEx(); + /** Gets the `FlowState` of this node. */ + abstract FlowState getState(); + abstract string toString(); predicate isSource() { none() } @@ -2559,6 +2562,8 @@ module MakeImpl Lang> { override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } } class StagePathNodeSinkGrp extends StagePathNodeImpl, TStagePathNodeSinkGrp { @@ -2567,6 +2572,8 @@ module MakeImpl Lang> { override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } override NodeEx getNodeEx() { none() } + + override FlowState getState() { none() } } class StagePathNodeMid extends StagePathNodeImpl, TStagePathNodeMid { @@ -2585,6 +2592,8 @@ module MakeImpl Lang> { override NodeEx getNodeEx() { result = node } + override FlowState getState() { result = state } + override string toString() { result = node.toString() + " " + cc.toString() + " " + t.toString() + " " + ap.toString() From 9429e5ccba23a09397eac402654de39a49e75491 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 20 Aug 2024 11:54:56 +0200 Subject: [PATCH 052/404] Dataflow: Update StagePathNode.toString. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 8e70f6235fe..b9a4193dbb6 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2542,6 +2542,7 @@ module MakeImpl Lang> { /** Gets the `FlowState` of this node. */ abstract FlowState getState(); + /** Gets a textual representation of this element. */ abstract string toString(); predicate isSource() { none() } @@ -2594,9 +2595,39 @@ module MakeImpl Lang> { override FlowState getState() { result = state } - override string toString() { + private string ppType() { + exists(string ppt | ppt = t.toString() | + if ppt = "" then result = "" else result = " : " + ppt + ) + } + + private string ppAp() { + exists(string s | s = ap.toString() | + if s = "" then result = "" else result = " " + s + ) + } + + private string ppCtx() { result = " <" + cc + ">" } + + private string ppSummaryCtx() { + summaryCtx instanceof TParamNodeNone and result = "" + or + exists(ParamNode p, Ap argAp0 | + summaryCtx = TParamNodeSome(p) and argAp = apSome(argAp0) + | + result = " <" + p + " : " + argT + " " + argAp0 + ">" + ) + } + + override string toString() { result = node.toString() + this.ppType() + this.ppAp() } + + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + string toStringWithContext() { result = - node.toString() + " " + cc.toString() + " " + t.toString() + " " + ap.toString() + node.toString() + this.ppType() + this.ppAp() + this.ppCtx() + this.ppSummaryCtx() } override predicate isSource() { From bc1dd45d4fede041a78f6065d3af5fa5dcf7a9d5 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 20 Aug 2024 11:56:08 +0200 Subject: [PATCH 053/404] Dataflow: Make private --- .../dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index b9a4193dbb6..77eec1e907b 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2557,7 +2557,7 @@ module MakeImpl Lang> { predicate isArbitrarySink() { this instanceof TStagePathNodeSinkGrp } } - class StagePathNodeSrcGrp extends StagePathNodeImpl, TStagePathNodeSrcGrp { + private class StagePathNodeSrcGrp extends StagePathNodeImpl, TStagePathNodeSrcGrp { override string toString() { result = "" } override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } @@ -2567,7 +2567,7 @@ module MakeImpl Lang> { override FlowState getState() { none() } } - class StagePathNodeSinkGrp extends StagePathNodeImpl, TStagePathNodeSinkGrp { + private class StagePathNodeSinkGrp extends StagePathNodeImpl, TStagePathNodeSinkGrp { override string toString() { result = "" } override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } @@ -2577,7 +2577,11 @@ module MakeImpl Lang> { override FlowState getState() { none() } } - class StagePathNodeMid extends StagePathNodeImpl, TStagePathNodeMid { + /** + * An intermediate flow graph node. This is a tuple consisting of a node, + * a `FlowState`, a call context, a summary context, a tracked type, and an access path. + */ + private class StagePathNodeMid extends StagePathNodeImpl, TStagePathNodeMid { NodeEx node; FlowState state; Cc cc; From b8d0b691da807ead4a6bdfb4bbb092a1f0529a4d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 20 Aug 2024 14:25:24 +0200 Subject: [PATCH 054/404] Dataflow: Introduce sink projection and add successor as member predicate. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 143 +++++++++++++++--- 1 file changed, 122 insertions(+), 21 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 77eec1e907b..ed00319dc0d 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2533,6 +2533,13 @@ module MakeImpl Lang> { fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) and revFlow(node, state, _, _, ap) } or + TStagePathNodeSink(NodeEx node, FlowState state) { + exists(StagePathNodeMid sink | + sink.isAtSink() and + node = sink.getNodeEx() and + state = sink.getState() + ) + } or TStagePathNodeSrcGrp() or TStagePathNodeSinkGrp() @@ -2542,13 +2549,17 @@ module MakeImpl Lang> { /** Gets the `FlowState` of this node. */ abstract FlowState getState(); + /** Holds if this node is a source. */ + abstract predicate isSource(); + + /** Holds if this node is a sink. */ + predicate isSink() { this instanceof TStagePathNodeSink } + + abstract StagePathNodeImpl getASuccessorImpl(string label); + /** Gets a textual representation of this element. */ abstract string toString(); - predicate isSource() { none() } - - predicate isSink() { none() } - /** Gets the location of this node. */ Location getLocation() { result = this.getNodeEx().getLocation() } @@ -2565,6 +2576,12 @@ module MakeImpl Lang> { override NodeEx getNodeEx() { none() } override FlowState getState() { none() } + + override StagePathNodeImpl getASuccessorImpl(string label) { + result.isSource() and label = "" + } + + override predicate isSource() { none() } } private class StagePathNodeSinkGrp extends StagePathNodeImpl, TStagePathNodeSinkGrp { @@ -2575,6 +2592,10 @@ module MakeImpl Lang> { override NodeEx getNodeEx() { none() } override FlowState getState() { none() } + + override StagePathNodeImpl getASuccessorImpl(string label) { none() } + + override predicate isSource() { none() } } /** @@ -2599,6 +2620,48 @@ module MakeImpl Lang> { override FlowState getState() { result = state } + private StagePathNodeMid getSuccMid(string label) { + localStep(this, result, label) + or + nonLocalStep(this, result, label) + } + + private predicate isSourceWithLabel(string labelprefix) { + exists(string model | + this.isSource() and + sourceModel(node, model) and + model != "" and + labelprefix = "Src:" + model + " " + ) + } + + override StagePathNodeImpl getASuccessorImpl(string label) { + // an intermediate step to another intermediate node + exists(string l2 | result = this.getSuccMid(l2) | + not this.isSourceWithLabel(_) and label = l2 + or + exists(string l1 | + this.isSourceWithLabel(l1) and + label = l1 + l2 + ) + ) + or + // a final step to a sink + exists(string l2, string sinkmodel | + result = this.getSuccMid(l2).projectToSink(sinkmodel) + | + not this.isSourceWithLabel(_) and + if sinkmodel != "" then label = l2 + " Sink:" + sinkmodel else label = l2 + or + exists(string l1 | + this.isSourceWithLabel(l1) and + if sinkmodel != "" + then label = l1 + l2 + " Sink:" + sinkmodel + else label = l1 + l2 + ) + ) + } + private string ppType() { exists(string ppt | ppt = t.toString() | if ppt = "" then result = "" else result = " : " + ppt @@ -2642,7 +2705,7 @@ module MakeImpl Lang> { ap instanceof ApNil } - override predicate isSink() { + predicate isAtSink() { sinkNode(node, state) and ap instanceof ApNil and // For `FeatureHasSinkCallContext` the condition `cc instanceof CallContextNoCall` @@ -2662,6 +2725,37 @@ module MakeImpl Lang> { then instanceofCcNoCall(cc) else any() } + + StagePathNodeSink projectToSink(string model) { + this.isAtSink() and + sinkModel(node, model) and + result.getNodeEx() = node and + result.getState() = state + } + } + + /** + * A flow graph node corresponding to a sink. This is disjoint from the + * intermediate nodes in order to uniquely correspond to a given sink by + * excluding the call context. + */ + private class StagePathNodeSink extends StagePathNodeImpl, TStagePathNodeSink { + NodeEx node; + FlowState state; + + StagePathNodeSink() { this = TStagePathNodeSink(node, state) } + + override NodeEx getNodeEx() { result = node } + + override FlowState getState() { result = state } + + override string toString() { result = node.toString() } + + override StagePathNodeImpl getASuccessorImpl(string label) { + result.isArbitrarySink() and label = "" + } + + override predicate isSource() { sourceNode(node, state) } } pragma[nomagic] @@ -2795,7 +2889,7 @@ module MakeImpl Lang> { ) { pn1 = pn2 and summaryLabel = "" and - subpaths(_, pn1, _, _) + subpathsImpl(_, pn1, _, _) or exists(StagePathNodeImpl mid, string l1, string l2 | summaryLabel(pn1, mid, l1) and @@ -2806,7 +2900,7 @@ module MakeImpl Lang> { private predicate summaryStep(StagePathNodeImpl arg, StagePathNodeImpl out, string label) { exists(StagePathNodeImpl par, StagePathNodeImpl ret | - subpaths(arg, par, ret, out) and + subpathsImpl(arg, par, ret, out) and summaryLabel(par, ret, label) ) } @@ -2881,30 +2975,37 @@ module MakeImpl Lang> { ) } - query predicate subpaths( + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + * + * All of the nodes may be hidden. + */ + private predicate subpathsImpl( StagePathNodeImpl arg, StagePathNodeImpl par, StagePathNodeImpl ret, StagePathNodeImpl out ) { exists( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t0, Ap ap + ApOption argAp, Typ t0, Ap ap, StagePathNodeImpl out0 | fwdFlowThroughStep2(arg, par, ret, node, cc, state, summaryCtx, argT, argAp, t0, ap) and - out = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) + out0 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) + | + out = out0 or out = out0.(StagePathNodeMid).projectToSink(_) ) } - query predicate edges(StagePathNodeImpl pn1, StagePathNodeImpl pn2, string key, string val) { - key = "provenance" and - ( - localStep(pn1, pn2, val) - or - nonLocalStep(pn1, pn2, val) - or - pn1.isArbitrarySource() and pn2.isSource() and val = "" - or - pn1.isSink() and pn2.isArbitrarySink() and val = "" - ) + module StagePathGraph { + predicate edges(StagePathNodeImpl a, StagePathNodeImpl b, string key, string val) { + a.getASuccessorImpl(val) = b and + key = "provenance" + } + + query predicate nodes(StagePathNodeImpl n, string key, string val) { + key = "semmle.label" and val = n.toString() + } + + query predicate subpaths = subpathsImpl/4; } } From c2b25c7f2b984aa2145c2248caff24f58fdda94e Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 20 Aug 2024 15:08:47 +0200 Subject: [PATCH 055/404] Dataflow: Check clearsContent on store targets in StagePathGraph. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 55 +++++++++++++++---- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index ed00319dc0d..da1825f8879 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1406,6 +1406,9 @@ module MakeImpl Lang> { bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t); + bindingset[node, ap, isStoreStep] + predicate stepFilter(NodeEx node, Ap ap, boolean isStoreStep); + bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType); @@ -2842,11 +2845,12 @@ module MakeImpl Lang> { private predicate localStep( StagePathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, - TypOption argT, ApOption argAp, Typ t, Ap ap, string label + TypOption argT, ApOption argAp, Typ t, Ap ap, string label, boolean isStoreStep ) { exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | pn1 = TStagePathNodeMid(mid, state0, cc, summaryCtx, argT, argAp, t0, ap) and - localCc = getLocalCc(cc) + localCc = getLocalCc(cc) and + isStoreStep = false | localStep(mid, state0, node, state, true, _, localCc, label) and t = t0 @@ -2860,7 +2864,8 @@ module MakeImpl Lang> { pn1 = TStagePathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and fwdFlowStore(mid, t0, ap0, c, t, node, state, cc, summaryCtx, argT, argAp) and ap = apCons(c, t0, ap0) and - label = "" + label = "" and + isStoreStep = true ) or // read @@ -2868,17 +2873,19 @@ module MakeImpl Lang> { pn1 = TStagePathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and fwdFlowRead(t0, ap0, c, mid, node, state, cc, summaryCtx, argT, argAp) and fwdFlowConsCand(t0, ap0, c, t, ap) and - label = "" + label = "" and + isStoreStep = false ) } private predicate localStep(StagePathNodeImpl pn1, StagePathNodeImpl pn2, string label) { exists( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t0, Ap ap + ApOption argAp, Typ t0, Ap ap, boolean isStoreStep | - localStep(pn1, node, state, cc, summaryCtx, argT, argAp, t0, ap, label) and - pn2 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) + localStep(pn1, node, state, cc, summaryCtx, argT, argAp, t0, ap, label, isStoreStep) and + pn2 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and + stepFilter(node, ap, isStoreStep) ) or summaryStep(pn1, pn2, label) @@ -2971,7 +2978,8 @@ module MakeImpl Lang> { ApOption argAp, Typ t0, Ap ap | nonLocalStep(pn1, node, state, cc, summaryCtx, argT, argAp, t0, ap, label) and - pn2 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) + pn2 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and + stepFilter(node, ap, false) ) } @@ -2989,7 +2997,8 @@ module MakeImpl Lang> { ApOption argAp, Typ t0, Ap ap, StagePathNodeImpl out0 | fwdFlowThroughStep2(arg, par, ret, node, cc, state, summaryCtx, argT, argAp, t0, ap) and - out0 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) + out0 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and + stepFilter(node, ap, false) | out = out0 or out = out0.(StagePathNodeMid).projectToSink(_) ) @@ -3181,6 +3190,9 @@ module MakeImpl Lang> { ) } + bindingset[node, ap, isStoreStep] + predicate stepFilter(NodeEx node, Ap ap, boolean isStoreStep) { any() } + bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType) { any() } @@ -3459,6 +3471,9 @@ module MakeImpl Lang> { ) } + bindingset[node, ap, isStoreStep] + predicate stepFilter(NodeEx node, Ap ap, boolean isStoreStep) { any() } + bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType) { any() } } @@ -3543,10 +3558,15 @@ module MakeImpl Lang> { private predicate clear(NodeEx node, Ap ap) { // When `node` is the target of a store, we interpret `clearsContent` as // only pertaining to _earlier_ store steps. In this case, we need to postpone - // checking `clearsContent` to the `pathStep` predicate + // checking `clearsContent` to the step creation. clearContent(node, ap.getHead(), false) } + pragma[nomagic] + private predicate clearExceptStore(NodeEx node, Ap ap) { + clearContent(node, ap.getHead(), true) + } + pragma[nomagic] private predicate expectsContentCand(NodeEx node, Ap ap) { exists(Content c | @@ -3569,6 +3589,11 @@ module MakeImpl Lang> { ) } + bindingset[node, ap, isStoreStep] + predicate stepFilter(NodeEx node, Ap ap, boolean isStoreStep) { + if clearExceptStore(node, ap) then isStoreStep = true else any() + } + bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType) { // We need to typecheck stores here, since reverse flow through a getter @@ -3829,6 +3854,16 @@ module MakeImpl Lang> { exists(ap) } + pragma[nomagic] + private predicate clearExceptStore(NodeEx node, Ap ap) { + Stage4Param::clearContent(node, ap.getHead(), true) + } + + bindingset[node, ap, isStoreStep] + predicate stepFilter(NodeEx node, Ap ap, boolean isStoreStep) { + if clearExceptStore(node, ap) then isStoreStep = true else any() + } + bindingset[typ, contentType] predicate typecheckStore(Typ typ, DataFlowType contentType) { compatibleTypesFilter(typ, contentType) From e594e7283d90d77e6d7fe1b7e03b5b29883f036c Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 21 Aug 2024 10:18:01 +0200 Subject: [PATCH 056/404] Dataflow: Check stateful in/out-barriers in each stage. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index da1825f8879..6054dc4e27c 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1578,6 +1578,7 @@ module MakeImpl Lang> { fwdFlowThrough(call, cc, state, ccc, summaryCtx, argT, argAp, t, ap, apa, ret, innerArgApa) and flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa) and + not inBarrier(node, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -1610,6 +1611,8 @@ module MakeImpl Lang> { ) { exists(DataFlowType contentType, DataFlowType containerType, ApApprox apa1 | fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t1, ap1, apa1) and + not outBarrier(node1, state) and + not inBarrier(node2, state) and PrevStage::storeStepCand(node1, apa1, c, node2, contentType, containerType) and t2 = getTyp(containerType) and typecheckStore(t1, contentType) @@ -1651,6 +1654,8 @@ module MakeImpl Lang> { ) { exists(ApHeadContent apc | fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and + not outBarrier(node1, state) and + not inBarrier(node2, state) and apc = getHeadContent(ap) and readStepCand0(node1, apc, c, node2) ) @@ -1761,6 +1766,8 @@ module MakeImpl Lang> { or viableImplArgNotCallContextReduced(call, arg, outercc) ) and + not outBarrier(arg, state) and + not inBarrier(p, state) and callEdgeArgParamRestrictedInlineLate(call, inner, arg, p, allowsFieldFlow, apa) and (if allowsFieldFlow = false then emptyAp = true else any()) and if allowsFieldFlowThrough(call, inner) @@ -1888,6 +1895,7 @@ module MakeImpl Lang> { ApOption argAp, Typ t, Ap ap, ApApprox apa ) { instanceofCcNoCall(cc) and + not outBarrier(ret, state) and fwdFlow(ret, state, cc, summaryCtx, argT, argAp, t, ap, apa) } @@ -1925,6 +1933,7 @@ module MakeImpl Lang> { exists(RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow | fwdFlowIntoRet(ret, state, innercc, summaryCtx, argT, argAp, t, ap, apa) and fwdFlowOutValidEdge(call, ret, innercc, inner, out, outercc, apa, allowsFieldFlow) and + not inBarrier(out, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -2018,6 +2027,7 @@ module MakeImpl Lang> { fwdFlow(pragma[only_bind_into](ret), state, ccc, TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), TypOption::some(argT), pragma[only_bind_into](apSome(argAp)), t, ap, pragma[only_bind_into](apa)) and + not outBarrier(ret, state) and kind = ret.getKind() and parameterFlowThroughAllowed(summaryCtx, kind) and argApa = getApprox(argAp) and @@ -2839,6 +2849,7 @@ module MakeImpl Lang> { fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, ccc, summaryCtx, argT, argAp, t, ap, apa, ret, innerArgApa) and flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa) and + not inBarrier(node, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -2926,11 +2937,15 @@ module MakeImpl Lang> { | jumpStepEx(mid, node) and state = state0 and + not outBarrier(mid, state) and + not inBarrier(node, state) and t = t0 and label = "" or additionalJumpStep(mid, node, label) and state = state0 and + not outBarrier(mid, state) and + not inBarrier(node, state) and t = getNodeTyp(node) and ap instanceof ApNil or @@ -2967,6 +2982,7 @@ module MakeImpl Lang> { pn1 = TStagePathNodeMid(ret, state, innercc, summaryCtx, argT, argAp, t, ap) and fwdFlowIntoRet(ret, state, innercc, summaryCtx, argT, argAp, t, ap, apa) and fwdFlowOutValidEdge(_, ret, innercc, _, node, cc, apa, allowsFieldFlow) and + not inBarrier(node, state) and label = "" and if allowsFieldFlow = false then ap instanceof ApNil else any() ) From 831a66d812b4a4782c4247d1017e4e22cadd095f Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 21 Aug 2024 10:21:32 +0200 Subject: [PATCH 057/404] Dataflow: Add getANonHiddenSuccessor to StagePathNodeImpl. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 6054dc4e27c..be41f435225 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2570,6 +2570,38 @@ module MakeImpl Lang> { abstract StagePathNodeImpl getASuccessorImpl(string label); + private StagePathNodeImpl getASuccessorIfHidden(string label) { + this.isHidden() and + result = this.getASuccessorImpl(label) + } + + private StagePathNodeImpl getASuccessorFromNonHidden(string label) { + result = this.getASuccessorImpl(label) and + not this.isHidden() + or + exists(string l1, string l2 | + result = this.getASuccessorFromNonHidden(l1).getASuccessorIfHidden(l2) and + label = mergeLabels(l1, l2) + ) + } + + final StagePathNodeImpl getANonHiddenSuccessor(string label) { + result = this.getASuccessorFromNonHidden(label) and not result.isHidden() + } + + predicate isHidden() { + not Config::includeHiddenNodes() and + ( + hiddenNode(this.getNodeEx().asNode()) and + not this.isSource() and + not this instanceof StagePathNodeSink + or + this.getNodeEx() instanceof TNodeImplicitRead + or + hiddenNode(this.getNodeEx().asParamReturnNode()) + ) + } + /** Gets a textual representation of this element. */ abstract string toString(); From 74739bedfc3414cda2ee13c9c282bc6f077c449f Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 21 Aug 2024 10:27:51 +0200 Subject: [PATCH 058/404] Dataflow: Add Stage 6 instantiation. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index be41f435225..3992ce11697 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -4108,6 +4108,86 @@ module MakeImpl Lang> { ) } + private module Stage6Param implements MkStage::StageParam { + private module PrevStage = Stage5; + + class Typ = DataFlowType; + + class Ap = AccessPath; + + class ApNil = AccessPathNil; + + pragma[nomagic] + PrevStage::Ap getApprox(Ap ap) { result = ap.getApprox() } + + Typ getTyp(DataFlowType t) { result = t } + + bindingset[c, t, tail] + Ap apCons(Content c, Typ t, Ap tail) { result.isCons(c, t, tail) } + + class ApHeadContent = Content; + + pragma[noinline] + ApHeadContent getHeadContent(Ap ap) { result = ap.getHead() } + + ApHeadContent projectToHeadContent(Content c) { result = c } + + private module ApOption = Option; + + class ApOption = ApOption::Option; + + ApOption apNone() { result.isNone() } + + ApOption apSome(Ap ap) { result = ApOption::some(ap) } + + private module CallContextSensitivityInput implements CallContextSensitivityInputSig { + predicate relevantCallEdgeIn = PrevStage::relevantCallEdgeIn/2; + + predicate relevantCallEdgeOut = PrevStage::relevantCallEdgeOut/2; + + predicate reducedViableImplInCallContextCand = + Stage5Param::reducedViableImplInCallContext/3; + + predicate reducedViableImplInReturnCand = Stage5Param::reducedViableImplInReturn/2; + } + + import CallContextSensitivity + import LocalCallContext + + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + Typ t, LocalCc lcc, string label + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc, label) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and + PrevStage::revFlow(node2, pragma[only_bind_into](state2), _) + } + + bindingset[node, state, t0, ap] + predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { + strengthenType(node, t0, t) and + exists(state) and + exists(ap) + } + + pragma[nomagic] + private predicate clearExceptStore(NodeEx node, Ap ap) { + Stage4Param::clearContent(node, ap.getHead(), true) + } + + bindingset[node, ap, isStoreStep] + predicate stepFilter(NodeEx node, Ap ap, boolean isStoreStep) { + if clearExceptStore(node, ap) then isStoreStep = true else any() + } + + bindingset[typ, contentType] + predicate typecheckStore(Typ typ, DataFlowType contentType) { + compatibleTypesFilter(typ, contentType) + } + } + + module Stage6 = MkStage::Stage; + private module PrunedCallContextSensitivityStage5 { private module CallContextSensitivityInput implements CallContextSensitivityInputSig { predicate relevantCallEdgeIn = Stage5::relevantCallEdgeIn/2; From 1787bcb05a7ed8cb840a70c6dc0b5a81f9e151ae Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 21 Aug 2024 10:38:36 +0200 Subject: [PATCH 059/404] Dataflow: Replace PathNode with Stage implementation. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 1143 ++++------------- 1 file changed, 246 insertions(+), 897 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 3992ce11697..70c0b9ec6bf 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -3064,6 +3064,241 @@ module MakeImpl Lang> { query predicate subpaths = subpathsImpl/4; } + + module Public { + private StagePathNodeImpl localStep(StagePathNodeImpl n) { localStep(n, result, _) } + + private predicate localStepToHidden(StagePathNodeImpl n1, StagePathNodeImpl n2) { + n2 = localStep(n1) and + n2.isHidden() + } + + private predicate localStepFromHidden(StagePathNodeImpl n1, StagePathNodeImpl n2) { + n2 = localStep(n1) and + n1.isHidden() + } + + bindingset[par, ret] + pragma[inline_late] + private predicate localStepStar(StagePathNodeImpl par, StagePathNodeImpl ret) { + localStep*(par) = ret + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple. + * + * `par` and `ret` are not hidden. + */ + pragma[nomagic] + private predicate subpaths1( + StagePathNodeImpl arg, StagePathNodeImpl par, StagePathNodeImpl ret, + StagePathNodeImpl out + ) { + // direct subpath + subpathsImpl(arg, any(StagePathNodeImpl n | localStepFromHidden*(n, par)), + any(StagePathNodeImpl n | localStepToHidden*(ret, n)), out) and + not par.isHidden() and + not ret.isHidden() and + localStepStar(par, ret) + or + // wrapped subpath using hidden nodes, e.g. flow through a callback inside + // a summarized callable + exists(StagePathNodeImpl par0, StagePathNodeImpl ret0 | + subpaths1(any(StagePathNodeImpl n | localStepToHidden*(par0, n)), par, ret, + any(StagePathNodeImpl n | localStepFromHidden*(n, ret0))) and + subpathsImpl(arg, par0, ret0, out) + ) + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + * + * None of the nodes are hidden. + */ + pragma[nomagic] + private predicate subpaths2( + StagePathNodeImpl arg, StagePathNodeImpl par, StagePathNodeImpl ret, + StagePathNodeImpl out + ) { + exists(StagePathNodeImpl out0 | + subpaths1(any(StagePathNodeImpl n | localStepToHidden*(arg, n)), par, ret, + any(StagePathNodeImpl n | localStepFromHidden*(n, out0))) and + not arg.isHidden() and + not out0.isHidden() + | + out = out0 or out = out0.(StagePathNodeMid).projectToSink(_) + ) + } + + /** Holds if `n` is reachable from a source. */ + private predicate fwdReach(StagePathNodeImpl n) { + n.isArbitrarySource() + or + exists(StagePathNodeImpl mid | fwdReach(mid) and mid.getANonHiddenSuccessor(_) = n) + } + + /** Holds if `n` is reachable from a source and can reach a sink. */ + private predicate directReach(StagePathNodeImpl n) { + fwdReach(n) and + ( + n.isArbitrarySink() or + directReach(n.getANonHiddenSuccessor(_)) + ) + } + + /** + * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. + */ + private predicate retReach(StagePathNodeImpl n) { + fwdReach(n) and + ( + exists(StagePathNodeImpl out | subpaths2(_, _, n, out) | + directReach(out) or retReach(out) + ) + or + exists(StagePathNodeImpl mid | + retReach(mid) and + n.getANonHiddenSuccessor(_) = mid and + not subpaths2(_, mid, _, _) + ) + ) + } + + /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ + private predicate reach(StagePathNodeImpl n) { directReach(n) or retReach(n) } + + /** + * A `Node` augmented with a call context (except for sinks) and an access path. + * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. + */ + class PathNode instanceof StagePathNodeImpl { + PathNode() { + reach(this) and + not this instanceof StagePathNodeSrcGrp and + not this instanceof StagePathNodeSinkGrp + } + + /** Gets a textual representation of this element. */ + final string toString() { result = super.toString() } + + /** + * Gets a textual representation of this element, including a textual + * representation of the call context. + */ + final string toStringWithContext() { + result = this.(StagePathNodeMid).toStringWithContext() + or + not this instanceof StagePathNodeMid and result = this.toString() + } + + /** Gets the location of this node. */ + Location getLocation() { result = super.getLocation() } + + /** Gets the underlying `Node`. */ + final Node getNode() { super.getNodeEx().projectToNode() = result } + + /** Gets the parameter node through which data is returned, if any. */ + final ParameterNode asParameterReturnNode() { + result = super.getNodeEx().asParamReturnNode() + } + + /** Gets the `FlowState` of this node. */ + final FlowState getState() { result = super.getState() } + + /** Gets a successor of this node, if any. */ + final PathNode getASuccessor() { result = super.getANonHiddenSuccessor(_) } + + /** Holds if this node is a source. */ + final predicate isSource() { super.isSource() } + + /** Holds if this node is a sink. */ + final predicate isSink() { this instanceof StagePathNodeSink } + + /** + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + pragma[inline] + deprecated final predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { + this.getLocation() + .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) + } + + /** + * DEPRECATED: This functionality is no longer available. + * + * Holds if this node is a grouping of source nodes. + */ + deprecated final predicate isSourceGroup(string group) { none() } + + /** + * DEPRECATED: This functionality is no longer available. + * + * Holds if this node is a grouping of sink nodes. + */ + deprecated final predicate isSinkGroup(string group) { none() } + } + + /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ + private predicate pathSucc(StagePathNodeImpl n1, StagePathNodeImpl n2) { + n1.getANonHiddenSuccessor(_) = n2 and directReach(n2) + } + + private predicate tcSrc(StagePathNodeImpl n) { n.isSource() } + + private predicate tcSink(StagePathNodeImpl n) { n.isSink() } + + private predicate pathSuccPlus(StagePathNodeImpl n1, StagePathNodeImpl n2) = + doublyBoundedFastTC(pathSucc/2, tcSrc/1, tcSink/1)(n1, n2) + + /** + * Holds if data can flow from `source` to `sink`. + * + * The corresponding paths are generated from the end-points and the graph + * included in the module `PathGraph`. + */ + predicate flowPath(PathNode source, PathNode sink) { + exists(StagePathNodeImpl flowsource, StagePathNodeImpl flowsink | + source = flowsource and sink = flowsink + | + flowsource.isSource() and + (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and + flowsink.isSink() + ) + } + + /** + * Provides the query predicates needed to include a graph in a path-problem query. + */ + module PathGraph implements PathGraphSig { + /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ + query predicate edges(PathNode a, PathNode b, string key, string val) { + a.(StagePathNodeImpl).getANonHiddenSuccessor(val) = b and + key = "provenance" + } + + /** Holds if `n` is a node in the graph of data flow path explanations. */ + query predicate nodes(PathNode n, string key, string val) { + key = "semmle.label" and val = n.toString() + } + + /** + * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through + * a subpath between `par` and `ret` with the connecting edges `arg -> par` and + * `ret -> out` is summarized as the edge `arg -> out`. + */ + query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { + subpaths2(arg, par, ret, out) + } + } + } } additional predicate stats( @@ -4188,61 +4423,6 @@ module MakeImpl Lang> { module Stage6 = MkStage::Stage; - private module PrunedCallContextSensitivityStage5 { - private module CallContextSensitivityInput implements CallContextSensitivityInputSig { - predicate relevantCallEdgeIn = Stage5::relevantCallEdgeIn/2; - - predicate relevantCallEdgeOut = Stage5::relevantCallEdgeOut/2; - - predicate reducedViableImplInCallContextCand = - Stage5Param::reducedViableImplInCallContext/3; - - predicate reducedViableImplInReturnCand = Stage5Param::reducedViableImplInReturn/2; - } - - import CallContextSensitivity - import LocalCallContext - } - - private class CallContext = PrunedCallContextSensitivityStage5::Cc; - - private class CallContextCall = PrunedCallContextSensitivityStage5::CcCall; - - private class CallContextNoCall = PrunedCallContextSensitivityStage5::CcNoCall; - - private predicate callContextNone = PrunedCallContextSensitivityStage5::ccNone/0; - - private predicate callContextSomeCall = PrunedCallContextSensitivityStage5::ccSomeCall/0; - - private predicate sourceCallCtx(CallContext cc) { - if hasSourceCallCtx() then cc = callContextSomeCall() else cc = callContextNone() - } - - private newtype TPathNode = - TPathNodeMid( - NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap, - string summaryLabel - ) { - // A PathNode is introduced by a source ... - Stage5::revFlow(node, state) and - sourceNode(node, state) and - sourceCallCtx(cc) and - sc instanceof SummaryCtxNone and - t = node.getDataFlowType() and - ap = TAccessPathNil() and - summaryLabel = "-" - or - // ... or a step from an existing PathNode to another node. - pathStep(_, node, state, cc, sc, t, ap, summaryLabel, _) - } or - TPathNodeSink(NodeEx node, FlowState state) { - exists(PathNodeMid sink | - sink.isAtSink(_) and - node = sink.getNodeEx() and - state = sink.getState() - ) - } - /** * A list of `Content`s where nested tails are also paired with a * `DataFlowType`. If data flows from a source to a given node with a given @@ -4411,830 +4591,23 @@ module MakeImpl Lang> { } } - abstract private class PathNodeImpl extends TPathNode { - /** Gets the `FlowState` of this node. */ - abstract FlowState getState(); + private module S6Graph = Stage6::Graph; - /** Holds if this node is a source. */ - abstract predicate isSource(string model); + private module S6 = S6Graph::Public; - abstract PathNodeImpl getASuccessorImpl(string label); - - private PathNodeImpl getASuccessorIfHidden(string label) { - this.isHidden() and - result = this.getASuccessorImpl(label) - } - - private PathNodeImpl getASuccessorFromNonHidden(string label) { - result = this.getASuccessorImpl(label) and - not this.isHidden() - or - exists(string l1, string l2 | - result = this.getASuccessorFromNonHidden(l1).getASuccessorIfHidden(l2) and - label = mergeLabels(l1, l2) - ) - } - - final PathNodeImpl getANonHiddenSuccessor(string label) { - result = this.getASuccessorFromNonHidden(label) and not result.isHidden() - } - - abstract NodeEx getNodeEx(); - - predicate isHidden() { - not Config::includeHiddenNodes() and - ( - hiddenNode(this.getNodeEx().asNode()) and - not this.isSource(_) and - not this instanceof PathNodeSink - or - this.getNodeEx() instanceof TNodeImplicitRead - or - hiddenNode(this.getNodeEx().asParamReturnNode()) - ) - } - - predicate isFlowSource() { this.isSource(_) } - - predicate isFlowSink() { this instanceof PathNodeSink } - - private string ppType() { - this instanceof PathNodeSink and result = "" - or - exists(string t | t = this.(PathNodeMid).getType().toString() | - if t = "" then result = "" else result = " : " + t - ) - } - - private string ppAp() { - this instanceof PathNodeSink and result = "" - or - exists(string s | s = this.(PathNodeMid).getAp().toString() | - if s = "" then result = "" else result = " " + s - ) - } - - private string ppCtx() { - this instanceof PathNodeSink and result = "" - or - result = " <" + this.(PathNodeMid).getCallContext().toString() + ">" - } - - private string ppSummaryCtx() { - this instanceof PathNodeSink and result = "" - or - result = " <" + this.(PathNodeMid).getSummaryCtx().toString() + ">" - } - - /** Gets a textual representation of this element. */ - string toString() { result = this.getNodeEx().toString() + this.ppType() + this.ppAp() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - string toStringWithContext() { - result = - this.getNodeEx().toString() + this.ppType() + this.ppAp() + this.ppCtx() + - this.ppSummaryCtx() - } - - /** Gets the location of this node. */ - Location getLocation() { result = this.getNodeEx().getLocation() } - } - - /** Holds if `n` can reach a sink. */ - private predicate directReach(PathNodeImpl n) { - n instanceof PathNodeSink or - directReach(n.getANonHiddenSuccessor(_)) - } - - /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ - private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) } - - /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ - private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) { - n1.getANonHiddenSuccessor(_) = n2 and directReach(n2) - } - - private predicate tcSrc(PathNodeImpl n) { n.isFlowSource() or n.isSource(_) } - - private predicate tcSink(PathNodeImpl n) { n.isFlowSink() or n instanceof PathNodeSink } - - private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = - doublyBoundedFastTC(pathSucc/2, tcSrc/1, tcSink/1)(n1, n2) - - /** - * A `Node` augmented with a call context (except for sinks) and an access path. - * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. - */ - class PathNode instanceof PathNodeImpl { - PathNode() { reach(this) } - - /** Gets a textual representation of this element. */ - final string toString() { result = super.toString() } - - /** - * Gets a textual representation of this element, including a textual - * representation of the call context. - */ - final string toStringWithContext() { result = super.toStringWithContext() } - - /** Gets the location of this node. */ - Location getLocation() { result = super.getLocation() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - pragma[inline] - deprecated final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** Gets the underlying `Node`. */ - final Node getNode() { super.getNodeEx().projectToNode() = result } - - /** Gets the parameter node through which data is returned, if any. */ - final ParameterNode asParameterReturnNode() { result = super.getNodeEx().asParamReturnNode() } - - /** Gets the `FlowState` of this node. */ - final FlowState getState() { result = super.getState() } - - /** Gets a successor of this node, if any. */ - final PathNode getASuccessor() { result = super.getANonHiddenSuccessor(_) } - - /** Holds if this node is a source. */ - final predicate isSource() { super.isSource(_) } - - /** - * DEPRECATED: This functionality is no longer available. - * - * Holds if this node is a grouping of source nodes. - */ - deprecated final predicate isSourceGroup(string group) { none() } - - /** - * DEPRECATED: This functionality is no longer available. - * - * Holds if this node is a grouping of sink nodes. - */ - deprecated final predicate isSinkGroup(string group) { none() } - } - - /** - * Provides the query predicates needed to include a graph in a path-problem query. - */ - module PathGraph implements PathGraphSig { - /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b, string key, string val) { - a.(PathNodeImpl).getANonHiddenSuccessor(val) = b and - key = "provenance" - } - - /** Holds if `n` is a node in the graph of data flow path explanations. */ - query predicate nodes(PathNode n, string key, string val) { - key = "semmle.label" and val = n.toString() - } - - /** - * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through - * a subpath between `par` and `ret` with the connecting edges `arg -> par` and - * `ret -> out` is summarized as the edge `arg -> out`. - */ - query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) { - Subpaths::subpaths(arg, par, ret, out) - } - } - - /** - * An intermediate flow graph node. This is a tuple consisting of a `Node`, - * a `FlowState`, a `CallContext`, a `SummaryCtx`, and an `AccessPath`. - */ - private class PathNodeMid extends PathNodeImpl, TPathNodeMid { - NodeEx node; - FlowState state; - CallContext cc; - SummaryCtx sc; - DataFlowType t; - AccessPath ap; - string summaryLabel; - - PathNodeMid() { this = TPathNodeMid(node, state, cc, sc, t, ap, summaryLabel) } - - override NodeEx getNodeEx() { result = node } - - pragma[inline] - final NodeEx getNodeExOutgoing() { result = node and not outBarrier(node, state) } - - override FlowState getState() { result = state } - - CallContext getCallContext() { result = cc } - - SummaryCtx getSummaryCtx() { result = sc } - - DataFlowType getType() { result = t } - - AccessPath getAp() { result = ap } - - string getSummaryLabel() { result = summaryLabel } - - private PathNodeMid getSuccMid(string label) { - pathStep(this, result.getNodeEx(), result.getState(), result.getCallContext(), - result.getSummaryCtx(), result.getType(), result.getAp(), result.getSummaryLabel(), label) - } - - private predicate isSourceWithLabel(string labelprefix) { - exists(string model | - this.isSource(model) and - model != "" and - labelprefix = "Src:" + model + " " - ) - } - - override PathNodeImpl getASuccessorImpl(string label) { - // an intermediate step to another intermediate node - exists(string l2 | result = this.getSuccMid(l2) | - not this.isSourceWithLabel(_) and label = l2 - or - exists(string l1 | - this.isSourceWithLabel(l1) and - label = l1 + l2 - ) - ) - or - // a final step to a sink - exists(string l2, string sinkmodel | result = this.getSuccMid(l2).projectToSink(sinkmodel) | - not this.isSourceWithLabel(_) and - if sinkmodel != "" then label = l2 + " Sink:" + sinkmodel else label = l2 - or - exists(string l1 | - this.isSourceWithLabel(l1) and - if sinkmodel != "" then label = l1 + l2 + " Sink:" + sinkmodel else label = l1 + l2 - ) - ) - } - - override predicate isSource(string model) { - sourceNode(node, state) and - sourceModel(node, model) and - sourceCallCtx(cc) and - sc instanceof SummaryCtxNone and - t = node.getDataFlowType() and - ap = TAccessPathNil() - } - - predicate isAtSink(string model) { - sinkNode(node, state) and - sinkModel(node, model) and - ap instanceof AccessPathNil and - // For `FeatureHasSinkCallContext` the condition `cc instanceof CallContextNoCall` - // is exactly what we need to check. - // For `FeatureEqualSourceSinkCallContext` the initial call context was - // set to `CallContextSomeCall` and jumps are disallowed, so - // `cc instanceof CallContextNoCall` never holds. On the other hand, - // in this case there's never any need to enter a call except to identify - // a summary, so the condition in `pathIntoCallable` enforces this, which - // means that `sc instanceof SummaryCtxNone` holds if and only if we are - // in the call context of the source. - if Config::getAFeature() instanceof FeatureEqualSourceSinkCallContext - then sc instanceof SummaryCtxNone - else - if Config::getAFeature() instanceof FeatureHasSinkCallContext - then cc instanceof CallContextNoCall - else any() - } - - PathNodeSink projectToSink(string model) { - this.isAtSink(model) and - result.getNodeEx() = node and - result.getState() = state - } - } - - /** - * A flow graph node corresponding to a sink. This is disjoint from the - * intermediate nodes in order to uniquely correspond to a given sink by - * excluding the `CallContext`. - */ - private class PathNodeSink extends PathNodeImpl, TPathNodeSink { - NodeEx node; - FlowState state; - - PathNodeSink() { this = TPathNodeSink(node, state) } - - override NodeEx getNodeEx() { result = node } - - override FlowState getState() { result = state } - - override PathNodeImpl getASuccessorImpl(string label) { none() } - - override predicate isSource(string model) { - sourceNode(node, state) and sourceModel(node, model) - } - } - - private predicate pathNode( - PathNodeMid mid, NodeEx midnode, FlowState state, CallContext cc, SummaryCtx sc, - DataFlowType t, AccessPath ap, string summaryLabel, LocalCallContext localCC - ) { - midnode = mid.getNodeEx() and - state = mid.getState() and - cc = mid.getCallContext() and - sc = mid.getSummaryCtx() and - localCC = PrunedCallContextSensitivityStage5::getLocalCc(cc) and - t = mid.getType() and - ap = mid.getAp() and - summaryLabel = mid.getSummaryLabel() - } - - private predicate pathStep( - PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, - AccessPath ap, string summaryLabel, string label - ) { - exists(DataFlowType t0, boolean isStoreStep | - pathStep0(mid, pragma[only_bind_into](node), pragma[only_bind_into](state), cc, sc, t0, ap, - isStoreStep, summaryLabel, label) and - Stage5::revFlow(pragma[only_bind_into](node), pragma[only_bind_into](state), ap.getApprox()) and - strengthenType(node, t0, t) and - not inBarrier(node, state) and - if ap.storeTargetIsClearedAt(node) then isStoreStep = true else any() - ) - } - - /** - * Holds if data may flow from `mid` to `node`. The last step in or out of - * a callable is recorded by `cc`. - */ - pragma[nomagic] - private predicate pathStep0( - PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, - AccessPath ap, boolean isStoreStep, string summaryLabel, string label - ) { - exists(NodeEx midnode, FlowState state0, string sl, LocalCallContext localCC | - pathNode(mid, midnode, state0, cc, sc, t, ap, sl, localCC) and - localFlowBigStep(midnode, state0, node, state, true, _, localCC, label) and - isStoreStep = false and - summaryLabel = mergeLabels(sl, label) - ) - or - exists(NodeEx midnode, FlowState state0, string sl, LocalCallContext localCC | - pathNode(mid, midnode, state0, cc, sc, _, ap, sl, localCC) and - localFlowBigStep(midnode, state0, node, state, false, t, localCC, label) and - ap instanceof AccessPathNil and - isStoreStep = false and - summaryLabel = mergeLabels(sl, label) - ) - or - jumpStepEx(mid.getNodeExOutgoing(), node) and - state = mid.getState() and - cc = callContextNone() and - sc instanceof SummaryCtxNone and - t = mid.getType() and - ap = mid.getAp() and - isStoreStep = false and - summaryLabel = "-" and - label = "" - or - additionalJumpStep(mid.getNodeExOutgoing(), node, label) and - state = mid.getState() and - cc = callContextNone() and - sc instanceof SummaryCtxNone and - mid.getAp() instanceof AccessPathNil and - t = node.getDataFlowType() and - ap = TAccessPathNil() and - isStoreStep = false and - summaryLabel = "-" - or - additionalJumpStateStep(mid.getNodeExOutgoing(), mid.getState(), node, state) and - cc = callContextNone() and - sc instanceof SummaryCtxNone and - mid.getAp() instanceof AccessPathNil and - t = node.getDataFlowType() and - ap = TAccessPathNil() and - isStoreStep = false and - summaryLabel = "-" and - label = "Config" - or - exists(Content c, DataFlowType t0, AccessPath ap0 | - pathStoreStep(mid, node, state, t0, ap0, c, t, cc) and - ap.isCons(c, t0, ap0) and - sc = mid.getSummaryCtx() and - isStoreStep = true and - summaryLabel = mid.getSummaryLabel() and - label = "" - ) - or - exists(Content c, AccessPath ap0 | - pathReadStep(mid, node, state, ap0, c, cc) and - ap0.isCons(c, t, ap) and - sc = mid.getSummaryCtx() and - isStoreStep = false and - summaryLabel = mid.getSummaryLabel() and - label = "" - ) - or - pathIntoCallable(mid, node, state, _, cc, sc, _) and - t = mid.getType() and - ap = mid.getAp() and - isStoreStep = false and - (if sc instanceof SummaryCtxNone then summaryLabel = "-" else summaryLabel = "") and - label = "" - or - pathOutOfCallable(mid, node, state, cc) and - t = mid.getType() and - ap = mid.getAp() and - sc instanceof SummaryCtxNone and - isStoreStep = false and - summaryLabel = "-" and - label = "" - or - pathThroughCallable(mid, node, state, cc, t, ap, label) and - sc = mid.getSummaryCtx() and - isStoreStep = false and - summaryLabel = mergeLabels(mid.getSummaryLabel(), label) - } - - pragma[nomagic] - private predicate pathReadStep( - PathNodeMid mid, NodeEx node, FlowState state, AccessPath ap0, Content c, CallContext cc - ) { - ap0 = mid.getAp() and - c = ap0.getHead() and - Stage5::readStepCand(mid.getNodeExOutgoing(), c, node) and - state = mid.getState() and - cc = mid.getCallContext() - } - - pragma[nomagic] - private predicate pathStoreStep( - PathNodeMid mid, NodeEx node, FlowState state, DataFlowType t0, AccessPath ap0, Content c, - DataFlowType t, CallContext cc - ) { - exists(DataFlowType contentType | - t0 = mid.getType() and - ap0 = mid.getAp() and - Stage5::storeStepCand(mid.getNodeExOutgoing(), _, c, node, contentType, t) and - state = mid.getState() and - cc = mid.getCallContext() and - compatibleTypesFilter(t0, contentType) - ) - } - - private predicate pathOutOfCallable0( - PathNodeMid mid, ReturnPosition pos, FlowState state, CallContext innercc, - AccessPathApprox apa - ) { - exists(RetNodeEx retNode | - retNode = mid.getNodeEx() and - pos = retNode.getReturnPosition() and - state = mid.getState() and - not outBarrier(retNode, state) and - innercc = mid.getCallContext() and - innercc instanceof CallContextNoCall and - apa = mid.getAp().getApprox() and - not outBarrier(retNode, state) - ) - } - - pragma[nomagic] - private predicate pathOutOfCallable1( - PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, - AccessPathApprox apa - ) { - exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | - pathOutOfCallable0(mid, pos, state, innercc, apa) and - c = pos.getCallable() and - kind = pos.getKind() and - PrunedCallContextSensitivityStage5::resolveReturn(innercc, c, call) and - cc = PrunedCallContextSensitivityStage5::getCallContextReturn(c, call) - ) - } - - pragma[noinline] - private NodeEx getAnOutNodeFlow(ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa) { - result.asNode() = kind.getAnOutNode(call) and - Stage5::revFlow(result, _, apa) - } - - /** - * Holds if data may flow from `mid` to `out`. The last step of this path - * is a return from a callable and is recorded by `cc`, if needed. - */ - pragma[noinline] - private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, FlowState state, CallContext cc) { - exists(ReturnKindExt kind, DataFlowCall call, AccessPathApprox apa | - pathOutOfCallable1(mid, call, kind, state, cc, apa) and - out = getAnOutNodeFlow(kind, call, apa) and - not inBarrier(out, state) - ) - } - - /** - * Holds if data may flow from `mid` to the `i`th argument of `call` in `cc`. - */ - pragma[noinline] - private predicate pathIntoArg( - PathNodeMid mid, ParameterPosition ppos, FlowState state, CallContext cc, DataFlowCall call, - DataFlowType t, AccessPath ap, AccessPathApprox apa - ) { - exists(ArgNodeEx arg, ArgumentPosition apos | - pathNode(mid, arg, state, cc, _, t, ap, _, _) and - not outBarrier(arg, state) and - arg.asNode().(ArgNode).argumentOf(call, apos) and - apa = ap.getApprox() and - parameterMatch(ppos, apos) - ) - } - - pragma[nomagic] - private predicate parameterCand( - DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa - ) { - exists(ParamNodeEx p | - Stage5::revFlow(p, _, apa) and - p.isParameterOf(callable, pos) - ) - } - - pragma[nomagic] - private predicate pathIntoCallable0( - PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, - CallContext outercc, DataFlowCall call, DataFlowType t, AccessPath ap - ) { - exists(AccessPathApprox apa | - pathIntoArg(mid, pragma[only_bind_into](pos), state, outercc, call, t, ap, - pragma[only_bind_into](apa)) and - callable = PrunedCallContextSensitivityStage5::resolveCall(call, outercc) and - parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa)) - ) - } - - /** - * Holds if data may flow from `mid` to `p` through `call`. The contexts - * before and after entering the callable are `outercc` and `innercc`, - * respectively. - */ - pragma[nomagic] - private predicate pathIntoCallable( - PathNodeMid mid, ParamNodeEx p, FlowState state, CallContext outercc, CallContextCall innercc, - SummaryCtx sc, DataFlowCall call - ) { - exists(ParameterPosition pos, DataFlowCallable callable, DataFlowType t, AccessPath ap | - pathIntoCallable0(mid, callable, pos, state, outercc, call, t, ap) and - p.isParameterOf(callable, pos) and - not inBarrier(p, state) and - ( - sc = TSummaryCtxSome(p, state, t, ap) - or - not exists(TSummaryCtxSome(p, state, t, ap)) and - sc = TSummaryCtxNone() and - // When the call contexts of source and sink needs to match then there's - // never any reason to enter a callable except to find a summary. See also - // the comment in `PathNodeMid::isAtSink`. - not Config::getAFeature() instanceof FeatureEqualSourceSinkCallContext - ) and - innercc = PrunedCallContextSensitivityStage5::getCallContextCall(call, callable) - ) - } - - /** Holds if data may flow from a parameter given by `sc` to a return of kind `kind`. */ - pragma[nomagic] - private predicate paramFlowsThrough( - ReturnKindExt kind, FlowState state, CallContextCall cc, SummaryCtxSome sc, DataFlowType t, - AccessPath ap, AccessPathApprox apa, string summaryLabel - ) { - exists(RetNodeEx ret | - pathNode(_, ret, state, cc, sc, t, ap, summaryLabel, _) and - kind = ret.getKind() and - apa = ap.getApprox() and - parameterFlowThroughAllowed(sc.getParamNode(), kind) and - not outBarrier(ret, state) - ) - } - - pragma[nomagic] - private predicate pathThroughCallable0( - DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, - DataFlowType t, AccessPath ap, AccessPathApprox apa, string label - ) { - exists(CallContext innercc, SummaryCtx sc | - pathIntoCallable(mid, _, _, cc, innercc, sc, call) and - paramFlowsThrough(kind, state, innercc, sc, t, ap, apa, label) - ) - } - - /** - * Holds if data may flow from `mid` through a callable to the node `out`. - * The context `cc` is restored to its value prior to entering the callable. - */ - pragma[noinline] - private predicate pathThroughCallable( - PathNodeMid mid, NodeEx out, FlowState state, CallContext cc, DataFlowType t, AccessPath ap, - string label - ) { - exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa | - pathThroughCallable0(call, mid, kind, state, cc, t, ap, apa, label) and - out = getAnOutNodeFlow(kind, call, apa) - ) - } - - private module Subpaths { - /** - * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by - * `kind`, `sc`, `apout`, and `innercc`. - */ - pragma[nomagic] - private predicate subpaths01( - PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, - ReturnKindExt kind, NodeEx out, FlowState sout, DataFlowType t, AccessPath apout - ) { - pathThroughCallable(arg, out, pragma[only_bind_into](sout), _, pragma[only_bind_into](t), - pragma[only_bind_into](apout), _) and - pathIntoCallable(arg, par, _, _, innercc, sc, _) and - paramFlowsThrough(kind, pragma[only_bind_into](sout), innercc, sc, - pragma[only_bind_into](t), pragma[only_bind_into](apout), _, _) - } - - /** - * Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by - * `kind`, `sc`, `sout`, `apout`, and `innercc`. - */ - pragma[nomagic] - private predicate subpaths02( - PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, - ReturnKindExt kind, NodeEx out, FlowState sout, DataFlowType t, AccessPath apout - ) { - subpaths01(arg, par, sc, innercc, kind, out, sout, t, apout) and - out.asNode() = kind.getAnOutNode(_) - } - - /** - * Holds if `(arg, par, ret, out)` forms a subpath-tuple. - */ - pragma[nomagic] - private predicate subpaths03( - PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, - DataFlowType t, AccessPath apout - ) { - exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode | - subpaths02(arg, par, sc, innercc, kind, out, sout, t, apout) and - pathNode(ret, retnode, sout, innercc, sc, t, apout, _, _) and - kind = retnode.getKind() - ) - } - - private PathNodeImpl localStep(PathNodeImpl n) { - n.getASuccessorImpl(_) = result and - exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() | - localFlowBigStep(n1, _, n2, _, _, _, _, _) or - storeEx(n1, _, n2, _, _) or - readSetEx(n1, _, n2) - ) - } - - private PathNodeImpl summaryCtxStep(PathNodeImpl n) { - n.getASuccessorImpl(_) = result and - exists(SummaryCtxSome sc | - pathNode(n, _, _, _, pragma[only_bind_into](sc), _, _, _, _) and - pathNode(result, _, _, _, pragma[only_bind_into](sc), _, _, _, _) - ) - } - - private predicate localStepToHidden(PathNodeImpl n1, PathNodeImpl n2) { - n2 = localStep(n1) and - n2.isHidden() - } - - private predicate localStepFromHidden(PathNodeImpl n1, PathNodeImpl n2) { - n2 = localStep(n1) and - n1.isHidden() - } - - pragma[nomagic] - private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessorImpl(_) and - succNode = succ.getNodeEx() - } - - /** - * Holds if `(arg, par, ret, out)` forms a subpath-tuple. - * - * All of the nodes may be hidden. - */ - pragma[nomagic] - private predicate subpaths04( - PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out - ) { - exists( - ParamNodeEx p, NodeEx o, FlowState sout, DataFlowType t0, DataFlowType t, - AccessPath apout, PathNodeMid out0 - | - pragma[only_bind_into](arg).getASuccessorImpl(_) = pragma[only_bind_into](out0) and - subpaths03(pragma[only_bind_into](arg), p, ret, o, sout, t0, apout) and - hasSuccessor(pragma[only_bind_into](arg), par, p) and - strengthenType(o, t0, t) and - pathNode(out0, o, sout, _, _, t, apout, _, _) - | - out = out0 or out = out0.projectToSink(_) - ) - } - - bindingset[par, ret] - pragma[inline_late] - private predicate summaryCtxStepStar(PathNodeImpl par, PathNodeImpl ret) { - summaryCtxStep*(par) = ret - } - - /** - * Holds if `(arg, par, ret, out)` forms a subpath-tuple. - * - * `par` and `ret` are not hidden. - */ - pragma[nomagic] - private predicate subpaths05( - PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out - ) { - // direct subpath - subpaths04(arg, any(PathNodeImpl n | localStepFromHidden*(n, par)), - any(PathNodeImpl n | localStepToHidden*(ret, n)), out) and - not par.isHidden() and - not ret.isHidden() and - summaryCtxStepStar(par, ret) - or - // wrapped subpath using hidden nodes, e.g. flow through a callback inside - // a summarized callable - exists(PathNodeImpl par0, PathNodeImpl ret0 | - subpaths05(any(PathNodeImpl n | localStepToHidden*(par0, n)), par, ret, - any(PathNodeImpl n | localStepFromHidden*(n, ret0))) and - subpaths04(arg, par0, ret0, out) - ) - } - - /** - * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through - * a subpath between `par` and `ret` with the connecting edges `arg -> par` and - * `ret -> out` is summarized as the edge `arg -> out`. - * - * None of the nodes are hidden. - */ - pragma[nomagic] - predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) { - subpaths05(any(PathNodeImpl n | localStepToHidden*(arg, n)), par, ret, - any(PathNodeImpl n | localStepFromHidden*(n, out))) and - not arg.isHidden() and - not out.isHidden() - } - - /** - * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. - */ - predicate retReach(PathNodeImpl n) { - exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) - or - exists(PathNodeImpl mid | - retReach(mid) and - n.getANonHiddenSuccessor(_) = mid and - not subpaths(_, mid, _, _) - ) - } - } - - /** - * Holds if data can flow from `source` to `sink`. - * - * The corresponding paths are generated from the end-points and the graph - * included in the module `PathGraph`. - */ - predicate flowPath(PathNode source, PathNode sink) { - exists(PathNodeImpl flowsource, PathNodeImpl flowsink | - source = flowsource and sink = flowsink - | - flowsource.isFlowSource() and - (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and - flowsink.isFlowSink() - ) - } + import S6 /** DEPRECATED: Use `flowPath` instead. */ deprecated predicate hasFlowPath = flowPath/2; - private predicate flowsTo(PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink) { - flowsource.isSource(_) and - flowsource.getNodeEx().asNode() = source and - (flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and - flowsink.getNodeEx().asNode() = sink - } - /** * Holds if data can flow from `source` to `sink`. */ - predicate flow(Node source, Node sink) { flowsTo(_, _, source, sink) } + predicate flow(Node source, Node sink) { + exists(PathNode source0, PathNode sink0 | + flowPath(source0, sink0) and source0.getNode() = source and sink0.getNode() = sink + ) + } /** DEPRECATED: Use `flow` instead. */ deprecated predicate hasFlow = flow/2; @@ -5242,7 +4615,7 @@ module MakeImpl Lang> { /** * Holds if data can flow from some source to `sink`. */ - predicate flowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + predicate flowTo(Node sink) { exists(PathNode n | n.isSink() and n.getNode() = sink) } /** DEPRECATED: Use `flowTo` instead. */ deprecated predicate hasFlowTo = flowTo/1; @@ -5255,24 +4628,6 @@ module MakeImpl Lang> { /** DEPRECATED: Use `flowToExpr` instead. */ deprecated predicate hasFlowToExpr = flowToExpr/1; - private predicate finalStats( - boolean fwd, int nodes, int fields, int conscand, int states, int tuples - ) { - fwd = true and - nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0)) and - fields = count(Content f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and - conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and - states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and - tuples = count(PathNodeImpl pn) - or - fwd = false and - nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and - fields = count(Content f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and - conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and - states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and - tuples = count(PathNode pn) - } - /** * INTERNAL: Only for debugging. * @@ -5387,17 +4742,11 @@ module MakeImpl Lang> { or stage = "6 Fwd" and n = 60 and - finalStats(true, nodes, fields, conscand, states, tuples) and - calledges = -1 and - tfnodes = -1 and - tftuples = -1 + Stage6::stats(true, nodes, fields, conscand, states, tuples, calledges, tfnodes, tftuples) or stage = "6 Rev" and n = 65 and - finalStats(false, nodes, fields, conscand, states, tuples) and - calledges = -1 and - tfnodes = -1 and - tftuples = -1 + Stage6::stats(false, nodes, fields, conscand, states, tuples, calledges, tfnodes, tftuples) } } From 273c0bd1217c4efd2a58dc3e7a085345ae906784 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 20 Aug 2024 15:08:47 +0200 Subject: [PATCH 060/404] Dataflow: Delete dead code. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 53 ------------------- 1 file changed, 53 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 70c0b9ec6bf..d2441852c9f 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -4175,49 +4175,6 @@ module MakeImpl Lang> { ) } - private newtype TSummaryCtx = - TSummaryCtxNone() or - TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { - exists(AccessPathApprox apa | ap.getApprox() = apa | - Stage5::parameterMayFlowThrough(p, apa) and - Stage5::fwdFlow(p, state, _, _, Option::some(t), _, _, apa, _) and - Stage5::revFlow(p, state, _) - ) - } - - /** - * A context for generating flow summaries. This represents flow entry through - * a specific parameter with an access path of a specific shape. - * - * Summaries are only created for parameters that may flow through. - */ - abstract private class SummaryCtx extends TSummaryCtx { - abstract string toString(); - } - - /** A summary context from which no flow summary can be generated. */ - private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { - override string toString() { result = "" } - } - - /** A summary context from which a flow summary can be generated. */ - private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome { - private ParamNodeEx p; - private FlowState s; - private DataFlowType t; - private AccessPath ap; - - SummaryCtxSome() { this = TSummaryCtxSome(p, s, t, ap) } - - ParamNodeEx getParamNode() { result = p } - - private string ppTyp() { result = t.toString() and result != "" } - - override string toString() { result = p + concat(" : " + this.ppTyp()) + " " + ap } - - Location getLocation() { result = p.getLocation() } - } - pragma[nomagic] private predicate stage5ConsCand(Content c, DataFlowType t, AccessPathFront apf, int len) { Stage5::consCand(c, t, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1)) @@ -4448,16 +4405,6 @@ module MakeImpl Lang> { /** Gets a textual representation of this access path. */ abstract string toString(); - - /** Holds if `node`, which is the target of a store step, clears data stored in this access path. */ - pragma[nomagic] - predicate storeTargetIsClearedAt(NodeEx node) { - exists(AccessPathApprox apa | - apa = this.getApprox() and - Stage5::revFlowAp(node, apa) and - Stage4Param::clearContent(node, apa.getHead(), true) - ) - } } private class AccessPathNil extends AccessPath, TAccessPathNil { From 5fbdd83a23453ad6f80ee5c564d2f52cc57948e2 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 20 Aug 2024 11:39:55 +0200 Subject: [PATCH 061/404] Dataflow: Rename StagePathNode to PathNode. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 198 +++++++++--------- 1 file changed, 95 insertions(+), 103 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index d2441852c9f..379a618dbdf 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2538,25 +2538,25 @@ module MakeImpl Lang> { * Provides a graph representation of the data flow in this stage suitable for use in a `path-problem` query. */ additional module Graph { - private newtype TStagePathNode = - TStagePathNodeMid( + private newtype TPathNode = + TPathNodeMid( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap ) { fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) and revFlow(node, state, _, _, ap) } or - TStagePathNodeSink(NodeEx node, FlowState state) { - exists(StagePathNodeMid sink | + TPathNodeSink(NodeEx node, FlowState state) { + exists(PathNodeMid sink | sink.isAtSink() and node = sink.getNodeEx() and state = sink.getState() ) } or - TStagePathNodeSrcGrp() or - TStagePathNodeSinkGrp() + TPathNodeSrcGrp() or + TPathNodeSinkGrp() - class StagePathNodeImpl extends TStagePathNode { + class PathNodeImpl extends TPathNode { abstract NodeEx getNodeEx(); /** Gets the `FlowState` of this node. */ @@ -2566,16 +2566,16 @@ module MakeImpl Lang> { abstract predicate isSource(); /** Holds if this node is a sink. */ - predicate isSink() { this instanceof TStagePathNodeSink } + predicate isSink() { this instanceof TPathNodeSink } - abstract StagePathNodeImpl getASuccessorImpl(string label); + abstract PathNodeImpl getASuccessorImpl(string label); - private StagePathNodeImpl getASuccessorIfHidden(string label) { + private PathNodeImpl getASuccessorIfHidden(string label) { this.isHidden() and result = this.getASuccessorImpl(label) } - private StagePathNodeImpl getASuccessorFromNonHidden(string label) { + private PathNodeImpl getASuccessorFromNonHidden(string label) { result = this.getASuccessorImpl(label) and not this.isHidden() or @@ -2585,7 +2585,7 @@ module MakeImpl Lang> { ) } - final StagePathNodeImpl getANonHiddenSuccessor(string label) { + final PathNodeImpl getANonHiddenSuccessor(string label) { result = this.getASuccessorFromNonHidden(label) and not result.isHidden() } @@ -2594,7 +2594,7 @@ module MakeImpl Lang> { ( hiddenNode(this.getNodeEx().asNode()) and not this.isSource() and - not this instanceof StagePathNodeSink + not this instanceof PathNodeSink or this.getNodeEx() instanceof TNodeImplicitRead or @@ -2608,12 +2608,12 @@ module MakeImpl Lang> { /** Gets the location of this node. */ Location getLocation() { result = this.getNodeEx().getLocation() } - predicate isArbitrarySource() { this instanceof TStagePathNodeSrcGrp } + predicate isArbitrarySource() { this instanceof TPathNodeSrcGrp } - predicate isArbitrarySink() { this instanceof TStagePathNodeSinkGrp } + predicate isArbitrarySink() { this instanceof TPathNodeSinkGrp } } - private class StagePathNodeSrcGrp extends StagePathNodeImpl, TStagePathNodeSrcGrp { + private class PathNodeSrcGrp extends PathNodeImpl, TPathNodeSrcGrp { override string toString() { result = "" } override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } @@ -2622,14 +2622,14 @@ module MakeImpl Lang> { override FlowState getState() { none() } - override StagePathNodeImpl getASuccessorImpl(string label) { + override PathNodeImpl getASuccessorImpl(string label) { result.isSource() and label = "" } override predicate isSource() { none() } } - private class StagePathNodeSinkGrp extends StagePathNodeImpl, TStagePathNodeSinkGrp { + private class PathNodeSinkGrp extends PathNodeImpl, TPathNodeSinkGrp { override string toString() { result = "" } override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } @@ -2638,7 +2638,7 @@ module MakeImpl Lang> { override FlowState getState() { none() } - override StagePathNodeImpl getASuccessorImpl(string label) { none() } + override PathNodeImpl getASuccessorImpl(string label) { none() } override predicate isSource() { none() } } @@ -2647,7 +2647,7 @@ module MakeImpl Lang> { * An intermediate flow graph node. This is a tuple consisting of a node, * a `FlowState`, a call context, a summary context, a tracked type, and an access path. */ - private class StagePathNodeMid extends StagePathNodeImpl, TStagePathNodeMid { + private class PathNodeMid extends PathNodeImpl, TPathNodeMid { NodeEx node; FlowState state; Cc cc; @@ -2657,15 +2657,13 @@ module MakeImpl Lang> { Typ t; Ap ap; - StagePathNodeMid() { - this = TStagePathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) - } + PathNodeMid() { this = TPathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) } override NodeEx getNodeEx() { result = node } override FlowState getState() { result = state } - private StagePathNodeMid getSuccMid(string label) { + private PathNodeMid getSuccMid(string label) { localStep(this, result, label) or nonLocalStep(this, result, label) @@ -2680,7 +2678,7 @@ module MakeImpl Lang> { ) } - override StagePathNodeImpl getASuccessorImpl(string label) { + override PathNodeImpl getASuccessorImpl(string label) { // an intermediate step to another intermediate node exists(string l2 | result = this.getSuccMid(l2) | not this.isSourceWithLabel(_) and label = l2 @@ -2771,7 +2769,7 @@ module MakeImpl Lang> { else any() } - StagePathNodeSink projectToSink(string model) { + PathNodeSink projectToSink(string model) { this.isAtSink() and sinkModel(node, model) and result.getNodeEx() = node and @@ -2784,11 +2782,11 @@ module MakeImpl Lang> { * intermediate nodes in order to uniquely correspond to a given sink by * excluding the call context. */ - private class StagePathNodeSink extends StagePathNodeImpl, TStagePathNodeSink { + private class PathNodeSink extends PathNodeImpl, TPathNodeSink { NodeEx node; FlowState state; - StagePathNodeSink() { this = TStagePathNodeSink(node, state) } + PathNodeSink() { this = TPathNodeSink(node, state) } override NodeEx getNodeEx() { result = node } @@ -2796,7 +2794,7 @@ module MakeImpl Lang> { override string toString() { result = node.toString() } - override StagePathNodeImpl getASuccessorImpl(string label) { + override PathNodeImpl getASuccessorImpl(string label) { result.isArbitrarySink() and label = "" } @@ -2831,46 +2829,46 @@ module MakeImpl Lang> { bindingset[node, state, cc, summaryCtx, argT, argAp, t, ap] pragma[inline_late] - private StagePathNodeImpl mkStagePathNode( + private PathNodeImpl mkPathNode( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap ) { - result = TStagePathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) + result = TPathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) } - private StagePathNodeImpl typeStrengthenToStagePathNode( + private PathNodeImpl typeStrengthenToPathNode( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t0, Ap ap ) { exists(Typ t | fwdFlow1(node, state, cc, summaryCtx, argT, argAp, t0, t, ap, _) and - result = TStagePathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) + result = TPathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) ) } pragma[nomagic] private predicate fwdFlowThroughStep1( - StagePathNodeImpl pn1, StagePathNodeImpl pn2, StagePathNodeImpl pn3, DataFlowCall call, - Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa + PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, DataFlowCall call, Cc cc, + FlowState state, CcCall ccc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, + Typ t, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa ) { exists(FlowState state0, ArgNodeEx arg, ParamNodeEx p, Typ innerArgT, Ap innerArgAp | fwdFlowThroughStep0(call, arg, cc, state, ccc, summaryCtx, argT, argAp, t, ap, apa, ret, p, innerArgT, innerArgAp, innerArgApa) and revFlow(arg, state0, _, _, _) and - pn1 = mkStagePathNode(arg, state0, cc, summaryCtx, argT, argAp, innerArgT, innerArgAp) and + pn1 = mkPathNode(arg, state0, cc, summaryCtx, argT, argAp, innerArgT, innerArgAp) and pn2 = - typeStrengthenToStagePathNode(p, state0, ccc, TParamNodeSome(p.asNode()), + typeStrengthenToPathNode(p, state0, ccc, TParamNodeSome(p.asNode()), TypOption::some(innerArgT), apSome(innerArgAp), innerArgT, innerArgAp) and pn3 = - mkStagePathNode(ret, state, ccc, TParamNodeSome(p.asNode()), - TypOption::some(innerArgT), apSome(innerArgAp), t, ap) + mkPathNode(ret, state, ccc, TParamNodeSome(p.asNode()), TypOption::some(innerArgT), + apSome(innerArgAp), t, ap) ) } pragma[nomagic] private predicate fwdFlowThroughStep2( - StagePathNodeImpl pn1, StagePathNodeImpl pn2, StagePathNodeImpl pn3, NodeEx node, Cc cc, + PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, NodeEx node, Cc cc, FlowState state, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap ) { @@ -2887,11 +2885,11 @@ module MakeImpl Lang> { } private predicate localStep( - StagePathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, + PathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, string label, boolean isStoreStep ) { exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | - pn1 = TStagePathNodeMid(mid, state0, cc, summaryCtx, argT, argAp, t0, ap) and + pn1 = TPathNodeMid(mid, state0, cc, summaryCtx, argT, argAp, t0, ap) and localCc = getLocalCc(cc) and isStoreStep = false | @@ -2904,7 +2902,7 @@ module MakeImpl Lang> { or // store exists(NodeEx mid, Content c, Typ t0, Ap ap0 | - pn1 = TStagePathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and + pn1 = TPathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and fwdFlowStore(mid, t0, ap0, c, t, node, state, cc, summaryCtx, argT, argAp) and ap = apCons(c, t0, ap0) and label = "" and @@ -2913,7 +2911,7 @@ module MakeImpl Lang> { or // read exists(NodeEx mid, Typ t0, Ap ap0, Content c | - pn1 = TStagePathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and + pn1 = TPathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and fwdFlowRead(t0, ap0, c, mid, node, state, cc, summaryCtx, argT, argAp) and fwdFlowConsCand(t0, ap0, c, t, ap) and label = "" and @@ -2921,47 +2919,45 @@ module MakeImpl Lang> { ) } - private predicate localStep(StagePathNodeImpl pn1, StagePathNodeImpl pn2, string label) { + private predicate localStep(PathNodeImpl pn1, PathNodeImpl pn2, string label) { exists( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t0, Ap ap, boolean isStoreStep | localStep(pn1, node, state, cc, summaryCtx, argT, argAp, t0, ap, label, isStoreStep) and - pn2 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and + pn2 = typeStrengthenToPathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and stepFilter(node, ap, isStoreStep) ) or summaryStep(pn1, pn2, label) } - private predicate summaryLabel( - StagePathNodeImpl pn1, StagePathNodeImpl pn2, string summaryLabel - ) { + private predicate summaryLabel(PathNodeImpl pn1, PathNodeImpl pn2, string summaryLabel) { pn1 = pn2 and summaryLabel = "" and subpathsImpl(_, pn1, _, _) or - exists(StagePathNodeImpl mid, string l1, string l2 | + exists(PathNodeImpl mid, string l1, string l2 | summaryLabel(pn1, mid, l1) and localStep(mid, pn2, l2) and summaryLabel = mergeLabels(l1, l2) ) } - private predicate summaryStep(StagePathNodeImpl arg, StagePathNodeImpl out, string label) { - exists(StagePathNodeImpl par, StagePathNodeImpl ret | + private predicate summaryStep(PathNodeImpl arg, PathNodeImpl out, string label) { + exists(PathNodeImpl par, PathNodeImpl ret | subpathsImpl(arg, par, ret, out) and summaryLabel(par, ret, label) ) } private predicate nonLocalStep( - StagePathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, + PathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, string label ) { // jump exists(NodeEx mid, FlowState state0, Typ t0 | - pn1 = TStagePathNodeMid(mid, state0, _, _, _, _, t0, ap) and + pn1 = TPathNodeMid(mid, state0, _, _, _, _, t0, ap) and cc = ccNone() and summaryCtx = TParamNodeNone() and argT instanceof TypOption::None and @@ -2992,8 +2988,7 @@ module MakeImpl Lang> { ArgNodeEx arg, boolean allowsFlowThrough, Cc outercc, ParamNodeOption outerSummaryCtx, TypOption outerArgT, ApOption outerArgAp | - pn1 = - TStagePathNodeMid(arg, state, outercc, outerSummaryCtx, outerArgT, outerArgAp, t, ap) and + pn1 = TPathNodeMid(arg, state, outercc, outerSummaryCtx, outerArgT, outerArgAp, t, ap) and fwdFlowInStep(arg, node, state, outercc, cc, outerSummaryCtx, outerArgT, outerArgAp, t, ap, allowsFlowThrough) and label = "" and @@ -3011,7 +3006,7 @@ module MakeImpl Lang> { or // flow out of a callable exists(RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow, ApApprox apa | - pn1 = TStagePathNodeMid(ret, state, innercc, summaryCtx, argT, argAp, t, ap) and + pn1 = TPathNodeMid(ret, state, innercc, summaryCtx, argT, argAp, t, ap) and fwdFlowIntoRet(ret, state, innercc, summaryCtx, argT, argAp, t, ap, apa) and fwdFlowOutValidEdge(_, ret, innercc, _, node, cc, apa, allowsFieldFlow) and not inBarrier(node, state) and @@ -3020,13 +3015,13 @@ module MakeImpl Lang> { ) } - private predicate nonLocalStep(StagePathNodeImpl pn1, StagePathNodeImpl pn2, string label) { + private predicate nonLocalStep(PathNodeImpl pn1, PathNodeImpl pn2, string label) { exists( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t0, Ap ap | nonLocalStep(pn1, node, state, cc, summaryCtx, argT, argAp, t0, ap, label) and - pn2 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and + pn2 = typeStrengthenToPathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and stepFilter(node, ap, false) ) } @@ -3037,28 +3032,27 @@ module MakeImpl Lang> { * All of the nodes may be hidden. */ private predicate subpathsImpl( - StagePathNodeImpl arg, StagePathNodeImpl par, StagePathNodeImpl ret, - StagePathNodeImpl out + PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out ) { exists( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t0, Ap ap, StagePathNodeImpl out0 + ApOption argAp, Typ t0, Ap ap, PathNodeImpl out0 | fwdFlowThroughStep2(arg, par, ret, node, cc, state, summaryCtx, argT, argAp, t0, ap) and - out0 = typeStrengthenToStagePathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and + out0 = typeStrengthenToPathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and stepFilter(node, ap, false) | - out = out0 or out = out0.(StagePathNodeMid).projectToSink(_) + out = out0 or out = out0.(PathNodeMid).projectToSink(_) ) } module StagePathGraph { - predicate edges(StagePathNodeImpl a, StagePathNodeImpl b, string key, string val) { + predicate edges(PathNodeImpl a, PathNodeImpl b, string key, string val) { a.getASuccessorImpl(val) = b and key = "provenance" } - query predicate nodes(StagePathNodeImpl n, string key, string val) { + query predicate nodes(PathNodeImpl n, string key, string val) { key = "semmle.label" and val = n.toString() } @@ -3066,21 +3060,21 @@ module MakeImpl Lang> { } module Public { - private StagePathNodeImpl localStep(StagePathNodeImpl n) { localStep(n, result, _) } + private PathNodeImpl localStep(PathNodeImpl n) { localStep(n, result, _) } - private predicate localStepToHidden(StagePathNodeImpl n1, StagePathNodeImpl n2) { + private predicate localStepToHidden(PathNodeImpl n1, PathNodeImpl n2) { n2 = localStep(n1) and n2.isHidden() } - private predicate localStepFromHidden(StagePathNodeImpl n1, StagePathNodeImpl n2) { + private predicate localStepFromHidden(PathNodeImpl n1, PathNodeImpl n2) { n2 = localStep(n1) and n1.isHidden() } bindingset[par, ret] pragma[inline_late] - private predicate localStepStar(StagePathNodeImpl par, StagePathNodeImpl ret) { + private predicate localStepStar(PathNodeImpl par, PathNodeImpl ret) { localStep*(par) = ret } @@ -3091,21 +3085,20 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate subpaths1( - StagePathNodeImpl arg, StagePathNodeImpl par, StagePathNodeImpl ret, - StagePathNodeImpl out + PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out ) { // direct subpath - subpathsImpl(arg, any(StagePathNodeImpl n | localStepFromHidden*(n, par)), - any(StagePathNodeImpl n | localStepToHidden*(ret, n)), out) and + subpathsImpl(arg, any(PathNodeImpl n | localStepFromHidden*(n, par)), + any(PathNodeImpl n | localStepToHidden*(ret, n)), out) and not par.isHidden() and not ret.isHidden() and localStepStar(par, ret) or // wrapped subpath using hidden nodes, e.g. flow through a callback inside // a summarized callable - exists(StagePathNodeImpl par0, StagePathNodeImpl ret0 | - subpaths1(any(StagePathNodeImpl n | localStepToHidden*(par0, n)), par, ret, - any(StagePathNodeImpl n | localStepFromHidden*(n, ret0))) and + exists(PathNodeImpl par0, PathNodeImpl ret0 | + subpaths1(any(PathNodeImpl n | localStepToHidden*(par0, n)), par, ret, + any(PathNodeImpl n | localStepFromHidden*(n, ret0))) and subpathsImpl(arg, par0, ret0, out) ) } @@ -3119,28 +3112,27 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate subpaths2( - StagePathNodeImpl arg, StagePathNodeImpl par, StagePathNodeImpl ret, - StagePathNodeImpl out + PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out ) { - exists(StagePathNodeImpl out0 | - subpaths1(any(StagePathNodeImpl n | localStepToHidden*(arg, n)), par, ret, - any(StagePathNodeImpl n | localStepFromHidden*(n, out0))) and + exists(PathNodeImpl out0 | + subpaths1(any(PathNodeImpl n | localStepToHidden*(arg, n)), par, ret, + any(PathNodeImpl n | localStepFromHidden*(n, out0))) and not arg.isHidden() and not out0.isHidden() | - out = out0 or out = out0.(StagePathNodeMid).projectToSink(_) + out = out0 or out = out0.(PathNodeMid).projectToSink(_) ) } /** Holds if `n` is reachable from a source. */ - private predicate fwdReach(StagePathNodeImpl n) { + private predicate fwdReach(PathNodeImpl n) { n.isArbitrarySource() or - exists(StagePathNodeImpl mid | fwdReach(mid) and mid.getANonHiddenSuccessor(_) = n) + exists(PathNodeImpl mid | fwdReach(mid) and mid.getANonHiddenSuccessor(_) = n) } /** Holds if `n` is reachable from a source and can reach a sink. */ - private predicate directReach(StagePathNodeImpl n) { + private predicate directReach(PathNodeImpl n) { fwdReach(n) and ( n.isArbitrarySink() or @@ -3151,14 +3143,14 @@ module MakeImpl Lang> { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - private predicate retReach(StagePathNodeImpl n) { + private predicate retReach(PathNodeImpl n) { fwdReach(n) and ( - exists(StagePathNodeImpl out | subpaths2(_, _, n, out) | + exists(PathNodeImpl out | subpaths2(_, _, n, out) | directReach(out) or retReach(out) ) or - exists(StagePathNodeImpl mid | + exists(PathNodeImpl mid | retReach(mid) and n.getANonHiddenSuccessor(_) = mid and not subpaths2(_, mid, _, _) @@ -3167,17 +3159,17 @@ module MakeImpl Lang> { } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ - private predicate reach(StagePathNodeImpl n) { directReach(n) or retReach(n) } + private predicate reach(PathNodeImpl n) { directReach(n) or retReach(n) } /** * A `Node` augmented with a call context (except for sinks) and an access path. * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. */ - class PathNode instanceof StagePathNodeImpl { + class PathNode instanceof PathNodeImpl { PathNode() { reach(this) and - not this instanceof StagePathNodeSrcGrp and - not this instanceof StagePathNodeSinkGrp + not this instanceof PathNodeSrcGrp and + not this instanceof PathNodeSinkGrp } /** Gets a textual representation of this element. */ @@ -3188,9 +3180,9 @@ module MakeImpl Lang> { * representation of the call context. */ final string toStringWithContext() { - result = this.(StagePathNodeMid).toStringWithContext() + result = this.(PathNodeMid).toStringWithContext() or - not this instanceof StagePathNodeMid and result = this.toString() + not this instanceof PathNodeMid and result = this.toString() } /** Gets the location of this node. */ @@ -3214,7 +3206,7 @@ module MakeImpl Lang> { final predicate isSource() { super.isSource() } /** Holds if this node is a sink. */ - final predicate isSink() { this instanceof StagePathNodeSink } + final predicate isSink() { this instanceof PathNodeSink } /** * Holds if this element is at the specified location. @@ -3247,15 +3239,15 @@ module MakeImpl Lang> { } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ - private predicate pathSucc(StagePathNodeImpl n1, StagePathNodeImpl n2) { + private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) { n1.getANonHiddenSuccessor(_) = n2 and directReach(n2) } - private predicate tcSrc(StagePathNodeImpl n) { n.isSource() } + private predicate tcSrc(PathNodeImpl n) { n.isSource() } - private predicate tcSink(StagePathNodeImpl n) { n.isSink() } + private predicate tcSink(PathNodeImpl n) { n.isSink() } - private predicate pathSuccPlus(StagePathNodeImpl n1, StagePathNodeImpl n2) = + private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = doublyBoundedFastTC(pathSucc/2, tcSrc/1, tcSink/1)(n1, n2) /** @@ -3265,7 +3257,7 @@ module MakeImpl Lang> { * included in the module `PathGraph`. */ predicate flowPath(PathNode source, PathNode sink) { - exists(StagePathNodeImpl flowsource, StagePathNodeImpl flowsink | + exists(PathNodeImpl flowsource, PathNodeImpl flowsink | source = flowsource and sink = flowsink | flowsource.isSource() and @@ -3280,7 +3272,7 @@ module MakeImpl Lang> { module PathGraph implements PathGraphSig { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ query predicate edges(PathNode a, PathNode b, string key, string val) { - a.(StagePathNodeImpl).getANonHiddenSuccessor(val) = b and + a.(PathNodeImpl).getANonHiddenSuccessor(val) = b and key = "provenance" } From 525b6f30e3dbcfb150e4f7580b7cf0eb39df2834 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 19 Aug 2024 11:33:46 +0200 Subject: [PATCH 062/404] C++/C#/Java: Accept test changes. --- .../dataflow/fields/ir-path-flow.expected | 4 + .../dataflow/fields/path-flow.expected | 4 + .../collections/CollectionFlow.expected | 11 - .../global/TaintTrackingPath.expected | 20 ++ .../CWE-625/PermissiveDotRegex.expected | 5 - .../dataflow/capture/inlinetest.expected | 9 - .../apache-collections/test.expected | 208 ------------------ .../frameworks/spring/beans/test.expected | 18 -- .../frameworks/spring/cache/test.expected | 4 - .../frameworks/spring/util/test.expected | 8 - .../frameworks/stream/test.expected | 30 +++ 11 files changed, 58 insertions(+), 263 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected index 98ca0290f47..43725bb4524 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected @@ -848,6 +848,8 @@ edges | simple.cpp:120:8:120:8 | *a [i] | simple.cpp:120:10:120:10 | i | provenance | | | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | *ab [a] | provenance | | | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:8:15:9 | *ab [a] | provenance | | +| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:8:15:9 | *ab [a] | provenance | | +| struct_init.c:15:8:15:9 | *ab [a] | struct_init.c:15:12:15:12 | a | provenance | | | struct_init.c:15:8:15:9 | *ab [a] | struct_init.c:15:12:15:12 | a | provenance | | | struct_init.c:20:13:20:14 | *definition of ab [a] | struct_init.c:22:8:22:9 | *ab [a] | provenance | | | struct_init.c:20:13:20:14 | *definition of ab [a] | struct_init.c:24:10:24:12 | *& ... [a] | provenance | | @@ -1758,6 +1760,8 @@ nodes | simple.cpp:120:10:120:10 | i | semmle.label | i | | struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] | | struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] | +| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] | +| struct_init.c:15:8:15:9 | *ab [a] | semmle.label | *ab [a] | | struct_init.c:15:8:15:9 | *ab [a] | semmle.label | *ab [a] | | struct_init.c:15:12:15:12 | a | semmle.label | a | | struct_init.c:20:13:20:14 | *definition of ab [a] | semmle.label | *definition of ab [a] | diff --git a/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected index 17cd0b7ce02..98e93029073 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected @@ -737,6 +737,8 @@ edges | simple.cpp:120:8:120:8 | a [i] | simple.cpp:120:10:120:10 | i | provenance | | | struct_init.c:14:24:14:25 | ab [a] | struct_init.c:14:24:14:25 | ab [a] | provenance | | | struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [a] | provenance | | +| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [a] | provenance | | +| struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a | provenance | | | struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a | provenance | | | struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a | provenance | | | struct_init.c:15:8:15:9 | ab [post update] [a] | struct_init.c:14:24:14:25 | ab [a] | provenance | | @@ -1549,6 +1551,8 @@ nodes | simple.cpp:120:10:120:10 | i | semmle.label | i | | struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] | | struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] | +| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] | +| struct_init.c:15:8:15:9 | ab [a] | semmle.label | ab [a] | | struct_init.c:15:8:15:9 | ab [a] | semmle.label | ab [a] | | struct_init.c:15:8:15:9 | ab [post update] [a] | semmle.label | ab [post update] [a] | | struct_init.c:15:12:15:12 | a | semmle.label | a | diff --git a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected index aae5dff536d..dfc46ac8071 100644 --- a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected @@ -52,12 +52,10 @@ edges | CollectionFlow.cs:30:69:30:72 | access to parameter dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:69:30:79 | access to property Values : ICollection [element] : A | provenance | MaD:2 | | CollectionFlow.cs:30:69:30:72 | access to parameter dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:69:30:79 | access to property Values : ICollection [element] : A | provenance | MaD:8 | | CollectionFlow.cs:30:69:30:79 | access to property Values : ICollection [element] : A | CollectionFlow.cs:30:69:30:87 | call to method First : A | provenance | MaD:16 | -| CollectionFlow.cs:30:69:30:79 | access to property Values : ICollection [element] : A | CollectionFlow.cs:30:69:30:87 | call to method First : A | provenance | MaD:16 | | CollectionFlow.cs:32:58:32:61 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:67:32:70 | access to parameter dict : Dictionary [element, property Key] : A | provenance | | | CollectionFlow.cs:32:67:32:70 | access to parameter dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:67:32:75 | access to property Keys : ICollection [element] : A | provenance | MaD:1 | | CollectionFlow.cs:32:67:32:70 | access to parameter dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:67:32:75 | access to property Keys : ICollection [element] : A | provenance | MaD:7 | | CollectionFlow.cs:32:67:32:75 | access to property Keys : ICollection [element] : A | CollectionFlow.cs:32:67:32:83 | call to method First : A | provenance | MaD:16 | -| CollectionFlow.cs:32:67:32:75 | access to property Keys : ICollection [element] : A | CollectionFlow.cs:32:67:32:83 | call to method First : A | provenance | MaD:16 | | CollectionFlow.cs:34:57:34:60 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:34:66:34:69 | access to parameter dict : Dictionary [element, property Key] : A | provenance | | | CollectionFlow.cs:34:66:34:69 | access to parameter dict : Dictionary [element, property Key] : A | CollectionFlow.cs:34:66:34:77 | call to method First> : KeyValuePair [property Key] : A | provenance | MaD:16 | | CollectionFlow.cs:34:66:34:77 | call to method First> : KeyValuePair [property Key] : A | CollectionFlow.cs:34:66:34:81 | access to property Key : A | provenance | | @@ -378,14 +376,10 @@ nodes | CollectionFlow.cs:30:60:30:63 | dict : Dictionary [element, property Value] : A | semmle.label | dict : Dictionary [element, property Value] : A | | CollectionFlow.cs:30:69:30:72 | access to parameter dict : Dictionary [element, property Value] : A | semmle.label | access to parameter dict : Dictionary [element, property Value] : A | | CollectionFlow.cs:30:69:30:79 | access to property Values : ICollection [element] : A | semmle.label | access to property Values : ICollection [element] : A | -| CollectionFlow.cs:30:69:30:79 | access to property Values : ICollection [element] : A | semmle.label | access to property Values : ICollection [element] : A | -| CollectionFlow.cs:30:69:30:87 | call to method First : A | semmle.label | call to method First : A | | CollectionFlow.cs:30:69:30:87 | call to method First : A | semmle.label | call to method First : A | | CollectionFlow.cs:32:58:32:61 | dict : Dictionary [element, property Key] : A | semmle.label | dict : Dictionary [element, property Key] : A | | CollectionFlow.cs:32:67:32:70 | access to parameter dict : Dictionary [element, property Key] : A | semmle.label | access to parameter dict : Dictionary [element, property Key] : A | | CollectionFlow.cs:32:67:32:75 | access to property Keys : ICollection [element] : A | semmle.label | access to property Keys : ICollection [element] : A | -| CollectionFlow.cs:32:67:32:75 | access to property Keys : ICollection [element] : A | semmle.label | access to property Keys : ICollection [element] : A | -| CollectionFlow.cs:32:67:32:83 | call to method First : A | semmle.label | call to method First : A | | CollectionFlow.cs:32:67:32:83 | call to method First : A | semmle.label | call to method First : A | | CollectionFlow.cs:34:57:34:60 | dict : Dictionary [element, property Key] : A | semmle.label | dict : Dictionary [element, property Key] : A | | CollectionFlow.cs:34:66:34:69 | access to parameter dict : Dictionary [element, property Key] : A | semmle.label | access to parameter dict : Dictionary [element, property Key] : A | @@ -671,20 +665,15 @@ subpaths | CollectionFlow.cs:156:28:156:31 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:26:58:26:61 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:26:67:26:73 | access to indexer : A | CollectionFlow.cs:156:14:156:32 | call to method DictIndexZero | | CollectionFlow.cs:157:29:157:32 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:28:59:28:62 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:28:68:28:85 | access to property Value : A | CollectionFlow.cs:157:14:157:33 | call to method DictFirstValue | | CollectionFlow.cs:158:30:158:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:60:30:63 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:69:30:87 | call to method First : A | CollectionFlow.cs:158:14:158:34 | call to method DictValuesFirst | -| CollectionFlow.cs:158:30:158:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:60:30:63 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:69:30:87 | call to method First : A | CollectionFlow.cs:158:14:158:34 | call to method DictValuesFirst | | CollectionFlow.cs:178:28:178:31 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:26:58:26:61 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:26:67:26:73 | access to indexer : A | CollectionFlow.cs:178:14:178:32 | call to method DictIndexZero | | CollectionFlow.cs:179:29:179:32 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:28:59:28:62 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:28:68:28:85 | access to property Value : A | CollectionFlow.cs:179:14:179:33 | call to method DictFirstValue | | CollectionFlow.cs:180:30:180:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:60:30:63 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:69:30:87 | call to method First : A | CollectionFlow.cs:180:14:180:34 | call to method DictValuesFirst | -| CollectionFlow.cs:180:30:180:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:60:30:63 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:69:30:87 | call to method First : A | CollectionFlow.cs:180:14:180:34 | call to method DictValuesFirst | | CollectionFlow.cs:199:28:199:31 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:26:58:26:61 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:26:67:26:73 | access to indexer : A | CollectionFlow.cs:199:14:199:32 | call to method DictIndexZero | | CollectionFlow.cs:200:29:200:32 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:28:59:28:62 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:28:68:28:85 | access to property Value : A | CollectionFlow.cs:200:14:200:33 | call to method DictFirstValue | | CollectionFlow.cs:201:30:201:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:60:30:63 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:69:30:87 | call to method First : A | CollectionFlow.cs:201:14:201:34 | call to method DictValuesFirst | -| CollectionFlow.cs:201:30:201:33 | access to local variable dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:60:30:63 | dict : Dictionary [element, property Value] : A | CollectionFlow.cs:30:69:30:87 | call to method First : A | CollectionFlow.cs:201:14:201:34 | call to method DictValuesFirst | -| CollectionFlow.cs:221:28:221:31 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:58:32:61 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:67:32:83 | call to method First : A | CollectionFlow.cs:221:14:221:32 | call to method DictKeysFirst | | CollectionFlow.cs:221:28:221:31 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:58:32:61 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:67:32:83 | call to method First : A | CollectionFlow.cs:221:14:221:32 | call to method DictKeysFirst | | CollectionFlow.cs:222:27:222:30 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:34:57:34:60 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:34:66:34:81 | access to property Key : A | CollectionFlow.cs:222:14:222:31 | call to method DictFirstKey | | CollectionFlow.cs:240:28:240:31 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:58:32:61 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:67:32:83 | call to method First : A | CollectionFlow.cs:240:14:240:32 | call to method DictKeysFirst | -| CollectionFlow.cs:240:28:240:31 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:58:32:61 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:32:67:32:83 | call to method First : A | CollectionFlow.cs:240:14:240:32 | call to method DictKeysFirst | | CollectionFlow.cs:241:27:241:30 | access to local variable dict : Dictionary [element, property Key] : A | CollectionFlow.cs:34:57:34:60 | dict : Dictionary [element, property Key] : A | CollectionFlow.cs:34:66:34:81 | access to property Key : A | CollectionFlow.cs:241:14:241:31 | call to method DictFirstKey | | CollectionFlow.cs:334:23:334:23 | access to local variable a : A | CollectionFlow.cs:328:32:328:38 | element : A | CollectionFlow.cs:328:23:328:27 | array [Return] : A[] [element] : A | CollectionFlow.cs:334:18:334:20 | [post] access to local variable as : A[] [element] : A | | CollectionFlow.cs:337:20:337:22 | access to local variable as : A[] [element] : A | CollectionFlow.cs:22:34:22:35 | ts : A[] [element] : A | CollectionFlow.cs:22:41:22:45 | access to array element : A | CollectionFlow.cs:337:14:337:23 | call to method First | diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected index 24693500fbf..4bf73387c5d 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected @@ -301,14 +301,22 @@ edges | GlobalDataFlow.cs:89:13:89:18 | access to local variable sink17 : String | GlobalDataFlow.cs:90:15:90:20 | access to local variable sink17 | provenance | | | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate : String | GlobalDataFlow.cs:89:13:89:18 | access to local variable sink17 : String | provenance | | | GlobalDataFlow.cs:89:23:89:66 | (...) ... : null [element] : String | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate : String | provenance | MaD:2 | +| GlobalDataFlow.cs:89:23:89:66 | (...) ... : null [element] : String | GlobalDataFlow.cs:89:89:89:89 | s : String | provenance | MaD:2 | +| GlobalDataFlow.cs:89:23:89:66 | (...) ... : null [element] : String | GlobalDataFlow.cs:89:104:89:104 | x : String | provenance | MaD:2 | | GlobalDataFlow.cs:89:57:89:66 | { ..., ... } : null [element] : String | GlobalDataFlow.cs:89:23:89:66 | (...) ... : null [element] : String | provenance | | | GlobalDataFlow.cs:89:59:89:64 | access to local variable sink14 : String | GlobalDataFlow.cs:89:57:89:66 | { ..., ... } : null [element] : String | provenance | | +| GlobalDataFlow.cs:89:89:89:89 | s : String | GlobalDataFlow.cs:89:95:89:101 | ... + ... : String | provenance | | +| GlobalDataFlow.cs:89:104:89:104 | x : String | GlobalDataFlow.cs:89:109:89:109 | access to parameter x : String | provenance | | | GlobalDataFlow.cs:91:13:91:18 | access to local variable sink18 : String | GlobalDataFlow.cs:92:15:92:20 | access to local variable sink18 | provenance | | | GlobalDataFlow.cs:91:13:91:18 | access to local variable sink18 : String | GlobalDataFlow.cs:94:24:94:29 | access to local variable sink18 : String | provenance | | | GlobalDataFlow.cs:91:13:91:18 | access to local variable sink18 : String | GlobalDataFlow.cs:97:23:97:28 | access to local variable sink18 : String | provenance | | | GlobalDataFlow.cs:91:13:91:18 | access to local variable sink18 : String | GlobalDataFlow.cs:100:24:100:29 | access to local variable sink18 : String | provenance | | | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate : String | GlobalDataFlow.cs:91:13:91:18 | access to local variable sink18 : String | provenance | | | GlobalDataFlow.cs:91:75:91:80 | access to local variable sink14 : String | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate : String | provenance | MaD:3 | +| GlobalDataFlow.cs:91:75:91:80 | access to local variable sink14 : String | GlobalDataFlow.cs:91:84:91:86 | acc : String | provenance | MaD:3 | +| GlobalDataFlow.cs:91:75:91:80 | access to local variable sink14 : String | GlobalDataFlow.cs:91:104:91:104 | x : String | provenance | MaD:3 | +| GlobalDataFlow.cs:91:84:91:86 | acc : String | GlobalDataFlow.cs:91:95:91:101 | ... + ... : String | provenance | | +| GlobalDataFlow.cs:91:104:91:104 | x : String | GlobalDataFlow.cs:91:109:91:109 | access to parameter x : String | provenance | | | GlobalDataFlow.cs:94:24:94:29 | access to local variable sink18 : String | GlobalDataFlow.cs:94:36:94:41 | access to local variable sink21 : Int32 | provenance | MaD:22 | | GlobalDataFlow.cs:94:36:94:41 | access to local variable sink21 : Int32 | GlobalDataFlow.cs:95:15:95:20 | access to local variable sink21 | provenance | | | GlobalDataFlow.cs:97:23:97:28 | access to local variable sink18 : String | GlobalDataFlow.cs:97:35:97:40 | access to local variable sink22 : Boolean | provenance | MaD:20 | @@ -788,10 +796,18 @@ nodes | GlobalDataFlow.cs:89:23:89:66 | (...) ... : null [element] : String | semmle.label | (...) ... : null [element] : String | | GlobalDataFlow.cs:89:57:89:66 | { ..., ... } : null [element] : String | semmle.label | { ..., ... } : null [element] : String | | GlobalDataFlow.cs:89:59:89:64 | access to local variable sink14 : String | semmle.label | access to local variable sink14 : String | +| GlobalDataFlow.cs:89:89:89:89 | s : String | semmle.label | s : String | +| GlobalDataFlow.cs:89:95:89:101 | ... + ... : String | semmle.label | ... + ... : String | +| GlobalDataFlow.cs:89:104:89:104 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:89:109:89:109 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:90:15:90:20 | access to local variable sink17 | semmle.label | access to local variable sink17 | | GlobalDataFlow.cs:91:13:91:18 | access to local variable sink18 : String | semmle.label | access to local variable sink18 : String | | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate : String | semmle.label | call to method Aggregate : String | | GlobalDataFlow.cs:91:75:91:80 | access to local variable sink14 : String | semmle.label | access to local variable sink14 : String | +| GlobalDataFlow.cs:91:84:91:86 | acc : String | semmle.label | acc : String | +| GlobalDataFlow.cs:91:95:91:101 | ... + ... : String | semmle.label | ... + ... : String | +| GlobalDataFlow.cs:91:104:91:104 | x : String | semmle.label | x : String | +| GlobalDataFlow.cs:91:109:91:109 | access to parameter x : String | semmle.label | access to parameter x : String | | GlobalDataFlow.cs:92:15:92:20 | access to local variable sink18 | semmle.label | access to local variable sink18 | | GlobalDataFlow.cs:94:24:94:29 | access to local variable sink18 : String | semmle.label | access to local variable sink18 : String | | GlobalDataFlow.cs:94:36:94:41 | access to local variable sink21 : Int32 | semmle.label | access to local variable sink21 : Int32 | @@ -1102,6 +1118,10 @@ subpaths | GlobalDataFlow.cs:83:23:83:66 | (...) ... : null [element] : String | GlobalDataFlow.cs:315:31:315:40 | sinkParam8 : String | GlobalDataFlow.cs:318:16:318:25 | access to parameter sinkParam8 : String | GlobalDataFlow.cs:83:22:83:87 | call to method Select : IEnumerable [element] : String | | GlobalDataFlow.cs:85:23:85:66 | (...) ... : null [element] : String | GlobalDataFlow.cs:85:118:85:118 | x : String | GlobalDataFlow.cs:85:127:85:127 | access to parameter x : String | GlobalDataFlow.cs:85:22:85:128 | call to method Zip : IEnumerable [element] : String | | GlobalDataFlow.cs:87:70:87:113 | (...) ... : null [element] : String | GlobalDataFlow.cs:87:121:87:121 | y : String | GlobalDataFlow.cs:87:127:87:127 | access to parameter y : String | GlobalDataFlow.cs:87:22:87:128 | call to method Zip : IEnumerable [element] : String | +| GlobalDataFlow.cs:89:23:89:66 | (...) ... : null [element] : String | GlobalDataFlow.cs:89:89:89:89 | s : String | GlobalDataFlow.cs:89:95:89:101 | ... + ... : String | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate : String | +| GlobalDataFlow.cs:89:23:89:66 | (...) ... : null [element] : String | GlobalDataFlow.cs:89:104:89:104 | x : String | GlobalDataFlow.cs:89:109:89:109 | access to parameter x : String | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate : String | +| GlobalDataFlow.cs:91:75:91:80 | access to local variable sink14 : String | GlobalDataFlow.cs:91:84:91:86 | acc : String | GlobalDataFlow.cs:91:95:91:101 | ... + ... : String | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate : String | +| GlobalDataFlow.cs:91:75:91:80 | access to local variable sink14 : String | GlobalDataFlow.cs:91:104:91:104 | x : String | GlobalDataFlow.cs:91:109:91:109 | access to parameter x : String | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate : String | | GlobalDataFlow.cs:138:63:138:63 | access to parameter x : String | GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | | GlobalDataFlow.cs:139:29:139:33 | access to local variable sink3 : String | GlobalDataFlow.cs:138:40:138:40 | x : String | GlobalDataFlow.cs:138:45:138:64 | call to method ApplyFunc : String | GlobalDataFlow.cs:139:21:139:34 | delegate call : String | | GlobalDataFlow.cs:147:39:147:43 | access to local variable sink4 : String | GlobalDataFlow.cs:387:46:387:46 | x : String | GlobalDataFlow.cs:389:16:389:19 | delegate call : String | GlobalDataFlow.cs:147:21:147:44 | call to method ApplyFunc : String | diff --git a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected index 7832305e0ac..424cbc58af8 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-625/PermissiveDotRegex.expected @@ -32,7 +32,6 @@ edges | DotRegexSpring.java:71:11:71:42 | decode(...) : String | DotRegexSpring.java:71:29:71:32 | path : String | provenance | | | DotRegexSpring.java:71:11:71:42 | decode(...) : String | DotRegexSpring.java:73:10:73:13 | path : String | provenance | | | DotRegexSpring.java:71:29:71:32 | path : String | DotRegexSpring.java:71:11:71:42 | decode(...) : String | provenance | MaD:3 | -| DotRegexSpring.java:71:29:71:32 | path : String | DotRegexSpring.java:71:11:71:42 | decode(...) : String | provenance | MaD:3 | models | 1 | Source: javax.servlet.http; HttpServletRequest; false; getPathInfo; (); ; ReturnValue; uri-path; manual | | 2 | Source: javax.servlet.http; HttpServletRequest; false; getRequestURI; (); ; ReturnValue; uri-path; manual | @@ -61,11 +60,7 @@ nodes | DotRegexSpring.java:69:28:69:38 | path : String | semmle.label | path : String | | DotRegexSpring.java:71:11:71:42 | decode(...) : String | semmle.label | decode(...) : String | | DotRegexSpring.java:71:29:71:32 | path : String | semmle.label | path : String | -| DotRegexSpring.java:71:29:71:32 | path : String | semmle.label | path : String | -| DotRegexSpring.java:73:10:73:13 | path : String | semmle.label | path : String | | DotRegexSpring.java:73:10:73:13 | path : String | semmle.label | path : String | subpaths | DotRegexSpring.java:22:21:22:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | DotRegexSpring.java:73:10:73:13 | path : String | DotRegexSpring.java:22:10:22:25 | decodePath(...) : String | -| DotRegexSpring.java:22:21:22:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | DotRegexSpring.java:73:10:73:13 | path : String | DotRegexSpring.java:22:10:22:25 | decodePath(...) : String | -| DotRegexSpring.java:39:21:39:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | DotRegexSpring.java:73:10:73:13 | path : String | DotRegexSpring.java:39:10:39:25 | decodePath(...) : String | | DotRegexSpring.java:39:21:39:24 | path : String | DotRegexSpring.java:69:28:69:38 | path : String | DotRegexSpring.java:73:10:73:13 | path : String | DotRegexSpring.java:39:10:39:25 | decodePath(...) : String | diff --git a/java/ql/test/library-tests/dataflow/capture/inlinetest.expected b/java/ql/test/library-tests/dataflow/capture/inlinetest.expected index 0987959e449..5c08b6d3c31 100644 --- a/java/ql/test/library-tests/dataflow/capture/inlinetest.expected +++ b/java/ql/test/library-tests/dataflow/capture/inlinetest.expected @@ -116,16 +116,13 @@ edges | B.java:107:31:111:5 | ...->... : new Consumer(...) { ... } [String s] : String | B.java:107:31:111:5 | parameter this : new Consumer(...) { ... } [String s] : String | provenance | heuristic-callback | | B.java:107:31:111:5 | ...->... [post update] : new Consumer(...) { ... } [List out1, ] : String | B.java:107:31:111:5 | List out1 : ArrayList [] : String | provenance | | | B.java:107:31:111:5 | ...->... [post update] : new Consumer(...) { ... } [List out2, ] : String | B.java:107:31:111:5 | List out2 : ArrayList [] : String | provenance | | -| B.java:107:31:111:5 | ...->... [post update] : new Consumer(...) { ... } [List out2, ] : String | B.java:107:31:111:5 | List out2 : ArrayList [] : String | provenance | | | B.java:107:31:111:5 | List out1 : ArrayList [] : String | B.java:107:31:111:5 | this : new Consumer>(...) { ... } [List out1, ] : String | provenance | | | B.java:107:31:111:5 | List out2 : ArrayList [] : String | B.java:107:31:111:5 | this : new Consumer>(...) { ... } [List out2, ] : String | provenance | | -| B.java:107:31:111:5 | List out2 : ArrayList [] : String | B.java:107:31:111:5 | this : new Consumer>(...) { ... } [List out2, ] : String | provenance | | | B.java:107:31:111:5 | String s : String | B.java:107:31:111:5 | ...->... : new Consumer(...) { ... } [String s] : String | provenance | | | B.java:107:31:111:5 | parameter this : new Consumer(...) { ... } [String s] : String | B.java:108:12:108:12 | this : new Consumer(...) { ... } [String s] : String | provenance | | | B.java:107:31:111:5 | parameter this : new Consumer(...) { ... } [String s] : String | B.java:110:16:110:16 | this : new Consumer(...) { ... } [String s] : String | provenance | | | B.java:107:31:111:5 | this : new Consumer>(...) { ... } [List out1, ] : String | B.java:107:16:111:6 | parameter this [Return] : new Consumer>(...) { ... } [List out1, ] : String | provenance | | | B.java:107:31:111:5 | this : new Consumer>(...) { ... } [List out2, ] : String | B.java:107:16:111:6 | parameter this [Return] : new Consumer>(...) { ... } [List out2, ] : String | provenance | | -| B.java:107:31:111:5 | this : new Consumer>(...) { ... } [List out2, ] : String | B.java:107:16:111:6 | parameter this [Return] : new Consumer>(...) { ... } [List out2, ] : String | provenance | | | B.java:107:31:111:5 | this : new Consumer>(...) { ... } [String s] : String | B.java:107:31:111:5 | String s : String | provenance | | | B.java:108:12:108:12 | this : new Consumer(...) { ... } [String s] : String | B.java:108:12:108:12 | s | provenance | | | B.java:109:7:109:10 | out1 [post update] : ArrayList [] : String | B.java:109:7:109:10 | this : new Consumer(...) { ... } [List out1, ] : String | provenance | | @@ -363,23 +360,19 @@ nodes | B.java:107:16:111:6 | parameter this : new Consumer>(...) { ... } [String s] : String | semmle.label | parameter this : new Consumer>(...) { ... } [String s] : String | | B.java:107:16:111:6 | parameter this [Return] : new Consumer>(...) { ... } [List out1, ] : String | semmle.label | parameter this [Return] : new Consumer>(...) { ... } [List out1, ] : String | | B.java:107:16:111:6 | parameter this [Return] : new Consumer>(...) { ... } [List out2, ] : String | semmle.label | parameter this [Return] : new Consumer>(...) { ... } [List out2, ] : String | -| B.java:107:16:111:6 | parameter this [Return] : new Consumer>(...) { ... } [List out2, ] : String | semmle.label | parameter this [Return] : new Consumer>(...) { ... } [List out2, ] : String | | B.java:107:21:107:21 | l : ArrayList [] : String | semmle.label | l : ArrayList [] : String | | B.java:107:31:107:31 | x : String | semmle.label | x : String | | B.java:107:31:111:5 | ...->... : new Consumer(...) { ... } [String s] : String | semmle.label | ...->... : new Consumer(...) { ... } [String s] : String | | B.java:107:31:111:5 | ...->... [post update] : new Consumer(...) { ... } [List out1, ] : String | semmle.label | ...->... [post update] : new Consumer(...) { ... } [List out1, ] : String | | B.java:107:31:111:5 | ...->... [post update] : new Consumer(...) { ... } [List out2, ] : String | semmle.label | ...->... [post update] : new Consumer(...) { ... } [List out2, ] : String | -| B.java:107:31:111:5 | ...->... [post update] : new Consumer(...) { ... } [List out2, ] : String | semmle.label | ...->... [post update] : new Consumer(...) { ... } [List out2, ] : String | | B.java:107:31:111:5 | List out1 : ArrayList [] : String | semmle.label | List out1 : ArrayList [] : String | | B.java:107:31:111:5 | List out2 : ArrayList [] : String | semmle.label | List out2 : ArrayList [] : String | -| B.java:107:31:111:5 | List out2 : ArrayList [] : String | semmle.label | List out2 : ArrayList [] : String | | B.java:107:31:111:5 | String s : String | semmle.label | String s : String | | B.java:107:31:111:5 | parameter this : new Consumer(...) { ... } [String s] : String | semmle.label | parameter this : new Consumer(...) { ... } [String s] : String | | B.java:107:31:111:5 | parameter this [Return] : new Consumer(...) { ... } [List out1, ] : String | semmle.label | parameter this [Return] : new Consumer(...) { ... } [List out1, ] : String | | B.java:107:31:111:5 | parameter this [Return] : new Consumer(...) { ... } [List out2, ] : String | semmle.label | parameter this [Return] : new Consumer(...) { ... } [List out2, ] : String | | B.java:107:31:111:5 | this : new Consumer>(...) { ... } [List out1, ] : String | semmle.label | this : new Consumer>(...) { ... } [List out1, ] : String | | B.java:107:31:111:5 | this : new Consumer>(...) { ... } [List out2, ] : String | semmle.label | this : new Consumer>(...) { ... } [List out2, ] : String | -| B.java:107:31:111:5 | this : new Consumer>(...) { ... } [List out2, ] : String | semmle.label | this : new Consumer>(...) { ... } [List out2, ] : String | | B.java:107:31:111:5 | this : new Consumer>(...) { ... } [String s] : String | semmle.label | this : new Consumer>(...) { ... } [String s] : String | | B.java:108:12:108:12 | s | semmle.label | s | | B.java:108:12:108:12 | this : new Consumer(...) { ... } [String s] : String | semmle.label | this : new Consumer(...) { ... } [String s] : String | @@ -527,10 +520,8 @@ subpaths | B.java:46:13:46:14 | m1 : HashMap [] : String | B.java:38:23:38:45 | inp : HashMap [] : String | B.java:38:48:38:70 | out [Return] : HashMap [] : String | B.java:46:17:46:18 | m2 [post update] : HashMap [] : String | | B.java:107:5:107:6 | l2 : ArrayList [, ] : String | B.java:107:16:107:16 | l : ArrayList [] : String | B.java:107:16:111:6 | parameter this [Return] : new Consumer>(...) { ... } [List out1, ] : String | B.java:107:16:111:6 | ...->... [post update] : new Consumer>(...) { ... } [List out1, ] : String | | B.java:107:16:111:6 | ...->... : new Consumer>(...) { ... } [String s] : String | B.java:107:16:111:6 | parameter this : new Consumer>(...) { ... } [String s] : String | B.java:107:16:111:6 | parameter this [Return] : new Consumer>(...) { ... } [List out2, ] : String | B.java:107:16:111:6 | ...->... [post update] : new Consumer>(...) { ... } [List out2, ] : String | -| B.java:107:16:111:6 | ...->... : new Consumer>(...) { ... } [String s] : String | B.java:107:16:111:6 | parameter this : new Consumer>(...) { ... } [String s] : String | B.java:107:16:111:6 | parameter this [Return] : new Consumer>(...) { ... } [List out2, ] : String | B.java:107:16:111:6 | ...->... [post update] : new Consumer>(...) { ... } [List out2, ] : String | | B.java:107:21:107:21 | l : ArrayList [] : String | B.java:107:31:107:31 | x : String | B.java:107:31:111:5 | parameter this [Return] : new Consumer(...) { ... } [List out1, ] : String | B.java:107:31:111:5 | ...->... [post update] : new Consumer(...) { ... } [List out1, ] : String | | B.java:107:31:111:5 | ...->... : new Consumer(...) { ... } [String s] : String | B.java:107:31:111:5 | parameter this : new Consumer(...) { ... } [String s] : String | B.java:107:31:111:5 | parameter this [Return] : new Consumer(...) { ... } [List out2, ] : String | B.java:107:31:111:5 | ...->... [post update] : new Consumer(...) { ... } [List out2, ] : String | -| B.java:107:31:111:5 | ...->... : new Consumer(...) { ... } [String s] : String | B.java:107:31:111:5 | parameter this : new Consumer(...) { ... } [String s] : String | B.java:107:31:111:5 | parameter this [Return] : new Consumer(...) { ... } [List out2, ] : String | B.java:107:31:111:5 | ...->... [post update] : new Consumer(...) { ... } [List out2, ] : String | | B.java:137:5:137:5 | r : new TwoRuns(...) { ... } [List l1, ] : String | B.java:130:19:130:22 | parameter this : new TwoRuns(...) { ... } [List l1, ] : String | B.java:130:19:130:22 | parameter this [Return] : new TwoRuns(...) { ... } [List l2, ] : String | B.java:137:5:137:5 | r [post update] : new TwoRuns(...) { ... } [List l2, ] : String | | B.java:148:17:148:29 | new MyLocal(...) [pre constructor] : MyLocal [String s] : String | B.java:145:7:145:13 | parameter this : MyLocal [String s] : String | B.java:145:7:145:13 | parameter this [Return] : MyLocal [f] : String | B.java:148:17:148:29 | new MyLocal(...) : MyLocal [f] : String | | B.java:149:10:149:10 | m : MyLocal [f] : String | B.java:146:14:146:17 | parameter this : MyLocal [f] : String | B.java:146:30:146:35 | this.f : String | B.java:149:10:149:17 | getF(...) | diff --git a/java/ql/test/library-tests/frameworks/apache-collections/test.expected b/java/ql/test/library-tests/frameworks/apache-collections/test.expected index 76ef7c2b4cf..96a0a4853c3 100644 --- a/java/ql/test/library-tests/frameworks/apache-collections/test.expected +++ b/java/ql/test/library-tests/frameworks/apache-collections/test.expected @@ -1663,7 +1663,6 @@ edges | Test.java:257:91:257:97 | element : String | Test.java:257:73:257:98 | of(...) : FluentIterable [] : String | provenance | MaD:469 | | Test.java:258:49:258:57 | element : String | Test.java:258:110:258:116 | element : String | provenance | | | Test.java:258:104:258:104 | x [post update] : HashMultiSet [] : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | provenance | | -| Test.java:258:104:258:104 | x [post update] : HashMultiSet [] : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | provenance | | | Test.java:258:110:258:116 | element : String | Test.java:258:104:258:104 | x [post update] : HashMultiSet [] : String | provenance | MaD:2 | | Test.java:258:110:258:116 | element : String | Test.java:258:104:258:104 | x [post update] : HashMultiSet [] : String | provenance | MaD:673 | | Test.java:259:49:259:57 | element : String | Test.java:259:90:259:96 | element : String | provenance | | @@ -1683,17 +1682,13 @@ edges | Test.java:261:77:261:83 | element : String | Test.java:261:61:261:93 | new MultiKey(...) : MultiKey [] : String | provenance | MaD:215 | | Test.java:262:52:262:60 | element : String | Test.java:262:106:262:112 | element : String | provenance | | | Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | provenance | MaD:674 | -| Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | provenance | MaD:674 | | Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | provenance | | -| Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | provenance | | -| Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | Test.java:262:72:262:125 | getElement(...) : Entry [] : String | provenance | MaD:1 | | Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | Test.java:262:72:262:125 | getElement(...) : Entry [] : String | provenance | MaD:1 | | Test.java:262:106:262:112 | element : String | Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | provenance | MaD:2 | | Test.java:262:106:262:112 | element : String | Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | provenance | MaD:673 | | Test.java:262:106:262:112 | element : String | Test.java:263:41:263:49 | element : String | provenance | | | Test.java:263:41:263:49 | element : String | Test.java:263:102:263:108 | element : String | provenance | | | Test.java:263:96:263:96 | h [post update] : HashMultiSet [] : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | provenance | | -| Test.java:263:96:263:96 | h [post update] : HashMultiSet [] : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | provenance | | | Test.java:263:102:263:108 | element : String | Test.java:263:96:263:96 | h [post update] : HashMultiSet [] : String | provenance | MaD:2 | | Test.java:263:102:263:108 | element : String | Test.java:263:96:263:96 | h [post update] : HashMultiSet [] : String | provenance | MaD:673 | | Test.java:264:80:264:88 | element : String | Test.java:264:177:264:183 | element : String | provenance | | @@ -1708,8 +1703,6 @@ edges | Test.java:267:39:267:47 | element : ListIterator [] : String | Test.java:267:90:267:96 | element : ListIterator [] : String | provenance | | | Test.java:267:39:267:47 | element : String | Test.java:267:90:267:96 | element : String | provenance | | | Test.java:267:84:267:84 | b [post update] : TreeBag [, ] : String | Test.java:267:107:267:107 | b : TreeBag [, ] : String | provenance | | -| Test.java:267:84:267:84 | b [post update] : TreeBag [, ] : String | Test.java:267:107:267:107 | b : TreeBag [, ] : String | provenance | | -| Test.java:267:84:267:84 | b [post update] : TreeBag [] : String | Test.java:267:107:267:107 | b : TreeBag [] : String | provenance | | | Test.java:267:84:267:84 | b [post update] : TreeBag [] : String | Test.java:267:107:267:107 | b : TreeBag [] : String | provenance | | | Test.java:267:90:267:96 | element : ListIterator [] : String | Test.java:267:84:267:84 | b [post update] : TreeBag [, ] : String | provenance | MaD:2 | | Test.java:267:90:267:96 | element : ListIterator [] : String | Test.java:267:84:267:84 | b [post update] : TreeBag [, ] : String | provenance | MaD:395 | @@ -1734,7 +1727,6 @@ edges | Test.java:274:114:274:116 | key : String | Test.java:274:107:274:123 | of(...) : Map [] : String | provenance | MaD:11 | | Test.java:275:49:275:53 | key : String | Test.java:275:107:275:109 | key : String | provenance | | | Test.java:275:101:275:101 | m [post update] : HashedMap [] : String | Test.java:275:125:275:125 | m : HashedMap [] : String | provenance | | -| Test.java:275:101:275:101 | m [post update] : HashedMap [] : String | Test.java:275:125:275:125 | m : HashedMap [] : String | provenance | | | Test.java:275:107:275:109 | key : String | Test.java:275:101:275:101 | m [post update] : HashedMap [] : String | provenance | MaD:14 | | Test.java:275:107:275:109 | key : String | Test.java:275:101:275:101 | m [post update] : HashedMap [] : String | provenance | MaD:705 | | Test.java:276:49:276:53 | key : String | Test.java:276:96:276:98 | key : String | provenance | | @@ -1748,8 +1740,6 @@ edges | Test.java:277:122:277:124 | key : String | Test.java:277:115:277:131 | of(...) : Map [] : String | provenance | MaD:11 | | Test.java:279:47:279:51 | key : String | Test.java:279:113:279:115 | key : String | provenance | | | Test.java:279:107:279:107 | m [post update] : MultiValueMap [] : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | provenance | | -| Test.java:279:107:279:107 | m [post update] : MultiValueMap [] : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | provenance | | -| Test.java:279:107:279:107 | m [post update] : MultiValueMap [] : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | provenance | | | Test.java:279:113:279:115 | key : String | Test.java:279:107:279:107 | m [post update] : MultiValueMap [] : String | provenance | MaD:14 | | Test.java:279:113:279:115 | key : String | Test.java:279:107:279:107 | m [post update] : MultiValueMap [] : String | provenance | MaD:661 | | Test.java:279:113:279:115 | key : String | Test.java:279:107:279:107 | m [post update] : MultiValueMap [] : String | provenance | MaD:705 | @@ -1766,11 +1756,9 @@ edges | Test.java:282:102:282:104 | key : String | Test.java:7043:22:7043:26 | key : String | provenance | | | Test.java:283:53:283:57 | key : String | Test.java:283:111:283:113 | key : String | provenance | | | Test.java:283:105:283:105 | m [post update] : LinkedMap [] : String | Test.java:283:129:283:129 | m : LinkedMap [] : String | provenance | | -| Test.java:283:105:283:105 | m [post update] : LinkedMap [] : String | Test.java:283:129:283:129 | m : LinkedMap [] : String | provenance | | | Test.java:283:111:283:113 | key : String | Test.java:283:105:283:105 | m [post update] : LinkedMap [] : String | provenance | MaD:14 | | Test.java:283:111:283:113 | key : String | Test.java:283:105:283:105 | m [post update] : LinkedMap [] : String | provenance | MaD:705 | | Test.java:283:129:283:129 | m : LinkedMap [] : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | provenance | MaD:487 | -| Test.java:283:129:283:129 | m : LinkedMap [] : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | provenance | MaD:487 | | Test.java:285:47:285:51 | key : String | Test.java:285:103:285:105 | key : String | provenance | | | Test.java:285:97:285:97 | m [post update] : TreeMap [] : String | Test.java:285:121:285:121 | m : TreeMap [] : String | provenance | | | Test.java:285:103:285:105 | key : String | Test.java:285:97:285:97 | m [post update] : TreeMap [] : String | provenance | MaD:14 | @@ -1778,12 +1766,10 @@ edges | Test.java:286:113:286:115 | key : String | Test.java:286:62:286:116 | new TiedMapEntry(...) : TiedMapEntry [] : String | provenance | MaD:234 | | Test.java:287:75:287:79 | key : String | Test.java:287:137:287:139 | key : String | provenance | | | Test.java:287:131:287:131 | m [post update] : TreeBidiMap [] : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | provenance | | -| Test.java:287:131:287:131 | m [post update] : TreeBidiMap [] : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | provenance | | | Test.java:287:137:287:139 | key : String | Test.java:287:131:287:131 | m [post update] : TreeBidiMap [] : String | provenance | MaD:14 | | Test.java:287:137:287:139 | key : String | Test.java:287:131:287:131 | m [post update] : TreeBidiMap [] : String | provenance | MaD:705 | | Test.java:288:49:288:58 | key : String | Test.java:288:116:288:118 | key : String | provenance | | | Test.java:288:110:288:110 | m [post update] : PatriciaTrie [] : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | provenance | | -| Test.java:288:110:288:110 | m [post update] : PatriciaTrie [] : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | provenance | | | Test.java:288:116:288:118 | key : String | Test.java:288:110:288:110 | m [post update] : PatriciaTrie [] : String | provenance | MaD:14 | | Test.java:288:116:288:118 | key : String | Test.java:288:110:288:110 | m [post update] : PatriciaTrie [] : String | provenance | MaD:705 | | Test.java:290:60:290:66 | value : String | Test.java:290:151:290:155 | value : String | provenance | | @@ -1796,7 +1782,6 @@ edges | Test.java:292:124:292:128 | value : String | Test.java:292:111:292:129 | of(...) : Map [] : String | provenance | MaD:12 | | Test.java:293:51:293:57 | value : String | Test.java:293:116:293:120 | value : String | provenance | | | Test.java:293:105:293:105 | m [post update] : HashedMap [] : String | Test.java:293:131:293:131 | m : HashedMap [] : String | provenance | | -| Test.java:293:105:293:105 | m [post update] : HashedMap [] : String | Test.java:293:131:293:131 | m : HashedMap [] : String | provenance | | | Test.java:293:116:293:120 | value : String | Test.java:293:105:293:105 | m [post update] : HashedMap [] : String | provenance | MaD:15 | | Test.java:293:116:293:120 | value : String | Test.java:293:105:293:105 | m [post update] : HashedMap [] : String | provenance | MaD:706 | | Test.java:294:58:294:64 | value : String | Test.java:294:145:294:149 | value : String | provenance | | @@ -1817,7 +1802,6 @@ edges | Test.java:298:49:298:55 | value : String | Test.java:298:122:298:126 | value : String | provenance | | | Test.java:298:111:298:111 | m [post update] : MultiValueMap [, ] : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | provenance | | | Test.java:298:111:298:111 | m [post update] : MultiValueMap [] : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | provenance | | -| Test.java:298:111:298:111 | m [post update] : MultiValueMap [] : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | provenance | | | Test.java:298:122:298:126 | value : String | Test.java:298:111:298:111 | m [post update] : MultiValueMap [, ] : String | provenance | MaD:662 | | Test.java:298:122:298:126 | value : String | Test.java:298:111:298:111 | m [post update] : MultiValueMap [] : String | provenance | MaD:15 | | Test.java:298:122:298:126 | value : String | Test.java:298:111:298:111 | m [post update] : MultiValueMap [] : String | provenance | MaD:706 | @@ -1834,11 +1818,9 @@ edges | Test.java:301:145:301:149 | value : String | Test.java:301:125:301:150 | newMAMEWithMapValue(...) : MyAbstractMapEntry [] : String | provenance | MaD:196 | | Test.java:302:54:302:60 | value : String | Test.java:302:119:302:123 | value : String | provenance | | | Test.java:302:108:302:108 | m [post update] : LinkedMap [] : String | Test.java:302:134:302:134 | m : LinkedMap [] : String | provenance | | -| Test.java:302:108:302:108 | m [post update] : LinkedMap [] : String | Test.java:302:134:302:134 | m : LinkedMap [] : String | provenance | | | Test.java:302:119:302:123 | value : String | Test.java:302:108:302:108 | m [post update] : LinkedMap [] : String | provenance | MaD:15 | | Test.java:302:119:302:123 | value : String | Test.java:302:108:302:108 | m [post update] : LinkedMap [] : String | provenance | MaD:706 | | Test.java:302:134:302:134 | m : LinkedMap [] : String | Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | provenance | MaD:488 | -| Test.java:302:134:302:134 | m : LinkedMap [] : String | Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | provenance | MaD:488 | | Test.java:304:49:304:55 | value : Map | Test.java:304:112:304:116 | value : Map | provenance | | | Test.java:304:49:304:55 | value : String | Test.java:304:112:304:116 | value : String | provenance | | | Test.java:304:101:304:101 | m [post update] : TreeMap [] : Map | Test.java:304:127:304:127 | m : TreeMap [] : Map | provenance | | @@ -1851,12 +1833,10 @@ edges | Test.java:305:116:305:120 | value : String | Test.java:305:93:305:121 | newTreeMapWithMapValue(...) : TreeMap [] : String | provenance | MaD:15 | | Test.java:306:77:306:83 | value : String | Test.java:306:146:306:150 | value : String | provenance | | | Test.java:306:135:306:135 | m [post update] : TreeBidiMap [] : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | provenance | | -| Test.java:306:135:306:135 | m [post update] : TreeBidiMap [] : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | provenance | | | Test.java:306:146:306:150 | value : String | Test.java:306:135:306:135 | m [post update] : TreeBidiMap [] : String | provenance | MaD:15 | | Test.java:306:146:306:150 | value : String | Test.java:306:135:306:135 | m [post update] : TreeBidiMap [] : String | provenance | MaD:706 | | Test.java:307:50:307:56 | value : String | Test.java:307:114:307:118 | value : String | provenance | | | Test.java:307:103:307:103 | m [post update] : PatriciaTrie [] : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | provenance | | -| Test.java:307:103:307:103 | m [post update] : PatriciaTrie [] : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | provenance | | | Test.java:307:114:307:118 | value : String | Test.java:307:103:307:103 | m [post update] : PatriciaTrie [] : String | provenance | MaD:15 | | Test.java:307:114:307:118 | value : String | Test.java:307:103:307:103 | m [post update] : PatriciaTrie [] : String | provenance | MaD:706 | | Test.java:308:56:308:62 | value : String | Test.java:308:114:308:118 | value : String | provenance | | @@ -10555,7 +10535,6 @@ nodes | Test.java:239:18:239:57 | container : MyAbstractMapEntryDecorator [] : String | semmle.label | container : MyAbstractMapEntryDecorator [] : String | | Test.java:239:69:239:77 | container : MyAbstractMapEntryDecorator [] : String | semmle.label | container : MyAbstractMapEntryDecorator [] : String | | Test.java:239:69:239:86 | getKey(...) : String | semmle.label | getKey(...) : String | -| Test.java:239:69:239:86 | getKey(...) : String | semmle.label | getKey(...) : String | | Test.java:240:18:240:46 | container : ArrayListValuedHashMap [] : String | semmle.label | container : ArrayListValuedHashMap [] : String | | Test.java:240:18:240:46 | container : HashSetValuedHashMap [] : String | semmle.label | container : HashSetValuedHashMap [] : String | | Test.java:240:18:240:46 | container : MultiValuedMap [] : Object | semmle.label | container : MultiValuedMap [] : Object | @@ -10641,7 +10620,6 @@ nodes | Test.java:245:20:245:59 | container : MyAbstractMapEntryDecorator [] : String | semmle.label | container : MyAbstractMapEntryDecorator [] : String | | Test.java:245:71:245:79 | container : MyAbstractMapEntryDecorator [] : String | semmle.label | container : MyAbstractMapEntryDecorator [] : String | | Test.java:245:71:245:90 | getValue(...) : String | semmle.label | getValue(...) : String | -| Test.java:245:71:245:90 | getValue(...) : String | semmle.label | getValue(...) : String | | Test.java:246:20:246:47 | mapIterator : EntrySetToMapIteratorAdapter [] : String | semmle.label | mapIterator : EntrySetToMapIteratorAdapter [] : String | | Test.java:246:20:246:47 | mapIterator : MapIterator [] : Object | semmle.label | mapIterator : MapIterator [] : Object | | Test.java:246:20:246:47 | mapIterator : MapIterator [] : String | semmle.label | mapIterator : MapIterator [] : String | @@ -10732,10 +10710,8 @@ nodes | Test.java:257:91:257:97 | element : String | semmle.label | element : String | | Test.java:258:49:258:57 | element : String | semmle.label | element : String | | Test.java:258:104:258:104 | x [post update] : HashMultiSet [] : String | semmle.label | x [post update] : HashMultiSet [] : String | -| Test.java:258:104:258:104 | x [post update] : HashMultiSet [] : String | semmle.label | x [post update] : HashMultiSet [] : String | | Test.java:258:110:258:116 | element : String | semmle.label | element : String | | Test.java:258:127:258:127 | x : HashMultiSet [] : String | semmle.label | x : HashMultiSet [] : String | -| Test.java:258:127:258:127 | x : HashMultiSet [] : String | semmle.label | x : HashMultiSet [] : String | | Test.java:259:49:259:57 | element : String | semmle.label | element : String | | Test.java:259:69:259:97 | newVectorWithElement(...) : Vector [] : String | semmle.label | newVectorWithElement(...) : Vector [] : String | | Test.java:259:69:259:112 | listIterator(...) : ListIterator [] : String | semmle.label | listIterator(...) : ListIterator [] : String | @@ -10757,18 +10733,13 @@ nodes | Test.java:261:77:261:83 | element : String | semmle.label | element : String | | Test.java:262:52:262:60 | element : String | semmle.label | element : String | | Test.java:262:72:262:125 | getElement(...) : Entry [] : String | semmle.label | getElement(...) : Entry [] : String | -| Test.java:262:72:262:125 | getElement(...) : Entry [] : String | semmle.label | getElement(...) : Entry [] : String | | Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | semmle.label | newMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | semmle.label | newMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | semmle.label | entrySet(...) : Set [, ] : String | | Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | semmle.label | entrySet(...) : Set [, ] : String | | Test.java:262:106:262:112 | element : String | semmle.label | element : String | | Test.java:263:41:263:49 | element : String | semmle.label | element : String | | Test.java:263:96:263:96 | h [post update] : HashMultiSet [] : String | semmle.label | h [post update] : HashMultiSet [] : String | -| Test.java:263:96:263:96 | h [post update] : HashMultiSet [] : String | semmle.label | h [post update] : HashMultiSet [] : String | | Test.java:263:102:263:108 | element : String | semmle.label | element : String | | Test.java:263:119:263:119 | h : HashMultiSet [] : String | semmle.label | h : HashMultiSet [] : String | -| Test.java:263:119:263:119 | h : HashMultiSet [] : String | semmle.label | h : HashMultiSet [] : String | | Test.java:264:80:264:88 | element : String | semmle.label | element : String | | Test.java:264:171:264:171 | x [post update] : Builder [] : String | semmle.label | x [post update] : Builder [] : String | | Test.java:264:177:264:183 | element : String | semmle.label | element : String | @@ -10784,14 +10755,10 @@ nodes | Test.java:267:39:267:47 | element : ListIterator [] : String | semmle.label | element : ListIterator [] : String | | Test.java:267:39:267:47 | element : String | semmle.label | element : String | | Test.java:267:84:267:84 | b [post update] : TreeBag [, ] : String | semmle.label | b [post update] : TreeBag [, ] : String | -| Test.java:267:84:267:84 | b [post update] : TreeBag [, ] : String | semmle.label | b [post update] : TreeBag [, ] : String | -| Test.java:267:84:267:84 | b [post update] : TreeBag [] : String | semmle.label | b [post update] : TreeBag [] : String | | Test.java:267:84:267:84 | b [post update] : TreeBag [] : String | semmle.label | b [post update] : TreeBag [] : String | | Test.java:267:90:267:96 | element : ListIterator [] : String | semmle.label | element : ListIterator [] : String | | Test.java:267:90:267:96 | element : String | semmle.label | element : String | | Test.java:267:107:267:107 | b : TreeBag [, ] : String | semmle.label | b : TreeBag [, ] : String | -| Test.java:267:107:267:107 | b : TreeBag [, ] : String | semmle.label | b : TreeBag [, ] : String | -| Test.java:267:107:267:107 | b : TreeBag [] : String | semmle.label | b : TreeBag [] : String | | Test.java:267:107:267:107 | b : TreeBag [] : String | semmle.label | b : TreeBag [] : String | | Test.java:268:39:268:47 | element : String | semmle.label | element : String | | Test.java:268:84:268:84 | h [post update] : TreeSet [] : String | semmle.label | h [post update] : TreeSet [] : String | @@ -10818,10 +10785,8 @@ nodes | Test.java:274:114:274:116 | key : String | semmle.label | key : String | | Test.java:275:49:275:53 | key : String | semmle.label | key : String | | Test.java:275:101:275:101 | m [post update] : HashedMap [] : String | semmle.label | m [post update] : HashedMap [] : String | -| Test.java:275:101:275:101 | m [post update] : HashedMap [] : String | semmle.label | m [post update] : HashedMap [] : String | | Test.java:275:107:275:109 | key : String | semmle.label | key : String | | Test.java:275:125:275:125 | m : HashedMap [] : String | semmle.label | m : HashedMap [] : String | -| Test.java:275:125:275:125 | m : HashedMap [] : String | semmle.label | m : HashedMap [] : String | | Test.java:276:49:276:53 | key : String | semmle.label | key : String | | Test.java:276:65:276:106 | new LinkedMap(...) : LinkedMap [] : String | semmle.label | new LinkedMap(...) : LinkedMap [] : String | | Test.java:276:89:276:105 | of(...) : Map [] : String | semmle.label | of(...) : Map [] : String | @@ -10836,12 +10801,8 @@ nodes | Test.java:277:122:277:124 | key : String | semmle.label | key : String | | Test.java:279:47:279:51 | key : String | semmle.label | key : String | | Test.java:279:107:279:107 | m [post update] : MultiValueMap [] : String | semmle.label | m [post update] : MultiValueMap [] : String | -| Test.java:279:107:279:107 | m [post update] : MultiValueMap [] : String | semmle.label | m [post update] : MultiValueMap [] : String | -| Test.java:279:107:279:107 | m [post update] : MultiValueMap [] : String | semmle.label | m [post update] : MultiValueMap [] : String | | Test.java:279:113:279:115 | key : String | semmle.label | key : String | | Test.java:279:131:279:131 | m : MultiValueMap [] : String | semmle.label | m : MultiValueMap [] : String | -| Test.java:279:131:279:131 | m : MultiValueMap [] : String | semmle.label | m : MultiValueMap [] : String | -| Test.java:279:131:279:131 | m : MultiValueMap [] : String | semmle.label | m : MultiValueMap [] : String | | Test.java:280:53:280:57 | key : String | semmle.label | key : String | | Test.java:280:69:280:110 | new MyAbstractMapEntry(...) : MyAbstractMapEntry [] : String | semmle.label | new MyAbstractMapEntry(...) : MyAbstractMapEntry [] : String | | Test.java:280:102:280:104 | key : String | semmle.label | key : String | @@ -10854,11 +10815,8 @@ nodes | Test.java:282:102:282:104 | key : String | semmle.label | key : String | | Test.java:283:53:283:57 | key : String | semmle.label | key : String | | Test.java:283:105:283:105 | m [post update] : LinkedMap [] : String | semmle.label | m [post update] : LinkedMap [] : String | -| Test.java:283:105:283:105 | m [post update] : LinkedMap [] : String | semmle.label | m [post update] : LinkedMap [] : String | | Test.java:283:111:283:113 | key : String | semmle.label | key : String | | Test.java:283:129:283:129 | m : LinkedMap [] : String | semmle.label | m : LinkedMap [] : String | -| Test.java:283:129:283:129 | m : LinkedMap [] : String | semmle.label | m : LinkedMap [] : String | -| Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | semmle.label | mapIterator(...) : OrderedMapIterator [] : String | | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | semmle.label | mapIterator(...) : OrderedMapIterator [] : String | | Test.java:285:47:285:51 | key : String | semmle.label | key : String | | Test.java:285:97:285:97 | m [post update] : TreeMap [] : String | semmle.label | m [post update] : TreeMap [] : String | @@ -10869,16 +10827,12 @@ nodes | Test.java:286:113:286:115 | key : String | semmle.label | key : String | | Test.java:287:75:287:79 | key : String | semmle.label | key : String | | Test.java:287:131:287:131 | m [post update] : TreeBidiMap [] : String | semmle.label | m [post update] : TreeBidiMap [] : String | -| Test.java:287:131:287:131 | m [post update] : TreeBidiMap [] : String | semmle.label | m [post update] : TreeBidiMap [] : String | | Test.java:287:137:287:139 | key : String | semmle.label | key : String | | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | semmle.label | m : TreeBidiMap [] : String | -| Test.java:287:155:287:155 | m : TreeBidiMap [] : String | semmle.label | m : TreeBidiMap [] : String | | Test.java:288:49:288:58 | key : String | semmle.label | key : String | | Test.java:288:110:288:110 | m [post update] : PatriciaTrie [] : String | semmle.label | m [post update] : PatriciaTrie [] : String | -| Test.java:288:110:288:110 | m [post update] : PatriciaTrie [] : String | semmle.label | m [post update] : PatriciaTrie [] : String | | Test.java:288:116:288:118 | key : String | semmle.label | key : String | | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | semmle.label | m : PatriciaTrie [] : String | -| Test.java:288:134:288:134 | m : PatriciaTrie [] : String | semmle.label | m : PatriciaTrie [] : String | | Test.java:290:60:290:66 | value : String | semmle.label | value : String | | Test.java:290:140:290:140 | m [post update] : ArrayListValuedHashMap [, ] : String | semmle.label | m [post update] : ArrayListValuedHashMap [, ] : String | | Test.java:290:151:290:155 | value : String | semmle.label | value : String | @@ -10892,10 +10846,8 @@ nodes | Test.java:292:124:292:128 | value : String | semmle.label | value : String | | Test.java:293:51:293:57 | value : String | semmle.label | value : String | | Test.java:293:105:293:105 | m [post update] : HashedMap [] : String | semmle.label | m [post update] : HashedMap [] : String | -| Test.java:293:105:293:105 | m [post update] : HashedMap [] : String | semmle.label | m [post update] : HashedMap [] : String | | Test.java:293:116:293:120 | value : String | semmle.label | value : String | | Test.java:293:131:293:131 | m : HashedMap [] : String | semmle.label | m : HashedMap [] : String | -| Test.java:293:131:293:131 | m : HashedMap [] : String | semmle.label | m : HashedMap [] : String | | Test.java:294:58:294:64 | value : String | semmle.label | value : String | | Test.java:294:134:294:134 | m [post update] : HashSetValuedHashMap [, ] : String | semmle.label | m [post update] : HashSetValuedHashMap [, ] : String | | Test.java:294:145:294:149 | value : String | semmle.label | value : String | @@ -10919,11 +10871,9 @@ nodes | Test.java:298:49:298:55 | value : String | semmle.label | value : String | | Test.java:298:111:298:111 | m [post update] : MultiValueMap [, ] : String | semmle.label | m [post update] : MultiValueMap [, ] : String | | Test.java:298:111:298:111 | m [post update] : MultiValueMap [] : String | semmle.label | m [post update] : MultiValueMap [] : String | -| Test.java:298:111:298:111 | m [post update] : MultiValueMap [] : String | semmle.label | m [post update] : MultiValueMap [] : String | | Test.java:298:122:298:126 | value : String | semmle.label | value : String | | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | semmle.label | m : MultiValueMap [, ] : String | | Test.java:298:137:298:137 | m : MultiValueMap [] : String | semmle.label | m : MultiValueMap [] : String | -| Test.java:298:137:298:137 | m : MultiValueMap [] : String | semmle.label | m : MultiValueMap [] : String | | Test.java:299:55:299:61 | value : String | semmle.label | value : String | | Test.java:299:73:299:116 | new MyAbstractKeyValue(...) : MyAbstractKeyValue [] : String | semmle.label | new MyAbstractKeyValue(...) : MyAbstractKeyValue [] : String | | Test.java:299:111:299:115 | value : String | semmle.label | value : String | @@ -10936,11 +10886,8 @@ nodes | Test.java:301:145:301:149 | value : String | semmle.label | value : String | | Test.java:302:54:302:60 | value : String | semmle.label | value : String | | Test.java:302:108:302:108 | m [post update] : LinkedMap [] : String | semmle.label | m [post update] : LinkedMap [] : String | -| Test.java:302:108:302:108 | m [post update] : LinkedMap [] : String | semmle.label | m [post update] : LinkedMap [] : String | | Test.java:302:119:302:123 | value : String | semmle.label | value : String | | Test.java:302:134:302:134 | m : LinkedMap [] : String | semmle.label | m : LinkedMap [] : String | -| Test.java:302:134:302:134 | m : LinkedMap [] : String | semmle.label | m : LinkedMap [] : String | -| Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | semmle.label | mapIterator(...) : OrderedMapIterator [] : String | | Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | semmle.label | mapIterator(...) : OrderedMapIterator [] : String | | Test.java:304:49:304:55 | value : Map | semmle.label | value : Map | | Test.java:304:49:304:55 | value : String | semmle.label | value : String | @@ -10956,16 +10903,12 @@ nodes | Test.java:305:116:305:120 | value : String | semmle.label | value : String | | Test.java:306:77:306:83 | value : String | semmle.label | value : String | | Test.java:306:135:306:135 | m [post update] : TreeBidiMap [] : String | semmle.label | m [post update] : TreeBidiMap [] : String | -| Test.java:306:135:306:135 | m [post update] : TreeBidiMap [] : String | semmle.label | m [post update] : TreeBidiMap [] : String | | Test.java:306:146:306:150 | value : String | semmle.label | value : String | | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | semmle.label | m : TreeBidiMap [] : String | -| Test.java:306:161:306:161 | m : TreeBidiMap [] : String | semmle.label | m : TreeBidiMap [] : String | | Test.java:307:50:307:56 | value : String | semmle.label | value : String | | Test.java:307:103:307:103 | m [post update] : PatriciaTrie [] : String | semmle.label | m [post update] : PatriciaTrie [] : String | -| Test.java:307:103:307:103 | m [post update] : PatriciaTrie [] : String | semmle.label | m [post update] : PatriciaTrie [] : String | | Test.java:307:114:307:118 | value : String | semmle.label | value : String | | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | semmle.label | m : PatriciaTrie [] : String | -| Test.java:307:129:307:129 | m : PatriciaTrie [] : String | semmle.label | m : PatriciaTrie [] : String | | Test.java:308:56:308:62 | value : String | semmle.label | value : String | | Test.java:308:74:308:119 | new UnmodifiableMapEntry(...) : UnmodifiableMapEntry [] : String | semmle.label | new UnmodifiableMapEntry(...) : UnmodifiableMapEntry [] : String | | Test.java:308:114:308:118 | value : String | semmle.label | value : String | @@ -17799,10 +17742,6 @@ subpaths | Test.java:256:115:256:121 | element : String | Test.java:269:37:269:45 | element : String | Test.java:269:103:269:103 | v : Vector [] : String | Test.java:256:94:256:122 | newVectorWithElement(...) : Vector [] : String | | Test.java:259:90:259:96 | element : String | Test.java:269:37:269:45 | element : String | Test.java:269:103:269:103 | v : Vector [] : String | Test.java:259:69:259:97 | newVectorWithElement(...) : Vector [] : String | | Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:262:72:262:125 | getElement(...) : Entry [] : String | -| Test.java:262:83:262:124 | entrySet(...) : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:262:72:262:125 | getElement(...) : Entry [] : String | -| Test.java:262:106:262:112 | element : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:262:106:262:112 | element : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:262:106:262:112 | element : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:262:106:262:112 | element : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:262:83:262:113 | newMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:280:102:280:104 | key : String | Test.java:7057:22:7057:32 | key : String | Test.java:7057:3:7057:20 | parameter this [Return] : MyAbstractMapEntry [] : String | Test.java:280:69:280:110 | new MyAbstractMapEntry(...) : MyAbstractMapEntry [] : String | | Test.java:281:121:281:142 | newMAMEWithMapKey(...) : MyAbstractMapEntry [] : String | Test.java:7067:31:7067:57 | entry : MyAbstractMapEntry [] : String | Test.java:7067:3:7067:29 | parameter this [Return] : MyAbstractMapEntryDecorator [] : String | Test.java:281:79:281:143 | new MyAbstractMapEntryDecorator(...) : MyAbstractMapEntryDecorator [] : String | @@ -17843,11 +17782,9 @@ subpaths | Test.java:444:52:444:67 | (...)... : String | Test.java:280:53:280:57 | key : String | Test.java:280:69:280:110 | new MyAbstractMapEntry(...) : MyAbstractMapEntry [] : String | Test.java:444:34:444:68 | newMAMEWithMapKey(...) : MyAbstractMapEntry [] : String | | Test.java:445:42:445:43 | in : MyAbstractMapEntry [] : String | Test.java:7067:31:7067:57 | entry : MyAbstractMapEntry [] : String | Test.java:7067:3:7067:29 | parameter this [Return] : MyAbstractMapEntryDecorator [] : String | Test.java:445:10:445:44 | new MyAbstractMapEntryDecorator<>(...) : MyAbstractMapEntryDecorator [] : String | | Test.java:446:19:446:21 | out : MyAbstractMapEntryDecorator [] : String | Test.java:239:18:239:57 | container : MyAbstractMapEntryDecorator [] : String | Test.java:239:69:239:86 | getKey(...) : String | Test.java:446:9:446:22 | getMapKey(...) | -| Test.java:446:19:446:21 | out : MyAbstractMapEntryDecorator [] : String | Test.java:239:18:239:57 | container : MyAbstractMapEntryDecorator [] : String | Test.java:239:69:239:86 | getKey(...) : String | Test.java:446:9:446:22 | getMapKey(...) | | Test.java:451:54:451:69 | (...)... : String | Test.java:300:55:300:61 | value : String | Test.java:300:73:300:116 | new MyAbstractMapEntry(...) : MyAbstractMapEntry [] : String | Test.java:451:34:451:70 | newMAMEWithMapValue(...) : MyAbstractMapEntry [] : String | | Test.java:452:42:452:43 | in : MyAbstractMapEntry [] : String | Test.java:7067:31:7067:57 | entry : MyAbstractMapEntry [] : String | Test.java:7067:3:7067:29 | parameter this [Return] : MyAbstractMapEntryDecorator [] : String | Test.java:452:10:452:44 | new MyAbstractMapEntryDecorator<>(...) : MyAbstractMapEntryDecorator [] : String | | Test.java:453:21:453:23 | out : MyAbstractMapEntryDecorator [] : String | Test.java:245:20:245:59 | container : MyAbstractMapEntryDecorator [] : String | Test.java:245:71:245:90 | getValue(...) : String | Test.java:453:9:453:24 | getMapValue(...) | -| Test.java:453:21:453:23 | out : MyAbstractMapEntryDecorator [] : String | Test.java:245:20:245:59 | container : MyAbstractMapEntryDecorator [] : String | Test.java:245:71:245:90 | getValue(...) : String | Test.java:453:9:453:24 | getMapValue(...) | | Test.java:458:56:458:71 | (...)... : String | Test.java:281:63:281:67 | key : String | Test.java:281:79:281:143 | new MyAbstractMapEntryDecorator(...) : MyAbstractMapEntryDecorator [] : String | Test.java:458:37:458:72 | newMAMEDWithMapKey(...) : MyAbstractMapEntryDecorator [] : String | | Test.java:459:10:459:11 | in : MyAbstractMapEntryDecorator [] : String | Test.java:7071:19:7071:31 | parameter this : MyAbstractMapEntryDecorator [] : String | Test.java:7072:11:7072:29 | getMapEntry(...) : Entry [] : String | Test.java:459:10:459:27 | myGetMapEntry(...) : Entry [] : String | | Test.java:460:28:460:30 | out : Entry [] : String | Test.java:238:27:238:50 | container : Entry [] : String | Test.java:238:62:238:79 | getKey(...) : String | Test.java:460:9:460:31 | getMapKeyFromEntry(...) | @@ -18041,45 +17978,31 @@ subpaths | Test.java:1212:20:1212:22 | out : Bag [] : Object | Test.java:230:19:230:32 | it : Bag [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:1212:9:1212:23 | getElement(...) | | Test.java:1219:20:1219:22 | out : Bag [] : Object | Test.java:230:19:230:32 | it : Bag [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:1219:9:1219:23 | getElement(...) | | Test.java:1224:35:1224:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1224:13:1224:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1224:35:1224:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1224:13:1224:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1226:20:1226:22 | out : Set [] : String | Test.java:230:19:230:32 | it : Set [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1226:9:1226:23 | getElement(...) | | Test.java:1231:35:1231:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1231:13:1231:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1231:35:1231:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1231:13:1231:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1233:20:1233:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1233:9:1233:23 | getElement(...) | | Test.java:1238:35:1238:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1238:13:1238:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1238:35:1238:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1238:13:1238:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1240:20:1240:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1240:9:1240:23 | getElement(...) | | Test.java:1245:41:1245:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1245:19:1245:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1245:41:1245:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1245:19:1245:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1247:20:1247:22 | out : SortedBag [] : String | Test.java:230:19:230:32 | it : SortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1247:9:1247:23 | getElement(...) | | Test.java:1252:35:1252:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1252:13:1252:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1252:35:1252:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1252:13:1252:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1254:20:1254:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1254:9:1254:23 | getElement(...) | | Test.java:1259:41:1259:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1259:19:1259:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1259:41:1259:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1259:19:1259:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1261:20:1261:22 | out : SortedBag [] : String | Test.java:230:19:230:32 | it : SortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1261:9:1261:23 | getElement(...) | | Test.java:1266:35:1266:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1266:13:1266:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1266:35:1266:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1266:13:1266:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1268:20:1268:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1268:9:1268:23 | getElement(...) | | Test.java:1273:41:1273:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1273:19:1273:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1273:41:1273:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1273:19:1273:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1275:20:1275:22 | out : SortedBag [] : String | Test.java:230:19:230:32 | it : SortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1275:9:1275:23 | getElement(...) | | Test.java:1280:35:1280:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1280:13:1280:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1280:35:1280:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1280:13:1280:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1282:20:1282:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1282:9:1282:23 | getElement(...) | | Test.java:1287:41:1287:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1287:19:1287:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:1287:41:1287:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:1287:19:1287:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:1289:20:1289:22 | out : SortedBag [] : String | Test.java:230:19:230:32 | it : SortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1289:9:1289:23 | getElement(...) | | Test.java:1294:42:1294:57 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:1294:17:1294:58 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | -| Test.java:1294:42:1294:57 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:1294:17:1294:58 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | -| Test.java:1301:42:1301:57 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:1301:17:1301:58 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | | Test.java:1301:42:1301:57 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:1301:17:1301:58 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | | Test.java:1303:21:1303:23 | out : BidiMap [] : String | Test.java:232:20:232:31 | map : BidiMap [] : String | Test.java:232:43:232:55 | get(...) : String | Test.java:1303:9:1303:24 | getMapValue(...) | | Test.java:1308:44:1308:59 | (...)... : String | Test.java:306:77:306:83 | value : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | Test.java:1308:17:1308:60 | newTreeBidiMapWithMapValue(...) : TreeBidiMap [] : String | -| Test.java:1308:44:1308:59 | (...)... : String | Test.java:306:77:306:83 | value : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | Test.java:1308:17:1308:60 | newTreeBidiMapWithMapValue(...) : TreeBidiMap [] : String | | Test.java:1310:19:1310:21 | out : BidiMap [] : String | Test.java:228:18:228:29 | map : BidiMap [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:1310:9:1310:22 | getMapKey(...) | | Test.java:1315:42:1315:57 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:1315:17:1315:58 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | -| Test.java:1315:42:1315:57 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:1315:17:1315:58 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | | Test.java:1322:47:1322:62 | (...)... : String | Test.java:256:47:256:55 | element : String | Test.java:256:67:256:134 | new IteratorEnumeration(...) : IteratorEnumeration [] : String | Test.java:1322:21:1322:63 | newEnumerationWithElement(...) : IteratorEnumeration [] : String | | Test.java:1324:20:1324:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1324:9:1324:23 | getElement(...) | | Test.java:1329:39:1329:54 | (...)... : String | Test.java:269:37:269:45 | element : String | Test.java:269:103:269:103 | v : Vector [] : String | Test.java:1329:18:1329:55 | newVectorWithElement(...) : Vector [] : String | @@ -18230,87 +18153,58 @@ subpaths | Test.java:1908:39:1908:54 | (...)... : String | Test.java:269:37:269:45 | element : String | Test.java:269:103:269:103 | v : Vector [] : String | Test.java:1908:18:1908:55 | newVectorWithElement(...) : Vector [] : String | | Test.java:1911:20:1911:22 | out : FluentIterable [] : String | Test.java:230:19:230:32 | it : FluentIterable [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1911:9:1911:23 | getElement(...) | | Test.java:1916:40:1916:55 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:1916:23:1916:56 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:1916:40:1916:55 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:1916:23:1916:56 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:1916:40:1916:55 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:1916:23:1916:56 | newMVMWithMapKey(...) : MultiValueMap [] : String | | Test.java:1918:28:1918:42 | getElement(...) : Entry [] : String | Test.java:238:27:238:50 | container : Entry [] : String | Test.java:238:62:238:79 | getKey(...) : String | Test.java:1918:9:1918:43 | getMapKeyFromEntry(...) | | Test.java:1918:39:1918:41 | out : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:1918:28:1918:42 | getElement(...) : Entry [] : String | | Test.java:1923:39:1923:54 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:1923:13:1923:55 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | -| Test.java:1923:39:1923:54 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:1923:13:1923:55 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | | Test.java:1925:28:1925:42 | getElement(...) : Entry [] : String | Test.java:238:27:238:50 | container : Entry [] : String | Test.java:238:62:238:79 | getKey(...) : String | Test.java:1925:9:1925:43 | getMapKeyFromEntry(...) | | Test.java:1925:39:1925:41 | out : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:1925:28:1925:42 | getElement(...) : Entry [] : String | | Test.java:1930:47:1930:62 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:1930:30:1930:63 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:1930:47:1930:62 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:1930:30:1930:63 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:1930:47:1930:62 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:1930:30:1930:63 | newMVMWithMapKey(...) : MultiValueMap [] : String | | Test.java:1932:28:1932:42 | getElement(...) : Entry [] : String | Test.java:238:27:238:50 | container : Entry [] : String | Test.java:238:62:238:79 | getKey(...) : String | Test.java:1932:9:1932:43 | getMapKeyFromEntry(...) | | Test.java:1932:39:1932:41 | out : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:1932:28:1932:42 | getElement(...) : Entry [] : String | | Test.java:1937:42:1937:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1937:23:1937:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:1937:42:1937:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1937:23:1937:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:1939:30:1939:44 | getElement(...) : Entry [] : String | Test.java:244:29:244:52 | container : Entry [] : String | Test.java:244:64:244:83 | getValue(...) : String | Test.java:1939:9:1939:45 | getMapValueFromEntry(...) | | Test.java:1939:41:1939:43 | out : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:1939:30:1939:44 | getElement(...) : Entry [] : String | | Test.java:1944:41:1944:56 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:1944:13:1944:57 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | -| Test.java:1944:41:1944:56 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:1944:13:1944:57 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:1946:30:1946:44 | getElement(...) : Entry [] : String | Test.java:244:29:244:52 | container : Entry [] : String | Test.java:244:64:244:83 | getValue(...) : String | Test.java:1946:9:1946:45 | getMapValueFromEntry(...) | | Test.java:1946:41:1946:43 | out : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:1946:30:1946:44 | getElement(...) : Entry [] : String | | Test.java:1951:49:1951:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1951:30:1951:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:1951:49:1951:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1951:30:1951:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:1953:30:1953:44 | getElement(...) : Entry [] : String | Test.java:244:29:244:52 | container : Entry [] : String | Test.java:244:64:244:83 | getValue(...) : String | Test.java:1953:9:1953:45 | getMapValueFromEntry(...) | | Test.java:1953:41:1953:43 | out : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:1953:30:1953:44 | getElement(...) : Entry [] : String | | Test.java:1958:37:1958:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1958:18:1958:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:1958:37:1958:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1958:18:1958:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:1965:41:1965:56 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:1965:13:1965:57 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:1965:41:1965:56 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:1965:13:1965:57 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:1972:49:1972:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1972:30:1972:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:1972:49:1972:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1972:30:1972:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:1979:39:1979:54 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:1979:13:1979:55 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | | Test.java:1979:39:1979:54 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:1979:13:1979:55 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | | Test.java:1981:20:1981:22 | out : Set [] : String | Test.java:230:19:230:32 | it : Set [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1981:9:1981:23 | getElement(...) | | Test.java:1986:47:1986:62 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:1986:30:1986:63 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:1986:47:1986:62 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:1986:30:1986:63 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:1986:47:1986:62 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:1986:30:1986:63 | newMVMWithMapKey(...) : MultiValueMap [] : String | | Test.java:1988:20:1988:22 | out : Set [] : String | Test.java:230:19:230:32 | it : Set [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:1988:9:1988:23 | getElement(...) | | Test.java:1993:37:1993:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1993:18:1993:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:1993:37:1993:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:1993:18:1993:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:2000:41:2000:56 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:2000:13:2000:57 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:2000:41:2000:56 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:2000:13:2000:57 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:2007:49:2007:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2007:30:2007:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:2007:49:2007:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2007:30:2007:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:2014:44:2014:59 | (...)... : String | Test.java:306:77:306:83 | value : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | Test.java:2014:17:2014:60 | newTreeBidiMapWithMapValue(...) : TreeBidiMap [] : String | | Test.java:2014:44:2014:59 | (...)... : String | Test.java:306:77:306:83 | value : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | Test.java:2014:17:2014:60 | newTreeBidiMapWithMapValue(...) : TreeBidiMap [] : String | | Test.java:2016:20:2016:22 | out : Set [] : String | Test.java:230:19:230:32 | it : Set [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:2016:9:2016:23 | getElement(...) | | Test.java:2021:42:2021:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:2021:23:2021:58 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:2021:42:2021:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2021:23:2021:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:2021:42:2021:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2021:23:2021:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:2023:20:2023:22 | out : Collection [] : Object | Test.java:230:19:230:32 | it : Collection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:2023:9:2023:23 | getElement(...) | | Test.java:2023:20:2023:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:2023:9:2023:23 | getElement(...) | | Test.java:2028:37:2028:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:2028:18:2028:53 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:2028:37:2028:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2028:18:2028:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:2028:37:2028:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2028:18:2028:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:2030:20:2030:22 | out : Collection [] : Object | Test.java:230:19:230:32 | it : Collection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:2030:9:2030:23 | getElement(...) | | Test.java:2030:20:2030:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:2030:9:2030:23 | getElement(...) | | Test.java:2035:41:2035:56 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:2035:13:2035:57 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | -| Test.java:2035:41:2035:56 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:2035:13:2035:57 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:2037:20:2037:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:2037:9:2037:23 | getElement(...) | | Test.java:2042:49:2042:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2042:30:2042:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:2042:49:2042:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2042:30:2042:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:2044:20:2044:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:2044:9:2044:23 | getElement(...) | | Test.java:2049:45:2049:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:2049:20:2049:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | -| Test.java:2049:45:2049:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:2049:20:2049:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | | Test.java:2051:20:2051:22 | out : OrderedMapIterator [] : String | Test.java:231:19:231:32 | it : OrderedMapIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:2051:9:2051:23 | getElement(...) | | Test.java:2056:44:2056:59 | (...)... : String | Test.java:275:49:275:53 | key : String | Test.java:275:125:275:125 | m : HashedMap [] : String | Test.java:2056:21:2056:60 | newHashedMapWithMapKey(...) : HashedMap [] : String | -| Test.java:2056:44:2056:59 | (...)... : String | Test.java:275:49:275:53 | key : String | Test.java:275:125:275:125 | m : HashedMap [] : String | Test.java:2056:21:2056:60 | newHashedMapWithMapKey(...) : HashedMap [] : String | | Test.java:2058:20:2058:22 | out : MapIterator [] : String | Test.java:231:19:231:32 | it : MapIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:2058:9:2058:23 | getElement(...) | | Test.java:2063:46:2063:61 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:2063:29:2063:62 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:2063:46:2063:61 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:2063:29:2063:62 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:2063:46:2063:61 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:2063:29:2063:62 | newMVMWithMapKey(...) : MultiValueMap [] : String | | Test.java:2065:20:2065:22 | out : MapIterator [] : String | Test.java:231:19:231:32 | it : MapIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:2065:9:2065:23 | getElement(...) | | Test.java:2070:47:2070:62 | (...)... : String | Test.java:306:77:306:83 | value : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | Test.java:2070:20:2070:63 | newTreeBidiMapWithMapValue(...) : TreeBidiMap [] : String | -| Test.java:2070:47:2070:62 | (...)... : String | Test.java:306:77:306:83 | value : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | Test.java:2070:20:2070:63 | newTreeBidiMapWithMapValue(...) : TreeBidiMap [] : String | | Test.java:2072:21:2072:23 | out : OrderedMapIterator [] : String | Test.java:246:20:246:47 | mapIterator : OrderedMapIterator [] : String | Test.java:246:59:246:80 | getValue(...) : String | Test.java:2072:9:2072:24 | getMapValue(...) | | Test.java:2077:46:2077:61 | (...)... : String | Test.java:293:51:293:57 | value : String | Test.java:293:131:293:131 | m : HashedMap [] : String | Test.java:2077:21:2077:62 | newHashedMapWithMapValue(...) : HashedMap [] : String | -| Test.java:2077:46:2077:61 | (...)... : String | Test.java:293:51:293:57 | value : String | Test.java:293:131:293:131 | m : HashedMap [] : String | Test.java:2077:21:2077:62 | newHashedMapWithMapValue(...) : HashedMap [] : String | | Test.java:2079:21:2079:23 | out : MapIterator [] : String | Test.java:246:20:246:47 | mapIterator : MapIterator [] : String | Test.java:246:59:246:80 | getValue(...) : String | Test.java:2079:9:2079:24 | getMapValue(...) | | Test.java:2084:48:2084:63 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2084:29:2084:64 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:2084:48:2084:63 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:2084:29:2084:64 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:2086:21:2086:23 | out : MapIterator [] : String | Test.java:246:20:246:47 | mapIterator : MapIterator [] : String | Test.java:246:59:246:80 | getValue(...) : String | Test.java:2086:9:2086:24 | getMapValue(...) | | Test.java:2091:39:2091:54 | (...)... : String | Test.java:269:37:269:45 | element : String | Test.java:269:103:269:103 | v : Vector [] : String | Test.java:2091:18:2091:55 | newVectorWithElement(...) : Vector [] : String | | Test.java:2093:20:2093:22 | out : Iterable [] : String | Test.java:230:19:230:32 | it : Iterable [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:2093:9:2093:23 | getElement(...) | @@ -18473,10 +18367,8 @@ subpaths | Test.java:2721:49:2721:64 | (...)... : String | Test.java:259:49:259:57 | element : String | Test.java:259:69:259:112 | listIterator(...) : ListIterator [] : String | Test.java:2721:22:2721:65 | newListIteratorWithElement(...) : ListIterator [] : String | | Test.java:2723:20:2723:22 | out : ListIterator [] : String | Test.java:231:19:231:32 | it : ListIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:2723:9:2723:23 | getElement(...) | | Test.java:2728:39:2728:54 | (...)... : String | Test.java:283:53:283:57 | key : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:2728:21:2728:55 | newOMIWithElement(...) : OrderedMapIterator [] : String | -| Test.java:2728:39:2728:54 | (...)... : String | Test.java:283:53:283:57 | key : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:2728:21:2728:55 | newOMIWithElement(...) : OrderedMapIterator [] : String | | Test.java:2730:20:2730:22 | out : MapIterator [] : String | Test.java:231:19:231:32 | it : MapIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:2730:9:2730:23 | getElement(...) | | Test.java:2735:40:2735:55 | (...)... : String | Test.java:302:54:302:60 | value : String | Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:2735:21:2735:56 | newOMIWithMapValue(...) : OrderedMapIterator [] : String | -| Test.java:2735:40:2735:55 | (...)... : String | Test.java:302:54:302:60 | value : String | Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:2735:21:2735:56 | newOMIWithMapValue(...) : OrderedMapIterator [] : String | | Test.java:2737:21:2737:23 | out : MapIterator [] : String | Test.java:246:20:246:47 | mapIterator : MapIterator [] : String | Test.java:246:59:246:80 | getValue(...) : String | Test.java:2737:9:2737:24 | getMapValue(...) | | Test.java:2742:45:2742:60 | (...)... : String | Test.java:259:49:259:57 | element : String | Test.java:259:69:259:112 | listIterator(...) : ListIterator [] : String | Test.java:2742:18:2742:61 | newListIteratorWithElement(...) : ListIterator [] : String | | Test.java:2744:20:2744:22 | out : ZippingIterator [] : String | Test.java:231:19:231:32 | it : ZippingIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:2744:9:2744:23 | getElement(...) | @@ -18538,15 +18430,11 @@ subpaths | Test.java:2973:35:2973:50 | (...)... : String | Test.java:269:37:269:45 | element : String | Test.java:269:103:269:103 | v : Vector [] : String | Test.java:2973:14:2973:51 | newVectorWithElement(...) : Vector [] : String | | Test.java:2975:20:2975:22 | out : List [] : String | Test.java:230:19:230:32 | it : List [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:2975:9:2975:23 | getElement(...) | | Test.java:2980:39:2980:54 | (...)... : String | Test.java:283:53:283:57 | key : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:2980:21:2980:55 | newOMIWithElement(...) : OrderedMapIterator [] : String | -| Test.java:2980:39:2980:54 | (...)... : String | Test.java:283:53:283:57 | key : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:2980:21:2980:55 | newOMIWithElement(...) : OrderedMapIterator [] : String | -| Test.java:2987:40:2987:55 | (...)... : String | Test.java:302:54:302:60 | value : String | Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:2987:21:2987:56 | newOMIWithMapValue(...) : OrderedMapIterator [] : String | | Test.java:2987:40:2987:55 | (...)... : String | Test.java:302:54:302:60 | value : String | Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:2987:21:2987:56 | newOMIWithMapValue(...) : OrderedMapIterator [] : String | | Test.java:2996:21:2996:23 | out : MapIterator [] : Object | Test.java:246:20:246:47 | mapIterator : MapIterator [] : Object | Test.java:246:59:246:80 | getValue(...) : Object | Test.java:2996:9:2996:24 | getMapValue(...) | | Test.java:3001:40:3001:55 | (...)... : String | Test.java:302:54:302:60 | value : String | Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:3001:21:3001:56 | newOMIWithMapValue(...) : OrderedMapIterator [] : String | -| Test.java:3001:40:3001:55 | (...)... : String | Test.java:302:54:302:60 | value : String | Test.java:302:134:302:148 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:3001:21:3001:56 | newOMIWithMapValue(...) : OrderedMapIterator [] : String | | Test.java:3008:37:3008:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:3008:18:3008:53 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:3008:37:3008:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3008:18:3008:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:3008:37:3008:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3008:18:3008:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:3010:20:3010:22 | out : Collection [] : Object | Test.java:230:19:230:32 | it : Collection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:3010:9:3010:23 | getElement(...) | | Test.java:3010:20:3010:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3010:9:3010:23 | getElement(...) | | Test.java:3017:19:3017:21 | out : MultiValueMap [] : Object | Test.java:228:18:228:29 | map : MultiValueMap [] : Object | Test.java:228:41:228:70 | next(...) : Object | Test.java:3017:9:3017:22 | getMapKey(...) | @@ -18561,12 +18449,10 @@ subpaths | Test.java:3038:44:3038:46 | out : MultiMap [] : Object | Test.java:232:20:232:31 | map : MultiMap [] : Object | Test.java:232:43:232:55 | get(...) : Object | Test.java:3038:32:3038:47 | getMapValue(...) : Object | | Test.java:3043:42:3043:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:3043:23:3043:58 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:3043:42:3043:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3043:23:3043:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:3043:42:3043:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3043:23:3043:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:3045:20:3045:22 | out : Collection [] : Object | Test.java:230:19:230:32 | it : Collection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:3045:9:3045:23 | getElement(...) | | Test.java:3045:20:3045:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3045:9:3045:23 | getElement(...) | | Test.java:3050:37:3050:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:3050:18:3050:53 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:3050:37:3050:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3050:18:3050:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:3050:37:3050:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3050:18:3050:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:3052:20:3052:22 | out : Collection [] : Object | Test.java:230:19:230:32 | it : Collection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:3052:9:3052:23 | getElement(...) | | Test.java:3052:20:3052:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3052:9:3052:23 | getElement(...) | | Test.java:3064:43:3064:58 | (...)... : String | Test.java:272:58:272:62 | key : String | Test.java:272:160:272:160 | m : ArrayListValuedHashMap [] : String | Test.java:3064:24:3064:59 | newALVHMWithMapKey(...) : ArrayListValuedHashMap [] : String | @@ -18594,24 +18480,18 @@ subpaths | Test.java:3129:20:3129:35 | getMapValue(...) : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3129:9:3129:36 | getElement(...) | | Test.java:3129:32:3129:34 | out : MultiValuedMap [, ] : String | Test.java:247:32:247:60 | container : MultiValuedMap [, ] : String | Test.java:247:72:247:90 | get(...) : Collection [] : String | Test.java:3129:20:3129:35 | getMapValue(...) : Collection [] : String | | Test.java:3134:52:3134:67 | (...)... : String | Test.java:262:52:262:60 | element : String | Test.java:262:72:262:125 | getElement(...) : Entry [] : String | Test.java:3134:24:3134:68 | newMultiSetEntryWithElement(...) : Entry [] : String | -| Test.java:3134:52:3134:67 | (...)... : String | Test.java:262:52:262:60 | element : String | Test.java:262:72:262:125 | getElement(...) : Entry [] : String | Test.java:3134:24:3134:68 | newMultiSetEntryWithElement(...) : Entry [] : String | | Test.java:3143:20:3143:22 | out : MultiSet [] : Object | Test.java:230:19:230:32 | it : MultiSet [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:3143:9:3143:23 | getElement(...) | | Test.java:3150:20:3150:22 | out : MultiSet [] : Object | Test.java:230:19:230:32 | it : MultiSet [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:3150:9:3150:23 | getElement(...) | | Test.java:3155:41:3155:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3155:18:3155:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:3155:41:3155:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3155:18:3155:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:3157:20:3157:34 | getElement(...) : Entry [] : String | Test.java:235:19:235:45 | container : Entry [] : String | Test.java:235:57:235:78 | getElement(...) : String | Test.java:3157:9:3157:35 | getElement(...) | | Test.java:3157:31:3157:33 | out : Set [, ] : String | Test.java:230:19:230:32 | it : Set [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:3157:20:3157:34 | getElement(...) : Entry [] : String | | Test.java:3162:41:3162:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3162:18:3162:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:3162:41:3162:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3162:18:3162:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:3164:20:3164:22 | out : Set [] : String | Test.java:230:19:230:32 | it : Set [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3164:9:3164:23 | getElement(...) | | Test.java:3169:41:3169:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3169:18:3169:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:3169:41:3169:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3169:18:3169:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:3171:20:3171:22 | out : MultiSet [] : String | Test.java:230:19:230:32 | it : MultiSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3171:9:3171:23 | getElement(...) | | Test.java:3176:41:3176:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3176:18:3176:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:3176:41:3176:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3176:18:3176:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:3178:20:3178:22 | out : MultiSet [] : String | Test.java:230:19:230:32 | it : MultiSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3178:9:3178:23 | getElement(...) | | Test.java:3183:41:3183:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3183:18:3183:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:3183:41:3183:56 | (...)... : String | Test.java:263:41:263:49 | element : String | Test.java:263:119:263:119 | h : HashMultiSet [] : String | Test.java:3183:18:3183:57 | newMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:3185:20:3185:22 | out : MultiSet [] : String | Test.java:230:19:230:32 | it : MultiSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3185:9:3185:23 | getElement(...) | | Test.java:3190:45:3190:60 | (...)... : String | Test.java:290:60:290:66 | value : String | Test.java:290:166:290:166 | m : ArrayListValuedHashMap [, ] : String | Test.java:3190:24:3190:61 | newALVHMWithMapValue(...) : ArrayListValuedHashMap [, ] : String | | Test.java:3192:20:3192:47 | (...)... : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3192:9:3192:48 | getElement(...) | @@ -18658,16 +18538,10 @@ subpaths | Test.java:3330:45:3330:60 | (...)... : String | Test.java:290:60:290:66 | value : String | Test.java:290:166:290:166 | m : ArrayListValuedHashMap [, ] : String | Test.java:3330:24:3330:61 | newALVHMWithMapValue(...) : ArrayListValuedHashMap [, ] : String | | Test.java:3332:20:3332:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3332:9:3332:23 | getElement(...) | | Test.java:3337:46:3337:61 | (...)... : String | Test.java:283:53:283:57 | key : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:3337:28:3337:62 | newOMIWithElement(...) : OrderedMapIterator [] : String | -| Test.java:3337:46:3337:61 | (...)... : String | Test.java:283:53:283:57 | key : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:3337:28:3337:62 | newOMIWithElement(...) : OrderedMapIterator [] : String | -| Test.java:3344:43:3344:58 | (...)... : String | Test.java:283:53:283:57 | key : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:3344:25:3344:59 | newOMIWithElement(...) : OrderedMapIterator [] : String | | Test.java:3344:43:3344:58 | (...)... : String | Test.java:283:53:283:57 | key : String | Test.java:283:129:283:143 | mapIterator(...) : OrderedMapIterator [] : String | Test.java:3344:25:3344:59 | newOMIWithElement(...) : OrderedMapIterator [] : String | | Test.java:3351:45:3351:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:3351:20:3351:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | -| Test.java:3351:45:3351:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:3351:20:3351:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | -| Test.java:3358:45:3358:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:3358:20:3358:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | | Test.java:3358:45:3358:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:3358:20:3358:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | | Test.java:3365:45:3365:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:3365:20:3365:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | -| Test.java:3365:45:3365:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:3365:20:3365:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | -| Test.java:3372:45:3372:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:3372:20:3372:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | | Test.java:3372:45:3372:60 | (...)... : String | Test.java:287:75:287:79 | key : String | Test.java:287:155:287:155 | m : TreeBidiMap [] : String | Test.java:3372:20:3372:61 | newTreeBidiMapWithMapKey(...) : TreeBidiMap [] : String | | Test.java:3381:26:3381:28 | out : Put [] : Object | Test.java:242:27:242:44 | container : Put [] : Object | Test.java:242:56:242:85 | getMapKey(...) : Object | Test.java:3381:9:3381:29 | getMapKeyFromPut(...) | | Test.java:3388:19:3388:21 | out : MultiValueMap [] : Object | Test.java:228:18:228:29 | map : MultiValueMap [] : Object | Test.java:228:41:228:70 | next(...) : Object | Test.java:3388:9:3388:22 | getMapKey(...) | @@ -18680,14 +18554,9 @@ subpaths | Test.java:3437:21:3437:23 | out : BidiMap [] : Object | Test.java:232:20:232:31 | map : BidiMap [] : Object | Test.java:232:43:232:55 | get(...) : Object | Test.java:3437:9:3437:24 | getMapValue(...) | | Test.java:3444:21:3444:23 | out : AbstractMapDecorator [] : Object | Test.java:232:20:232:31 | map : AbstractMapDecorator [] : Object | Test.java:232:43:232:55 | get(...) : Object | Test.java:3444:9:3444:24 | getMapValue(...) | | Test.java:3449:38:3449:53 | (...)... : String | Test.java:293:51:293:57 | value : String | Test.java:293:131:293:131 | m : HashedMap [] : String | Test.java:3449:13:3449:54 | newHashedMapWithMapValue(...) : HashedMap [] : String | -| Test.java:3449:38:3449:53 | (...)... : String | Test.java:293:51:293:57 | value : String | Test.java:293:131:293:131 | m : HashedMap [] : String | Test.java:3449:13:3449:54 | newHashedMapWithMapValue(...) : HashedMap [] : String | -| Test.java:3456:42:3456:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3456:23:3456:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:3456:42:3456:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3456:23:3456:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:3463:37:3463:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3463:18:3463:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:3463:37:3463:52 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3463:18:3463:53 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:3470:44:3470:59 | (...)... : String | Test.java:306:77:306:83 | value : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | Test.java:3470:17:3470:60 | newTreeBidiMapWithMapValue(...) : TreeBidiMap [] : String | -| Test.java:3470:44:3470:59 | (...)... : String | Test.java:306:77:306:83 | value : String | Test.java:306:161:306:161 | m : TreeBidiMap [] : String | Test.java:3470:17:3470:60 | newTreeBidiMapWithMapValue(...) : TreeBidiMap [] : String | -| Test.java:3477:49:3477:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3477:30:3477:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:3477:49:3477:64 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:3477:30:3477:65 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:3484:34:3484:49 | (...)... : String | Test.java:285:47:285:51 | key : String | Test.java:285:121:285:121 | m : TreeMap [] : String | Test.java:3484:13:3484:50 | newTreeMapWithMapKey(...) : TreeMap [] : String | | Test.java:3486:26:3486:28 | out : Put [] : String | Test.java:242:27:242:44 | container : Put [] : String | Test.java:242:56:242:85 | getMapKey(...) : String | Test.java:3486:9:3486:29 | getMapKeyFromPut(...) | @@ -18757,35 +18626,24 @@ subpaths | Test.java:3722:41:3722:56 | (...)... : String | Test.java:268:39:268:47 | element : String | Test.java:268:107:268:107 | h : TreeSet [] : String | Test.java:3722:19:3722:57 | newTreeSetWithElement(...) : TreeSet [] : String | | Test.java:3724:20:3724:22 | out : SortedSet [] : String | Test.java:230:19:230:32 | it : SortedSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3724:9:3724:23 | getElement(...) | | Test.java:3729:41:3729:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3729:19:3729:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3729:41:3729:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3729:19:3729:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3736:41:3736:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3736:19:3736:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3736:41:3736:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3736:19:3736:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3743:36:3743:51 | (...)... : String | Test.java:275:49:275:53 | key : String | Test.java:275:125:275:125 | m : HashedMap [] : String | Test.java:3743:13:3743:52 | newHashedMapWithMapKey(...) : HashedMap [] : String | | Test.java:3743:36:3743:51 | (...)... : String | Test.java:275:49:275:53 | key : String | Test.java:275:125:275:125 | m : HashedMap [] : String | Test.java:3743:13:3743:52 | newHashedMapWithMapKey(...) : HashedMap [] : String | | Test.java:3745:19:3745:21 | out : IterableMap [] : String | Test.java:228:18:228:29 | map : IterableMap [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:3745:9:3745:22 | getMapKey(...) | | Test.java:3750:38:3750:53 | (...)... : String | Test.java:293:51:293:57 | value : String | Test.java:293:131:293:131 | m : HashedMap [] : String | Test.java:3750:13:3750:54 | newHashedMapWithMapValue(...) : HashedMap [] : String | -| Test.java:3750:38:3750:53 | (...)... : String | Test.java:293:51:293:57 | value : String | Test.java:293:131:293:131 | m : HashedMap [] : String | Test.java:3750:13:3750:54 | newHashedMapWithMapValue(...) : HashedMap [] : String | | Test.java:3752:21:3752:23 | out : IterableMap [] : String | Test.java:232:20:232:31 | map : IterableMap [] : String | Test.java:232:43:232:55 | get(...) : String | Test.java:3752:9:3752:24 | getMapValue(...) | | Test.java:3757:36:3757:51 | (...)... : String | Test.java:275:49:275:53 | key : String | Test.java:275:125:275:125 | m : HashedMap [] : String | Test.java:3757:13:3757:52 | newHashedMapWithMapKey(...) : HashedMap [] : String | -| Test.java:3757:36:3757:51 | (...)... : String | Test.java:275:49:275:53 | key : String | Test.java:275:125:275:125 | m : HashedMap [] : String | Test.java:3757:13:3757:52 | newHashedMapWithMapKey(...) : HashedMap [] : String | | Test.java:3759:19:3759:21 | out : Map [] : String | Test.java:228:18:228:29 | map : Map [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:3759:9:3759:22 | getMapKey(...) | | Test.java:3764:38:3764:53 | (...)... : String | Test.java:293:51:293:57 | value : String | Test.java:293:131:293:131 | m : HashedMap [] : String | Test.java:3764:13:3764:54 | newHashedMapWithMapValue(...) : HashedMap [] : String | -| Test.java:3764:38:3764:53 | (...)... : String | Test.java:293:51:293:57 | value : String | Test.java:293:131:293:131 | m : HashedMap [] : String | Test.java:3764:13:3764:54 | newHashedMapWithMapValue(...) : HashedMap [] : String | | Test.java:3766:21:3766:23 | out : Map [] : String | Test.java:232:20:232:31 | map : Map [] : String | Test.java:232:43:232:55 | get(...) : String | Test.java:3766:9:3766:24 | getMapValue(...) | | Test.java:3771:40:3771:55 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:3771:14:3771:56 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | -| Test.java:3771:40:3771:55 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:3771:14:3771:56 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | | Test.java:3773:19:3773:21 | out : SortedMap [] : String | Test.java:228:18:228:29 | map : SortedMap [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:3773:9:3773:22 | getMapKey(...) | | Test.java:3778:42:3778:57 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:3778:14:3778:58 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | -| Test.java:3778:42:3778:57 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:3778:14:3778:58 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:3780:21:3780:23 | out : SortedMap [] : String | Test.java:232:20:232:31 | map : SortedMap [] : String | Test.java:232:43:232:55 | get(...) : String | Test.java:3780:9:3780:24 | getMapValue(...) | | Test.java:3785:40:3785:55 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:3785:14:3785:56 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | -| Test.java:3785:40:3785:55 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:3785:14:3785:56 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | | Test.java:3787:19:3787:21 | out : Trie [] : String | Test.java:228:18:228:29 | map : Trie [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:3787:9:3787:22 | getMapKey(...) | | Test.java:3792:42:3792:57 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:3792:14:3792:58 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | -| Test.java:3792:42:3792:57 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:3792:14:3792:58 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:3794:21:3794:23 | out : Trie [] : String | Test.java:232:20:232:31 | map : Trie [] : String | Test.java:232:43:232:55 | get(...) : String | Test.java:3794:9:3794:24 | getMapValue(...) | | Test.java:3799:35:3799:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3799:13:3799:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3799:35:3799:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3799:13:3799:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3800:37:3800:38 | in : TreeBag [] : String | Test.java:7104:33:7104:48 | bag : TreeBag [] : String | Test.java:7104:10:7104:31 | parameter this [Return] : MyAbstractBagDecorator [] : String | Test.java:3800:10:3800:39 | new MyAbstractBagDecorator<>(...) : MyAbstractBagDecorator [] : String | | Test.java:3801:20:3801:22 | out : MyAbstractBagDecorator [] : String | Test.java:230:19:230:32 | it : MyAbstractBagDecorator [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3801:9:3801:23 | getElement(...) | | Test.java:3807:31:3807:32 | in : Map [] : String | Test.java:7110:27:7110:58 | map : Map [] : String | Test.java:7110:10:7110:25 | parameter this [Return] : MyAbstractMapBag [] : String | Test.java:3807:10:3807:33 | new MyAbstractMapBag<>(...) : MyAbstractMapBag [] : String | @@ -18794,50 +18652,35 @@ subpaths | Test.java:3814:10:3814:11 | in : MyAbstractMapBag [] : String | Test.java:7113:33:7113:40 | parameter this : MyAbstractMapBag [] : String | Test.java:7114:11:7114:24 | getMap(...) : Map [] : String | Test.java:3814:10:3814:22 | myGetMap(...) : Map [] : String | | Test.java:3815:19:3815:21 | out : Map [] : String | Test.java:228:18:228:29 | map : Map [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:3815:9:3815:22 | getMapKey(...) | | Test.java:3820:41:3820:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3820:19:3820:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3820:41:3820:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3820:19:3820:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3821:43:3821:44 | in : TreeBag [] : String | Test.java:7119:39:7119:60 | bag : TreeBag [] : String | Test.java:7119:10:7119:37 | parameter this [Return] : MyAbstractSortedBagDecorator [] : String | Test.java:3821:10:3821:45 | new MyAbstractSortedBagDecorator<>(...) : MyAbstractSortedBagDecorator [] : String | | Test.java:3822:20:3822:22 | out : MyAbstractSortedBagDecorator [] : String | Test.java:230:19:230:32 | it : MyAbstractSortedBagDecorator [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3822:9:3822:23 | getElement(...) | | Test.java:3827:35:3827:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3827:13:3827:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3827:35:3827:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3827:13:3827:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3829:20:3829:22 | out : CollectionBag [] : String | Test.java:230:19:230:32 | it : CollectionBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3829:9:3829:23 | getElement(...) | | Test.java:3834:35:3834:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3834:13:3834:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3834:35:3834:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3834:13:3834:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3836:20:3836:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3836:9:3836:23 | getElement(...) | | Test.java:3841:41:3841:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3841:19:3841:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3841:41:3841:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3841:19:3841:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3843:20:3843:22 | out : CollectionSortedBag [] : String | Test.java:230:19:230:32 | it : CollectionSortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3843:9:3843:23 | getElement(...) | | Test.java:3848:41:3848:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3848:19:3848:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3848:41:3848:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3848:19:3848:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3850:20:3850:22 | out : SortedBag [] : String | Test.java:230:19:230:32 | it : SortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3850:9:3850:23 | getElement(...) | | Test.java:3855:42:3855:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3855:20:3855:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3855:42:3855:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3855:20:3855:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3857:20:3857:22 | out : HashBag [] : String | Test.java:230:19:230:32 | it : HashBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3857:9:3857:23 | getElement(...) | | Test.java:3862:35:3862:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3862:13:3862:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3862:35:3862:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3862:13:3862:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3864:20:3864:22 | out : PredicatedBag [] : String | Test.java:230:19:230:32 | it : PredicatedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3864:9:3864:23 | getElement(...) | | Test.java:3869:41:3869:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3869:19:3869:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3869:41:3869:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3869:19:3869:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3871:20:3871:22 | out : PredicatedSortedBag [] : String | Test.java:230:19:230:32 | it : PredicatedSortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3871:9:3871:23 | getElement(...) | | Test.java:3876:35:3876:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3876:13:3876:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3876:35:3876:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3876:13:3876:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3878:20:3878:22 | out : SynchronizedBag [] : String | Test.java:230:19:230:32 | it : SynchronizedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3878:9:3878:23 | getElement(...) | | Test.java:3883:41:3883:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3883:19:3883:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3883:41:3883:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3883:19:3883:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3885:20:3885:22 | out : SynchronizedSortedBag [] : String | Test.java:230:19:230:32 | it : SynchronizedSortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3885:9:3885:23 | getElement(...) | | Test.java:3890:35:3890:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3890:13:3890:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3890:35:3890:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3890:13:3890:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3892:20:3892:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3892:9:3892:23 | getElement(...) | | Test.java:3897:41:3897:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3897:19:3897:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3897:41:3897:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3897:19:3897:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3899:20:3899:22 | out : TransformedSortedBag [] : String | Test.java:230:19:230:32 | it : TransformedSortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3899:9:3899:23 | getElement(...) | | Test.java:3904:42:3904:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3904:20:3904:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3904:42:3904:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3904:20:3904:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3906:20:3906:22 | out : TreeBag [] : String | Test.java:230:19:230:32 | it : TreeBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3906:9:3906:23 | getElement(...) | | Test.java:3911:35:3911:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3911:13:3911:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3911:35:3911:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3911:13:3911:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3913:20:3913:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3913:9:3913:23 | getElement(...) | | Test.java:3918:41:3918:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3918:19:3918:57 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:3918:41:3918:56 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:3918:19:3918:57 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:3920:20:3920:22 | out : SortedBag [] : String | Test.java:230:19:230:32 | it : SortedBag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:3920:9:3920:23 | getElement(...) | | Test.java:3925:46:3925:61 | (...)... : String | Test.java:274:61:274:65 | key : String | Test.java:274:77:274:124 | new DualTreeBidiMap(...) : DualTreeBidiMap [] : String | Test.java:3925:17:3925:62 | newDualTreeBidiMapWithMapKey(...) : DualTreeBidiMap [] : String | | Test.java:3926:41:3926:42 | in : DualTreeBidiMap [] : String | Test.java:7125:37:7125:59 | map : DualTreeBidiMap [] : String | Test.java:7125:10:7125:35 | parameter this [Return] : MyAbstractBidiMapDecorator [] : String | Test.java:3926:10:3926:43 | new MyAbstractBidiMapDecorator<>(...) : MyAbstractBidiMapDecorator [] : String | @@ -18908,72 +18751,52 @@ subpaths | Test.java:4142:54:4142:69 | (...)... : String | Test.java:292:63:292:69 | value : String | Test.java:292:81:292:130 | new DualTreeBidiMap(...) : DualTreeBidiMap [] : String | Test.java:4142:23:4142:70 | newDualTreeBidiMapWithMapValue(...) : DualTreeBidiMap [] : String | | Test.java:4144:21:4144:23 | out : SortedBidiMap [] : String | Test.java:232:20:232:31 | map : SortedBidiMap [] : String | Test.java:232:43:232:55 | get(...) : String | Test.java:4144:9:4144:24 | getMapValue(...) | | Test.java:4149:42:4149:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4149:20:4149:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4149:42:4149:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4149:20:4149:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4150:44:4150:45 | in : TreeBag [] : String | Test.java:7149:40:7149:63 | coll : TreeBag [] : String | Test.java:7149:10:7149:38 | parameter this [Return] : MyAbstractCollectionDecorator [] : String | Test.java:4150:10:4150:46 | new MyAbstractCollectionDecorator<>(...) : MyAbstractCollectionDecorator [] : String | | Test.java:4151:20:4151:22 | out : MyAbstractCollectionDecorator [] : String | Test.java:230:19:230:32 | it : MyAbstractCollectionDecorator [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4151:9:4151:23 | getElement(...) | | Test.java:4156:73:4156:111 | newTreeBagWithElement(...) : TreeBag [] : String | Test.java:7149:40:7149:63 | coll : TreeBag [] : String | Test.java:7149:10:7149:38 | parameter this [Return] : MyAbstractCollectionDecorator [] : String | Test.java:4156:39:4156:112 | new MyAbstractCollectionDecorator<>(...) : MyAbstractCollectionDecorator [] : String | | Test.java:4156:95:4156:110 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4156:73:4156:111 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4156:95:4156:110 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4156:73:4156:111 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4157:10:4157:11 | in : MyAbstractCollectionDecorator [] : String | Test.java:7152:24:7152:34 | parameter this : MyAbstractCollectionDecorator [] : String | Test.java:7153:11:7153:27 | decorated(...) : Collection [] : String | Test.java:4157:10:4157:25 | myDecorated(...) : Collection [] : String | | Test.java:4158:20:4158:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4158:9:4158:23 | getElement(...) | | Test.java:4163:42:4163:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4163:20:4163:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4163:42:4163:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4163:20:4163:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4164:24:4164:25 | in : TreeBag [] : String | Test.java:7155:31:7155:54 | coll : TreeBag [] : String | Test.java:7155:15:7155:29 | parameter this [Return] : MyAbstractCollectionDecorator [] : String | Test.java:4164:4:4164:6 | out [post update] : MyAbstractCollectionDecorator [] : String | | Test.java:4165:20:4165:22 | out : MyAbstractCollectionDecorator [] : String | Test.java:230:19:230:32 | it : MyAbstractCollectionDecorator [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4165:9:4165:23 | getElement(...) | | Test.java:4173:20:4173:22 | out : CompositeCollection [] : Object | Test.java:230:19:230:32 | it : CompositeCollection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:4173:9:4173:23 | getElement(...) | | Test.java:4181:20:4181:34 | getElement(...) : Collection [] : Object | Test.java:230:19:230:32 | it : Collection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:4181:9:4181:35 | getElement(...) | | Test.java:4181:31:4181:33 | out : List [, ] : Object | Test.java:230:19:230:32 | it : List [, ] : Object | Test.java:230:44:230:63 | next(...) : Object [] : Object | Test.java:4181:20:4181:34 | getElement(...) : Collection [] : Object | | Test.java:4186:42:4186:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4186:20:4186:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4186:42:4186:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4186:20:4186:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4189:20:4189:22 | out : CompositeCollection [] : String | Test.java:230:19:230:32 | it : CompositeCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4189:9:4189:23 | getElement(...) | | Test.java:4194:42:4194:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4194:20:4194:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4194:42:4194:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4194:20:4194:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4197:20:4197:34 | getElement(...) : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4197:9:4197:35 | getElement(...) | | Test.java:4197:31:4197:33 | out : List [, ] : String | Test.java:230:19:230:32 | it : List [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:4197:20:4197:34 | getElement(...) : Collection [] : String | | Test.java:4202:42:4202:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4202:20:4202:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4202:42:4202:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4202:20:4202:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4204:20:4204:22 | out : CompositeCollection [] : String | Test.java:230:19:230:32 | it : CompositeCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4204:9:4204:23 | getElement(...) | | Test.java:4209:42:4209:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4209:20:4209:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4209:42:4209:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4209:20:4209:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4211:20:4211:22 | out : CompositeCollection [] : String | Test.java:230:19:230:32 | it : CompositeCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4211:9:4211:23 | getElement(...) | | Test.java:4216:42:4216:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4216:20:4216:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4216:42:4216:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4216:20:4216:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4218:20:4218:22 | out : CompositeCollection [] : String | Test.java:230:19:230:32 | it : CompositeCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4218:9:4218:23 | getElement(...) | | Test.java:4223:61:4223:76 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4223:39:4223:77 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4223:61:4223:76 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4223:39:4223:77 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4225:20:4225:22 | out : CompositeCollection [] : String | Test.java:230:19:230:32 | it : CompositeCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4225:9:4225:23 | getElement(...) | | Test.java:4230:42:4230:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4230:20:4230:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4230:42:4230:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4230:20:4230:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4232:20:4232:22 | out : CompositeCollection [] : String | Test.java:230:19:230:32 | it : CompositeCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4232:9:4232:23 | getElement(...) | | Test.java:4237:42:4237:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4237:20:4237:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4237:42:4237:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4237:20:4237:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4239:20:4239:22 | out : CompositeCollection [] : String | Test.java:230:19:230:32 | it : CompositeCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4239:9:4239:23 | getElement(...) | | Test.java:4244:42:4244:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4244:20:4244:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4244:42:4244:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4244:20:4244:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4246:20:4246:22 | out : CompositeCollection [] : String | Test.java:230:19:230:32 | it : CompositeCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4246:9:4246:23 | getElement(...) | | Test.java:4251:61:4251:76 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4251:39:4251:77 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4251:61:4251:76 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4251:39:4251:77 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4253:20:4253:22 | out : CompositeCollection [] : String | Test.java:230:19:230:32 | it : CompositeCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4253:9:4253:23 | getElement(...) | | Test.java:4258:75:4258:90 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4258:53:4258:91 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4258:75:4258:90 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4258:53:4258:91 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4260:20:4260:34 | getElement(...) : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4260:9:4260:35 | getElement(...) | | Test.java:4260:31:4260:33 | out : List [, ] : String | Test.java:230:19:230:32 | it : List [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:4260:20:4260:34 | getElement(...) : Collection [] : String | | Test.java:4265:75:4265:90 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4265:53:4265:91 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4265:75:4265:90 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4265:53:4265:91 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4267:20:4267:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4267:9:4267:23 | getElement(...) | | Test.java:4272:42:4272:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4272:20:4272:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4272:42:4272:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4272:20:4272:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4274:20:4274:22 | out : IndexedCollection [] : String | Test.java:230:19:230:32 | it : IndexedCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4274:9:4274:23 | getElement(...) | | Test.java:4279:71:4279:86 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4279:49:4279:87 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4279:71:4279:86 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4279:49:4279:87 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4286:42:4286:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4286:20:4286:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4286:42:4286:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4286:20:4286:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4288:20:4288:22 | out : IndexedCollection [] : String | Test.java:230:19:230:32 | it : IndexedCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4288:9:4288:23 | getElement(...) | | Test.java:4293:42:4293:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4293:20:4293:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4293:42:4293:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4293:20:4293:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4295:20:4295:22 | out : IndexedCollection [] : String | Test.java:230:19:230:32 | it : IndexedCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4295:9:4295:23 | getElement(...) | | Test.java:4300:71:4300:86 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4300:49:4300:87 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4300:71:4300:86 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4300:49:4300:87 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4302:20:4302:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4302:9:4302:23 | getElement(...) | | Test.java:4309:20:4309:45 | createPredicatedList(...) : List [] : String | Test.java:230:19:230:32 | it : List [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4309:9:4309:46 | getElement(...) | | Test.java:4316:20:4316:45 | createPredicatedList(...) : List [] : String | Test.java:230:19:230:32 | it : List [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4316:9:4316:46 | getElement(...) | @@ -18982,7 +18805,6 @@ subpaths | Test.java:4328:80:4328:95 | (...)... : String | Test.java:264:80:264:88 | element : String | Test.java:264:194:264:194 | x : Builder [] : String | Test.java:4328:38:4328:96 | newPredicatedCollectionBuilderWithElement(...) : Builder [] : String | | Test.java:4330:20:4330:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4330:9:4330:23 | getElement(...) | | Test.java:4335:35:4335:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4335:13:4335:51 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4335:35:4335:50 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4335:13:4335:51 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4338:20:4338:22 | out : Bag [] : String | Test.java:230:19:230:32 | it : Bag [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4338:9:4338:23 | getElement(...) | | Test.java:4343:80:4343:95 | (...)... : String | Test.java:264:80:264:88 | element : String | Test.java:264:194:264:194 | x : Builder [] : String | Test.java:4343:38:4343:96 | newPredicatedCollectionBuilderWithElement(...) : Builder [] : String | | Test.java:4345:20:4345:22 | out : List [] : String | Test.java:230:19:230:32 | it : List [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4345:9:4345:23 | getElement(...) | @@ -18994,7 +18816,6 @@ subpaths | Test.java:4372:80:4372:95 | (...)... : String | Test.java:264:80:264:88 | element : String | Test.java:264:194:264:194 | x : Builder [] : String | Test.java:4372:38:4372:96 | newPredicatedCollectionBuilderWithElement(...) : Builder [] : String | | Test.java:4374:20:4374:22 | out : MultiSet [] : String | Test.java:230:19:230:32 | it : MultiSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4374:9:4374:23 | getElement(...) | | Test.java:4379:45:4379:60 | (...)... : String | Test.java:258:49:258:57 | element : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | Test.java:4379:18:4379:61 | newHashMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:4379:45:4379:60 | (...)... : String | Test.java:258:49:258:57 | element : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | Test.java:4379:18:4379:61 | newHashMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:4382:20:4382:22 | out : MultiSet [] : String | Test.java:230:19:230:32 | it : MultiSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4382:9:4382:23 | getElement(...) | | Test.java:4387:80:4387:95 | (...)... : String | Test.java:264:80:264:88 | element : String | Test.java:264:194:264:194 | x : Builder [] : String | Test.java:4387:38:4387:96 | newPredicatedCollectionBuilderWithElement(...) : Builder [] : String | | Test.java:4389:20:4389:22 | out : Queue [] : String | Test.java:230:19:230:32 | it : Queue [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4389:9:4389:23 | getElement(...) | @@ -19011,21 +18832,16 @@ subpaths | Test.java:4431:80:4431:95 | (...)... : String | Test.java:264:80:264:88 | element : String | Test.java:264:194:264:194 | x : Builder [] : String | Test.java:4431:38:4431:96 | newPredicatedCollectionBuilderWithElement(...) : Builder [] : String | | Test.java:4433:20:4433:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4433:9:4433:23 | getElement(...) | | Test.java:4438:42:4438:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4438:20:4438:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4438:42:4438:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4438:20:4438:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4440:20:4440:22 | out : PredicatedCollection [] : String | Test.java:230:19:230:32 | it : PredicatedCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4440:9:4440:23 | getElement(...) | | Test.java:4445:42:4445:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4445:20:4445:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4445:42:4445:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4445:20:4445:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4447:20:4447:22 | out : SynchronizedCollection [] : String | Test.java:230:19:230:32 | it : SynchronizedCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4447:9:4447:23 | getElement(...) | | Test.java:4452:42:4452:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4452:20:4452:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4452:42:4452:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4452:20:4452:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4454:20:4454:22 | out : TransformedCollection [] : String | Test.java:230:19:230:32 | it : TransformedCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4454:9:4454:23 | getElement(...) | | Test.java:4459:42:4459:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4459:20:4459:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4459:42:4459:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4459:20:4459:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4461:20:4461:22 | out : BoundedCollection [] : String | Test.java:230:19:230:32 | it : BoundedCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4461:9:4461:23 | getElement(...) | | Test.java:4466:59:4466:74 | (...)... : String | Test.java:253:59:253:67 | element : String | Test.java:253:147:253:147 | x : CircularFifoQueue [] : String | Test.java:4466:27:4466:75 | newCircularFifoQueueWithElement(...) : CircularFifoQueue [] : String | | Test.java:4468:20:4468:22 | out : BoundedCollection [] : String | Test.java:230:19:230:32 | it : BoundedCollection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4468:9:4468:23 | getElement(...) | | Test.java:4473:42:4473:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4473:20:4473:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4473:42:4473:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4473:20:4473:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4475:20:4475:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:4475:9:4475:23 | getElement(...) | | Test.java:4480:45:4480:60 | (...)... : String | Test.java:259:49:259:57 | element : String | Test.java:259:69:259:112 | listIterator(...) : ListIterator [] : String | Test.java:4480:18:4480:61 | newListIteratorWithElement(...) : ListIterator [] : String | | Test.java:4481:42:4481:43 | in : ListIterator [] : String | Test.java:7161:38:7161:63 | iterator : ListIterator [] : String | Test.java:7161:10:7161:36 | parameter this [Return] : MyAbstractIteratorDecorator [] : String | Test.java:4481:10:4481:44 | new MyAbstractIteratorDecorator<>(...) : MyAbstractIteratorDecorator [] : String | @@ -19128,7 +18944,6 @@ subpaths | Test.java:4753:49:4753:64 | (...)... : String | Test.java:259:49:259:57 | element : String | Test.java:259:69:259:112 | listIterator(...) : ListIterator [] : String | Test.java:4753:22:4753:65 | newListIteratorWithElement(...) : ListIterator [] : String | | Test.java:4755:20:4755:22 | out : FilterListIterator [] : String | Test.java:231:19:231:32 | it : FilterListIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:4755:9:4755:23 | getElement(...) | | Test.java:4760:42:4760:85 | newListIteratorWithElement(...) : ListIterator [] : String | Test.java:267:39:267:47 | element : ListIterator [] : String | Test.java:267:107:267:107 | b : TreeBag [, ] : String | Test.java:4760:20:4760:86 | newTreeBagWithElement(...) : TreeBag [, ] : String | -| Test.java:4760:42:4760:85 | newListIteratorWithElement(...) : ListIterator [] : String | Test.java:267:39:267:47 | element : ListIterator [] : String | Test.java:267:107:267:107 | b : TreeBag [, ] : String | Test.java:4760:20:4760:86 | newTreeBagWithElement(...) : TreeBag [, ] : String | | Test.java:4760:69:4760:84 | (...)... : String | Test.java:259:49:259:57 | element : String | Test.java:259:69:259:112 | listIterator(...) : ListIterator [] : String | Test.java:4760:42:4760:85 | newListIteratorWithElement(...) : ListIterator [] : String | | Test.java:4762:20:4762:22 | out : IteratorChain [] : String | Test.java:231:19:231:32 | it : IteratorChain [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:4762:9:4762:23 | getElement(...) | | Test.java:4767:45:4767:60 | (...)... : String | Test.java:259:49:259:57 | element : String | Test.java:259:69:259:112 | listIterator(...) : ListIterator [] : String | Test.java:4767:18:4767:61 | newListIteratorWithElement(...) : ListIterator [] : String | @@ -19154,7 +18969,6 @@ subpaths | Test.java:4837:45:4837:60 | (...)... : String | Test.java:259:49:259:57 | element : String | Test.java:259:69:259:112 | listIterator(...) : ListIterator [] : String | Test.java:4837:18:4837:61 | newListIteratorWithElement(...) : ListIterator [] : String | | Test.java:4839:20:4839:22 | out : ListIteratorWrapper [] : String | Test.java:231:19:231:32 | it : ListIteratorWrapper [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:4839:9:4839:23 | getElement(...) | | Test.java:4844:42:4844:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4844:20:4844:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:4844:42:4844:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:4844:20:4844:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:4846:20:4846:22 | out : LoopingIterator [] : String | Test.java:231:19:231:32 | it : LoopingIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:4846:9:4846:23 | getElement(...) | | Test.java:4853:20:4853:22 | out : LoopingListIterator [] : String | Test.java:231:19:231:32 | it : LoopingListIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:4853:9:4853:23 | getElement(...) | | Test.java:4860:20:4860:22 | out : ObjectArrayIterator [] : String | Test.java:231:19:231:32 | it : ObjectArrayIterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:4860:9:4860:23 | getElement(...) | @@ -19229,7 +19043,6 @@ subpaths | Test.java:5208:41:5208:56 | (...)... : String | Test.java:261:41:261:49 | element : String | Test.java:261:61:261:93 | new MultiKey(...) : MultiKey [] : String | Test.java:5208:18:5208:57 | newMultiKeyWithElement(...) : MultiKey [] : String | | Test.java:5210:25:5210:27 | out : Object[] [[]] : String | Test.java:229:24:229:32 | array : Object[] [[]] : String | Test.java:229:44:229:51 | ...[...] : String | Test.java:5210:9:5210:28 | getArrayElement(...) | | Test.java:5215:42:5215:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:5215:20:5215:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:5215:42:5215:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:5215:20:5215:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:5216:35:5216:36 | in : TreeBag [] : String | Test.java:7204:31:7204:64 | coll : TreeBag [] : String | Test.java:7204:10:7204:29 | parameter this [Return] : MyAbstractLinkedList [] : String | Test.java:5216:10:5216:37 | new MyAbstractLinkedList<>(...) : MyAbstractLinkedList [] : String | | Test.java:5217:20:5217:22 | out : MyAbstractLinkedList [] : String | Test.java:230:19:230:32 | it : MyAbstractLinkedList [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:5217:9:5217:23 | getElement(...) | | Test.java:5224:20:5224:22 | out : AbstractLinkedList [] : Object | Test.java:230:19:230:32 | it : AbstractLinkedList [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:5224:9:5224:23 | getElement(...) | @@ -19418,24 +19231,19 @@ subpaths | Test.java:6169:40:6169:55 | (...)... : String | Test.java:297:47:297:53 | value : String | Test.java:297:136:297:136 | m : MultiKeyMap [] : String | Test.java:6169:21:6169:56 | newMKMWithMapValue(...) : MultiKeyMap [] : String | | Test.java:6176:42:6176:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:6176:23:6176:58 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:6176:42:6176:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6176:23:6176:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:6176:42:6176:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6176:23:6176:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:6178:20:6178:22 | out : Collection [] : Object | Test.java:230:19:230:32 | it : Collection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:6178:9:6178:23 | getElement(...) | | Test.java:6178:20:6178:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6178:9:6178:23 | getElement(...) | | Test.java:6183:57:6183:72 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:6183:38:6183:73 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:6183:57:6183:72 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6183:38:6183:73 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:6183:57:6183:72 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6183:38:6183:73 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:6185:30:6185:44 | getElement(...) : Entry [] : Object | Test.java:244:29:244:52 | container : Entry [] : Object | Test.java:244:64:244:83 | getValue(...) : Object | Test.java:6185:9:6185:45 | getMapValueFromEntry(...) | | Test.java:6185:30:6185:44 | getElement(...) : Entry [] : String | Test.java:244:29:244:52 | container : Entry [] : String | Test.java:244:64:244:83 | getValue(...) : String | Test.java:6185:9:6185:45 | getMapValueFromEntry(...) | | Test.java:6185:41:6185:43 | out : Iterator [, ] : Object | Test.java:231:19:231:32 | it : Iterator [, ] : Object | Test.java:231:44:231:52 | next(...) : Object [] : Object | Test.java:6185:30:6185:44 | getElement(...) : Entry [] : Object | | Test.java:6185:41:6185:43 | out : Iterator [, ] : String | Test.java:231:19:231:32 | it : Iterator [, ] : String | Test.java:231:44:231:52 | next(...) : Object [] : String | Test.java:6185:30:6185:44 | getElement(...) : Entry [] : String | | Test.java:6190:55:6190:70 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:6190:38:6190:71 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:6190:55:6190:70 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:6190:38:6190:71 | newMVMWithMapKey(...) : MultiValueMap [] : String | -| Test.java:6190:55:6190:70 | (...)... : String | Test.java:279:47:279:51 | key : String | Test.java:279:131:279:131 | m : MultiValueMap [] : String | Test.java:6190:38:6190:71 | newMVMWithMapKey(...) : MultiValueMap [] : String | | Test.java:6192:28:6192:42 | getElement(...) : Entry [] : String | Test.java:238:27:238:50 | container : Entry [] : String | Test.java:238:62:238:79 | getKey(...) : String | Test.java:6192:9:6192:43 | getMapKeyFromEntry(...) | | Test.java:6192:39:6192:41 | out : Iterator [, ] : String | Test.java:231:19:231:32 | it : Iterator [, ] : String | Test.java:231:44:231:52 | next(...) : Object [] : String | Test.java:6192:28:6192:42 | getElement(...) : Entry [] : String | | Test.java:6197:57:6197:72 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:6197:38:6197:73 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:6197:57:6197:72 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6197:38:6197:73 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:6197:57:6197:72 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6197:38:6197:73 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:6199:20:6199:22 | out : Iterator [] : Object | Test.java:231:19:231:32 | it : Iterator [] : Object | Test.java:231:44:231:52 | next(...) : Object | Test.java:6199:9:6199:23 | getElement(...) | | Test.java:6199:20:6199:22 | out : Iterator [] : String | Test.java:231:19:231:32 | it : Iterator [] : String | Test.java:231:44:231:52 | next(...) : String | Test.java:6199:9:6199:23 | getElement(...) | | Test.java:6204:47:6204:62 | (...)... : String | Test.java:269:37:269:45 | element : String | Test.java:269:103:269:103 | v : Vector [] : String | Test.java:6204:26:6204:63 | newVectorWithElement(...) : Vector [] : String | @@ -19452,7 +19260,6 @@ subpaths | Test.java:6241:19:6241:21 | out : MultiValueMap [] : String | Test.java:228:18:228:29 | map : MultiValueMap [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:6241:9:6241:22 | getMapKey(...) | | Test.java:6246:32:6246:47 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:6246:13:6246:48 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:6246:32:6246:47 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6246:13:6246:48 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:6246:32:6246:47 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6246:13:6246:48 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:6248:20:6248:47 | (...)... : Collection [] : Object | Test.java:230:19:230:32 | it : Collection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:6248:9:6248:48 | getElement(...) | | Test.java:6248:20:6248:47 | (...)... : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6248:9:6248:48 | getElement(...) | | Test.java:6248:44:6248:46 | out : MultiValueMap [, ] : Object | Test.java:232:20:232:31 | map : MultiValueMap [, ] : Object | Test.java:232:43:232:55 | get(...) : Object [] : Object | Test.java:6248:32:6248:47 | getMapValue(...) : Object [] : Object | @@ -19463,12 +19270,10 @@ subpaths | Test.java:6255:44:6255:46 | out : MultiValueMap [] : Object | Test.java:232:20:232:31 | map : MultiValueMap [] : Object | Test.java:232:43:232:55 | get(...) : Object | Test.java:6255:32:6255:47 | getMapValue(...) : Object | | Test.java:6262:19:6262:21 | out : MultiValueMap [] : Object | Test.java:228:18:228:29 | map : MultiValueMap [] : Object | Test.java:228:41:228:70 | next(...) : Object | Test.java:6262:9:6262:22 | getMapKey(...) | | Test.java:6267:42:6267:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6267:20:6267:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:6267:42:6267:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6267:20:6267:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:6269:20:6269:47 | (...)... : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6269:9:6269:48 | getElement(...) | | Test.java:6269:44:6269:46 | out : MultiValueMap [, ] : String | Test.java:232:20:232:31 | map : MultiValueMap [, ] : String | Test.java:232:43:232:55 | get(...) : Object [] : String | Test.java:6269:32:6269:47 | getMapValue(...) : Object [] : String | | Test.java:6274:42:6274:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [, ] : String | Test.java:6274:23:6274:58 | newMVMWithMapValue(...) : MultiValueMap [, ] : String | | Test.java:6274:42:6274:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6274:23:6274:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | -| Test.java:6274:42:6274:57 | (...)... : String | Test.java:298:49:298:55 | value : String | Test.java:298:137:298:137 | m : MultiValueMap [] : String | Test.java:6274:23:6274:58 | newMVMWithMapValue(...) : MultiValueMap [] : String | | Test.java:6276:20:6276:22 | out : Collection [] : Object | Test.java:230:19:230:32 | it : Collection [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:6276:9:6276:23 | getElement(...) | | Test.java:6276:20:6276:22 | out : Collection [] : String | Test.java:230:19:230:32 | it : Collection [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6276:9:6276:23 | getElement(...) | | Test.java:6283:19:6283:21 | out : PassiveExpiringMap [] : String | Test.java:228:18:228:29 | map : PassiveExpiringMap [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:6283:9:6283:22 | getMapKey(...) | @@ -19549,19 +19354,14 @@ subpaths | Test.java:6589:43:6589:58 | (...)... : String | Test.java:272:58:272:62 | key : String | Test.java:272:160:272:160 | m : ArrayListValuedHashMap [] : String | Test.java:6589:24:6589:59 | newALVHMWithMapKey(...) : ArrayListValuedHashMap [] : String | | Test.java:6591:19:6591:21 | out : UnmodifiableMultiValuedMap [] : String | Test.java:240:18:240:46 | container : UnmodifiableMultiValuedMap [] : String | Test.java:240:58:240:93 | next(...) : String | Test.java:6591:9:6591:22 | getMapKey(...) | | Test.java:6596:42:6596:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6596:20:6596:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:6596:42:6596:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6596:20:6596:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:6598:20:6598:22 | out : HashMultiSet [] : String | Test.java:230:19:230:32 | it : HashMultiSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6598:9:6598:23 | getElement(...) | | Test.java:6603:45:6603:60 | (...)... : String | Test.java:258:49:258:57 | element : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | Test.java:6603:18:6603:61 | newHashMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:6603:45:6603:60 | (...)... : String | Test.java:258:49:258:57 | element : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | Test.java:6603:18:6603:61 | newHashMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:6605:20:6605:22 | out : PredicatedMultiSet [] : String | Test.java:230:19:230:32 | it : PredicatedMultiSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6605:9:6605:23 | getElement(...) | | Test.java:6610:45:6610:60 | (...)... : String | Test.java:258:49:258:57 | element : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | Test.java:6610:18:6610:61 | newHashMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:6610:45:6610:60 | (...)... : String | Test.java:258:49:258:57 | element : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | Test.java:6610:18:6610:61 | newHashMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:6612:20:6612:22 | out : SynchronizedMultiSet [] : String | Test.java:230:19:230:32 | it : SynchronizedMultiSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6612:9:6612:23 | getElement(...) | | Test.java:6617:45:6617:60 | (...)... : String | Test.java:258:49:258:57 | element : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | Test.java:6617:18:6617:61 | newHashMultiSetWithElement(...) : HashMultiSet [] : String | -| Test.java:6617:45:6617:60 | (...)... : String | Test.java:258:49:258:57 | element : String | Test.java:258:127:258:127 | x : HashMultiSet [] : String | Test.java:6617:18:6617:61 | newHashMultiSetWithElement(...) : HashMultiSet [] : String | | Test.java:6619:20:6619:22 | out : MultiSet [] : String | Test.java:230:19:230:32 | it : MultiSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6619:9:6619:23 | getElement(...) | | Test.java:6688:42:6688:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6688:20:6688:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:6688:42:6688:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6688:20:6688:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:6690:20:6690:22 | out : CircularFifoQueue [] : String | Test.java:230:19:230:32 | it : CircularFifoQueue [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6690:9:6690:23 | getElement(...) | | Test.java:6695:59:6695:74 | (...)... : String | Test.java:253:59:253:67 | element : String | Test.java:253:147:253:147 | x : CircularFifoQueue [] : String | Test.java:6695:27:6695:75 | newCircularFifoQueueWithElement(...) : CircularFifoQueue [] : String | | Test.java:6702:47:6702:62 | (...)... : String | Test.java:253:59:253:67 | element : String | Test.java:253:147:253:147 | x : CircularFifoQueue [] : String | Test.java:6702:15:6702:63 | newCircularFifoQueueWithElement(...) : CircularFifoQueue [] : String | @@ -19585,10 +19385,8 @@ subpaths | Test.java:6762:20:6762:34 | getElement(...) : Set [] : Object | Test.java:230:19:230:32 | it : Set [] : Object | Test.java:230:44:230:63 | next(...) : Object | Test.java:6762:9:6762:35 | getElement(...) | | Test.java:6762:31:6762:33 | out : List [, ] : Object | Test.java:230:19:230:32 | it : List [, ] : Object | Test.java:230:44:230:63 | next(...) : Object [] : Object | Test.java:6762:20:6762:34 | getElement(...) : Set [] : Object | | Test.java:6767:42:6767:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6767:20:6767:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:6767:42:6767:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6767:20:6767:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:6770:20:6770:22 | out : CompositeSet [] : String | Test.java:230:19:230:32 | it : CompositeSet [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6770:9:6770:23 | getElement(...) | | Test.java:6775:42:6775:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6775:20:6775:58 | newTreeBagWithElement(...) : TreeBag [] : String | -| Test.java:6775:42:6775:57 | (...)... : String | Test.java:267:39:267:47 | element : String | Test.java:267:107:267:107 | b : TreeBag [] : String | Test.java:6775:20:6775:58 | newTreeBagWithElement(...) : TreeBag [] : String | | Test.java:6778:20:6778:34 | getElement(...) : Set [] : String | Test.java:230:19:230:32 | it : Set [] : String | Test.java:230:44:230:63 | next(...) : String | Test.java:6778:9:6778:35 | getElement(...) | | Test.java:6778:31:6778:33 | out : List [, ] : String | Test.java:230:19:230:32 | it : List [, ] : String | Test.java:230:44:230:63 | next(...) : Object [] : String | Test.java:6778:20:6778:34 | getElement(...) : Set [] : String | | Test.java:6783:42:6783:57 | (...)... : String | Test.java:260:53:260:61 | element : String | Test.java:260:135:260:135 | x : ListOrderedSet [] : String | Test.java:6783:13:6783:58 | newListOrderedSetWithElement(...) : ListOrderedSet [] : String | @@ -19643,19 +19441,13 @@ subpaths | Test.java:6988:19:6988:21 | out : PatriciaTrie [] : String | Test.java:228:18:228:29 | map : PatriciaTrie [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:6988:9:6988:22 | getMapKey(...) | | Test.java:6995:21:6995:23 | out : PatriciaTrie [] : String | Test.java:232:20:232:31 | map : PatriciaTrie [] : String | Test.java:232:43:232:55 | get(...) : String | Test.java:6995:9:6995:24 | getMapValue(...) | | Test.java:6999:56:6999:71 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:6999:30:6999:72 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | -| Test.java:6999:56:6999:71 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:6999:30:6999:72 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | | Test.java:7002:28:7002:30 | out : Entry [] : String | Test.java:238:27:238:50 | container : Entry [] : String | Test.java:238:62:238:79 | getKey(...) : String | Test.java:7002:9:7002:31 | getMapKeyFromEntry(...) | | Test.java:7006:58:7006:73 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:7006:30:7006:74 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | -| Test.java:7006:58:7006:73 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:7006:30:7006:74 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:7009:30:7009:32 | out : Entry [] : String | Test.java:244:29:244:52 | container : Entry [] : String | Test.java:244:64:244:83 | getValue(...) : String | Test.java:7009:9:7009:33 | getMapValueFromEntry(...) | | Test.java:7013:56:7013:71 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:7013:30:7013:72 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | -| Test.java:7013:56:7013:71 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:7013:30:7013:72 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | | Test.java:7020:58:7020:73 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:7020:30:7020:74 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | -| Test.java:7020:58:7020:73 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:7020:30:7020:74 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | -| Test.java:7028:40:7028:55 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:7028:14:7028:56 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | | Test.java:7028:40:7028:55 | (...)... : String | Test.java:288:49:288:58 | key : String | Test.java:288:134:288:134 | m : PatriciaTrie [] : String | Test.java:7028:14:7028:56 | newPatriciaTrieWithMapKey(...) : PatriciaTrie [] : String | | Test.java:7030:19:7030:21 | out : Trie [] : String | Test.java:228:18:228:29 | map : Trie [] : String | Test.java:228:41:228:70 | next(...) : String | Test.java:7030:9:7030:22 | getMapKey(...) | | Test.java:7035:42:7035:57 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:7035:14:7035:58 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | -| Test.java:7035:42:7035:57 | (...)... : String | Test.java:307:50:307:56 | value : String | Test.java:307:129:307:129 | m : PatriciaTrie [] : String | Test.java:7035:14:7035:58 | newPatriciaTrieWithMapValue(...) : PatriciaTrie [] : String | | Test.java:7037:21:7037:23 | out : Trie [] : String | Test.java:232:20:232:31 | map : Trie [] : String | Test.java:232:43:232:55 | get(...) : String | Test.java:7037:9:7037:24 | getMapValue(...) | testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/beans/test.expected b/java/ql/test/library-tests/frameworks/spring/beans/test.expected index 8c015c105f9..f2ed45d01da 100644 --- a/java/ql/test/library-tests/frameworks/spring/beans/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/beans/test.expected @@ -312,13 +312,8 @@ nodes | Test.java:21:10:21:18 | container : MutablePropertyValues [] : PropertyValue | semmle.label | container : MutablePropertyValues [] : PropertyValue | | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | semmle.label | getPropertyValue(...) : PropertyValue | | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | semmle.label | getPropertyValue(...) : PropertyValue | -| Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | semmle.label | getPropertyValue(...) : PropertyValue | -| Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | semmle.label | getPropertyValue(...) : PropertyValue | -| Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | semmle.label | getPropertyValue(...) : PropertyValue [] : Object | | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | semmle.label | getPropertyValue(...) : PropertyValue [] : Object | | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : String | semmle.label | getPropertyValue(...) : PropertyValue [] : String | -| Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : String | semmle.label | getPropertyValue(...) : PropertyValue [] : String | -| Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | semmle.label | getPropertyValue(...) : PropertyValue [] : Object | | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | semmle.label | getPropertyValue(...) : PropertyValue [] : Object | | Test.java:24:26:24:48 | container : PropertyValue [] : Object | semmle.label | container : PropertyValue [] : Object | | Test.java:24:26:24:48 | container : PropertyValue [] : String | semmle.label | container : PropertyValue [] : String | @@ -540,39 +535,27 @@ nodes | Test.java:279:25:279:27 | out : PropertyValue[] [[]] : PropertyValue | semmle.label | out : PropertyValue[] [[]] : PropertyValue | subpaths | Test.java:57:27:57:29 | out : MutablePropertyValues [] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:57:9:57:30 | getElementDefault(...) | -| Test.java:57:27:57:29 | out : MutablePropertyValues [] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:57:9:57:30 | getElementDefault(...) | | Test.java:64:26:64:47 | getElementDefault(...) : PropertyValue [] : Object | Test.java:24:26:24:48 | container : PropertyValue [] : Object | Test.java:25:10:25:28 | getName(...) : String | Test.java:64:9:64:48 | getMapKeyDefault(...) | | Test.java:64:44:64:46 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:64:26:64:47 | getElementDefault(...) : PropertyValue [] : Object | -| Test.java:64:44:64:46 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:64:26:64:47 | getElementDefault(...) : PropertyValue [] : Object | | Test.java:71:28:71:49 | getElementDefault(...) : PropertyValue [] : Object | Test.java:28:28:28:50 | container : PropertyValue [] : Object | Test.java:29:10:29:29 | getValue(...) : Object | Test.java:71:9:71:50 | getMapValueDefault(...) | | Test.java:71:46:71:48 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:71:28:71:49 | getElementDefault(...) : PropertyValue [] : Object | -| Test.java:71:46:71:48 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:71:28:71:49 | getElementDefault(...) : PropertyValue [] : Object | | Test.java:76:60:76:83 | (...)... : PropertyValue | Test.java:32:60:32:80 | element : PropertyValue | Test.java:33:10:33:52 | new MutablePropertyValues(...) : MutablePropertyValues [] : PropertyValue | Test.java:76:24:76:84 | newMutablePropertyValuesWithElement(...) : MutablePropertyValues [] : PropertyValue | | Test.java:78:27:78:29 | out : MutablePropertyValues [] : PropertyValue | Test.java:20:34:20:64 | container : MutablePropertyValues [] : PropertyValue | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:78:9:78:30 | getElementDefault(...) | -| Test.java:78:27:78:29 | out : MutablePropertyValues [] : PropertyValue | Test.java:20:34:20:64 | container : MutablePropertyValues [] : PropertyValue | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:78:9:78:30 | getElementDefault(...) | | Test.java:92:26:92:47 | getElementDefault(...) : PropertyValue [] : String | Test.java:24:26:24:48 | container : PropertyValue [] : String | Test.java:25:10:25:28 | getName(...) : String | Test.java:92:9:92:48 | getMapKeyDefault(...) | | Test.java:92:44:92:46 | out : MutablePropertyValues [, ] : String | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : String | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : String | Test.java:92:26:92:47 | getElementDefault(...) : PropertyValue [] : String | -| Test.java:92:44:92:46 | out : MutablePropertyValues [, ] : String | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : String | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : String | Test.java:92:26:92:47 | getElementDefault(...) : PropertyValue [] : String | | Test.java:99:28:99:49 | getElementDefault(...) : PropertyValue [] : Object | Test.java:28:28:28:50 | container : PropertyValue [] : Object | Test.java:29:10:29:29 | getValue(...) : Object | Test.java:99:9:99:50 | getMapValueDefault(...) | | Test.java:99:46:99:48 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:99:28:99:49 | getElementDefault(...) : PropertyValue [] : Object | -| Test.java:99:46:99:48 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:99:28:99:49 | getElementDefault(...) : PropertyValue [] : Object | -| Test.java:113:27:113:29 | out : MutablePropertyValues [] : PropertyValue | Test.java:20:34:20:64 | container : MutablePropertyValues [] : PropertyValue | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:113:9:113:30 | getElementDefault(...) | | Test.java:113:27:113:29 | out : MutablePropertyValues [] : PropertyValue | Test.java:20:34:20:64 | container : MutablePropertyValues [] : PropertyValue | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:113:9:113:30 | getElementDefault(...) | | Test.java:120:26:120:47 | getElementDefault(...) : PropertyValue [] : String | Test.java:24:26:24:48 | container : PropertyValue [] : String | Test.java:25:10:25:28 | getName(...) : String | Test.java:120:9:120:48 | getMapKeyDefault(...) | | Test.java:120:44:120:46 | out : MutablePropertyValues [, ] : String | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : String | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : String | Test.java:120:26:120:47 | getElementDefault(...) : PropertyValue [] : String | -| Test.java:120:44:120:46 | out : MutablePropertyValues [, ] : String | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : String | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : String | Test.java:120:26:120:47 | getElementDefault(...) : PropertyValue [] : String | | Test.java:127:28:127:49 | getElementDefault(...) : PropertyValue [] : Object | Test.java:28:28:28:50 | container : PropertyValue [] : Object | Test.java:29:10:29:29 | getValue(...) : Object | Test.java:127:9:127:50 | getMapValueDefault(...) | | Test.java:127:46:127:48 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:127:28:127:49 | getElementDefault(...) : PropertyValue [] : Object | -| Test.java:127:46:127:48 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:127:28:127:49 | getElementDefault(...) : PropertyValue [] : Object | | Test.java:141:26:141:47 | getElementDefault(...) : PropertyValue [] : Object | Test.java:24:26:24:48 | container : PropertyValue [] : Object | Test.java:25:10:25:28 | getName(...) : String | Test.java:141:9:141:48 | getMapKeyDefault(...) | | Test.java:141:44:141:46 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:141:26:141:47 | getElementDefault(...) : PropertyValue [] : Object | -| Test.java:141:44:141:46 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:141:26:141:47 | getElementDefault(...) : PropertyValue [] : Object | | Test.java:148:28:148:49 | getElementDefault(...) : PropertyValue [] : Object | Test.java:28:28:28:50 | container : PropertyValue [] : Object | Test.java:29:10:29:29 | getValue(...) : Object | Test.java:148:9:148:50 | getMapValueDefault(...) | | Test.java:148:46:148:48 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:148:28:148:49 | getElementDefault(...) : PropertyValue [] : Object | -| Test.java:148:46:148:48 | out : MutablePropertyValues [, ] : Object | Test.java:20:34:20:64 | container : MutablePropertyValues [, ] : Object | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue [] : Object | Test.java:148:28:148:49 | getElementDefault(...) : PropertyValue [] : Object | | Test.java:160:60:160:83 | (...)... : PropertyValue | Test.java:32:60:32:80 | element : PropertyValue | Test.java:33:10:33:52 | new MutablePropertyValues(...) : MutablePropertyValues [] : PropertyValue | Test.java:160:24:160:84 | newMutablePropertyValuesWithElement(...) : MutablePropertyValues [] : PropertyValue | | Test.java:162:27:162:29 | out : MutablePropertyValues [] : PropertyValue | Test.java:20:34:20:64 | container : MutablePropertyValues [] : PropertyValue | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:162:9:162:30 | getElementDefault(...) | -| Test.java:162:27:162:29 | out : MutablePropertyValues [] : PropertyValue | Test.java:20:34:20:64 | container : MutablePropertyValues [] : PropertyValue | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:162:9:162:30 | getElementDefault(...) | | Test.java:167:68:167:75 | source(...) : Object | Test.java:40:61:40:74 | element : Object | Test.java:41:10:41:57 | new MutablePropertyValues(...) : MutablePropertyValues [, ] : Object | Test.java:167:31:167:76 | newMutablePropertyValuesWithMapValue(...) : MutablePropertyValues [, ] : Object | | Test.java:175:42:175:65 | (...)... : PropertyValue | Test.java:32:60:32:80 | element : PropertyValue | Test.java:33:10:33:52 | new MutablePropertyValues(...) : MutablePropertyValues [] : PropertyValue | Test.java:175:6:175:66 | newMutablePropertyValuesWithElement(...) : MutablePropertyValues [] : PropertyValue | | Test.java:183:42:183:65 | (...)... : PropertyValue | Test.java:32:60:32:80 | element : PropertyValue | Test.java:33:10:33:52 | new MutablePropertyValues(...) : MutablePropertyValues [] : PropertyValue | Test.java:183:6:183:66 | newMutablePropertyValuesWithElement(...) : MutablePropertyValues [] : PropertyValue | @@ -580,7 +563,6 @@ subpaths | Test.java:191:42:191:65 | (...)... : PropertyValue | Test.java:32:60:32:80 | element : PropertyValue | Test.java:33:10:33:52 | new MutablePropertyValues(...) : MutablePropertyValues [] : PropertyValue | Test.java:191:6:191:66 | newMutablePropertyValuesWithElement(...) : MutablePropertyValues [] : PropertyValue | | Test.java:193:25:193:27 | out : PropertyValue[] [[]] : PropertyValue | Test.java:12:24:12:32 | array : PropertyValue[] [[]] : PropertyValue | Test.java:13:10:13:17 | ...[...] : PropertyValue | Test.java:193:9:193:28 | getArrayElement(...) | | Test.java:200:27:200:29 | out : MutablePropertyValues [] : PropertyValue | Test.java:20:34:20:64 | container : MutablePropertyValues [] : PropertyValue | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:200:9:200:30 | getElementDefault(...) | -| Test.java:200:27:200:29 | out : MutablePropertyValues [] : PropertyValue | Test.java:20:34:20:64 | container : MutablePropertyValues [] : PropertyValue | Test.java:21:10:21:39 | getPropertyValue(...) : PropertyValue | Test.java:200:9:200:30 | getElementDefault(...) | | Test.java:214:26:214:28 | out : PropertyValue [] : String | Test.java:24:26:24:48 | container : PropertyValue [] : String | Test.java:25:10:25:28 | getName(...) : String | Test.java:214:9:214:29 | getMapKeyDefault(...) | | Test.java:221:28:221:30 | out : PropertyValue [] : Object | Test.java:28:28:28:50 | container : PropertyValue [] : Object | Test.java:29:10:29:29 | getValue(...) : Object | Test.java:221:9:221:31 | getMapValueDefault(...) | | Test.java:228:26:228:28 | out : PropertyValue [] : String | Test.java:24:26:24:48 | container : PropertyValue [] : String | Test.java:25:10:25:28 | getName(...) : String | Test.java:228:9:228:29 | getMapKeyDefault(...) | diff --git a/java/ql/test/library-tests/frameworks/spring/cache/test.expected b/java/ql/test/library-tests/frameworks/spring/cache/test.expected index 3d15ea5d79f..5183f66ad64 100644 --- a/java/ql/test/library-tests/frameworks/spring/cache/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/cache/test.expected @@ -156,7 +156,6 @@ nodes | Test.java:42:21:42:48 | container : ValueWrapper [] : Object | semmle.label | container : ValueWrapper [] : Object | | Test.java:42:60:42:68 | container : ValueWrapper [] : Object | semmle.label | container : ValueWrapper [] : Object | | Test.java:42:60:42:74 | get(...) : Object | semmle.label | get(...) : Object | -| Test.java:42:60:42:74 | get(...) : Object | semmle.label | get(...) : Object | | Test.java:51:16:51:23 | source(...) : Object | semmle.label | source(...) : Object | | Test.java:52:10:52:58 | new ValueRetrievalException(...) : ValueRetrievalException [] : Object | semmle.label | new ValueRetrievalException(...) : ValueRetrievalException [] : Object | | Test.java:52:44:52:45 | in : Object | semmle.label | in : Object | @@ -228,13 +227,11 @@ nodes | Test.java:137:21:137:23 | out : ValueWrapper [] : Object | semmle.label | out : ValueWrapper [] : Object | subpaths | Test.java:42:60:42:68 | container : ValueWrapper [] : Object | Test.java:18:17:18:19 | parameter this : ValueWrapper [] : Object | Test.java:18:32:18:45 | get(...) : Object | Test.java:42:60:42:74 | get(...) : Object | -| Test.java:42:60:42:68 | container : ValueWrapper [] : Object | Test.java:18:17:18:19 | parameter this : ValueWrapper [] : Object | Test.java:18:32:18:45 | get(...) : Object | Test.java:42:60:42:74 | get(...) : Object | | Test.java:53:19:53:21 | out : ValueRetrievalException [] : Object | Test.java:39:19:39:57 | container : ValueRetrievalException [] : Object | Test.java:39:69:39:86 | getKey(...) : Object | Test.java:53:9:53:22 | getMapKey(...) | | Test.java:65:45:65:52 | source(...) : Object | Test.java:13:16:13:29 | element : Object | Test.java:13:3:13:14 | parameter this [Return] : ValueWrapper [] : Object | Test.java:65:28:65:53 | new ValueWrapper(...) : ValueWrapper [] : Object | | Test.java:66:10:66:11 | in : ValueWrapper [] : Object | Test.java:18:17:18:19 | parameter this : ValueWrapper [] : Object | Test.java:18:32:18:45 | get(...) : Object | Test.java:66:10:66:17 | get(...) : Object | | Test.java:72:36:72:43 | source(...) : Object | Test.java:22:26:22:37 | value : Object | Test.java:22:3:22:12 | parameter this [Return] : DummyCache [] : Object | Test.java:72:15:72:44 | new DummyCache(...) : DummyCache [] : Object | | Test.java:74:21:74:23 | out : ValueWrapper [] : Object | Test.java:42:21:42:48 | container : ValueWrapper [] : Object | Test.java:42:60:42:74 | get(...) : Object | Test.java:74:9:74:24 | getMapValue(...) | -| Test.java:74:21:74:23 | out : ValueWrapper [] : Object | Test.java:42:21:42:48 | container : ValueWrapper [] : Object | Test.java:42:60:42:74 | get(...) : Object | Test.java:74:9:74:24 | getMapValue(...) | | Test.java:79:36:79:43 | source(...) : Object | Test.java:22:26:22:37 | value : Object | Test.java:22:3:22:12 | parameter this [Return] : DummyCache [] : Object | Test.java:79:15:79:44 | new DummyCache(...) : DummyCache [] : Object | | Test.java:86:36:86:43 | source(...) : Object | Test.java:22:26:22:37 | value : Object | Test.java:22:3:22:12 | parameter this [Return] : DummyCache [] : Object | Test.java:86:15:86:44 | new DummyCache(...) : DummyCache [] : Object | | Test.java:93:30:93:37 | source(...) : Object | Test.java:22:14:22:23 | key : Object | Test.java:22:3:22:12 | parameter this [Return] : DummyCache [] : Object | Test.java:93:15:93:44 | new DummyCache(...) : DummyCache [] : Object | @@ -247,5 +244,4 @@ subpaths | Test.java:130:21:130:23 | out : Cache [] : Object | Test.java:41:21:41:35 | container : Cache [] : Object | Test.java:41:47:41:78 | get(...) : Object | Test.java:130:9:130:24 | getMapValue(...) | | Test.java:135:36:135:43 | source(...) : Object | Test.java:22:26:22:37 | value : Object | Test.java:22:3:22:12 | parameter this [Return] : DummyCache [] : Object | Test.java:135:15:135:44 | new DummyCache(...) : DummyCache [] : Object | | Test.java:137:21:137:23 | out : ValueWrapper [] : Object | Test.java:42:21:42:48 | container : ValueWrapper [] : Object | Test.java:42:60:42:74 | get(...) : Object | Test.java:137:9:137:24 | getMapValue(...) | -| Test.java:137:21:137:23 | out : ValueWrapper [] : Object | Test.java:42:21:42:48 | container : ValueWrapper [] : Object | Test.java:42:60:42:74 | get(...) : Object | Test.java:137:9:137:24 | getMapValue(...) | testFailures diff --git a/java/ql/test/library-tests/frameworks/spring/util/test.expected b/java/ql/test/library-tests/frameworks/spring/util/test.expected index f27398764b8..bb5944e8dee 100644 --- a/java/ql/test/library-tests/frameworks/spring/util/test.expected +++ b/java/ql/test/library-tests/frameworks/spring/util/test.expected @@ -208,12 +208,10 @@ edges | Test.java:53:70:53:76 | element : Object | Test.java:53:56:53:77 | {...} : Object[] [[]] : Object | provenance | | | Test.java:54:37:54:50 | element : Object | Test.java:54:94:54:100 | element : Object | provenance | | | Test.java:54:88:54:88 | p [post update] : Properties [] : Object | Test.java:54:117:54:117 | p : Properties [] : Object | provenance | | -| Test.java:54:88:54:88 | p [post update] : Properties [] : Object | Test.java:54:117:54:117 | p : Properties [] : Object | provenance | | | Test.java:54:94:54:100 | element : Object | Test.java:54:88:54:88 | p [post update] : Properties [] : Object | provenance | MaD:5 | | Test.java:54:94:54:100 | element : Object | Test.java:54:88:54:88 | p [post update] : Properties [] : Object | provenance | MaD:13 | | Test.java:55:39:55:52 | element : Object | Test.java:55:102:55:108 | element : Object | provenance | | | Test.java:55:90:55:90 | p [post update] : Properties [] : Object | Test.java:55:119:55:119 | p : Properties [] : Object | provenance | | -| Test.java:55:90:55:90 | p [post update] : Properties [] : Object | Test.java:55:119:55:119 | p : Properties [] : Object | provenance | | | Test.java:55:102:55:108 | element : Object | Test.java:55:90:55:90 | p [post update] : Properties [] : Object | provenance | MaD:6 | | Test.java:55:102:55:108 | element : Object | Test.java:55:90:55:90 | p [post update] : Properties [] : Object | provenance | MaD:14 | | Test.java:66:17:66:32 | (...)... : String | Test.java:67:33:67:34 | in : String | provenance | | @@ -1264,16 +1262,12 @@ nodes | Test.java:53:70:53:76 | element : Object | semmle.label | element : Object | | Test.java:54:37:54:50 | element : Object | semmle.label | element : Object | | Test.java:54:88:54:88 | p [post update] : Properties [] : Object | semmle.label | p [post update] : Properties [] : Object | -| Test.java:54:88:54:88 | p [post update] : Properties [] : Object | semmle.label | p [post update] : Properties [] : Object | | Test.java:54:94:54:100 | element : Object | semmle.label | element : Object | | Test.java:54:117:54:117 | p : Properties [] : Object | semmle.label | p : Properties [] : Object | -| Test.java:54:117:54:117 | p : Properties [] : Object | semmle.label | p : Properties [] : Object | | Test.java:55:39:55:52 | element : Object | semmle.label | element : Object | | Test.java:55:90:55:90 | p [post update] : Properties [] : Object | semmle.label | p [post update] : Properties [] : Object | -| Test.java:55:90:55:90 | p [post update] : Properties [] : Object | semmle.label | p [post update] : Properties [] : Object | | Test.java:55:102:55:108 | element : Object | semmle.label | element : Object | | Test.java:55:119:55:119 | p : Properties [] : Object | semmle.label | p : Properties [] : Object | -| Test.java:55:119:55:119 | p : Properties [] : Object | semmle.label | p : Properties [] : Object | | Test.java:66:17:66:32 | (...)... : String | semmle.label | (...)... : String | | Test.java:66:25:66:32 | source(...) : Object | semmle.label | source(...) : Object | | Test.java:67:33:67:34 | in : String | semmle.label | in : String | @@ -2338,10 +2332,8 @@ subpaths | Test.java:251:38:251:45 | source(...) : Object | Test.java:53:31:53:44 | element : Object | Test.java:53:56:53:77 | new Object[] : Object[] [[]] : Object | Test.java:251:18:251:46 | newWithArrayElement(...) : Object[] [[]] : Object | | Test.java:253:20:253:22 | out : Collection [] : Object | Test.java:49:19:49:41 | container : Collection [] : Object | Test.java:49:53:49:79 | next(...) : Object | Test.java:253:9:253:23 | getElement(...) | | Test.java:258:44:258:51 | source(...) : Object | Test.java:54:37:54:50 | element : Object | Test.java:54:117:54:117 | p : Properties [] : Object | Test.java:258:20:258:52 | newPropertiesWithMapKey(...) : Properties [] : Object | -| Test.java:258:44:258:51 | source(...) : Object | Test.java:54:37:54:50 | element : Object | Test.java:54:117:54:117 | p : Properties [] : Object | Test.java:258:20:258:52 | newPropertiesWithMapKey(...) : Properties [] : Object | | Test.java:260:19:260:21 | out : Map [] : Object | Test.java:51:21:51:39 | container : Map [] : Object | Test.java:51:51:51:86 | next(...) : Object | Test.java:260:9:260:22 | getMapKey(...) | | Test.java:265:46:265:53 | source(...) : Object | Test.java:55:39:55:52 | element : Object | Test.java:55:119:55:119 | p : Properties [] : Object | Test.java:265:20:265:54 | newPropertiesWithMapValue(...) : Properties [] : Object | -| Test.java:265:46:265:53 | source(...) : Object | Test.java:55:39:55:52 | element : Object | Test.java:55:119:55:119 | p : Properties [] : Object | Test.java:265:20:265:54 | newPropertiesWithMapValue(...) : Properties [] : Object | | Test.java:267:21:267:23 | out : Map [] : Object | Test.java:52:23:52:41 | container : Map [] : Object | Test.java:52:53:52:71 | get(...) : Object | Test.java:267:9:267:24 | getMapValue(...) | | Test.java:274:20:274:22 | out : Iterator [] : Object | Test.java:50:19:50:39 | container : Iterator [] : Object | Test.java:50:51:50:66 | next(...) : Object | Test.java:274:9:274:23 | getElement(...) | | Test.java:281:20:281:35 | getMapValue(...) : List [] : Object | Test.java:49:19:49:41 | container : List [] : Object | Test.java:49:53:49:79 | next(...) : Object | Test.java:281:9:281:36 | getElement(...) | diff --git a/java/ql/test/library-tests/frameworks/stream/test.expected b/java/ql/test/library-tests/frameworks/stream/test.expected index ddb42b6a63d..8fc629e7fd7 100644 --- a/java/ql/test/library-tests/frameworks/stream/test.expected +++ b/java/ql/test/library-tests/frameworks/stream/test.expected @@ -305,12 +305,16 @@ edges | Test.java:239:18:239:19 | a1 [Return] : Object[] [[]] : Object | Test.java:250:18:250:18 | a : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | | Test.java:239:18:239:19 | a1 [Return] : Object[] [[]] : Object | Test.java:254:18:254:19 | a1 : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | | Test.java:239:18:239:19 | a1 [Return] : Object[] [[]] : Object | Test.java:254:22:254:23 | a2 : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | +| Test.java:239:18:239:19 | a1 [Return] : Object[] [[]] : Object | Test.java:265:18:265:19 | a1 : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | +| Test.java:239:18:239:19 | a1 [Return] : Object[] [[]] : Object | Test.java:265:22:265:23 | a2 : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | | Test.java:239:22:239:23 | a2 [Return] : Object[] [[]] : Object | Test.java:238:18:238:18 | a : Object[] [[]] : Object | provenance | MaD:16 | | Test.java:239:22:239:23 | a2 [Return] : Object[] [[]] : Object | Test.java:238:18:238:18 | a : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | | Test.java:239:22:239:23 | a2 [Return] : Object[] [[]] : Object | Test.java:250:18:250:18 | a : Object[] [[]] : Object | provenance | MaD:16 | | Test.java:239:22:239:23 | a2 [Return] : Object[] [[]] : Object | Test.java:250:18:250:18 | a : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | | Test.java:239:22:239:23 | a2 [Return] : Object[] [[]] : Object | Test.java:254:18:254:19 | a1 : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | | Test.java:239:22:239:23 | a2 [Return] : Object[] [[]] : Object | Test.java:254:22:254:23 | a2 : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | +| Test.java:239:22:239:23 | a2 [Return] : Object[] [[]] : Object | Test.java:265:18:265:19 | a1 : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | +| Test.java:239:22:239:23 | a2 [Return] : Object[] [[]] : Object | Test.java:265:22:265:23 | a2 : Object[] [[]] : Object | provenance | MaD:16+MaD:14 | | Test.java:240:21:240:22 | a1 [post update] : Object[] [[]] : Object | Test.java:239:18:239:19 | a1 [Return] : Object[] [[]] : Object | provenance | | | Test.java:240:29:240:47 | source(...) : Object | Test.java:240:21:240:22 | a1 [post update] : Object[] [[]] : Object | provenance | | | Test.java:241:21:241:22 | a2 [post update] : Object[] [[]] : Object | Test.java:239:22:239:23 | a2 [Return] : Object[] [[]] : Object | provenance | | @@ -324,6 +328,8 @@ edges | Test.java:249:23:249:58 | new Object[] : Object[] [[]] : Object | Test.java:250:18:250:18 | a : Object[] [[]] : Object | provenance | MaD:13+MaD:14 | | Test.java:249:23:249:58 | new Object[] : Object[] [[]] : Object | Test.java:254:18:254:19 | a1 : Object[] [[]] : Object | provenance | MaD:13+MaD:14 | | Test.java:249:23:249:58 | new Object[] : Object[] [[]] : Object | Test.java:254:22:254:23 | a2 : Object[] [[]] : Object | provenance | MaD:13+MaD:14 | +| Test.java:249:23:249:58 | new Object[] : Object[] [[]] : Object | Test.java:265:18:265:19 | a1 : Object[] [[]] : Object | provenance | MaD:13+MaD:14 | +| Test.java:249:23:249:58 | new Object[] : Object[] [[]] : Object | Test.java:265:22:265:23 | a2 : Object[] [[]] : Object | provenance | MaD:13+MaD:14 | | Test.java:249:23:249:58 | {...} : Object[] [[]] : Object | Test.java:249:23:249:58 | new Object[] : Object[] [[]] : Object | provenance | | | Test.java:249:38:249:56 | source(...) : Object | Test.java:249:23:249:58 | {...} : Object[] [[]] : Object | provenance | | | Test.java:250:18:250:18 | a : Object[] [[]] : Object | Test.java:251:26:251:26 | a : Object[] [[]] : Object | provenance | | @@ -335,6 +341,8 @@ edges | Test.java:250:18:250:18 | a [Return] : Object[] [[]] : Object | Test.java:250:18:250:18 | a : Object[] [[]] : Object | provenance | MaD:14+MaD:16 | | Test.java:250:18:250:18 | a [Return] : Object[] [[]] : Object | Test.java:254:18:254:19 | a1 : Object[] [[]] : Object | provenance | MaD:14 | | Test.java:250:18:250:18 | a [Return] : Object[] [[]] : Object | Test.java:254:22:254:23 | a2 : Object[] [[]] : Object | provenance | MaD:14 | +| Test.java:250:18:250:18 | a [Return] : Object[] [[]] : Object | Test.java:265:18:265:19 | a1 : Object[] [[]] : Object | provenance | MaD:14 | +| Test.java:250:18:250:18 | a [Return] : Object[] [[]] : Object | Test.java:265:22:265:23 | a2 : Object[] [[]] : Object | provenance | MaD:14 | | Test.java:251:26:251:26 | a : Object[] [[]] : Object | Test.java:251:26:251:29 | ...[...] | provenance | | | Test.java:252:21:252:21 | a [post update] : Object[] [[]] : Object | Test.java:250:18:250:18 | a [Return] : Object[] [[]] : Object | provenance | | | Test.java:252:28:252:46 | source(...) : Object | Test.java:252:21:252:21 | a [post update] : Object[] [[]] : Object | provenance | | @@ -347,10 +355,20 @@ edges | Test.java:261:43:261:61 | source(...) : Object | Test.java:261:33:261:62 | of(...) : Stream [] : Object | provenance | MaD:56 | | Test.java:262:28:262:29 | in : Stream [] : Object | Test.java:262:28:268:18 | collect(...) : Object[] [[]] : Object | provenance | MaD:12 | | Test.java:262:28:262:29 | in : Stream [] : Object | Test.java:264:21:264:21 | x : Object | provenance | MaD:12 | +| Test.java:262:28:262:29 | in : Stream [] : Object | Test.java:265:18:265:19 | a1 : Object[] [[]] : Object | provenance | MaD:12 | +| Test.java:262:28:262:29 | in : Stream [] : Object | Test.java:265:22:265:23 | a2 : Object[] [[]] : Object | provenance | MaD:12 | | Test.java:262:28:268:18 | collect(...) : Object[] [[]] : Object | Test.java:269:18:269:20 | out : Object[] [[]] : Object | provenance | | | Test.java:264:21:264:21 | x : Object | Test.java:264:36:264:36 | x : Object | provenance | | | Test.java:264:29:264:29 | a [post update] : Object[] [[]] : Object | Test.java:264:18:264:18 | a [Return] : Object[] [[]] : Object | provenance | | | Test.java:264:36:264:36 | x : Object | Test.java:264:29:264:29 | a [post update] : Object[] [[]] : Object | provenance | | +| Test.java:265:18:265:19 | a1 : Object[] [[]] : Object | Test.java:267:29:267:30 | a1 : Object[] [[]] : Object | provenance | | +| Test.java:265:22:265:23 | a2 : Object[] [[]] : Object | Test.java:266:29:266:30 | a2 : Object[] [[]] : Object | provenance | | +| Test.java:266:21:266:22 | a1 [post update] : Object[] [[]] : Object | Test.java:265:18:265:19 | a1 [Return] : Object[] [[]] : Object | provenance | | +| Test.java:266:29:266:30 | a2 : Object[] [[]] : Object | Test.java:266:29:266:33 | ...[...] : Object | provenance | | +| Test.java:266:29:266:33 | ...[...] : Object | Test.java:266:21:266:22 | a1 [post update] : Object[] [[]] : Object | provenance | | +| Test.java:267:21:267:22 | a2 [post update] : Object[] [[]] : Object | Test.java:265:22:265:23 | a2 [Return] : Object[] [[]] : Object | provenance | | +| Test.java:267:29:267:30 | a1 : Object[] [[]] : Object | Test.java:267:29:267:33 | ...[...] : Object | provenance | | +| Test.java:267:29:267:33 | ...[...] : Object | Test.java:267:21:267:22 | a2 [post update] : Object[] [[]] : Object | provenance | | | Test.java:269:18:269:20 | out : Object[] [[]] : Object | Test.java:269:18:269:23 | ...[...] | provenance | | | Test.java:273:33:273:62 | of(...) : Stream [] : Object | Test.java:274:13:274:14 | in : Stream [] : Object | provenance | | | Test.java:273:43:273:61 | source(...) : Object | Test.java:273:33:273:62 | of(...) : Stream [] : Object | provenance | MaD:56 | @@ -790,6 +808,16 @@ nodes | Test.java:264:21:264:21 | x : Object | semmle.label | x : Object | | Test.java:264:29:264:29 | a [post update] : Object[] [[]] : Object | semmle.label | a [post update] : Object[] [[]] : Object | | Test.java:264:36:264:36 | x : Object | semmle.label | x : Object | +| Test.java:265:18:265:19 | a1 : Object[] [[]] : Object | semmle.label | a1 : Object[] [[]] : Object | +| Test.java:265:18:265:19 | a1 [Return] : Object[] [[]] : Object | semmle.label | a1 [Return] : Object[] [[]] : Object | +| Test.java:265:22:265:23 | a2 : Object[] [[]] : Object | semmle.label | a2 : Object[] [[]] : Object | +| Test.java:265:22:265:23 | a2 [Return] : Object[] [[]] : Object | semmle.label | a2 [Return] : Object[] [[]] : Object | +| Test.java:266:21:266:22 | a1 [post update] : Object[] [[]] : Object | semmle.label | a1 [post update] : Object[] [[]] : Object | +| Test.java:266:29:266:30 | a2 : Object[] [[]] : Object | semmle.label | a2 : Object[] [[]] : Object | +| Test.java:266:29:266:33 | ...[...] : Object | semmle.label | ...[...] : Object | +| Test.java:267:21:267:22 | a2 [post update] : Object[] [[]] : Object | semmle.label | a2 [post update] : Object[] [[]] : Object | +| Test.java:267:29:267:30 | a1 : Object[] [[]] : Object | semmle.label | a1 : Object[] [[]] : Object | +| Test.java:267:29:267:33 | ...[...] : Object | semmle.label | ...[...] : Object | | Test.java:269:18:269:20 | out : Object[] [[]] : Object | semmle.label | out : Object[] [[]] : Object | | Test.java:269:18:269:23 | ...[...] | semmle.label | ...[...] | | Test.java:273:33:273:62 | of(...) : Stream [] : Object | semmle.label | of(...) : Stream [] : Object | @@ -1010,6 +1038,8 @@ subpaths | Test.java:208:34:208:36 | out : Object[] [[]] : Object | Test.java:16:27:16:35 | array : Object[] [[]] : Object | Test.java:16:47:16:54 | ...[...] : Object | Test.java:208:18:208:37 | getArrayElement(...) | | Test.java:215:29:215:31 | out : List [] : Object | Test.java:18:22:18:35 | it : List [] : Object | Test.java:18:47:18:66 | next(...) : Object | Test.java:215:18:215:32 | getElement(...) | | Test.java:262:28:262:29 | in : Stream [] : Object | Test.java:264:21:264:21 | x : Object | Test.java:264:18:264:18 | a [Return] : Object[] [[]] : Object | Test.java:262:28:268:18 | collect(...) : Object[] [[]] : Object | +| Test.java:262:28:262:29 | in : Stream [] : Object | Test.java:265:18:265:19 | a1 : Object[] [[]] : Object | Test.java:265:22:265:23 | a2 [Return] : Object[] [[]] : Object | Test.java:262:28:268:18 | collect(...) : Object[] [[]] : Object | +| Test.java:262:28:262:29 | in : Stream [] : Object | Test.java:265:22:265:23 | a2 : Object[] [[]] : Object | Test.java:265:18:265:19 | a1 [Return] : Object[] [[]] : Object | Test.java:262:28:268:18 | collect(...) : Object[] [[]] : Object | | Test.java:289:29:289:31 | out : Stream [] : Object | Test.java:17:22:17:38 | s : Stream [] : Object | Test.java:17:50:17:68 | next(...) : Object | Test.java:289:18:289:32 | getElement(...) | | Test.java:319:29:319:31 | out : Stream [] : Object | Test.java:17:22:17:38 | s : Stream [] : Object | Test.java:17:50:17:68 | next(...) : Object | Test.java:319:18:319:32 | getElement(...) | | Test.java:335:29:335:31 | out : Stream [] : Object | Test.java:17:22:17:38 | s : Stream [] : Object | Test.java:17:50:17:68 | next(...) : Object | Test.java:335:18:335:32 | getElement(...) | From c99a84689b8665d8d2664218c524365fd4aabc53 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 21 Aug 2024 09:56:08 +0100 Subject: [PATCH 063/404] Switch test expectations to use unix-style paths --- .../all-platforms/go/configure-baseline/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py b/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py index ea414349666..b0dbb86365b 100644 --- a/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py +++ b/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py @@ -6,4 +6,4 @@ def test(codeql, go): baseline_info_path = os.path.join("test-db", "baseline-info.json") with open(baseline_info_path, "r") as f: baseline_info = json.load(f) - assert set(baseline_info["languages"]["go"]["files"]) == set(["root.go", os.path.join("c", "vendor", "cvendor.go")]), "Expected root.go and cvendor.go in baseline" + assert set(baseline_info["languages"]["go"]["files"]) == set(["root.go", "c/vendor/cvendor.go")]), "Expected root.go and cvendor.go in baseline" From 2939cefc68d38685c069ad90aa780a8b9a264308 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 21 Aug 2024 10:15:44 +0100 Subject: [PATCH 064/404] Use platform path separators for file testing, and forward-slashes for reporting to CodeQL --- go/extractor/configurebaseline/configurebaseline.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go/extractor/configurebaseline/configurebaseline.go b/go/extractor/configurebaseline/configurebaseline.go index fa8023f24a8..f8e2c998f8c 100644 --- a/go/extractor/configurebaseline/configurebaseline.go +++ b/go/extractor/configurebaseline/configurebaseline.go @@ -18,7 +18,7 @@ func fileExists(path string) bool { // Decides if `dirPath` is a vendor directory by testing whether it is called `vendor` // and contains a `modules.txt` file. func isGolangVendorDirectory(dirPath string) bool { - return path.Base(dirPath) == "vendor" && fileExists(path.Join(dirPath, "modules.txt")) + return filepath.Base(dirPath) == "vendor" && fileExists(filepath.Join(dirPath, "modules.txt")) } type BaselineConfig struct { @@ -38,7 +38,8 @@ func GetConfigBaselineAsJSON(rootDir string) ([]byte, error) { return nil } if isGolangVendorDirectory(dirPath) { - vendorDirs = append(vendorDirs, path.Join(dirPath, "**")) + // Note that CodeQL expects a forward-slash-separated path, even on Windows. + vendorDirs = append(vendorDirs, path.Join(filepath.ToSlash(dirPath), "**")) return filepath.SkipDir } else { return nil From f13f19d5dc749666da62136cb1e8e5efa27e2000 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 21 Aug 2024 10:22:42 +0100 Subject: [PATCH 065/404] Fix typo --- .../all-platforms/go/configure-baseline/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py b/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py index b0dbb86365b..e92cc868cab 100644 --- a/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py +++ b/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py @@ -6,4 +6,4 @@ def test(codeql, go): baseline_info_path = os.path.join("test-db", "baseline-info.json") with open(baseline_info_path, "r") as f: baseline_info = json.load(f) - assert set(baseline_info["languages"]["go"]["files"]) == set(["root.go", "c/vendor/cvendor.go")]), "Expected root.go and cvendor.go in baseline" + assert set(baseline_info["languages"]["go"]["files"]) == set(["root.go", "c/vendor/cvendor.go"]), "Expected root.go and cvendor.go in baseline" From 5d14307ea24750a8ba9e8443ebf76e339e03c75e Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 21 Aug 2024 11:53:50 +0200 Subject: [PATCH 066/404] C#: Add a SQL injection test case for ASP.NET. --- .../Security Features/CWE-089/SqlInjection.cs | 29 +++++ .../CWE-089/SqlInjection.expected | 110 +++++++++--------- .../Security Features/CWE-089/options | 1 + 3 files changed, 85 insertions(+), 55 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.cs b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.cs index b698edfddce..38dcf94ef8d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.cs @@ -10,7 +10,12 @@ namespace Test using System.Data; using System.Data.Entity; using System.Data.SqlClient; + using System.Diagnostics.CodeAnalysis; + using System.Threading; + using System.Threading.Tasks; using System.Web.UI.WebControls; + using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Mvc; public class EntityFrameworkContext : DbContext { @@ -110,4 +115,28 @@ namespace Test System.Windows.Forms.TextBox box1; } + + public abstract class MyController : Controller + { + [HttpPost("{userId:string}")] + public async Task GetUserById([FromRoute] string userId, CancellationToken cancellationToken) + { + // This is a vulnerable method due to SQL injection + string query = "SELECT * FROM Users WHERE UserId = '" + userId + "'"; + + using (SqlConnection connection = new SqlConnection("YourConnectionString")) + { + SqlCommand command = new SqlCommand(query, connection); + connection.Open(); + + SqlDataReader reader = command.ExecuteReader(); + while (reader.Read()) + { + Console.WriteLine(String.Format("{0}, {1}", reader["UserId"], reader["Username"])); + } + } + + return Ok(); + } + } } diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected index a6f74041843..df48e097cf8 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected @@ -1,14 +1,14 @@ #select | SecondOrderSqlInjection.cs:25:71:25:145 | ... + ... | SecondOrderSqlInjection.cs:20:48:20:78 | call to method ExecuteReader : SqlDataReader | SecondOrderSqlInjection.cs:25:71:25:145 | ... + ... | This query depends on $@. | SecondOrderSqlInjection.cs:20:48:20:78 | call to method ExecuteReader : SqlDataReader | this database input | | SecondOrderSqlInjection.cs:45:57:45:59 | access to local variable sql | SecondOrderSqlInjection.cs:33:36:33:78 | object creation of type FileStream : FileStream | SecondOrderSqlInjection.cs:45:57:45:59 | access to local variable sql | This query depends on $@. | SecondOrderSqlInjection.cs:33:36:33:78 | object creation of type FileStream : FileStream | this file stream | -| SqlInjection.cs:34:50:34:55 | access to local variable query1 | SqlInjection.cs:33:21:33:35 | access to field categoryTextBox : TextBox | SqlInjection.cs:34:50:34:55 | access to local variable query1 | This query depends on $@. | SqlInjection.cs:33:21:33:35 | access to field categoryTextBox : TextBox | this ASP.NET user input | -| SqlInjection.cs:69:56:69:61 | access to local variable query1 | SqlInjection.cs:68:33:68:47 | access to field categoryTextBox : TextBox | SqlInjection.cs:69:56:69:61 | access to local variable query1 | This query depends on $@. | SqlInjection.cs:68:33:68:47 | access to field categoryTextBox : TextBox | this ASP.NET user input | -| SqlInjection.cs:70:55:70:60 | access to local variable query1 | SqlInjection.cs:68:33:68:47 | access to field categoryTextBox : TextBox | SqlInjection.cs:70:55:70:60 | access to local variable query1 | This query depends on $@. | SqlInjection.cs:68:33:68:47 | access to field categoryTextBox : TextBox | this ASP.NET user input | -| SqlInjection.cs:83:50:83:55 | access to local variable query1 | SqlInjection.cs:82:21:82:29 | access to property Text : String | SqlInjection.cs:83:50:83:55 | access to local variable query1 | This query depends on $@. | SqlInjection.cs:82:21:82:29 | access to property Text : String | this TextBox text | -| SqlInjection.cs:93:42:93:52 | access to local variable queryString | SqlInjection.cs:92:21:92:29 | access to property Text : String | SqlInjection.cs:93:42:93:52 | access to local variable queryString | This query depends on $@. | SqlInjection.cs:92:21:92:29 | access to property Text : String | this TextBox text | -| SqlInjection.cs:94:50:94:52 | access to local variable cmd | SqlInjection.cs:92:21:92:29 | access to property Text : String | SqlInjection.cs:94:50:94:52 | access to local variable cmd | This query depends on $@. | SqlInjection.cs:92:21:92:29 | access to property Text : String | this TextBox text | -| SqlInjection.cs:104:42:104:52 | access to local variable queryString | SqlInjection.cs:103:21:103:38 | call to method ReadLine : String | SqlInjection.cs:104:42:104:52 | access to local variable queryString | This query depends on $@. | SqlInjection.cs:103:21:103:38 | call to method ReadLine : String | this read from stdin | -| SqlInjection.cs:105:50:105:52 | access to local variable cmd | SqlInjection.cs:103:21:103:38 | call to method ReadLine : String | SqlInjection.cs:105:50:105:52 | access to local variable cmd | This query depends on $@. | SqlInjection.cs:103:21:103:38 | call to method ReadLine : String | this read from stdin | +| SqlInjection.cs:39:50:39:55 | access to local variable query1 | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox : TextBox | SqlInjection.cs:39:50:39:55 | access to local variable query1 | This query depends on $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox : TextBox | this ASP.NET user input | +| SqlInjection.cs:74:56:74:61 | access to local variable query1 | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | This query depends on $@. | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | this ASP.NET user input | +| SqlInjection.cs:75:55:75:60 | access to local variable query1 | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | This query depends on $@. | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | this ASP.NET user input | +| SqlInjection.cs:88:50:88:55 | access to local variable query1 | SqlInjection.cs:87:21:87:29 | access to property Text : String | SqlInjection.cs:88:50:88:55 | access to local variable query1 | This query depends on $@. | SqlInjection.cs:87:21:87:29 | access to property Text : String | this TextBox text | +| SqlInjection.cs:98:42:98:52 | access to local variable queryString | SqlInjection.cs:97:21:97:29 | access to property Text : String | SqlInjection.cs:98:42:98:52 | access to local variable queryString | This query depends on $@. | SqlInjection.cs:97:21:97:29 | access to property Text : String | this TextBox text | +| SqlInjection.cs:99:50:99:52 | access to local variable cmd | SqlInjection.cs:97:21:97:29 | access to property Text : String | SqlInjection.cs:99:50:99:52 | access to local variable cmd | This query depends on $@. | SqlInjection.cs:97:21:97:29 | access to property Text : String | this TextBox text | +| SqlInjection.cs:109:42:109:52 | access to local variable queryString | SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | SqlInjection.cs:109:42:109:52 | access to local variable queryString | This query depends on $@. | SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | this read from stdin | +| SqlInjection.cs:110:50:110:52 | access to local variable cmd | SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | SqlInjection.cs:110:50:110:52 | access to local variable cmd | This query depends on $@. | SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | this read from stdin | | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | This query depends on $@. | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | this TextBox text | | SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | SqlInjectionDapper.cs:29:86:29:94 | access to property Text : String | SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | This query depends on $@. | SqlInjectionDapper.cs:29:86:29:94 | access to property Text : String | this TextBox text | | SqlInjectionDapper.cs:39:63:39:67 | access to local variable query | SqlInjectionDapper.cs:38:86:38:94 | access to property Text : String | SqlInjectionDapper.cs:39:63:39:67 | access to local variable query | This query depends on $@. | SqlInjectionDapper.cs:38:86:38:94 | access to property Text : String | this TextBox text | @@ -40,27 +40,27 @@ edges | SecondOrderSqlInjection.cs:40:25:40:27 | access to local variable sql : String | SecondOrderSqlInjection.cs:45:57:45:59 | access to local variable sql | provenance | Sink:MaD:10 | | SecondOrderSqlInjection.cs:40:31:40:33 | access to local variable sql : String | SecondOrderSqlInjection.cs:40:31:40:40 | call to method Trim : String | provenance | MaD:28 | | SecondOrderSqlInjection.cs:40:31:40:40 | call to method Trim : String | SecondOrderSqlInjection.cs:40:25:40:27 | access to local variable sql : String | provenance | | -| SqlInjection.cs:32:21:32:26 | access to local variable query1 : String | SqlInjection.cs:34:50:34:55 | access to local variable query1 | provenance | Sink:MaD:18 | -| SqlInjection.cs:33:21:33:35 | access to field categoryTextBox : TextBox | SqlInjection.cs:33:21:33:40 | access to property Text : String | provenance | MaD:26 | -| SqlInjection.cs:33:21:33:40 | access to property Text : String | SqlInjection.cs:32:21:32:26 | access to local variable query1 : String | provenance | | -| SqlInjection.cs:67:25:67:30 | access to local variable query1 : String | SqlInjection.cs:69:56:69:61 | access to local variable query1 | provenance | Sink:MaD:7 | -| SqlInjection.cs:67:25:67:30 | access to local variable query1 : String | SqlInjection.cs:70:55:70:60 | access to local variable query1 | provenance | Sink:MaD:8 | -| SqlInjection.cs:68:33:68:47 | access to field categoryTextBox : TextBox | SqlInjection.cs:68:33:68:52 | access to property Text : String | provenance | MaD:26 | -| SqlInjection.cs:68:33:68:52 | access to property Text : String | SqlInjection.cs:67:25:67:30 | access to local variable query1 : String | provenance | | -| SqlInjection.cs:81:21:81:26 | access to local variable query1 : String | SqlInjection.cs:83:50:83:55 | access to local variable query1 | provenance | Sink:MaD:18 | -| SqlInjection.cs:82:21:82:29 | access to property Text : String | SqlInjection.cs:81:21:81:26 | access to local variable query1 : String | provenance | | -| SqlInjection.cs:91:21:91:31 | access to local variable queryString : String | SqlInjection.cs:93:42:93:52 | access to local variable queryString | provenance | Sink:MaD:15 | -| SqlInjection.cs:91:21:91:31 | access to local variable queryString : String | SqlInjection.cs:93:42:93:52 | access to local variable queryString : String | provenance | | -| SqlInjection.cs:92:21:92:29 | access to property Text : String | SqlInjection.cs:91:21:91:31 | access to local variable queryString : String | provenance | | -| SqlInjection.cs:93:21:93:23 | access to local variable cmd : SqlCommand | SqlInjection.cs:94:50:94:52 | access to local variable cmd | provenance | Sink:MaD:17 | -| SqlInjection.cs:93:27:93:53 | object creation of type SqlCommand : SqlCommand | SqlInjection.cs:93:21:93:23 | access to local variable cmd : SqlCommand | provenance | | -| SqlInjection.cs:93:42:93:52 | access to local variable queryString : String | SqlInjection.cs:93:27:93:53 | object creation of type SqlCommand : SqlCommand | provenance | MaD:19 | -| SqlInjection.cs:102:21:102:31 | access to local variable queryString : String | SqlInjection.cs:104:42:104:52 | access to local variable queryString | provenance | Sink:MaD:15 | -| SqlInjection.cs:102:21:102:31 | access to local variable queryString : String | SqlInjection.cs:104:42:104:52 | access to local variable queryString : String | provenance | | -| SqlInjection.cs:103:21:103:38 | call to method ReadLine : String | SqlInjection.cs:102:21:102:31 | access to local variable queryString : String | provenance | Src:MaD:27 | -| SqlInjection.cs:104:21:104:23 | access to local variable cmd : SqlCommand | SqlInjection.cs:105:50:105:52 | access to local variable cmd | provenance | Sink:MaD:17 | -| SqlInjection.cs:104:27:104:53 | object creation of type SqlCommand : SqlCommand | SqlInjection.cs:104:21:104:23 | access to local variable cmd : SqlCommand | provenance | | -| SqlInjection.cs:104:42:104:52 | access to local variable queryString : String | SqlInjection.cs:104:27:104:53 | object creation of type SqlCommand : SqlCommand | provenance | MaD:19 | +| SqlInjection.cs:37:21:37:26 | access to local variable query1 : String | SqlInjection.cs:39:50:39:55 | access to local variable query1 | provenance | Sink:MaD:18 | +| SqlInjection.cs:38:21:38:35 | access to field categoryTextBox : TextBox | SqlInjection.cs:38:21:38:40 | access to property Text : String | provenance | MaD:26 | +| SqlInjection.cs:38:21:38:40 | access to property Text : String | SqlInjection.cs:37:21:37:26 | access to local variable query1 : String | provenance | | +| SqlInjection.cs:72:25:72:30 | access to local variable query1 : String | SqlInjection.cs:74:56:74:61 | access to local variable query1 | provenance | Sink:MaD:7 | +| SqlInjection.cs:72:25:72:30 | access to local variable query1 : String | SqlInjection.cs:75:55:75:60 | access to local variable query1 | provenance | Sink:MaD:8 | +| SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | SqlInjection.cs:73:33:73:52 | access to property Text : String | provenance | MaD:26 | +| SqlInjection.cs:73:33:73:52 | access to property Text : String | SqlInjection.cs:72:25:72:30 | access to local variable query1 : String | provenance | | +| SqlInjection.cs:86:21:86:26 | access to local variable query1 : String | SqlInjection.cs:88:50:88:55 | access to local variable query1 | provenance | Sink:MaD:18 | +| SqlInjection.cs:87:21:87:29 | access to property Text : String | SqlInjection.cs:86:21:86:26 | access to local variable query1 : String | provenance | | +| SqlInjection.cs:96:21:96:31 | access to local variable queryString : String | SqlInjection.cs:98:42:98:52 | access to local variable queryString | provenance | Sink:MaD:15 | +| SqlInjection.cs:96:21:96:31 | access to local variable queryString : String | SqlInjection.cs:98:42:98:52 | access to local variable queryString : String | provenance | | +| SqlInjection.cs:97:21:97:29 | access to property Text : String | SqlInjection.cs:96:21:96:31 | access to local variable queryString : String | provenance | | +| SqlInjection.cs:98:21:98:23 | access to local variable cmd : SqlCommand | SqlInjection.cs:99:50:99:52 | access to local variable cmd | provenance | Sink:MaD:17 | +| SqlInjection.cs:98:27:98:53 | object creation of type SqlCommand : SqlCommand | SqlInjection.cs:98:21:98:23 | access to local variable cmd : SqlCommand | provenance | | +| SqlInjection.cs:98:42:98:52 | access to local variable queryString : String | SqlInjection.cs:98:27:98:53 | object creation of type SqlCommand : SqlCommand | provenance | MaD:19 | +| SqlInjection.cs:107:21:107:31 | access to local variable queryString : String | SqlInjection.cs:109:42:109:52 | access to local variable queryString | provenance | Sink:MaD:15 | +| SqlInjection.cs:107:21:107:31 | access to local variable queryString : String | SqlInjection.cs:109:42:109:52 | access to local variable queryString : String | provenance | | +| SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | SqlInjection.cs:107:21:107:31 | access to local variable queryString : String | provenance | Src:MaD:27 | +| SqlInjection.cs:109:21:109:23 | access to local variable cmd : SqlCommand | SqlInjection.cs:110:50:110:52 | access to local variable cmd | provenance | Sink:MaD:17 | +| SqlInjection.cs:109:27:109:53 | object creation of type SqlCommand : SqlCommand | SqlInjection.cs:109:21:109:23 | access to local variable cmd : SqlCommand | provenance | | +| SqlInjection.cs:109:42:109:52 | access to local variable queryString : String | SqlInjection.cs:109:27:109:53 | object creation of type SqlCommand : SqlCommand | provenance | MaD:19 | | SqlInjectionDapper.cs:20:21:20:25 | access to local variable query : String | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | provenance | Sink:MaD:4 | | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | SqlInjectionDapper.cs:20:21:20:25 | access to local variable query : String | provenance | | | SqlInjectionDapper.cs:29:21:29:25 | access to local variable query : String | SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | provenance | Sink:MaD:5 | @@ -144,32 +144,32 @@ nodes | SecondOrderSqlInjection.cs:40:31:40:33 | access to local variable sql : String | semmle.label | access to local variable sql : String | | SecondOrderSqlInjection.cs:40:31:40:40 | call to method Trim : String | semmle.label | call to method Trim : String | | SecondOrderSqlInjection.cs:45:57:45:59 | access to local variable sql | semmle.label | access to local variable sql | -| SqlInjection.cs:32:21:32:26 | access to local variable query1 : String | semmle.label | access to local variable query1 : String | -| SqlInjection.cs:33:21:33:35 | access to field categoryTextBox : TextBox | semmle.label | access to field categoryTextBox : TextBox | -| SqlInjection.cs:33:21:33:40 | access to property Text : String | semmle.label | access to property Text : String | -| SqlInjection.cs:34:50:34:55 | access to local variable query1 | semmle.label | access to local variable query1 | -| SqlInjection.cs:67:25:67:30 | access to local variable query1 : String | semmle.label | access to local variable query1 : String | -| SqlInjection.cs:68:33:68:47 | access to field categoryTextBox : TextBox | semmle.label | access to field categoryTextBox : TextBox | -| SqlInjection.cs:68:33:68:52 | access to property Text : String | semmle.label | access to property Text : String | -| SqlInjection.cs:69:56:69:61 | access to local variable query1 | semmle.label | access to local variable query1 | -| SqlInjection.cs:70:55:70:60 | access to local variable query1 | semmle.label | access to local variable query1 | -| SqlInjection.cs:81:21:81:26 | access to local variable query1 : String | semmle.label | access to local variable query1 : String | -| SqlInjection.cs:82:21:82:29 | access to property Text : String | semmle.label | access to property Text : String | -| SqlInjection.cs:83:50:83:55 | access to local variable query1 | semmle.label | access to local variable query1 | -| SqlInjection.cs:91:21:91:31 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | -| SqlInjection.cs:92:21:92:29 | access to property Text : String | semmle.label | access to property Text : String | -| SqlInjection.cs:93:21:93:23 | access to local variable cmd : SqlCommand | semmle.label | access to local variable cmd : SqlCommand | -| SqlInjection.cs:93:27:93:53 | object creation of type SqlCommand : SqlCommand | semmle.label | object creation of type SqlCommand : SqlCommand | -| SqlInjection.cs:93:42:93:52 | access to local variable queryString | semmle.label | access to local variable queryString | -| SqlInjection.cs:93:42:93:52 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | -| SqlInjection.cs:94:50:94:52 | access to local variable cmd | semmle.label | access to local variable cmd | -| SqlInjection.cs:102:21:102:31 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | -| SqlInjection.cs:103:21:103:38 | call to method ReadLine : String | semmle.label | call to method ReadLine : String | -| SqlInjection.cs:104:21:104:23 | access to local variable cmd : SqlCommand | semmle.label | access to local variable cmd : SqlCommand | -| SqlInjection.cs:104:27:104:53 | object creation of type SqlCommand : SqlCommand | semmle.label | object creation of type SqlCommand : SqlCommand | -| SqlInjection.cs:104:42:104:52 | access to local variable queryString | semmle.label | access to local variable queryString | -| SqlInjection.cs:104:42:104:52 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | -| SqlInjection.cs:105:50:105:52 | access to local variable cmd | semmle.label | access to local variable cmd | +| SqlInjection.cs:37:21:37:26 | access to local variable query1 : String | semmle.label | access to local variable query1 : String | +| SqlInjection.cs:38:21:38:35 | access to field categoryTextBox : TextBox | semmle.label | access to field categoryTextBox : TextBox | +| SqlInjection.cs:38:21:38:40 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjection.cs:39:50:39:55 | access to local variable query1 | semmle.label | access to local variable query1 | +| SqlInjection.cs:72:25:72:30 | access to local variable query1 : String | semmle.label | access to local variable query1 : String | +| SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | semmle.label | access to field categoryTextBox : TextBox | +| SqlInjection.cs:73:33:73:52 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjection.cs:74:56:74:61 | access to local variable query1 | semmle.label | access to local variable query1 | +| SqlInjection.cs:75:55:75:60 | access to local variable query1 | semmle.label | access to local variable query1 | +| SqlInjection.cs:86:21:86:26 | access to local variable query1 : String | semmle.label | access to local variable query1 : String | +| SqlInjection.cs:87:21:87:29 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjection.cs:88:50:88:55 | access to local variable query1 | semmle.label | access to local variable query1 | +| SqlInjection.cs:96:21:96:31 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | +| SqlInjection.cs:97:21:97:29 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjection.cs:98:21:98:23 | access to local variable cmd : SqlCommand | semmle.label | access to local variable cmd : SqlCommand | +| SqlInjection.cs:98:27:98:53 | object creation of type SqlCommand : SqlCommand | semmle.label | object creation of type SqlCommand : SqlCommand | +| SqlInjection.cs:98:42:98:52 | access to local variable queryString | semmle.label | access to local variable queryString | +| SqlInjection.cs:98:42:98:52 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | +| SqlInjection.cs:99:50:99:52 | access to local variable cmd | semmle.label | access to local variable cmd | +| SqlInjection.cs:107:21:107:31 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | +| SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | semmle.label | call to method ReadLine : String | +| SqlInjection.cs:109:21:109:23 | access to local variable cmd : SqlCommand | semmle.label | access to local variable cmd : SqlCommand | +| SqlInjection.cs:109:27:109:53 | object creation of type SqlCommand : SqlCommand | semmle.label | object creation of type SqlCommand : SqlCommand | +| SqlInjection.cs:109:42:109:52 | access to local variable queryString | semmle.label | access to local variable queryString | +| SqlInjection.cs:109:42:109:52 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | +| SqlInjection.cs:110:50:110:52 | access to local variable cmd | semmle.label | access to local variable cmd | | SqlInjectionDapper.cs:20:21:20:25 | access to local variable query : String | semmle.label | access to local variable query : String | | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | semmle.label | access to property Text : String | | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | semmle.label | access to local variable query | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/options b/csharp/ql/test/query-tests/Security Features/CWE-089/options index 656d05b7449..c6ef0c87f2d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/options @@ -3,3 +3,4 @@ semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resour semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SqlClient/4.8.5/System.Data.SqlClient.csproj semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/System.Data.SQLite/1.0.118/System.Data.SQLite.csproj semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Windows.cs +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj From 75772c58321ca70f682c4b18d995fc485db71d67 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 21 Aug 2024 12:08:21 +0200 Subject: [PATCH 067/404] C#: Add abstract controller remote flow source example. --- .../aspremote/AspRemoteFlowSource.cs | 7 ++++- .../frameworks/microsoft/AspNetCore.cs | 26 +++++++++---------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs index 7f110e5c6fd..176f95e4a89 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/AspRemoteFlowSource.cs @@ -58,4 +58,9 @@ namespace Testing app.Run(); } } -} \ No newline at end of file + + public abstract class AbstractTestController : Controller + { + public void MyActionMethod(string param) { } + } +} diff --git a/csharp/ql/test/library-tests/frameworks/microsoft/AspNetCore.cs b/csharp/ql/test/library-tests/frameworks/microsoft/AspNetCore.cs index 78095254d09..bcf0c766f34 100644 --- a/csharp/ql/test/library-tests/frameworks/microsoft/AspNetCore.cs +++ b/csharp/ql/test/library-tests/frameworks/microsoft/AspNetCore.cs @@ -56,6 +56,15 @@ public class HomeController5 : HomeController4 } } +// is abstract +public abstract class HomeController6 : Controller +{ + public string Index() + { + return "This is Home Controller"; + } +} + // is not public internal class NotHomeController : Controller { @@ -65,17 +74,8 @@ internal class NotHomeController : Controller } } -// is abstract -public abstract class NotHomeController2 : Controller -{ - public string Index() - { - return "This is Home Controller"; - } -} - // contains generic parameters -public class NotHomeController3 : Controller +public class NotHomeController2 : Controller { public string Index() { @@ -85,7 +85,7 @@ public class NotHomeController3 : Controller // has [NonController] attribute [NonController] -public class NotHomeController4 : Controller +public class NotHomeController3 : Controller { public string Index() { @@ -94,10 +94,10 @@ public class NotHomeController4 : Controller } // derived from a class that has [NonController] attribute -public class NotController : NotHomeController4 +public class NotController : NotHomeController3 { public string Index() { return "This is Home Controller"; } -} \ No newline at end of file +} From 79718f1cd6d71d0e79819ae7aeac9a56f419e02e Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 21 Aug 2024 12:09:09 +0200 Subject: [PATCH 068/404] C#: Remove requirement that a controller is not allowed to be abstract. --- .../lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll index 08ff4df55cb..350465052d1 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll @@ -205,7 +205,6 @@ class MicrosoftAspNetCoreMvcController extends Class { ) ) and this.isPublic() and - (not this.isAbstract() or this instanceof MicrosoftAspNetCoreMvcControllerBaseClass) and not this instanceof Generic and ( this.getABaseType*() instanceof MicrosoftAspNetCoreMvcControllerBaseClass From 45d4d5138ac4aa12fafa479659782c35519c23d7 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 21 Aug 2024 12:18:50 +0200 Subject: [PATCH 069/404] C#: Update expected test output. --- .../flowsources/aspremote/aspRemoteFlowSource.expected | 1 + .../library-tests/frameworks/microsoft/AspNetCore.expected | 1 + .../Security Features/CWE-089/SqlInjection.expected | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected index 199ed69f28f..a7442a80839 100644 --- a/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected +++ b/csharp/ql/test/library-tests/dataflow/flowsources/aspremote/aspRemoteFlowSource.expected @@ -12,3 +12,4 @@ remoteFlowSources | AspRemoteFlowSource.cs:53:63:53:73 | mapPutParam | | AspRemoteFlowSource.cs:54:69:54:82 | mapDeleteParam | | AspRemoteFlowSource.cs:56:41:56:44 | item | +| AspRemoteFlowSource.cs:64:43:64:47 | param | diff --git a/csharp/ql/test/library-tests/frameworks/microsoft/AspNetCore.expected b/csharp/ql/test/library-tests/frameworks/microsoft/AspNetCore.expected index c4c58957115..e9866698ccd 100644 --- a/csharp/ql/test/library-tests/frameworks/microsoft/AspNetCore.expected +++ b/csharp/ql/test/library-tests/frameworks/microsoft/AspNetCore.expected @@ -4,3 +4,4 @@ | AspNetCore.cs:32:14:32:28 | HomeController3 | | AspNetCore.cs:42:14:42:28 | HomeController4 | | AspNetCore.cs:51:14:51:28 | HomeController5 | +| AspNetCore.cs:60:23:60:37 | HomeController6 | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected index df48e097cf8..7a0e0fad181 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected @@ -9,6 +9,7 @@ | SqlInjection.cs:99:50:99:52 | access to local variable cmd | SqlInjection.cs:97:21:97:29 | access to property Text : String | SqlInjection.cs:99:50:99:52 | access to local variable cmd | This query depends on $@. | SqlInjection.cs:97:21:97:29 | access to property Text : String | this TextBox text | | SqlInjection.cs:109:42:109:52 | access to local variable queryString | SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | SqlInjection.cs:109:42:109:52 | access to local variable queryString | This query depends on $@. | SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | this read from stdin | | SqlInjection.cs:110:50:110:52 | access to local variable cmd | SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | SqlInjection.cs:110:50:110:52 | access to local variable cmd | This query depends on $@. | SqlInjection.cs:108:21:108:38 | call to method ReadLine : String | this read from stdin | +| SqlInjection.cs:129:53:129:57 | access to local variable query | SqlInjection.cs:122:73:122:78 | userId : String | SqlInjection.cs:129:53:129:57 | access to local variable query | This query depends on $@. | SqlInjection.cs:122:73:122:78 | userId : String | this ASP.NET Core MVC action method parameter | | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | This query depends on $@. | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | this TextBox text | | SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | SqlInjectionDapper.cs:29:86:29:94 | access to property Text : String | SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | This query depends on $@. | SqlInjectionDapper.cs:29:86:29:94 | access to property Text : String | this TextBox text | | SqlInjectionDapper.cs:39:63:39:67 | access to local variable query | SqlInjectionDapper.cs:38:86:38:94 | access to property Text : String | SqlInjectionDapper.cs:39:63:39:67 | access to local variable query | This query depends on $@. | SqlInjectionDapper.cs:38:86:38:94 | access to property Text : String | this TextBox text | @@ -61,6 +62,8 @@ edges | SqlInjection.cs:109:21:109:23 | access to local variable cmd : SqlCommand | SqlInjection.cs:110:50:110:52 | access to local variable cmd | provenance | Sink:MaD:17 | | SqlInjection.cs:109:27:109:53 | object creation of type SqlCommand : SqlCommand | SqlInjection.cs:109:21:109:23 | access to local variable cmd : SqlCommand | provenance | | | SqlInjection.cs:109:42:109:52 | access to local variable queryString : String | SqlInjection.cs:109:27:109:53 | object creation of type SqlCommand : SqlCommand | provenance | MaD:19 | +| SqlInjection.cs:122:73:122:78 | userId : String | SqlInjection.cs:125:20:125:24 | access to local variable query : String | provenance | | +| SqlInjection.cs:125:20:125:24 | access to local variable query : String | SqlInjection.cs:129:53:129:57 | access to local variable query | provenance | Sink:MaD:16 | | SqlInjectionDapper.cs:20:21:20:25 | access to local variable query : String | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | provenance | Sink:MaD:4 | | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | SqlInjectionDapper.cs:20:21:20:25 | access to local variable query : String | provenance | | | SqlInjectionDapper.cs:29:21:29:25 | access to local variable query : String | SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | provenance | Sink:MaD:5 | @@ -170,6 +173,9 @@ nodes | SqlInjection.cs:109:42:109:52 | access to local variable queryString | semmle.label | access to local variable queryString | | SqlInjection.cs:109:42:109:52 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | | SqlInjection.cs:110:50:110:52 | access to local variable cmd | semmle.label | access to local variable cmd | +| SqlInjection.cs:122:73:122:78 | userId : String | semmle.label | userId : String | +| SqlInjection.cs:125:20:125:24 | access to local variable query : String | semmle.label | access to local variable query : String | +| SqlInjection.cs:129:53:129:57 | access to local variable query | semmle.label | access to local variable query | | SqlInjectionDapper.cs:20:21:20:25 | access to local variable query : String | semmle.label | access to local variable query : String | | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | semmle.label | access to property Text : String | | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | semmle.label | access to local variable query | From 5751fc2d3a7fa4d00aa1ade792f2f62ce6fef1a3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 21 Aug 2024 13:36:47 +0200 Subject: [PATCH 070/404] Java: Reveal false negative in test One of the sinks was flagged for the wrong reason in the test case. The flow into the 'startActivities' sink isn't working properly, but this was not revealed by the test since an alternate, spurious path exists. The spurious path goes through the implicit read at the prior sink and takes a use-use step to the 'startActivities' sink. Swapping the order of the two sinks reveals the false negative. --- .../security/CWE-927/ImplicitPendingIntentsTest.expected | 1 + .../security/CWE-927/ImplicitPendingIntentsTest.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected index 48de9172b36..1dc60bf81c4 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected @@ -1,2 +1,3 @@ failures testFailures +| ImplicitPendingIntentsTest.java:35:60:35:87 | // $hasImplicitPendingIntent | Missing result:hasImplicitPendingIntent= | diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java index 746c9ca83dc..bb680ebf35c 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java @@ -32,8 +32,8 @@ public class ImplicitPendingIntentsTest { PendingIntent pi = PendingIntent.getActivity(ctx, 0, baseIntent, 0); Intent fwdIntent = new Intent(); fwdIntent.putExtra("fwdIntent", pi); - ctx.startActivity(fwdIntent); // $hasImplicitPendingIntent ctx.startActivities(new Intent[] {fwdIntent}); // $hasImplicitPendingIntent + ctx.startActivity(fwdIntent); // $hasImplicitPendingIntent ctx.startService(fwdIntent); // Safe ctx.sendBroadcast(fwdIntent); // $hasImplicitPendingIntent From f7ea8a15639f6562215024c9c7867dc77b16af2f Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 21 Aug 2024 13:37:38 +0200 Subject: [PATCH 071/404] Java: trivial result set re-order --- .../security/CWE-927/ImplicitPendingIntentsTest.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected index 1dc60bf81c4..20a754571c4 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected @@ -1,3 +1,3 @@ -failures testFailures | ImplicitPendingIntentsTest.java:35:60:35:87 | // $hasImplicitPendingIntent | Missing result:hasImplicitPendingIntent= | +failures From 3aa32e4aff844d141de435e90276ade6ada19563 Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 21 Aug 2024 13:40:40 +0200 Subject: [PATCH 072/404] Java: use MISSING inline annotation --- .../security/CWE-927/ImplicitPendingIntentsTest.expected | 1 - .../security/CWE-927/ImplicitPendingIntentsTest.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected index 20a754571c4..8ec8033d086 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.expected @@ -1,3 +1,2 @@ testFailures -| ImplicitPendingIntentsTest.java:35:60:35:87 | // $hasImplicitPendingIntent | Missing result:hasImplicitPendingIntent= | failures diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java index bb680ebf35c..80f66149221 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java @@ -32,7 +32,7 @@ public class ImplicitPendingIntentsTest { PendingIntent pi = PendingIntent.getActivity(ctx, 0, baseIntent, 0); Intent fwdIntent = new Intent(); fwdIntent.putExtra("fwdIntent", pi); - ctx.startActivities(new Intent[] {fwdIntent}); // $hasImplicitPendingIntent + ctx.startActivities(new Intent[] {fwdIntent}); // $ MISSING: hasImplicitPendingIntent ctx.startActivity(fwdIntent); // $hasImplicitPendingIntent ctx.startService(fwdIntent); // Safe ctx.sendBroadcast(fwdIntent); // $hasImplicitPendingIntent From 7049499e95fcbc69a2ccd9a479b9eb4d665a2c31 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 21 Aug 2024 14:38:55 +0200 Subject: [PATCH 073/404] C#: Add change-note. --- .../ql/lib/change-notes/2024-08-21-abstract-asp-controller.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2024-08-21-abstract-asp-controller.md diff --git a/csharp/ql/lib/change-notes/2024-08-21-abstract-asp-controller.md b/csharp/ql/lib/change-notes/2024-08-21-abstract-asp-controller.md new file mode 100644 index 00000000000..61d4f6ec600 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-08-21-abstract-asp-controller.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Parameters of public methods in abstract controller-like classes are now considered remote flow sources. From 7c4733e88f7f54c8a9afd5c1405ac1882447034d Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 21 Aug 2024 15:13:14 +0200 Subject: [PATCH 074/404] C#: Change reporting location of partial methods --- .../Entities/OrdinaryMethod.cs | 2 +- .../library-tests/partial/MethodIsPartial.expected | 2 +- csharp/ql/test/library-tests/partial/Partial1.expected | 2 +- csharp/ql/test/library-tests/partial/Partial2.expected | 4 ++-- .../library-tests/partial/PartialMethodBody.expected | 2 +- csharp/ql/test/library-tests/partial/PrintAst.expected | 10 +++++----- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/OrdinaryMethod.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/OrdinaryMethod.cs index 9ecfb3687b6..bd3a637a624 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/OrdinaryMethod.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/OrdinaryMethod.cs @@ -21,7 +21,7 @@ namespace Semmle.Extraction.CSharp.Entities public override Microsoft.CodeAnalysis.Location ReportingLocation => IsCompilerGeneratedDelegate() ? Symbol.ContainingType.GetSymbolLocation() - : Symbol.GetSymbolLocation(); + : BodyDeclaringSymbol.GetSymbolLocation(); public override bool NeedsPopulation => base.NeedsPopulation || IsCompilerGeneratedDelegate(); diff --git a/csharp/ql/test/library-tests/partial/MethodIsPartial.expected b/csharp/ql/test/library-tests/partial/MethodIsPartial.expected index 8ee8f25b0c8..66f2dc7d3a0 100644 --- a/csharp/ql/test/library-tests/partial/MethodIsPartial.expected +++ b/csharp/ql/test/library-tests/partial/MethodIsPartial.expected @@ -1,6 +1,6 @@ -| Partial.cs:3:18:3:39 | PartialMethodWithBody1 | true | | Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 | true | | Partial.cs:5:17:5:23 | Method2 | false | +| Partial.cs:10:18:10:39 | PartialMethodWithBody1 | true | | Partial.cs:11:17:11:23 | Method3 | false | | Partial.cs:16:18:16:42 | PartialMethodWithoutBody2 | true | | Partial.cs:17:17:17:23 | Method4 | false | diff --git a/csharp/ql/test/library-tests/partial/Partial1.expected b/csharp/ql/test/library-tests/partial/Partial1.expected index 722482cac4f..6830307e8e7 100644 --- a/csharp/ql/test/library-tests/partial/Partial1.expected +++ b/csharp/ql/test/library-tests/partial/Partial1.expected @@ -1,6 +1,6 @@ | Partial.cs:1:15:1:26 | TwoPartClass | -| Partial.cs:3:18:3:39 | PartialMethodWithBody1 | | Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 | | Partial.cs:8:15:8:26 | TwoPartClass | +| Partial.cs:10:18:10:39 | PartialMethodWithBody1 | | Partial.cs:14:15:14:33 | OnePartPartialClass | | Partial.cs:16:18:16:42 | PartialMethodWithoutBody2 | diff --git a/csharp/ql/test/library-tests/partial/Partial2.expected b/csharp/ql/test/library-tests/partial/Partial2.expected index 6723b575fc7..de1327fe159 100644 --- a/csharp/ql/test/library-tests/partial/Partial2.expected +++ b/csharp/ql/test/library-tests/partial/Partial2.expected @@ -1,10 +1,10 @@ -| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:3:18:3:39 | PartialMethodWithBody1 | | Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 | | Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:5:17:5:23 | Method2 | +| Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:10:18:10:39 | PartialMethodWithBody1 | | Partial.cs:1:15:1:26 | TwoPartClass | Partial.cs:11:17:11:23 | Method3 | -| Partial.cs:8:15:8:26 | TwoPartClass | Partial.cs:3:18:3:39 | PartialMethodWithBody1 | | Partial.cs:8:15:8:26 | TwoPartClass | Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 | | Partial.cs:8:15:8:26 | TwoPartClass | Partial.cs:5:17:5:23 | Method2 | +| Partial.cs:8:15:8:26 | TwoPartClass | Partial.cs:10:18:10:39 | PartialMethodWithBody1 | | Partial.cs:8:15:8:26 | TwoPartClass | Partial.cs:11:17:11:23 | Method3 | | Partial.cs:14:15:14:33 | OnePartPartialClass | Partial.cs:16:18:16:42 | PartialMethodWithoutBody2 | | Partial.cs:14:15:14:33 | OnePartPartialClass | Partial.cs:17:17:17:23 | Method4 | diff --git a/csharp/ql/test/library-tests/partial/PartialMethodBody.expected b/csharp/ql/test/library-tests/partial/PartialMethodBody.expected index e6592704f1a..b440bfb640b 100644 --- a/csharp/ql/test/library-tests/partial/PartialMethodBody.expected +++ b/csharp/ql/test/library-tests/partial/PartialMethodBody.expected @@ -1,3 +1,3 @@ -| Partial.cs:3:18:3:39 | PartialMethodWithBody1 | true | | Partial.cs:4:18:4:42 | PartialMethodWithoutBody1 | false | +| Partial.cs:10:18:10:39 | PartialMethodWithBody1 | true | | Partial.cs:16:18:16:42 | PartialMethodWithoutBody2 | false | diff --git a/csharp/ql/test/library-tests/partial/PrintAst.expected b/csharp/ql/test/library-tests/partial/PrintAst.expected index 264e06ce944..08e8e66d40e 100644 --- a/csharp/ql/test/library-tests/partial/PrintAst.expected +++ b/csharp/ql/test/library-tests/partial/PrintAst.expected @@ -1,13 +1,13 @@ Partial.cs: # 1| [Class] TwoPartClass -# 3| 5: [Method] PartialMethodWithBody1 -# 3| -1: [TypeMention] Void -# 10| 4: [BlockStmt] {...} -# 4| 6: [Method] PartialMethodWithoutBody1 +# 4| 5: [Method] PartialMethodWithoutBody1 # 4| -1: [TypeMention] Void -# 5| 7: [Method] Method2 +# 5| 6: [Method] Method2 # 5| -1: [TypeMention] Void # 5| 4: [BlockStmt] {...} +# 10| 7: [Method] PartialMethodWithBody1 +# 3| -1: [TypeMention] Void +# 10| 4: [BlockStmt] {...} # 11| 8: [Method] Method3 # 11| -1: [TypeMention] Void # 11| 4: [BlockStmt] {...} From 113ab755d95468766e3539c0b6da7e7ecd57780a Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Wed, 21 Aug 2024 14:18:11 +0100 Subject: [PATCH 075/404] Give clearer example of multiple query predicates in one ql file The new names aren't great, so feel free to change them, but I think we do need an explicit example of updating two relations using one ql file. --- docs/prepare-db-upgrade.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/prepare-db-upgrade.md b/docs/prepare-db-upgrade.md index 7b0a1c6fe48..58806ecebeb 100644 --- a/docs/prepare-db-upgrade.md +++ b/docs/prepare-db-upgrade.md @@ -59,14 +59,16 @@ extended.rel: reorder input.rel (int id, string name, int parent) id name parent // QLL library, and will run in the context of the *old* dbscheme. relationname.rel: run relationname.qlo -// Create relationname.rel by running the query predicate 'predicatename' in -// relationname.qlo and writing the query results as a .rel file. This command +// Create relation1.rel by running the query predicate 'predicate1' in upgrade.qlo +// and writing the query results as a .rel file, and running 'predicate2' in +// upgrade.qlo and writing the query results as a .rel file. This command // expects the upgrade relation to be a query predicate, which has the advantage // of allowing multiple upgrade relations to appear in the same .ql file as -// multiple query predicates. The query file should be named relationname.ql and +// multiple query predicates. The query file should be named upgrade.ql and // should be placed in the upgrade directory. It should avoid using the default // QLL library, and will run in the context of the *old* dbscheme. -relationname.rel: run relationname.qlo predicatename +relation1.rel: run upgrade.qlo predicate1 +relation2.rel: run upgrade.qlo predicate2 ``` ### Testing your scripts From f7bf5e89be3933ab8994df4e4efaafe1031ec2b2 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 21 Aug 2024 15:58:05 +0200 Subject: [PATCH 076/404] Add change note --- csharp/ql/lib/change-notes/2024-08-21-partial-methods.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2024-08-21-partial-methods.md diff --git a/csharp/ql/lib/change-notes/2024-08-21-partial-methods.md b/csharp/ql/lib/change-notes/2024-08-21-partial-methods.md new file mode 100644 index 00000000000..f750ccacf57 --- /dev/null +++ b/csharp/ql/lib/change-notes/2024-08-21-partial-methods.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The reported location of `partial` methods has been changed from the definition to the implementation part. From b0003c045373965438cb71ecd32837e23db326d4 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 21 Aug 2024 16:58:53 +0200 Subject: [PATCH 077/404] Ruby: Remove two redundant checks --- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 78f0491ff13..20db26be92f 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -1191,8 +1191,7 @@ private module ParameterNodes { /** Holds if a read-step should be added into parameter `p`. */ predicate readInto(ParameterNode p, ContentSet c) { exists(int n | - isParameterNode(p, callable, any(ParameterPosition pos | pos.isPositional(n))) and - not exists(int i | splatParameterAt(callable.asCfgScope(), i) and i < n) + isParameterNode(p, callable, any(ParameterPosition pos | pos.isPositional(n))) | c = getArrayContent(n) or @@ -1465,7 +1464,6 @@ module ArgumentNodes { exists(int n, ArgumentPosition pos | arg.isArgumentOf(call, pos) and pos.isPositional(n) and - not exists(int i | splatArgumentAt(call, i) and i < n) and c = getArrayContent(n) ) } From cb1b1da422a8d46dad6ead972112134637a316a5 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 21 Aug 2024 19:05:56 +0200 Subject: [PATCH 078/404] Ruby: Add another array flow test --- .../dataflow/array-flow/array-flow.expected | 24 +++++++++++++++++++ .../dataflow/array-flow/array_flow.rb | 15 ++++++++++++ .../type-tracking-array-flow.expected | 1 + 3 files changed, 40 insertions(+) diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected index a9bd1236f47..3899a648b45 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected @@ -2356,6 +2356,16 @@ edges | array_flow.rb:1686:14:1686:14 | w | array_flow.rb:1690:10:1690:10 | w | provenance | | | array_flow.rb:1686:18:1686:18 | a [element 2] | array_flow.rb:1686:11:1686:11 | z | provenance | | | array_flow.rb:1686:18:1686:18 | a [element 3] | array_flow.rb:1686:14:1686:14 | w | provenance | | +| array_flow.rb:1693:10:1693:14 | *args [element 1] | array_flow.rb:1694:17:1694:20 | args [element 1] | provenance | | +| array_flow.rb:1694:16:1694:20 | * ... [element 1] | array_flow.rb:1694:5:1694:21 | call to [] [element 1] | provenance | | +| array_flow.rb:1694:17:1694:20 | args [element 1] | array_flow.rb:1694:16:1694:20 | * ... [element 1] | provenance | | +| array_flow.rb:1697:13:1697:13 | y | array_flow.rb:1699:10:1699:10 | y | provenance | | +| array_flow.rb:1704:5:1704:5 | a [element 1] | array_flow.rb:1705:11:1705:11 | a [element 1] | provenance | | +| array_flow.rb:1704:9:1704:31 | call to m141 [element 1] | array_flow.rb:1704:5:1704:5 | a [element 1] | provenance | | +| array_flow.rb:1704:17:1704:27 | call to source | array_flow.rb:1693:10:1693:14 | *args [element 1] | provenance | | +| array_flow.rb:1704:17:1704:27 | call to source | array_flow.rb:1704:9:1704:31 | call to m141 [element 1] | provenance | | +| array_flow.rb:1705:10:1705:11 | * ... [element 1] | array_flow.rb:1697:13:1697:13 | y | provenance | | +| array_flow.rb:1705:11:1705:11 | a [element 1] | array_flow.rb:1705:10:1705:11 | * ... [element 1] | provenance | | nodes | array_flow.rb:2:5:2:5 | a [element 0] | semmle.label | a [element 0] | | array_flow.rb:2:9:2:20 | * ... [element 0] | semmle.label | * ... [element 0] | @@ -4849,11 +4859,23 @@ nodes | array_flow.rb:1686:18:1686:18 | a [element 3] | semmle.label | a [element 3] | | array_flow.rb:1689:10:1689:10 | z | semmle.label | z | | array_flow.rb:1690:10:1690:10 | w | semmle.label | w | +| array_flow.rb:1693:10:1693:14 | *args [element 1] | semmle.label | *args [element 1] | +| array_flow.rb:1694:5:1694:21 | call to [] [element 1] | semmle.label | call to [] [element 1] | +| array_flow.rb:1694:16:1694:20 | * ... [element 1] | semmle.label | * ... [element 1] | +| array_flow.rb:1694:17:1694:20 | args [element 1] | semmle.label | args [element 1] | +| array_flow.rb:1697:13:1697:13 | y | semmle.label | y | +| array_flow.rb:1699:10:1699:10 | y | semmle.label | y | +| array_flow.rb:1704:5:1704:5 | a [element 1] | semmle.label | a [element 1] | +| array_flow.rb:1704:9:1704:31 | call to m141 [element 1] | semmle.label | call to m141 [element 1] | +| array_flow.rb:1704:17:1704:27 | call to source | semmle.label | call to source | +| array_flow.rb:1705:10:1705:11 | * ... [element 1] | semmle.label | * ... [element 1] | +| array_flow.rb:1705:11:1705:11 | a [element 1] | semmle.label | a [element 1] | subpaths | array_flow.rb:251:9:251:9 | a [element 2] | array_flow.rb:251:30:251:30 | x | array_flow.rb:253:9:253:25 | call to [] [element 0] | array_flow.rb:251:9:254:7 | call to collect_concat [element] | | array_flow.rb:507:9:507:9 | a [element 3] | array_flow.rb:507:26:507:26 | x | array_flow.rb:509:9:509:9 | x | array_flow.rb:507:9:510:7 | call to filter_map [element] | | array_flow.rb:571:9:571:9 | a [element 2] | array_flow.rb:571:24:571:24 | x | array_flow.rb:573:9:573:25 | call to [] [element 0] | array_flow.rb:571:9:574:7 | call to flat_map [element] | | array_flow.rb:1678:9:1678:9 | a [element 2] | array_flow.rb:1678:19:1678:19 | x | array_flow.rb:1679:9:1679:9 | x | array_flow.rb:1678:9:1680:7 | call to map [element] | +| array_flow.rb:1704:17:1704:27 | call to source | array_flow.rb:1693:10:1693:14 | *args [element 1] | array_flow.rb:1694:5:1694:21 | call to [] [element 1] | array_flow.rb:1704:9:1704:31 | call to m141 [element 1] | testFailures arrayLiteral | array_flow.rb:9:9:9:25 | call to [] | @@ -5046,6 +5068,7 @@ arrayLiteral | array_flow.rb:1668:14:1668:41 | ...[...] | | array_flow.rb:1677:9:1677:29 | call to [] | | array_flow.rb:1685:9:1685:44 | call to [] | +| array_flow.rb:1694:5:1694:21 | call to [] | #select | array_flow.rb:3:10:3:13 | ...[...] | array_flow.rb:2:10:2:20 | call to source | array_flow.rb:3:10:3:13 | ...[...] | $@ | array_flow.rb:2:10:2:20 | call to source | call to source | | array_flow.rb:5:10:5:13 | ...[...] | array_flow.rb:2:10:2:20 | call to source | array_flow.rb:5:10:5:13 | ...[...] | $@ | array_flow.rb:2:10:2:20 | call to source | call to source | @@ -5749,3 +5772,4 @@ arrayLiteral | array_flow.rb:1681:10:1681:13 | ...[...] | array_flow.rb:1677:16:1677:28 | call to source | array_flow.rb:1681:10:1681:13 | ...[...] | $@ | array_flow.rb:1677:16:1677:28 | call to source | call to source | | array_flow.rb:1689:10:1689:10 | z | array_flow.rb:1685:16:1685:28 | call to source | array_flow.rb:1689:10:1689:10 | z | $@ | array_flow.rb:1685:16:1685:28 | call to source | call to source | | array_flow.rb:1690:10:1690:10 | w | array_flow.rb:1685:31:1685:43 | call to source | array_flow.rb:1690:10:1690:10 | w | $@ | array_flow.rb:1685:31:1685:43 | call to source | call to source | +| array_flow.rb:1699:10:1699:10 | y | array_flow.rb:1704:17:1704:27 | call to source | array_flow.rb:1699:10:1699:10 | y | $@ | array_flow.rb:1704:17:1704:27 | call to source | call to source | diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb b/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb index cb07ce96ca6..2edfef21688 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb +++ b/ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb @@ -1689,3 +1689,18 @@ def m140 sink z # $ hasValueFlow=140.1 sink w # $ hasValueFlow=140.2 end + +def m141(*args) + ::Array.[](*args) +end + +def m142(x, y, z) + sink(x) + sink(y) # $ hasValueFlow=143 + sink(z) +end + +def m143 + a = m141(0, source(143), 1) + m142(*a) +end diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected index bbb3be53b54..9750c7a94b2 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected @@ -64,4 +64,5 @@ testFailures | array_flow.rb:1626:19:1626:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 | | array_flow.rb:1626:19:1626:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.2 | | array_flow.rb:1627:19:1627:40 | # $ hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 | +| array_flow.rb:1699:13:1699:32 | # $ hasValueFlow=143 | Missing result:hasValueFlow=143 | failures From e94fabcc193ca6e3cc2527386786958cf590ebe0 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 22 Aug 2024 08:27:15 +0200 Subject: [PATCH 079/404] Address review comment --- .../lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll | 2 -- 1 file changed, 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index 84e486c7a55..df876aae455 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -314,8 +314,6 @@ class ContentSet extends TContentSet { this.isProperty(p1) and p2 = result.(PropertyContent).getProperty() | - p1 = p2 - or overridesOrImplementsSourceDecl(p2, p1) or overridesOrImplementsSourceDecl(p1, p2) From 81239dcd959749e8943d5b4c75c9fbfb161bad3d Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 20 Aug 2024 14:11:44 +0200 Subject: [PATCH 080/404] Java: add test case --- .../dataflow/implicit-read/A.java | 27 +++++++++++++++++++ .../dataflow/implicit-read/test.expected | 0 .../dataflow/implicit-read/test.ql | 22 +++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 java/ql/test/library-tests/dataflow/implicit-read/A.java create mode 100644 java/ql/test/library-tests/dataflow/implicit-read/test.expected create mode 100644 java/ql/test/library-tests/dataflow/implicit-read/test.ql diff --git a/java/ql/test/library-tests/dataflow/implicit-read/A.java b/java/ql/test/library-tests/dataflow/implicit-read/A.java new file mode 100644 index 00000000000..c845c7febe2 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/implicit-read/A.java @@ -0,0 +1,27 @@ +public class A { + String field; + + static String source(String name) { + return name; + } + + static void sink(Object o) {} + + static String step(Object o) { + return ""; + } + + static Object getA() { + A a = new A(); + a.field = source("source"); + return a; + } + + static void test() { + Object object = getA(); + + sink(step(object)); // $ hasTaintFlow=source + sink(object); // $ SPURIOUS: hasTaintFlow=source + sink(((A)object).field); // $ hasTaintFlow=source + } +} diff --git a/java/ql/test/library-tests/dataflow/implicit-read/test.expected b/java/ql/test/library-tests/dataflow/implicit-read/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/dataflow/implicit-read/test.ql b/java/ql/test/library-tests/dataflow/implicit-read/test.ql new file mode 100644 index 00000000000..4b07984456b --- /dev/null +++ b/java/ql/test/library-tests/dataflow/implicit-read/test.ql @@ -0,0 +1,22 @@ +import java +import TestUtilities.InlineFlowTest + +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { DefaultFlowConfig::isSource(source) } + + predicate isSink(DataFlow::Node sink) { DefaultFlowConfig::isSink(sink) } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(MethodCall call | + call.getMethod().getName() = "step" and + node1.asExpr() = call.getArgument(0) and + node2.asExpr() = call + ) + } + + predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet content) { + isAdditionalFlowStep(node, _) and content instanceof DataFlow::FieldContent + } +} + +import TaintFlowTest From 2edadbf42397708b896d8f52eab37e9e390bd835 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 22 Aug 2024 11:44:34 +0100 Subject: [PATCH 081/404] Try to fix packages in frameworks coverage --- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 3cd177f92eb..d905201fd45 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -213,16 +213,30 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) { ) } +bindingset[p] +private string cleanPackage(string p) { + exists(string noPrefix | + p = fixedVersionPrefix() + noPrefix + or + not p = fixedVersionPrefix() + any(string s) and + noPrefix = p + | + result = noPrefix.regexpReplaceAll(majorVersionSuffixRegex(), "") + ) +} + private predicate relevantPackage(string package) { - sourceModel(package, _, _, _, _, _, _, _, _, _) or - sinkModel(package, _, _, _, _, _, _, _, _, _) or - summaryModel(package, _, _, _, _, _, _, _, _, _, _) + exists(string p | package = cleanPackage(p) | + sourceModel(p, _, _, _, _, _, _, _, _, _) or + sinkModel(p, _, _, _, _, _, _, _, _, _) or + summaryModel(p, _, _, _, _, _, _, _, _, _, _) + ) } private predicate packageLink(string shortpkg, string longpkg) { relevantPackage(shortpkg) and relevantPackage(longpkg) and - longpkg.prefix(longpkg.indexOf(".")) = shortpkg + longpkg.prefix(longpkg.indexOf("/")) = shortpkg } private predicate canonicalPackage(string package) { @@ -245,26 +259,28 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int part = "source" and n = strictcount(string subpkg, string type, boolean subtypes, string name, string signature, - string ext, string output, string provenance | + string ext, string output, string provenance, string x | canonicalPkgLink(package, subpkg) and - sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind, provenance, _) + subpkg = cleanPackage(x) and + sourceModel(x, type, subtypes, name, signature, ext, output, kind, provenance, _) ) or part = "sink" and n = strictcount(string subpkg, string type, boolean subtypes, string name, string signature, - string ext, string input, string provenance | + string ext, string input, string provenance, string x | canonicalPkgLink(package, subpkg) and - sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind, provenance, _) + subpkg = cleanPackage(x) and + sinkModel(x, type, subtypes, name, signature, ext, input, kind, provenance, _) ) or part = "summary" and n = strictcount(string subpkg, string type, boolean subtypes, string name, string signature, - string ext, string input, string output, string provenance | + string ext, string input, string output, string provenance, string x | canonicalPkgLink(package, subpkg) and - summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, provenance, - _) + subpkg = cleanPackage(x) and + summaryModel(x, type, subtypes, name, signature, ext, input, output, kind, provenance, _) ) ) } From 4cd34531c6c08d11b8339724b42cb092e35d0f95 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 22 Aug 2024 15:07:45 +0200 Subject: [PATCH 082/404] Shared: Add a copy of the existing C# Content Dataflow implementation. --- .../dataflow/internal/ContentDataFlowImpl.qll | 504 ++++++++++++++++++ 1 file changed, 504 insertions(+) create mode 100644 shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll diff --git a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll new file mode 100644 index 00000000000..76936549051 --- /dev/null +++ b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll @@ -0,0 +1,504 @@ +/** + * Provides classes for performing global (inter-procedural) + * content-sensitive data flow analyses. + * + * Unlike `DataFlow::Global`, we allow for data to be stored (possibly nested) inside + * contents of sources and sinks. + * We track flow paths of the form + * + * ``` + * source --value-->* node + * (--read--> node --value-->* node)* + * --(non-value|value)-->* node + * (--store--> node --value-->* node)* + * --value-->* sink + * ``` + * + * where `--value-->` is a value-preserving flow step, `--read-->` is a read + * step, `--store-->` is a store step, and `--(non-value)-->` is a + * non-value-preserving flow step. + * + * That is, first a sequence of 0 or more reads, followed by 0 or more additional + * steps, followed by 0 or more stores, with value-preserving steps allowed in + * between all other steps. + */ + +private import csharp +private import codeql.util.Boolean +private import DataFlowImplCommon +private import DataFlowImplSpecific::Private +private import DataFlowImplSpecific::Private as DataFlowPrivate + +/** + * An input configuration for content data flow. + */ +signature module ConfigSig { + /** + * Holds if `source` is a relevant data flow source. + */ + predicate isSource(DataFlow::Node source); + + /** + * Holds if `sink` is a relevant data flow sink. + */ + predicate isSink(DataFlow::Node sink); + + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. + */ + default predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() } + + /** Holds if data flow into `node` is prohibited. */ + default predicate isBarrier(DataFlow::Node node) { none() } + + /** + * Gets a data flow configuration feature to add restrictions to the set of + * valid flow paths. + * + * - `FeatureHasSourceCallContext`: + * Assume that sources have some existing call context to disallow + * conflicting return-flow directly following the source. + * - `FeatureHasSinkCallContext`: + * Assume that sinks have some existing call context to disallow + * conflicting argument-to-parameter flow directly preceding the sink. + * - `FeatureEqualSourceSinkCallContext`: + * Implies both of the above and additionally ensures that the entire flow + * path preserves the call context. + */ + default DataFlow::FlowFeature getAFeature() { none() } + + /** Gets a limit on the number of reads out of sources and number of stores into sinks. */ + default int accessPathLimit() { result = DataFlowPrivate::accessPathLimit() } + + /** Holds if `c` is relevant for reads out of sources or stores into sinks. */ + default predicate isRelevantContent(DataFlow::ContentSet c) { any() } +} + +/** + * Constructs a global content data flow computation. + */ +module Global { + private module FlowConfig implements DataFlow::StateConfigSig { + class FlowState = State; + + predicate isSource(DataFlow::Node source, FlowState state) { + ContentConfig::isSource(source) and + state.(InitState).decode(true) + } + + predicate isSink(DataFlow::Node sink, FlowState state) { + ContentConfig::isSink(sink) and + ( + state instanceof InitState or + state instanceof StoreState or + state instanceof ReadState + ) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 + ) { + storeStep(node1, state1, _, node2, state2) or + readStep(node1, state1, _, node2, state2) or + additionalStep(node1, state1, node2, state2) + } + + predicate isAdditionalFlowStep = ContentConfig::isAdditionalFlowStep/2; + + predicate isBarrier = ContentConfig::isBarrier/1; + + DataFlow::FlowFeature getAFeature() { result = ContentConfig::getAFeature() } + + predicate accessPathLimit = ContentConfig::accessPathLimit/0; + + // needed to record reads/stores inside summarized callables + predicate includeHiddenNodes() { any() } + } + + private module Flow = DataFlow::GlobalWithState; + + /** + * Holds if data stored inside `sourceAp` on `source` flows to `sinkAp` inside `sink` + * for this configuration. `preservesValue` indicates whether any of the additional + * flow steps defined by `isAdditionalFlowStep` are needed. + * + * For the source access path, `sourceAp`, the top of the stack represents the content + * that was last read from. That is, if `sourceAp` is `Field1.Field2` (with `Field1` + * being the top of the stack), then there is flow from `source.Field2.Field1`. + * + * For the sink access path, `sinkAp`, the top of the stack represents the content + * that was last stored into. That is, if `sinkAp` is `Field1.Field2` (with `Field1` + * being the top of the stack), then there is flow into `sink.Field1.Field2`. + */ + predicate flow( + DataFlow::Node source, AccessPath sourceAp, DataFlow::Node sink, AccessPath sinkAp, + boolean preservesValue + ) { + exists(Flow::PathNode pathSource, Flow::PathNode pathSink | + Flow::flowPath(pathSource, pathSink) and + nodeReaches(pathSource, TAccessPathNil(), TAccessPathNil(), pathSink, sourceAp, sinkAp) and + source = pathSource.getNode() and + sink = pathSink.getNode() + | + pathSink.getState().(InitState).decode(preservesValue) + or + pathSink.getState().(ReadState).decode(_, preservesValue) + or + pathSink.getState().(StoreState).decode(_, preservesValue) + ) + } + + private newtype TState = + TInitState(Boolean preservesValue) or + TStoreState(int size, Boolean preservesValue) { + size in [1 .. ContentConfig::accessPathLimit()] + } or + TReadState(int size, Boolean preservesValue) { size in [1 .. ContentConfig::accessPathLimit()] } + + abstract private class State extends TState { + abstract string toString(); + } + + /** A flow state representing no reads or stores. */ + private class InitState extends State, TInitState { + private boolean preservesValue_; + + InitState() { this = TInitState(preservesValue_) } + + override string toString() { result = "Init(" + preservesValue_ + ")" } + + predicate decode(boolean preservesValue) { preservesValue = preservesValue_ } + } + + /** A flow state representing that content has been stored into. */ + private class StoreState extends State, TStoreState { + private boolean preservesValue_; + private int size_; + + StoreState() { this = TStoreState(size_, preservesValue_) } + + override string toString() { result = "StoreState(" + size_ + "," + preservesValue_ + ")" } + + predicate decode(int size, boolean preservesValue) { + size = size_ and preservesValue = preservesValue_ + } + } + + /** A flow state representing that content has been read from. */ + private class ReadState extends State, TReadState { + private boolean preservesValue_; + private int size_; + + ReadState() { this = TReadState(size_, preservesValue_) } + + override string toString() { result = "ReadState(" + size_ + "," + preservesValue_ + ")" } + + predicate decode(int size, boolean preservesValue) { + size = size_ and preservesValue = preservesValue_ + } + } + + private predicate storeStep( + DataFlow::Node node1, State state1, DataFlow::ContentSet c, DataFlow::Node node2, + StoreState state2 + ) { + exists(boolean preservesValue, int size | + storeSet(node1, c, node2, _, _) and + ContentConfig::isRelevantContent(c) and + state2.decode(size + 1, preservesValue) + | + state1.(InitState).decode(preservesValue) and size = 0 + or + state1.(ReadState).decode(_, preservesValue) and size = 0 + or + state1.(StoreState).decode(size, preservesValue) + ) + } + + private predicate readStep( + DataFlow::Node node1, State state1, DataFlow::ContentSet c, DataFlow::Node node2, + ReadState state2 + ) { + exists(int size | + readSet(node1, c, node2) and + ContentConfig::isRelevantContent(c) and + state2.decode(size + 1, true) + | + state1.(InitState).decode(true) and + size = 0 + or + state1.(ReadState).decode(size, true) + ) + } + + private predicate additionalStep( + DataFlow::Node node1, State state1, DataFlow::Node node2, State state2 + ) { + ContentConfig::isAdditionalFlowStep(node1, node2) and + ( + state1 instanceof InitState and + state2.(InitState).decode(false) + or + exists(int size | + state1.(ReadState).decode(size, _) and + state2.(ReadState).decode(size, false) + ) + ) + } + + private newtype TAccessPath = + TAccessPathNil() or + TAccessPathCons(DataFlow::ContentSet head, AccessPath tail) { + nodeReachesStore(_, _, _, _, head, _, tail) + or + nodeReachesRead(_, _, _, _, head, tail, _) + } + + /** An access path. */ + class AccessPath extends TAccessPath { + /** Gets the head of this access path, if any. */ + DataFlow::ContentSet getHead() { this = TAccessPathCons(result, _) } + + /** Gets the tail of this access path, if any. */ + AccessPath getTail() { this = TAccessPathCons(_, result) } + + /** + * Gets a textual representation of this access path. + * + * Elements are dot-separated, and the head of the stack is + * rendered first. + */ + string toString() { + this = TAccessPathNil() and + result = "" + or + exists(DataFlow::ContentSet head, AccessPath tail | + this = TAccessPathCons(head, tail) and + result = head + "." + tail + ) + } + } + + /** + * Provides a big-step flow relation, where flow stops at read/store steps that + * must be recorded, and flow via `subpaths` such that reads/stores inside + * summarized callables can be recorded as well. + */ + private module BigStepFlow { + private predicate reachesSink(Flow::PathNode node) { + FlowConfig::isSink(node.getNode(), node.getState()) + or + reachesSink(node.getASuccessor()) + } + + /** + * Holds if the flow step `pred -> succ` should not be allowed to be included + * in the big-step relation. + */ + pragma[nomagic] + private predicate excludeStep(Flow::PathNode pred, Flow::PathNode succ) { + pred.getASuccessor() = succ and + ( + // we need to record reads/stores inside summarized callables + Flow::PathGraph::subpaths(pred, _, _, succ) + or + // only allow flow into a summarized callable, as part of the big-step + // relation, when flow can reach a sink without going back out + Flow::PathGraph::subpaths(pred, succ, _, _) and + not reachesSink(succ) + or + // needed to record store steps + storeStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) + or + // needed to record read steps + readStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) + ) + } + + pragma[nomagic] + private DataFlowCallable getEnclosingCallableImpl(Flow::PathNode node) { + result = getNodeEnclosingCallable(node.getNode()) + } + + pragma[inline] + private DataFlowCallable getEnclosingCallable(Flow::PathNode node) { + pragma[only_bind_into](result) = getEnclosingCallableImpl(pragma[only_bind_out](node)) + } + + pragma[nomagic] + private predicate bigStepEntry(Flow::PathNode node) { + ( + FlowConfig::isSource(node.getNode(), node.getState()) + or + excludeStep(_, node) + or + Flow::PathGraph::subpaths(_, node, _, _) + ) + } + + pragma[nomagic] + private predicate bigStepExit(Flow::PathNode node) { + ( + bigStepEntry(node) + or + FlowConfig::isSink(node.getNode(), node.getState()) + or + excludeStep(node, _) + or + Flow::PathGraph::subpaths(_, _, node, _) + ) + } + + pragma[nomagic] + private predicate step(Flow::PathNode pred, Flow::PathNode succ) { + pred.getASuccessor() = succ and + not excludeStep(pred, succ) + } + + pragma[nomagic] + private predicate stepRec(Flow::PathNode pred, Flow::PathNode succ) { + step(pred, succ) and + not bigStepEntry(pred) + } + + private predicate stepRecPlus(Flow::PathNode n1, Flow::PathNode n2) = fastTC(stepRec/2)(n1, n2) + + /** + * Holds if there is flow `pathSucc+(pred) = succ`, and such a flow path does + * not go through any reads/stores that need to be recorded, or summarized + * steps. + */ + pragma[nomagic] + private predicate bigStep(Flow::PathNode pred, Flow::PathNode succ) { + exists(Flow::PathNode mid | + bigStepEntry(pred) and + step(pred, mid) + | + succ = mid + or + stepRecPlus(mid, succ) + ) and + bigStepExit(succ) + } + + pragma[nomagic] + predicate bigStepNotLocal(Flow::PathNode pred, Flow::PathNode succ) { + bigStep(pred, succ) and + not getEnclosingCallable(pred) = getEnclosingCallable(succ) + } + + pragma[nomagic] + predicate bigStepMaybeLocal(Flow::PathNode pred, Flow::PathNode succ) { + bigStep(pred, succ) and + getEnclosingCallable(pred) = getEnclosingCallable(succ) + } + } + + /** + * Holds if `source` can reach `node`, having read `reads` from the source and + * written `stores` into `node`. + * + * `source` is either a source from a configuration, in which case `scReads` and + * `scStores` are always empty, or it is the parameter of a summarized callable, + * in which case `scReads` and `scStores` record the reads/stores for a summary + * context, that is, the reads/stores for an argument that can reach the parameter. + */ + pragma[nomagic] + private predicate nodeReaches( + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, + AccessPath reads, AccessPath stores + ) { + node = source and + reads = scReads and + stores = scStores and + ( + Flow::flowPath(source, _) and + scReads = TAccessPathNil() and + scStores = TAccessPathNil() + or + // the argument in a sub path can be reached, so we start flow from the sub path + // parameter, while recording the read/store summary context + exists(Flow::PathNode arg | + nodeReachesSubpathArg(_, _, _, arg, scReads, scStores) and + Flow::PathGraph::subpaths(arg, source, _, _) + ) + ) + or + exists(Flow::PathNode mid | + nodeReaches(source, scReads, scStores, mid, reads, stores) and + BigStepFlow::bigStepMaybeLocal(mid, node) + ) + or + exists(Flow::PathNode mid | + nodeReaches(source, scReads, scStores, mid, reads, stores) and + BigStepFlow::bigStepNotLocal(mid, node) and + // when flow is not local, we cannot flow back out, so we may stop + // flow early when computing summary flow + Flow::flowPath(source, _) and + scReads = TAccessPathNil() and + scStores = TAccessPathNil() + ) + or + // store step + exists(AccessPath storesMid, DataFlow::ContentSet c | + nodeReachesStore(source, scReads, scStores, node, c, reads, storesMid) and + stores = TAccessPathCons(c, storesMid) + ) + or + // read step + exists(AccessPath readsMid, DataFlow::ContentSet c | + nodeReachesRead(source, scReads, scStores, node, c, readsMid, stores) and + reads = TAccessPathCons(c, readsMid) + ) + or + // flow-through step; match outer stores/reads with inner store/read summary contexts + exists(Flow::PathNode mid, AccessPath innerScReads, AccessPath innerScStores | + nodeReachesSubpathArg(source, scReads, scStores, mid, innerScReads, innerScStores) and + subpathArgReachesOut(mid, innerScReads, innerScStores, node, reads, stores) + ) + } + + pragma[nomagic] + private predicate nodeReachesStore( + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, + DataFlow::ContentSet c, AccessPath reads, AccessPath stores + ) { + exists(Flow::PathNode mid | + nodeReaches(source, scReads, scStores, mid, reads, stores) and + storeStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and + mid.getASuccessor() = node + ) + } + + pragma[nomagic] + private predicate nodeReachesRead( + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, + DataFlow::ContentSet c, AccessPath reads, AccessPath stores + ) { + exists(Flow::PathNode mid | + nodeReaches(source, scReads, scStores, mid, reads, stores) and + readStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and + mid.getASuccessor() = node + ) + } + + pragma[nomagic] + private predicate nodeReachesSubpathArg( + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode arg, + AccessPath reads, AccessPath stores + ) { + nodeReaches(source, scReads, scStores, arg, reads, stores) and + Flow::PathGraph::subpaths(arg, _, _, _) + } + + pragma[nomagic] + private predicate subpathArgReachesOut( + Flow::PathNode arg, AccessPath scReads, AccessPath scStores, Flow::PathNode out, + AccessPath reads, AccessPath stores + ) { + exists(Flow::PathNode source, Flow::PathNode ret | + nodeReaches(source, scReads, scStores, ret, reads, stores) and + Flow::PathGraph::subpaths(arg, source, ret, out) + ) + } +} From 6827bedaa731514827501408948c2f8eb7e31fa5 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 22 Aug 2024 14:53:43 +0200 Subject: [PATCH 083/404] C#: Add aggregated compiler and extractor message counts to extraction telemetry query --- .../Entities/Compilations/Compilation.cs | 11 ++++++++++- .../Semmle.Extraction.CSharp/Extractor/Analyser.cs | 2 ++ .../Semmle.Extraction.CSharp/Extractor/Extractor.cs | 1 + csharp/extractor/Semmle.Extraction/BUILD.bazel | 1 + .../Semmle.Extraction/Entities/ExtractionMessage.cs | 9 ++++++++- .../Semmle.Extraction/Semmle.Extraction.csproj | 2 ++ .../all-platforms/standalone/Diag.expected | 2 ++ .../all-platforms/standalone/Diag.ql | 3 ++- .../standalone_winforms/CompilationInfo.ql | 2 +- csharp/ql/src/Telemetry/ExtractorInformation.ql | 13 +++++++++++++ 10 files changed, 42 insertions(+), 4 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs index 8685c9d7a7d..ecb5d51d44d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.IO; using System.Linq; using Microsoft.CodeAnalysis; +using Semmle.Extraction.Entities; using Semmle.Util; namespace Semmle.Extraction.CSharp.Entities @@ -89,13 +90,21 @@ namespace Semmle.Extraction.CSharp.Entities trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds); } + public void PopulateAggregatedMessages() + { + ExtractionMessage.groupedMessageCounts.ForEach(pair => + { + Context.TrapWriter.Writer.compilation_info(this, $"Extractor message count for group '{pair.Key}'", pair.Value.ToString()); + }); + } + public override void WriteId(EscapingTextWriter trapFile) { trapFile.Write(hashCode); trapFile.Write(";compilation"); } - public override Location ReportingLocation => throw new NotImplementedException(); + public override Microsoft.CodeAnalysis.Location ReportingLocation => throw new NotImplementedException(); public override bool NeedsPopulation => Context.IsAssemblyScope; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs index 0b523e69b1a..b839d2c976a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs @@ -250,6 +250,8 @@ namespace Semmle.Extraction.CSharp public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p); + public void ExtractAggregatedMessages() => compilationEntity.PopulateAggregatedMessages(); + #nullable restore warnings ///

    diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs index ae3875f5028..d87f6fd24c0 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs @@ -458,6 +458,7 @@ namespace Semmle.Extraction.CSharp sw.Restart(); analyser.PerformExtraction(options.Threads); + analyser.ExtractAggregatedMessages(); sw.Stop(); var cpuTime2 = currentProcess.TotalProcessorTime; var userTime2 = currentProcess.UserProcessorTime; diff --git a/csharp/extractor/Semmle.Extraction/BUILD.bazel b/csharp/extractor/Semmle.Extraction/BUILD.bazel index de3a6c2d96a..83dfb8235e8 100644 --- a/csharp/extractor/Semmle.Extraction/BUILD.bazel +++ b/csharp/extractor/Semmle.Extraction/BUILD.bazel @@ -26,6 +26,7 @@ codeql_csharp_library( ], "//conditions:default": [], }), + internals_visible_to = ["Semmle.Extraction.CSharp"], visibility = ["//csharp:__subpackages__"], deps = [ "//csharp/extractor/Semmle.Util", diff --git a/csharp/extractor/Semmle.Extraction/Entities/ExtractionMessage.cs b/csharp/extractor/Semmle.Extraction/Entities/ExtractionMessage.cs index f417a170c10..514ce433c0a 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/ExtractionMessage.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/ExtractionMessage.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.Collections.Concurrent; +using System.IO; using System.Threading; using Semmle.Util; @@ -7,6 +8,8 @@ namespace Semmle.Extraction.Entities internal class ExtractionMessage : FreshEntity { private static readonly int limit = EnvironmentVariables.TryGetExtractorNumberOption("MESSAGE_LIMIT") ?? 10000; + + internal static readonly ConcurrentDictionary groupedMessageCounts = []; private static int messageCount = 0; private readonly Message msg; @@ -25,6 +28,10 @@ namespace Semmle.Extraction.Entities protected override void Populate(TextWriter trapFile) { + // For the time being we're counting the number of messages per severity, we could introduce other groupings in the future + var key = msg.Severity.ToString(); + groupedMessageCounts.AddOrUpdate(key, 1, (_, c) => c + 1); + if (!bypassLimit) { var val = Interlocked.Increment(ref messageCount); diff --git a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj index b4625b16017..2173a50f2ad 100644 --- a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj +++ b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj @@ -5,6 +5,8 @@ + + diff --git a/csharp/ql/integration-tests/all-platforms/standalone/Diag.expected b/csharp/ql/integration-tests/all-platforms/standalone/Diag.expected index 6d84e27e5ce..74314f2c0c9 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone/Diag.expected +++ b/csharp/ql/integration-tests/all-platforms/standalone/Diag.expected @@ -7,3 +7,5 @@ extractorMessagesLeachedLimit compilationInfo | Compiler diagnostic count for CS0103 | 3.0 | | Compiler diagnostic count for CS8019 | 7.0 | +| Extractor message count for group 'Error' | 8.0 | +| Extractor message count for group 'Warning' | 1.0 | diff --git a/csharp/ql/integration-tests/all-platforms/standalone/Diag.ql b/csharp/ql/integration-tests/all-platforms/standalone/Diag.ql index 8b1fbae6b2f..e2fa743471c 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone/Diag.ql +++ b/csharp/ql/integration-tests/all-platforms/standalone/Diag.ql @@ -11,7 +11,8 @@ query predicate extractorMessagesLeachedLimit(ExtractorMessage msg) { query predicate compilationInfo(string key, float value) { exists(Compilation c, string infoValue | - infoValue = c.getInfo(key) and key.matches("Compiler diagnostic count for%") + infoValue = c.getInfo(key) and + key.matches(["Compiler diagnostic count for%", "Extractor message count for group%"]) | value = infoValue.toFloat() ) diff --git a/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.ql b/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.ql index a96c2fd99a6..078e352be4d 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.ql +++ b/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.ql @@ -4,7 +4,7 @@ import semmle.code.csharp.commons.Diagnostics query predicate compilationInfo(string key, float value) { key != "Resolved references" and key != "Resolved assembly conflicts" and - not key.matches("Compiler diagnostic count for%") and + not key.matches(["Compiler diagnostic count for%", "Extractor message count for group%"]) and exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | key = infoKey and value = infoValue.toFloat() diff --git a/csharp/ql/src/Telemetry/ExtractorInformation.ql b/csharp/ql/src/Telemetry/ExtractorInformation.ql index c2d80f7c768..6fdaf9ca22d 100644 --- a/csharp/ql/src/Telemetry/ExtractorInformation.ql +++ b/csharp/ql/src/Telemetry/ExtractorInformation.ql @@ -12,6 +12,7 @@ import DatabaseQuality predicate compilationInfo(string key, float value) { not key.matches("Compiler diagnostic count for%") and + not key.matches("Extractor message count for group%") and exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | key = infoKey and value = infoValue.toFloat() @@ -22,6 +23,16 @@ predicate compilationInfo(string key, float value) { ) } +predicate compilerDiagnostics(string key, int value) { + key.matches("Compiler diagnostic count for%") and + strictsum(Compilation c | | c.getInfo(key).toInt()) = value +} + +predicate extractorMessages(string key, int value) { + key.matches("Extractor message count for group%") and + strictsum(Compilation c | | c.getInfo(key).toInt()) = value +} + predicate fileCount(string key, int value) { key = "Number of files" and value = strictcount(File f) @@ -140,6 +151,8 @@ from string key, float value where ( compilationInfo(key, value) or + compilerDiagnostics(key, value) or + extractorMessages(key, value) or fileCount(key, value) or fileCountByExtension(key, value) or totalNumberOfLines(key, value) or From e6424f0f45848b8f11a883a4d8688819b9f287e7 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 22 Aug 2024 15:45:34 +0200 Subject: [PATCH 084/404] Shared: Make ContentDataFlow reusable. --- .../dataflow/internal/ContentDataFlowImpl.qll | 888 +++++++++--------- 1 file changed, 444 insertions(+), 444 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll index 76936549051..18e44061967 100644 --- a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll @@ -23,482 +23,482 @@ * between all other steps. */ -private import csharp +private import codeql.dataflow.DataFlow private import codeql.util.Boolean +private import codeql.util.Location +private import DataFlowImpl private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Private as DataFlowPrivate -/** - * An input configuration for content data flow. - */ -signature module ConfigSig { - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(DataFlow::Node source); +module MakeImplContentDataFlow Lang> { + private import Lang + private import DataFlowMake + private import DataFlowImplCommon::MakeImplCommon /** - * Holds if `sink` is a relevant data flow sink. + * An input configuration for content data flow. */ - predicate isSink(DataFlow::Node sink); - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - default predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - /** Holds if data flow into `node` is prohibited. */ - default predicate isBarrier(DataFlow::Node node) { none() } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - */ - default DataFlow::FlowFeature getAFeature() { none() } - - /** Gets a limit on the number of reads out of sources and number of stores into sinks. */ - default int accessPathLimit() { result = DataFlowPrivate::accessPathLimit() } - - /** Holds if `c` is relevant for reads out of sources or stores into sinks. */ - default predicate isRelevantContent(DataFlow::ContentSet c) { any() } -} - -/** - * Constructs a global content data flow computation. - */ -module Global { - private module FlowConfig implements DataFlow::StateConfigSig { - class FlowState = State; - - predicate isSource(DataFlow::Node source, FlowState state) { - ContentConfig::isSource(source) and - state.(InitState).decode(true) - } - - predicate isSink(DataFlow::Node sink, FlowState state) { - ContentConfig::isSink(sink) and - ( - state instanceof InitState or - state instanceof StoreState or - state instanceof ReadState - ) - } - - predicate isAdditionalFlowStep( - DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 - ) { - storeStep(node1, state1, _, node2, state2) or - readStep(node1, state1, _, node2, state2) or - additionalStep(node1, state1, node2, state2) - } - - predicate isAdditionalFlowStep = ContentConfig::isAdditionalFlowStep/2; - - predicate isBarrier = ContentConfig::isBarrier/1; - - DataFlow::FlowFeature getAFeature() { result = ContentConfig::getAFeature() } - - predicate accessPathLimit = ContentConfig::accessPathLimit/0; - - // needed to record reads/stores inside summarized callables - predicate includeHiddenNodes() { any() } - } - - private module Flow = DataFlow::GlobalWithState; - - /** - * Holds if data stored inside `sourceAp` on `source` flows to `sinkAp` inside `sink` - * for this configuration. `preservesValue` indicates whether any of the additional - * flow steps defined by `isAdditionalFlowStep` are needed. - * - * For the source access path, `sourceAp`, the top of the stack represents the content - * that was last read from. That is, if `sourceAp` is `Field1.Field2` (with `Field1` - * being the top of the stack), then there is flow from `source.Field2.Field1`. - * - * For the sink access path, `sinkAp`, the top of the stack represents the content - * that was last stored into. That is, if `sinkAp` is `Field1.Field2` (with `Field1` - * being the top of the stack), then there is flow into `sink.Field1.Field2`. - */ - predicate flow( - DataFlow::Node source, AccessPath sourceAp, DataFlow::Node sink, AccessPath sinkAp, - boolean preservesValue - ) { - exists(Flow::PathNode pathSource, Flow::PathNode pathSink | - Flow::flowPath(pathSource, pathSink) and - nodeReaches(pathSource, TAccessPathNil(), TAccessPathNil(), pathSink, sourceAp, sinkAp) and - source = pathSource.getNode() and - sink = pathSink.getNode() - | - pathSink.getState().(InitState).decode(preservesValue) - or - pathSink.getState().(ReadState).decode(_, preservesValue) - or - pathSink.getState().(StoreState).decode(_, preservesValue) - ) - } - - private newtype TState = - TInitState(Boolean preservesValue) or - TStoreState(int size, Boolean preservesValue) { - size in [1 .. ContentConfig::accessPathLimit()] - } or - TReadState(int size, Boolean preservesValue) { size in [1 .. ContentConfig::accessPathLimit()] } - - abstract private class State extends TState { - abstract string toString(); - } - - /** A flow state representing no reads or stores. */ - private class InitState extends State, TInitState { - private boolean preservesValue_; - - InitState() { this = TInitState(preservesValue_) } - - override string toString() { result = "Init(" + preservesValue_ + ")" } - - predicate decode(boolean preservesValue) { preservesValue = preservesValue_ } - } - - /** A flow state representing that content has been stored into. */ - private class StoreState extends State, TStoreState { - private boolean preservesValue_; - private int size_; - - StoreState() { this = TStoreState(size_, preservesValue_) } - - override string toString() { result = "StoreState(" + size_ + "," + preservesValue_ + ")" } - - predicate decode(int size, boolean preservesValue) { - size = size_ and preservesValue = preservesValue_ - } - } - - /** A flow state representing that content has been read from. */ - private class ReadState extends State, TReadState { - private boolean preservesValue_; - private int size_; - - ReadState() { this = TReadState(size_, preservesValue_) } - - override string toString() { result = "ReadState(" + size_ + "," + preservesValue_ + ")" } - - predicate decode(int size, boolean preservesValue) { - size = size_ and preservesValue = preservesValue_ - } - } - - private predicate storeStep( - DataFlow::Node node1, State state1, DataFlow::ContentSet c, DataFlow::Node node2, - StoreState state2 - ) { - exists(boolean preservesValue, int size | - storeSet(node1, c, node2, _, _) and - ContentConfig::isRelevantContent(c) and - state2.decode(size + 1, preservesValue) - | - state1.(InitState).decode(preservesValue) and size = 0 - or - state1.(ReadState).decode(_, preservesValue) and size = 0 - or - state1.(StoreState).decode(size, preservesValue) - ) - } - - private predicate readStep( - DataFlow::Node node1, State state1, DataFlow::ContentSet c, DataFlow::Node node2, - ReadState state2 - ) { - exists(int size | - readSet(node1, c, node2) and - ContentConfig::isRelevantContent(c) and - state2.decode(size + 1, true) - | - state1.(InitState).decode(true) and - size = 0 - or - state1.(ReadState).decode(size, true) - ) - } - - private predicate additionalStep( - DataFlow::Node node1, State state1, DataFlow::Node node2, State state2 - ) { - ContentConfig::isAdditionalFlowStep(node1, node2) and - ( - state1 instanceof InitState and - state2.(InitState).decode(false) - or - exists(int size | - state1.(ReadState).decode(size, _) and - state2.(ReadState).decode(size, false) - ) - ) - } - - private newtype TAccessPath = - TAccessPathNil() or - TAccessPathCons(DataFlow::ContentSet head, AccessPath tail) { - nodeReachesStore(_, _, _, _, head, _, tail) - or - nodeReachesRead(_, _, _, _, head, tail, _) - } - - /** An access path. */ - class AccessPath extends TAccessPath { - /** Gets the head of this access path, if any. */ - DataFlow::ContentSet getHead() { this = TAccessPathCons(result, _) } - - /** Gets the tail of this access path, if any. */ - AccessPath getTail() { this = TAccessPathCons(_, result) } + signature module ConfigSig { + /** + * Holds if `source` is a relevant data flow source. + */ + predicate isSource(Node source); /** - * Gets a textual representation of this access path. + * Holds if `sink` is a relevant data flow sink. + */ + predicate isSink(Node sink); + + /** + * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. + */ + default predicate isAdditionalFlowStep(Node node1, Node node2) { none() } + + /** Holds if data flow into `node` is prohibited. */ + default predicate isBarrier(Node node) { none() } + + /** + * Gets a data flow configuration feature to add restrictions to the set of + * valid flow paths. * - * Elements are dot-separated, and the head of the stack is - * rendered first. + * - `FeatureHasSourceCallContext`: + * Assume that sources have some existing call context to disallow + * conflicting return-flow directly following the source. + * - `FeatureHasSinkCallContext`: + * Assume that sinks have some existing call context to disallow + * conflicting argument-to-parameter flow directly preceding the sink. + * - `FeatureEqualSourceSinkCallContext`: + * Implies both of the above and additionally ensures that the entire flow + * path preserves the call context. */ - string toString() { - this = TAccessPathNil() and - result = "" - or - exists(DataFlow::ContentSet head, AccessPath tail | - this = TAccessPathCons(head, tail) and - result = head + "." + tail - ) - } + default FlowFeature getAFeature() { none() } + + /** Gets a limit on the number of reads out of sources and number of stores into sinks. */ + default int accessPathLimit() { result = Lang::accessPathLimit() } + + /** Holds if `c` is relevant for reads out of sources or stores into sinks. */ + default predicate isRelevantContent(ContentSet c) { any() } } /** - * Provides a big-step flow relation, where flow stops at read/store steps that - * must be recorded, and flow via `subpaths` such that reads/stores inside - * summarized callables can be recorded as well. + * Constructs a global content data flow computation. */ - private module BigStepFlow { - private predicate reachesSink(Flow::PathNode node) { - FlowConfig::isSink(node.getNode(), node.getState()) - or - reachesSink(node.getASuccessor()) + module Global { + private module FlowConfig implements StateConfigSig { + class FlowState = State; + + predicate isSource(Node source, FlowState state) { + ContentConfig::isSource(source) and + state.(InitState).decode(true) + } + + predicate isSink(Node sink, FlowState state) { + ContentConfig::isSink(sink) and + ( + state instanceof InitState or + state instanceof StoreState or + state instanceof ReadState + ) + } + + predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { + storeStep(node1, state1, _, node2, state2) or + readStep(node1, state1, _, node2, state2) or + additionalStep(node1, state1, node2, state2) + } + + predicate isAdditionalFlowStep = ContentConfig::isAdditionalFlowStep/2; + + predicate isBarrier = ContentConfig::isBarrier/1; + + FlowFeature getAFeature() { result = ContentConfig::getAFeature() } + + predicate accessPathLimit = ContentConfig::accessPathLimit/0; + + // needed to record reads/stores inside summarized callables + predicate includeHiddenNodes() { any() } + } + + private module Flow = GlobalWithState; + + /** + * Holds if data stored inside `sourceAp` on `source` flows to `sinkAp` inside `sink` + * for this configuration. `preservesValue` indicates whether any of the additional + * flow steps defined by `isAdditionalFlowStep` are needed. + * + * For the source access path, `sourceAp`, the top of the stack represents the content + * that was last read from. That is, if `sourceAp` is `Field1.Field2` (with `Field1` + * being the top of the stack), then there is flow from `source.Field2.Field1`. + * + * For the sink access path, `sinkAp`, the top of the stack represents the content + * that was last stored into. That is, if `sinkAp` is `Field1.Field2` (with `Field1` + * being the top of the stack), then there is flow into `sink.Field1.Field2`. + */ + predicate flow( + Node source, AccessPath sourceAp, Node sink, AccessPath sinkAp, boolean preservesValue + ) { + exists(Flow::PathNode pathSource, Flow::PathNode pathSink | + Flow::flowPath(pathSource, pathSink) and + nodeReaches(pathSource, TAccessPathNil(), TAccessPathNil(), pathSink, sourceAp, sinkAp) and + source = pathSource.getNode() and + sink = pathSink.getNode() + | + pathSink.getState().(InitState).decode(preservesValue) + or + pathSink.getState().(ReadState).decode(_, preservesValue) + or + pathSink.getState().(StoreState).decode(_, preservesValue) + ) + } + + private newtype TState = + TInitState(Boolean preservesValue) or + TStoreState(int size, Boolean preservesValue) { + size in [1 .. ContentConfig::accessPathLimit()] + } or + TReadState(int size, Boolean preservesValue) { + size in [1 .. ContentConfig::accessPathLimit()] + } + + abstract private class State extends TState { + abstract string toString(); + } + + /** A flow state representing no reads or stores. */ + private class InitState extends State, TInitState { + private boolean preservesValue_; + + InitState() { this = TInitState(preservesValue_) } + + override string toString() { result = "Init(" + preservesValue_ + ")" } + + predicate decode(boolean preservesValue) { preservesValue = preservesValue_ } + } + + /** A flow state representing that content has been stored into. */ + private class StoreState extends State, TStoreState { + private boolean preservesValue_; + private int size_; + + StoreState() { this = TStoreState(size_, preservesValue_) } + + override string toString() { result = "StoreState(" + size_ + "," + preservesValue_ + ")" } + + predicate decode(int size, boolean preservesValue) { + size = size_ and preservesValue = preservesValue_ + } + } + + /** A flow state representing that content has been read from. */ + private class ReadState extends State, TReadState { + private boolean preservesValue_; + private int size_; + + ReadState() { this = TReadState(size_, preservesValue_) } + + override string toString() { result = "ReadState(" + size_ + "," + preservesValue_ + ")" } + + predicate decode(int size, boolean preservesValue) { + size = size_ and preservesValue = preservesValue_ + } + } + + private predicate storeStep( + Node node1, State state1, ContentSet c, Node node2, StoreState state2 + ) { + exists(boolean preservesValue, int size | + storeSet(node1, c, node2, _, _) and + ContentConfig::isRelevantContent(c) and + state2.decode(size + 1, preservesValue) + | + state1.(InitState).decode(preservesValue) and size = 0 + or + state1.(ReadState).decode(_, preservesValue) and size = 0 + or + state1.(StoreState).decode(size, preservesValue) + ) + } + + private predicate readStep(Node node1, State state1, ContentSet c, Node node2, ReadState state2) { + exists(int size | + readSet(node1, c, node2) and + ContentConfig::isRelevantContent(c) and + state2.decode(size + 1, true) + | + state1.(InitState).decode(true) and + size = 0 + or + state1.(ReadState).decode(size, true) + ) + } + + private predicate additionalStep(Node node1, State state1, Node node2, State state2) { + ContentConfig::isAdditionalFlowStep(node1, node2) and + ( + state1 instanceof InitState and + state2.(InitState).decode(false) + or + exists(int size | + state1.(ReadState).decode(size, _) and + state2.(ReadState).decode(size, false) + ) + ) + } + + private newtype TAccessPath = + TAccessPathNil() or + TAccessPathCons(ContentSet head, AccessPath tail) { + nodeReachesStore(_, _, _, _, head, _, tail) + or + nodeReachesRead(_, _, _, _, head, tail, _) + } + + /** An access path. */ + class AccessPath extends TAccessPath { + /** Gets the head of this access path, if any. */ + ContentSet getHead() { this = TAccessPathCons(result, _) } + + /** Gets the tail of this access path, if any. */ + AccessPath getTail() { this = TAccessPathCons(_, result) } + + /** + * Gets a textual representation of this access path. + * + * Elements are dot-separated, and the head of the stack is + * rendered first. + */ + string toString() { + this = TAccessPathNil() and + result = "" + or + exists(ContentSet head, AccessPath tail | + this = TAccessPathCons(head, tail) and + result = head + "." + tail + ) + } } /** - * Holds if the flow step `pred -> succ` should not be allowed to be included - * in the big-step relation. + * Provides a big-step flow relation, where flow stops at read/store steps that + * must be recorded, and flow via `subpaths` such that reads/stores inside + * summarized callables can be recorded as well. */ - pragma[nomagic] - private predicate excludeStep(Flow::PathNode pred, Flow::PathNode succ) { - pred.getASuccessor() = succ and - ( - // we need to record reads/stores inside summarized callables - Flow::PathGraph::subpaths(pred, _, _, succ) - or - // only allow flow into a summarized callable, as part of the big-step - // relation, when flow can reach a sink without going back out - Flow::PathGraph::subpaths(pred, succ, _, _) and - not reachesSink(succ) - or - // needed to record store steps - storeStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) - or - // needed to record read steps - readStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) - ) - } - - pragma[nomagic] - private DataFlowCallable getEnclosingCallableImpl(Flow::PathNode node) { - result = getNodeEnclosingCallable(node.getNode()) - } - - pragma[inline] - private DataFlowCallable getEnclosingCallable(Flow::PathNode node) { - pragma[only_bind_into](result) = getEnclosingCallableImpl(pragma[only_bind_out](node)) - } - - pragma[nomagic] - private predicate bigStepEntry(Flow::PathNode node) { - ( - FlowConfig::isSource(node.getNode(), node.getState()) - or - excludeStep(_, node) - or - Flow::PathGraph::subpaths(_, node, _, _) - ) - } - - pragma[nomagic] - private predicate bigStepExit(Flow::PathNode node) { - ( - bigStepEntry(node) - or + private module BigStepFlow { + private predicate reachesSink(Flow::PathNode node) { FlowConfig::isSink(node.getNode(), node.getState()) or - excludeStep(node, _) - or - Flow::PathGraph::subpaths(_, _, node, _) - ) - } + reachesSink(node.getASuccessor()) + } - pragma[nomagic] - private predicate step(Flow::PathNode pred, Flow::PathNode succ) { - pred.getASuccessor() = succ and - not excludeStep(pred, succ) - } + /** + * Holds if the flow step `pred -> succ` should not be allowed to be included + * in the big-step relation. + */ + pragma[nomagic] + private predicate excludeStep(Flow::PathNode pred, Flow::PathNode succ) { + pred.getASuccessor() = succ and + ( + // we need to record reads/stores inside summarized callables + Flow::PathGraph::subpaths(pred, _, _, succ) + or + // only allow flow into a summarized callable, as part of the big-step + // relation, when flow can reach a sink without going back out + Flow::PathGraph::subpaths(pred, succ, _, _) and + not reachesSink(succ) + or + // needed to record store steps + storeStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) + or + // needed to record read steps + readStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) + ) + } - pragma[nomagic] - private predicate stepRec(Flow::PathNode pred, Flow::PathNode succ) { - step(pred, succ) and - not bigStepEntry(pred) - } + pragma[nomagic] + private DataFlowCallable getEnclosingCallableImpl(Flow::PathNode node) { + result = getNodeEnclosingCallable(node.getNode()) + } - private predicate stepRecPlus(Flow::PathNode n1, Flow::PathNode n2) = fastTC(stepRec/2)(n1, n2) + pragma[inline] + private DataFlowCallable getEnclosingCallable(Flow::PathNode node) { + pragma[only_bind_into](result) = getEnclosingCallableImpl(pragma[only_bind_out](node)) + } + + pragma[nomagic] + private predicate bigStepEntry(Flow::PathNode node) { + ( + FlowConfig::isSource(node.getNode(), node.getState()) + or + excludeStep(_, node) + or + Flow::PathGraph::subpaths(_, node, _, _) + ) + } + + pragma[nomagic] + private predicate bigStepExit(Flow::PathNode node) { + ( + bigStepEntry(node) + or + FlowConfig::isSink(node.getNode(), node.getState()) + or + excludeStep(node, _) + or + Flow::PathGraph::subpaths(_, _, node, _) + ) + } + + pragma[nomagic] + private predicate step(Flow::PathNode pred, Flow::PathNode succ) { + pred.getASuccessor() = succ and + not excludeStep(pred, succ) + } + + pragma[nomagic] + private predicate stepRec(Flow::PathNode pred, Flow::PathNode succ) { + step(pred, succ) and + not bigStepEntry(pred) + } + + private predicate stepRecPlus(Flow::PathNode n1, Flow::PathNode n2) = + fastTC(stepRec/2)(n1, n2) + + /** + * Holds if there is flow `pathSucc+(pred) = succ`, and such a flow path does + * not go through any reads/stores that need to be recorded, or summarized + * steps. + */ + pragma[nomagic] + private predicate bigStep(Flow::PathNode pred, Flow::PathNode succ) { + exists(Flow::PathNode mid | + bigStepEntry(pred) and + step(pred, mid) + | + succ = mid + or + stepRecPlus(mid, succ) + ) and + bigStepExit(succ) + } + + pragma[nomagic] + predicate bigStepNotLocal(Flow::PathNode pred, Flow::PathNode succ) { + bigStep(pred, succ) and + not getEnclosingCallable(pred) = getEnclosingCallable(succ) + } + + pragma[nomagic] + predicate bigStepMaybeLocal(Flow::PathNode pred, Flow::PathNode succ) { + bigStep(pred, succ) and + getEnclosingCallable(pred) = getEnclosingCallable(succ) + } + } /** - * Holds if there is flow `pathSucc+(pred) = succ`, and such a flow path does - * not go through any reads/stores that need to be recorded, or summarized - * steps. + * Holds if `source` can reach `node`, having read `reads` from the source and + * written `stores` into `node`. + * + * `source` is either a source from a configuration, in which case `scReads` and + * `scStores` are always empty, or it is the parameter of a summarized callable, + * in which case `scReads` and `scStores` record the reads/stores for a summary + * context, that is, the reads/stores for an argument that can reach the parameter. */ pragma[nomagic] - private predicate bigStep(Flow::PathNode pred, Flow::PathNode succ) { - exists(Flow::PathNode mid | - bigStepEntry(pred) and - step(pred, mid) - | - succ = mid + private predicate nodeReaches( + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, + AccessPath reads, AccessPath stores + ) { + node = source and + reads = scReads and + stores = scStores and + ( + Flow::flowPath(source, _) and + scReads = TAccessPathNil() and + scStores = TAccessPathNil() or - stepRecPlus(mid, succ) - ) and - bigStepExit(succ) - } - - pragma[nomagic] - predicate bigStepNotLocal(Flow::PathNode pred, Flow::PathNode succ) { - bigStep(pred, succ) and - not getEnclosingCallable(pred) = getEnclosingCallable(succ) - } - - pragma[nomagic] - predicate bigStepMaybeLocal(Flow::PathNode pred, Flow::PathNode succ) { - bigStep(pred, succ) and - getEnclosingCallable(pred) = getEnclosingCallable(succ) - } - } - - /** - * Holds if `source` can reach `node`, having read `reads` from the source and - * written `stores` into `node`. - * - * `source` is either a source from a configuration, in which case `scReads` and - * `scStores` are always empty, or it is the parameter of a summarized callable, - * in which case `scReads` and `scStores` record the reads/stores for a summary - * context, that is, the reads/stores for an argument that can reach the parameter. - */ - pragma[nomagic] - private predicate nodeReaches( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, - AccessPath reads, AccessPath stores - ) { - node = source and - reads = scReads and - stores = scStores and - ( - Flow::flowPath(source, _) and - scReads = TAccessPathNil() and - scStores = TAccessPathNil() - or - // the argument in a sub path can be reached, so we start flow from the sub path - // parameter, while recording the read/store summary context - exists(Flow::PathNode arg | - nodeReachesSubpathArg(_, _, _, arg, scReads, scStores) and - Flow::PathGraph::subpaths(arg, source, _, _) + // the argument in a sub path can be reached, so we start flow from the sub path + // parameter, while recording the read/store summary context + exists(Flow::PathNode arg | + nodeReachesSubpathArg(_, _, _, arg, scReads, scStores) and + Flow::PathGraph::subpaths(arg, source, _, _) + ) ) - ) - or - exists(Flow::PathNode mid | - nodeReaches(source, scReads, scStores, mid, reads, stores) and - BigStepFlow::bigStepMaybeLocal(mid, node) - ) - or - exists(Flow::PathNode mid | - nodeReaches(source, scReads, scStores, mid, reads, stores) and - BigStepFlow::bigStepNotLocal(mid, node) and - // when flow is not local, we cannot flow back out, so we may stop - // flow early when computing summary flow - Flow::flowPath(source, _) and - scReads = TAccessPathNil() and - scStores = TAccessPathNil() - ) - or - // store step - exists(AccessPath storesMid, DataFlow::ContentSet c | - nodeReachesStore(source, scReads, scStores, node, c, reads, storesMid) and - stores = TAccessPathCons(c, storesMid) - ) - or - // read step - exists(AccessPath readsMid, DataFlow::ContentSet c | - nodeReachesRead(source, scReads, scStores, node, c, readsMid, stores) and - reads = TAccessPathCons(c, readsMid) - ) - or - // flow-through step; match outer stores/reads with inner store/read summary contexts - exists(Flow::PathNode mid, AccessPath innerScReads, AccessPath innerScStores | - nodeReachesSubpathArg(source, scReads, scStores, mid, innerScReads, innerScStores) and - subpathArgReachesOut(mid, innerScReads, innerScStores, node, reads, stores) - ) - } + or + exists(Flow::PathNode mid | + nodeReaches(source, scReads, scStores, mid, reads, stores) and + BigStepFlow::bigStepMaybeLocal(mid, node) + ) + or + exists(Flow::PathNode mid | + nodeReaches(source, scReads, scStores, mid, reads, stores) and + BigStepFlow::bigStepNotLocal(mid, node) and + // when flow is not local, we cannot flow back out, so we may stop + // flow early when computing summary flow + Flow::flowPath(source, _) and + scReads = TAccessPathNil() and + scStores = TAccessPathNil() + ) + or + // store step + exists(AccessPath storesMid, ContentSet c | + nodeReachesStore(source, scReads, scStores, node, c, reads, storesMid) and + stores = TAccessPathCons(c, storesMid) + ) + or + // read step + exists(AccessPath readsMid, ContentSet c | + nodeReachesRead(source, scReads, scStores, node, c, readsMid, stores) and + reads = TAccessPathCons(c, readsMid) + ) + or + // flow-through step; match outer stores/reads with inner store/read summary contexts + exists(Flow::PathNode mid, AccessPath innerScReads, AccessPath innerScStores | + nodeReachesSubpathArg(source, scReads, scStores, mid, innerScReads, innerScStores) and + subpathArgReachesOut(mid, innerScReads, innerScStores, node, reads, stores) + ) + } - pragma[nomagic] - private predicate nodeReachesStore( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, - DataFlow::ContentSet c, AccessPath reads, AccessPath stores - ) { - exists(Flow::PathNode mid | - nodeReaches(source, scReads, scStores, mid, reads, stores) and - storeStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and - mid.getASuccessor() = node - ) - } + pragma[nomagic] + private predicate nodeReachesStore( + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, + ContentSet c, AccessPath reads, AccessPath stores + ) { + exists(Flow::PathNode mid | + nodeReaches(source, scReads, scStores, mid, reads, stores) and + storeStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and + mid.getASuccessor() = node + ) + } - pragma[nomagic] - private predicate nodeReachesRead( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, - DataFlow::ContentSet c, AccessPath reads, AccessPath stores - ) { - exists(Flow::PathNode mid | - nodeReaches(source, scReads, scStores, mid, reads, stores) and - readStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and - mid.getASuccessor() = node - ) - } + pragma[nomagic] + private predicate nodeReachesRead( + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, + ContentSet c, AccessPath reads, AccessPath stores + ) { + exists(Flow::PathNode mid | + nodeReaches(source, scReads, scStores, mid, reads, stores) and + readStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and + mid.getASuccessor() = node + ) + } - pragma[nomagic] - private predicate nodeReachesSubpathArg( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode arg, - AccessPath reads, AccessPath stores - ) { - nodeReaches(source, scReads, scStores, arg, reads, stores) and - Flow::PathGraph::subpaths(arg, _, _, _) - } + pragma[nomagic] + private predicate nodeReachesSubpathArg( + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode arg, + AccessPath reads, AccessPath stores + ) { + nodeReaches(source, scReads, scStores, arg, reads, stores) and + Flow::PathGraph::subpaths(arg, _, _, _) + } - pragma[nomagic] - private predicate subpathArgReachesOut( - Flow::PathNode arg, AccessPath scReads, AccessPath scStores, Flow::PathNode out, - AccessPath reads, AccessPath stores - ) { - exists(Flow::PathNode source, Flow::PathNode ret | - nodeReaches(source, scReads, scStores, ret, reads, stores) and - Flow::PathGraph::subpaths(arg, source, ret, out) - ) + pragma[nomagic] + private predicate subpathArgReachesOut( + Flow::PathNode arg, AccessPath scReads, AccessPath scStores, Flow::PathNode out, + AccessPath reads, AccessPath stores + ) { + exists(Flow::PathNode source, Flow::PathNode ret | + nodeReaches(source, scReads, scStores, ret, reads, stores) and + Flow::PathGraph::subpaths(arg, source, ret, out) + ) + } } } From d935c472318de67e07311990991839fc4349c41b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 22 Aug 2024 15:43:41 +0200 Subject: [PATCH 085/404] C#: Use the shared content flow implementation. --- .../dataflow/internal/ContentDataFlow.qll | 508 +----------------- 1 file changed, 4 insertions(+), 504 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ContentDataFlow.qll index 76936549051..a0368f1c335 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/ContentDataFlow.qll @@ -1,504 +1,4 @@ -/** - * Provides classes for performing global (inter-procedural) - * content-sensitive data flow analyses. - * - * Unlike `DataFlow::Global`, we allow for data to be stored (possibly nested) inside - * contents of sources and sinks. - * We track flow paths of the form - * - * ``` - * source --value-->* node - * (--read--> node --value-->* node)* - * --(non-value|value)-->* node - * (--store--> node --value-->* node)* - * --value-->* sink - * ``` - * - * where `--value-->` is a value-preserving flow step, `--read-->` is a read - * step, `--store-->` is a store step, and `--(non-value)-->` is a - * non-value-preserving flow step. - * - * That is, first a sequence of 0 or more reads, followed by 0 or more additional - * steps, followed by 0 or more stores, with value-preserving steps allowed in - * between all other steps. - */ - -private import csharp -private import codeql.util.Boolean -private import DataFlowImplCommon -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Private as DataFlowPrivate - -/** - * An input configuration for content data flow. - */ -signature module ConfigSig { - /** - * Holds if `source` is a relevant data flow source. - */ - predicate isSource(DataFlow::Node source); - - /** - * Holds if `sink` is a relevant data flow sink. - */ - predicate isSink(DataFlow::Node sink); - - /** - * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps. - */ - default predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() } - - /** Holds if data flow into `node` is prohibited. */ - default predicate isBarrier(DataFlow::Node node) { none() } - - /** - * Gets a data flow configuration feature to add restrictions to the set of - * valid flow paths. - * - * - `FeatureHasSourceCallContext`: - * Assume that sources have some existing call context to disallow - * conflicting return-flow directly following the source. - * - `FeatureHasSinkCallContext`: - * Assume that sinks have some existing call context to disallow - * conflicting argument-to-parameter flow directly preceding the sink. - * - `FeatureEqualSourceSinkCallContext`: - * Implies both of the above and additionally ensures that the entire flow - * path preserves the call context. - */ - default DataFlow::FlowFeature getAFeature() { none() } - - /** Gets a limit on the number of reads out of sources and number of stores into sinks. */ - default int accessPathLimit() { result = DataFlowPrivate::accessPathLimit() } - - /** Holds if `c` is relevant for reads out of sources or stores into sinks. */ - default predicate isRelevantContent(DataFlow::ContentSet c) { any() } -} - -/** - * Constructs a global content data flow computation. - */ -module Global { - private module FlowConfig implements DataFlow::StateConfigSig { - class FlowState = State; - - predicate isSource(DataFlow::Node source, FlowState state) { - ContentConfig::isSource(source) and - state.(InitState).decode(true) - } - - predicate isSink(DataFlow::Node sink, FlowState state) { - ContentConfig::isSink(sink) and - ( - state instanceof InitState or - state instanceof StoreState or - state instanceof ReadState - ) - } - - predicate isAdditionalFlowStep( - DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 - ) { - storeStep(node1, state1, _, node2, state2) or - readStep(node1, state1, _, node2, state2) or - additionalStep(node1, state1, node2, state2) - } - - predicate isAdditionalFlowStep = ContentConfig::isAdditionalFlowStep/2; - - predicate isBarrier = ContentConfig::isBarrier/1; - - DataFlow::FlowFeature getAFeature() { result = ContentConfig::getAFeature() } - - predicate accessPathLimit = ContentConfig::accessPathLimit/0; - - // needed to record reads/stores inside summarized callables - predicate includeHiddenNodes() { any() } - } - - private module Flow = DataFlow::GlobalWithState; - - /** - * Holds if data stored inside `sourceAp` on `source` flows to `sinkAp` inside `sink` - * for this configuration. `preservesValue` indicates whether any of the additional - * flow steps defined by `isAdditionalFlowStep` are needed. - * - * For the source access path, `sourceAp`, the top of the stack represents the content - * that was last read from. That is, if `sourceAp` is `Field1.Field2` (with `Field1` - * being the top of the stack), then there is flow from `source.Field2.Field1`. - * - * For the sink access path, `sinkAp`, the top of the stack represents the content - * that was last stored into. That is, if `sinkAp` is `Field1.Field2` (with `Field1` - * being the top of the stack), then there is flow into `sink.Field1.Field2`. - */ - predicate flow( - DataFlow::Node source, AccessPath sourceAp, DataFlow::Node sink, AccessPath sinkAp, - boolean preservesValue - ) { - exists(Flow::PathNode pathSource, Flow::PathNode pathSink | - Flow::flowPath(pathSource, pathSink) and - nodeReaches(pathSource, TAccessPathNil(), TAccessPathNil(), pathSink, sourceAp, sinkAp) and - source = pathSource.getNode() and - sink = pathSink.getNode() - | - pathSink.getState().(InitState).decode(preservesValue) - or - pathSink.getState().(ReadState).decode(_, preservesValue) - or - pathSink.getState().(StoreState).decode(_, preservesValue) - ) - } - - private newtype TState = - TInitState(Boolean preservesValue) or - TStoreState(int size, Boolean preservesValue) { - size in [1 .. ContentConfig::accessPathLimit()] - } or - TReadState(int size, Boolean preservesValue) { size in [1 .. ContentConfig::accessPathLimit()] } - - abstract private class State extends TState { - abstract string toString(); - } - - /** A flow state representing no reads or stores. */ - private class InitState extends State, TInitState { - private boolean preservesValue_; - - InitState() { this = TInitState(preservesValue_) } - - override string toString() { result = "Init(" + preservesValue_ + ")" } - - predicate decode(boolean preservesValue) { preservesValue = preservesValue_ } - } - - /** A flow state representing that content has been stored into. */ - private class StoreState extends State, TStoreState { - private boolean preservesValue_; - private int size_; - - StoreState() { this = TStoreState(size_, preservesValue_) } - - override string toString() { result = "StoreState(" + size_ + "," + preservesValue_ + ")" } - - predicate decode(int size, boolean preservesValue) { - size = size_ and preservesValue = preservesValue_ - } - } - - /** A flow state representing that content has been read from. */ - private class ReadState extends State, TReadState { - private boolean preservesValue_; - private int size_; - - ReadState() { this = TReadState(size_, preservesValue_) } - - override string toString() { result = "ReadState(" + size_ + "," + preservesValue_ + ")" } - - predicate decode(int size, boolean preservesValue) { - size = size_ and preservesValue = preservesValue_ - } - } - - private predicate storeStep( - DataFlow::Node node1, State state1, DataFlow::ContentSet c, DataFlow::Node node2, - StoreState state2 - ) { - exists(boolean preservesValue, int size | - storeSet(node1, c, node2, _, _) and - ContentConfig::isRelevantContent(c) and - state2.decode(size + 1, preservesValue) - | - state1.(InitState).decode(preservesValue) and size = 0 - or - state1.(ReadState).decode(_, preservesValue) and size = 0 - or - state1.(StoreState).decode(size, preservesValue) - ) - } - - private predicate readStep( - DataFlow::Node node1, State state1, DataFlow::ContentSet c, DataFlow::Node node2, - ReadState state2 - ) { - exists(int size | - readSet(node1, c, node2) and - ContentConfig::isRelevantContent(c) and - state2.decode(size + 1, true) - | - state1.(InitState).decode(true) and - size = 0 - or - state1.(ReadState).decode(size, true) - ) - } - - private predicate additionalStep( - DataFlow::Node node1, State state1, DataFlow::Node node2, State state2 - ) { - ContentConfig::isAdditionalFlowStep(node1, node2) and - ( - state1 instanceof InitState and - state2.(InitState).decode(false) - or - exists(int size | - state1.(ReadState).decode(size, _) and - state2.(ReadState).decode(size, false) - ) - ) - } - - private newtype TAccessPath = - TAccessPathNil() or - TAccessPathCons(DataFlow::ContentSet head, AccessPath tail) { - nodeReachesStore(_, _, _, _, head, _, tail) - or - nodeReachesRead(_, _, _, _, head, tail, _) - } - - /** An access path. */ - class AccessPath extends TAccessPath { - /** Gets the head of this access path, if any. */ - DataFlow::ContentSet getHead() { this = TAccessPathCons(result, _) } - - /** Gets the tail of this access path, if any. */ - AccessPath getTail() { this = TAccessPathCons(_, result) } - - /** - * Gets a textual representation of this access path. - * - * Elements are dot-separated, and the head of the stack is - * rendered first. - */ - string toString() { - this = TAccessPathNil() and - result = "" - or - exists(DataFlow::ContentSet head, AccessPath tail | - this = TAccessPathCons(head, tail) and - result = head + "." + tail - ) - } - } - - /** - * Provides a big-step flow relation, where flow stops at read/store steps that - * must be recorded, and flow via `subpaths` such that reads/stores inside - * summarized callables can be recorded as well. - */ - private module BigStepFlow { - private predicate reachesSink(Flow::PathNode node) { - FlowConfig::isSink(node.getNode(), node.getState()) - or - reachesSink(node.getASuccessor()) - } - - /** - * Holds if the flow step `pred -> succ` should not be allowed to be included - * in the big-step relation. - */ - pragma[nomagic] - private predicate excludeStep(Flow::PathNode pred, Flow::PathNode succ) { - pred.getASuccessor() = succ and - ( - // we need to record reads/stores inside summarized callables - Flow::PathGraph::subpaths(pred, _, _, succ) - or - // only allow flow into a summarized callable, as part of the big-step - // relation, when flow can reach a sink without going back out - Flow::PathGraph::subpaths(pred, succ, _, _) and - not reachesSink(succ) - or - // needed to record store steps - storeStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) - or - // needed to record read steps - readStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) - ) - } - - pragma[nomagic] - private DataFlowCallable getEnclosingCallableImpl(Flow::PathNode node) { - result = getNodeEnclosingCallable(node.getNode()) - } - - pragma[inline] - private DataFlowCallable getEnclosingCallable(Flow::PathNode node) { - pragma[only_bind_into](result) = getEnclosingCallableImpl(pragma[only_bind_out](node)) - } - - pragma[nomagic] - private predicate bigStepEntry(Flow::PathNode node) { - ( - FlowConfig::isSource(node.getNode(), node.getState()) - or - excludeStep(_, node) - or - Flow::PathGraph::subpaths(_, node, _, _) - ) - } - - pragma[nomagic] - private predicate bigStepExit(Flow::PathNode node) { - ( - bigStepEntry(node) - or - FlowConfig::isSink(node.getNode(), node.getState()) - or - excludeStep(node, _) - or - Flow::PathGraph::subpaths(_, _, node, _) - ) - } - - pragma[nomagic] - private predicate step(Flow::PathNode pred, Flow::PathNode succ) { - pred.getASuccessor() = succ and - not excludeStep(pred, succ) - } - - pragma[nomagic] - private predicate stepRec(Flow::PathNode pred, Flow::PathNode succ) { - step(pred, succ) and - not bigStepEntry(pred) - } - - private predicate stepRecPlus(Flow::PathNode n1, Flow::PathNode n2) = fastTC(stepRec/2)(n1, n2) - - /** - * Holds if there is flow `pathSucc+(pred) = succ`, and such a flow path does - * not go through any reads/stores that need to be recorded, or summarized - * steps. - */ - pragma[nomagic] - private predicate bigStep(Flow::PathNode pred, Flow::PathNode succ) { - exists(Flow::PathNode mid | - bigStepEntry(pred) and - step(pred, mid) - | - succ = mid - or - stepRecPlus(mid, succ) - ) and - bigStepExit(succ) - } - - pragma[nomagic] - predicate bigStepNotLocal(Flow::PathNode pred, Flow::PathNode succ) { - bigStep(pred, succ) and - not getEnclosingCallable(pred) = getEnclosingCallable(succ) - } - - pragma[nomagic] - predicate bigStepMaybeLocal(Flow::PathNode pred, Flow::PathNode succ) { - bigStep(pred, succ) and - getEnclosingCallable(pred) = getEnclosingCallable(succ) - } - } - - /** - * Holds if `source` can reach `node`, having read `reads` from the source and - * written `stores` into `node`. - * - * `source` is either a source from a configuration, in which case `scReads` and - * `scStores` are always empty, or it is the parameter of a summarized callable, - * in which case `scReads` and `scStores` record the reads/stores for a summary - * context, that is, the reads/stores for an argument that can reach the parameter. - */ - pragma[nomagic] - private predicate nodeReaches( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, - AccessPath reads, AccessPath stores - ) { - node = source and - reads = scReads and - stores = scStores and - ( - Flow::flowPath(source, _) and - scReads = TAccessPathNil() and - scStores = TAccessPathNil() - or - // the argument in a sub path can be reached, so we start flow from the sub path - // parameter, while recording the read/store summary context - exists(Flow::PathNode arg | - nodeReachesSubpathArg(_, _, _, arg, scReads, scStores) and - Flow::PathGraph::subpaths(arg, source, _, _) - ) - ) - or - exists(Flow::PathNode mid | - nodeReaches(source, scReads, scStores, mid, reads, stores) and - BigStepFlow::bigStepMaybeLocal(mid, node) - ) - or - exists(Flow::PathNode mid | - nodeReaches(source, scReads, scStores, mid, reads, stores) and - BigStepFlow::bigStepNotLocal(mid, node) and - // when flow is not local, we cannot flow back out, so we may stop - // flow early when computing summary flow - Flow::flowPath(source, _) and - scReads = TAccessPathNil() and - scStores = TAccessPathNil() - ) - or - // store step - exists(AccessPath storesMid, DataFlow::ContentSet c | - nodeReachesStore(source, scReads, scStores, node, c, reads, storesMid) and - stores = TAccessPathCons(c, storesMid) - ) - or - // read step - exists(AccessPath readsMid, DataFlow::ContentSet c | - nodeReachesRead(source, scReads, scStores, node, c, readsMid, stores) and - reads = TAccessPathCons(c, readsMid) - ) - or - // flow-through step; match outer stores/reads with inner store/read summary contexts - exists(Flow::PathNode mid, AccessPath innerScReads, AccessPath innerScStores | - nodeReachesSubpathArg(source, scReads, scStores, mid, innerScReads, innerScStores) and - subpathArgReachesOut(mid, innerScReads, innerScStores, node, reads, stores) - ) - } - - pragma[nomagic] - private predicate nodeReachesStore( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, - DataFlow::ContentSet c, AccessPath reads, AccessPath stores - ) { - exists(Flow::PathNode mid | - nodeReaches(source, scReads, scStores, mid, reads, stores) and - storeStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and - mid.getASuccessor() = node - ) - } - - pragma[nomagic] - private predicate nodeReachesRead( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, - DataFlow::ContentSet c, AccessPath reads, AccessPath stores - ) { - exists(Flow::PathNode mid | - nodeReaches(source, scReads, scStores, mid, reads, stores) and - readStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and - mid.getASuccessor() = node - ) - } - - pragma[nomagic] - private predicate nodeReachesSubpathArg( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode arg, - AccessPath reads, AccessPath stores - ) { - nodeReaches(source, scReads, scStores, arg, reads, stores) and - Flow::PathGraph::subpaths(arg, _, _, _) - } - - pragma[nomagic] - private predicate subpathArgReachesOut( - Flow::PathNode arg, AccessPath scReads, AccessPath scStores, Flow::PathNode out, - AccessPath reads, AccessPath stores - ) { - exists(Flow::PathNode source, Flow::PathNode ret | - nodeReaches(source, scReads, scStores, ret, reads, stores) and - Flow::PathGraph::subpaths(arg, source, ret, out) - ) - } -} +private import semmle.code.csharp.Location +private import DataFlowImplSpecific +private import codeql.dataflow.internal.ContentDataFlowImpl +import MakeImplContentDataFlow From c1c9ef2c1fd5d3ba8bd3fa688bab80c52a07237c Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Wed, 21 Aug 2024 16:25:02 -0700 Subject: [PATCH 086/404] Add a pull request template --- .github/pull_request_template.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000000..520020522cc --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,7 @@ +### Pull Request checklist + +- [ ] Add a change note if necessary. See [the documentation](https://github.com/github/codeql/blob/main/docs/change-notes.md). +- [ ] If this PR makes significant changes to `.ql`, `.qll`, or `.qhelp` files, make sure that autofixes generated based on these changes are valid. See [the documentation](https://github.com/github/codeql-team/blob/main/docs/best-practices/validating-autofix-for-query-changes.md) (internal access required). +- [ ] All new queries has appropriate `.qhelp`. +- [ ] QL tests are added if necessary. +- [ ] Test your changes in [DCA](https://github.com/github/codeql-dca/) (internal access required). From 19c2eb17c4088ca37fea1070b94517f063afe14b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 23 Aug 2024 09:04:13 +0200 Subject: [PATCH 087/404] C#: Remove redundant imports. --- .../dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll | 2 -- 1 file changed, 2 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll index 18e44061967..a4d3e413625 100644 --- a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll @@ -26,8 +26,6 @@ private import codeql.dataflow.DataFlow private import codeql.util.Boolean private import codeql.util.Location -private import DataFlowImpl -private import DataFlowImplCommon module MakeImplContentDataFlow Lang> { private import Lang From c3b36325b2b5d73b1527247c6aa80f6b77f78656 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 22 Aug 2024 11:25:44 +0200 Subject: [PATCH 088/404] Shared: prevent use-use flow through implicit reads (part 1) --- .../codeql/dataflow/internal/DataFlowImpl.qll | 46 +++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 379a618dbdf..d290306ff35 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -173,6 +173,11 @@ module MakeImpl Lang> { Node asNode() { this = TNodeNormal(result) } + /** Gets the corresponding Node if this is a normal node or its post-implicit read node. */ + Node asNodeOrImplicitRead() { + this = TNodeNormal(result) or this = TNodeImplicitRead(result, true) + } + predicate isImplicitReadNode(Node n, boolean hasRead) { this = TNodeImplicitRead(n, hasRead) } ParameterNode asParamReturnNode() { this = TParamReturnNode(result, _) } @@ -241,6 +246,16 @@ module MakeImpl Lang> { ReturnKindExt getKind() { result = pos.getKind() } } + /** If `node` corresponds to a sink, gets the normal node for that sink. */ + pragma[nomagic] + private NodeEx toNormalSinkNodeEx(NodeEx node) { + exists(Node n | + node.asNodeOrImplicitRead() = n and + (Config::isSink(n) or Config::isSink(n, _)) and + result.asNode() = n + ) + } + private predicate inBarrier(NodeEx node) { exists(Node n | node.asNode() = n and @@ -260,7 +275,7 @@ module MakeImpl Lang> { private predicate outBarrier(NodeEx node) { exists(Node n | - node.asNode() = n and + node.asNodeOrImplicitRead() = n and Config::isBarrierOut(n) | Config::isSink(n, _) @@ -272,7 +287,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate outBarrier(NodeEx node, FlowState state) { exists(Node n | - node.asNode() = n and + node.asNodeOrImplicitRead() = n and Config::isBarrierOut(n, state) | Config::isSink(n, state) @@ -318,7 +333,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate sinkNodeWithState(NodeEx node, FlowState state) { - Config::isSink(node.asNode(), state) and + Config::isSink(node.asNodeOrImplicitRead(), state) and not fullBarrier(node) and not stateBarrier(node, state) } @@ -380,26 +395,19 @@ module MakeImpl Lang> { */ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, string model) { exists(Node n1, Node n2 | - node1.asNode() = n1 and + node1.asNodeOrImplicitRead() = n1 and node2.asNode() = n2 and Config::isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2), model) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2) ) - or - exists(Node n | - node1.isImplicitReadNode(n, true) and - node2.asNode() = n and - not fullBarrier(node2) and - model = "" - ) } private predicate additionalLocalStateStep( NodeEx node1, FlowState s1, NodeEx node2, FlowState s2 ) { exists(Node n1, Node n2 | - node1.asNode() = n1 and + node1.asNodeOrImplicitRead() = n1 and node2.asNode() = n2 and Config::isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and @@ -425,7 +433,7 @@ module MakeImpl Lang> { */ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, string model) { exists(Node n1, Node n2 | - node1.asNode() = n1 and + node1.asNodeOrImplicitRead() = n1 and node2.asNode() = n2 and Config::isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2), model) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and @@ -436,7 +444,7 @@ module MakeImpl Lang> { private predicate additionalJumpStateStep(NodeEx node1, FlowState s1, NodeEx node2, FlowState s2) { exists(Node n1, Node n2 | - node1.asNode() = n1 and + node1.asNodeOrImplicitRead() = n1 and node2.asNode() = n2 and Config::isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and @@ -729,7 +737,7 @@ module MakeImpl Lang> { additional predicate sinkNode(NodeEx node, FlowState state) { fwdFlow(node) and fwdFlowState(state) and - Config::isSink(node.asNode()) + Config::isSink(node.asNodeOrImplicitRead()) or fwdFlow(node) and fwdFlowState(state) and @@ -1052,7 +1060,7 @@ module MakeImpl Lang> { private predicate sinkModel(NodeEx node, string model) { sinkNode(node, _) and - exists(Node n | n = node.asNode() | + exists(Node n | n = node.asNodeOrImplicitRead() | knownSinkModel(n, model) or not knownSinkModel(n, _) and model = "" @@ -2549,7 +2557,7 @@ module MakeImpl Lang> { TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | sink.isAtSink() and - node = sink.getNodeEx() and + node = toNormalSinkNodeEx(sink.getNodeEx()) and state = sink.getState() ) } or @@ -2772,7 +2780,7 @@ module MakeImpl Lang> { PathNodeSink projectToSink(string model) { this.isAtSink() and sinkModel(node, model) and - result.getNodeEx() = node and + result.getNodeEx() = toNormalSinkNodeEx(node) and result.getState() = state } } @@ -4851,7 +4859,7 @@ module MakeImpl Lang> { private predicate revSinkNode(NodeEx node, FlowState state) { sinkNodeWithState(node, state) or - Config::isSink(node.asNode()) and + Config::isSink(node.asNodeOrImplicitRead()) and relevantState(state) and not fullBarrier(node) and not stateBarrier(node, state) From 6bc8407bd60fcf215e6614247c3a0f005e1c7844 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 20 Aug 2024 14:14:30 +0200 Subject: [PATCH 089/404] Java: Update test output --- java/ql/test/library-tests/dataflow/implicit-read/A.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/library-tests/dataflow/implicit-read/A.java b/java/ql/test/library-tests/dataflow/implicit-read/A.java index c845c7febe2..fbc4212b3b2 100644 --- a/java/ql/test/library-tests/dataflow/implicit-read/A.java +++ b/java/ql/test/library-tests/dataflow/implicit-read/A.java @@ -21,7 +21,7 @@ public class A { Object object = getA(); sink(step(object)); // $ hasTaintFlow=source - sink(object); // $ SPURIOUS: hasTaintFlow=source + sink(object); sink(((A)object).field); // $ hasTaintFlow=source } } From 9703f6779421dc3a1287bb4bdf62908342b0a40b Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 23 Aug 2024 11:03:26 +0200 Subject: [PATCH 090/404] Test output updates that only affect nodes/edges --- .../dataflow/summaries/test.expected | 6 --- .../dataflow/summaries/test.expected | 6 --- .../CWE-200/SensitiveAndroidFileLeak.expected | 4 +- .../apache-commons-lang3/flow.expected | 5 --- .../dataflow/taint/core/Taint.expected | 18 --------- .../Security/CWE-094/UnsafeJsEval.expected | 8 +--- .../CWE-321/HardcodedEncryptionKey.expected | 9 ----- .../Security/CWE-757/InsecureTLS.expected | 38 ------------------- 8 files changed, 3 insertions(+), 91 deletions(-) diff --git a/java/ql/test-kotlin1/library-tests/dataflow/summaries/test.expected b/java/ql/test-kotlin1/library-tests/dataflow/summaries/test.expected index 7f55b285880..84fdf028642 100644 --- a/java/ql/test-kotlin1/library-tests/dataflow/summaries/test.expected +++ b/java/ql/test-kotlin1/library-tests/dataflow/summaries/test.expected @@ -36,19 +36,14 @@ edges | apply.kt:6:28:6:41 | $this$apply : String | apply.kt:6:35:6:38 | this | provenance | | | apply.kt:7:14:7:25 | taint(...) : String | apply.kt:7:14:7:40 | apply(...) | provenance | MaD:31 | | list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:7:14:7:14 | l | provenance | | -| list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:8:14:8:14 | l : List | provenance | | | list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:8:14:8:14 | l : List [] : String | provenance | | | list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:9:19:9:19 | l : List [] : String | provenance | | -| list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:10:18:10:18 | s | provenance | | | list.kt:6:16:6:25 | taint(...) : String | list.kt:6:9:6:9 | l [post update] : List [] : String | provenance | MaD:27 | -| list.kt:8:14:8:14 | l : List | list.kt:8:14:8:17 | get(...) | provenance | MaD:26 | | list.kt:8:14:8:14 | l : List [] : String | list.kt:8:14:8:17 | get(...) | provenance | MaD:26 | | list.kt:9:19:9:19 | l : List [] : String | list.kt:10:18:10:18 | s | provenance | | | list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:14:14:14:14 | a | provenance | | | list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:15:14:15:14 | a : String[] [[]] : String | provenance | | -| list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:15:14:15:17 | ...[...] | provenance | | | list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:16:19:16:19 | a : String[] [[]] : String | provenance | | -| list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:17:18:17:18 | s | provenance | | | list.kt:13:25:13:34 | taint(...) : String | list.kt:13:17:13:40 | {...} : String[] [[]] : String | provenance | | | list.kt:15:14:15:14 | a : String[] [[]] : String | list.kt:15:14:15:17 | ...[...] | provenance | | | list.kt:16:19:16:19 | a : String[] [[]] : String | list.kt:17:18:17:18 | s | provenance | | @@ -134,7 +129,6 @@ nodes | list.kt:6:9:6:9 | l [post update] : List [] : String | semmle.label | l [post update] : List [] : String | | list.kt:6:16:6:25 | taint(...) : String | semmle.label | taint(...) : String | | list.kt:7:14:7:14 | l | semmle.label | l | -| list.kt:8:14:8:14 | l : List | semmle.label | l : List | | list.kt:8:14:8:14 | l : List [] : String | semmle.label | l : List [] : String | | list.kt:8:14:8:17 | get(...) | semmle.label | get(...) | | list.kt:9:19:9:19 | l : List [] : String | semmle.label | l : List [] : String | diff --git a/java/ql/test-kotlin2/library-tests/dataflow/summaries/test.expected b/java/ql/test-kotlin2/library-tests/dataflow/summaries/test.expected index 7f55b285880..84fdf028642 100644 --- a/java/ql/test-kotlin2/library-tests/dataflow/summaries/test.expected +++ b/java/ql/test-kotlin2/library-tests/dataflow/summaries/test.expected @@ -36,19 +36,14 @@ edges | apply.kt:6:28:6:41 | $this$apply : String | apply.kt:6:35:6:38 | this | provenance | | | apply.kt:7:14:7:25 | taint(...) : String | apply.kt:7:14:7:40 | apply(...) | provenance | MaD:31 | | list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:7:14:7:14 | l | provenance | | -| list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:8:14:8:14 | l : List | provenance | | | list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:8:14:8:14 | l : List [] : String | provenance | | | list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:9:19:9:19 | l : List [] : String | provenance | | -| list.kt:6:9:6:9 | l [post update] : List [] : String | list.kt:10:18:10:18 | s | provenance | | | list.kt:6:16:6:25 | taint(...) : String | list.kt:6:9:6:9 | l [post update] : List [] : String | provenance | MaD:27 | -| list.kt:8:14:8:14 | l : List | list.kt:8:14:8:17 | get(...) | provenance | MaD:26 | | list.kt:8:14:8:14 | l : List [] : String | list.kt:8:14:8:17 | get(...) | provenance | MaD:26 | | list.kt:9:19:9:19 | l : List [] : String | list.kt:10:18:10:18 | s | provenance | | | list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:14:14:14:14 | a | provenance | | | list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:15:14:15:14 | a : String[] [[]] : String | provenance | | -| list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:15:14:15:17 | ...[...] | provenance | | | list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:16:19:16:19 | a : String[] [[]] : String | provenance | | -| list.kt:13:17:13:40 | {...} : String[] [[]] : String | list.kt:17:18:17:18 | s | provenance | | | list.kt:13:25:13:34 | taint(...) : String | list.kt:13:17:13:40 | {...} : String[] [[]] : String | provenance | | | list.kt:15:14:15:14 | a : String[] [[]] : String | list.kt:15:14:15:17 | ...[...] | provenance | | | list.kt:16:19:16:19 | a : String[] [[]] : String | list.kt:17:18:17:18 | s | provenance | | @@ -134,7 +129,6 @@ nodes | list.kt:6:9:6:9 | l [post update] : List [] : String | semmle.label | l [post update] : List [] : String | | list.kt:6:16:6:25 | taint(...) : String | semmle.label | taint(...) : String | | list.kt:7:14:7:14 | l | semmle.label | l | -| list.kt:8:14:8:14 | l : List | semmle.label | l : List | | list.kt:8:14:8:14 | l : List [] : String | semmle.label | l : List [] : String | | list.kt:8:14:8:17 | get(...) | semmle.label | get(...) | | list.kt:9:19:9:19 | l : List [] : String | semmle.label | l : List [] : String | diff --git a/java/ql/test/experimental/query-tests/security/CWE-200/SensitiveAndroidFileLeak.expected b/java/ql/test/experimental/query-tests/security/CWE-200/SensitiveAndroidFileLeak.expected index f232f30d6b1..4282361f89e 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-200/SensitiveAndroidFileLeak.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-200/SensitiveAndroidFileLeak.expected @@ -6,8 +6,7 @@ edges | FileService.java:20:31:20:43 | intent : Intent | FileService.java:21:28:21:33 | intent : Intent | provenance | | | FileService.java:21:28:21:33 | intent : Intent | FileService.java:21:28:21:64 | getStringExtra(...) : String | provenance | MaD:2 | | FileService.java:21:28:21:64 | getStringExtra(...) : String | FileService.java:25:42:25:50 | localPath : String | provenance | | -| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] | FileService.java:40:41:40:55 | params : Object[] | provenance | Config | -| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : String | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] | provenance | | +| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : String | FileService.java:40:41:40:55 | params : Object[] | provenance | Config | | FileService.java:25:42:25:50 | localPath : String | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : String | provenance | | | FileService.java:25:42:25:50 | localPath : String | FileService.java:32:13:32:28 | sourceUri : String | provenance | | | FileService.java:32:13:32:28 | sourceUri : String | FileService.java:35:17:35:25 | sourceUri : String | provenance | | @@ -33,7 +32,6 @@ nodes | FileService.java:20:31:20:43 | intent : Intent | semmle.label | intent : Intent | | FileService.java:21:28:21:33 | intent : Intent | semmle.label | intent : Intent | | FileService.java:21:28:21:64 | getStringExtra(...) : String | semmle.label | getStringExtra(...) : String | -| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] | semmle.label | makeParamsToExecute(...) : Object[] | | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] [[]] : String | semmle.label | makeParamsToExecute(...) : Object[] [[]] : String | | FileService.java:25:42:25:50 | localPath : String | semmle.label | localPath : String | | FileService.java:32:13:32:28 | sourceUri : String | semmle.label | sourceUri : String | diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected index 93eaf02d839..5a5618355c0 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected @@ -745,12 +745,9 @@ edges | ArrayUtilsTest.java:68:27:68:57 | {...} : int[] [[]] : Number | ArrayUtilsTest.java:69:56:69:66 | taintedInts : int[] [[]] : Number | provenance | | | ArrayUtilsTest.java:68:39:68:55 | taint(...) : Number | ArrayUtilsTest.java:68:27:68:57 | {...} : int[] [[]] : Number | provenance | | | ArrayUtilsTest.java:69:36:69:67 | toObject(...) : Integer[] [[]] : Number | ArrayUtilsTest.java:70:12:70:27 | taintedBoxedInts | provenance | | -| ArrayUtilsTest.java:69:36:69:67 | toObject(...) : Integer[] [[]] : Number | ArrayUtilsTest.java:71:35:71:50 | taintedBoxedInts : Integer[] | provenance | | | ArrayUtilsTest.java:69:36:69:67 | toObject(...) : Integer[] [[]] : Number | ArrayUtilsTest.java:71:35:71:50 | taintedBoxedInts : Integer[] [[]] : Number | provenance | | | ArrayUtilsTest.java:69:56:69:66 | taintedInts : int[] [[]] : Number | ArrayUtilsTest.java:69:36:69:67 | toObject(...) : Integer[] [[]] : Number | provenance | MaD:53 | | ArrayUtilsTest.java:71:12:71:51 | toPrimitive(...) : int[] [[]] : Number | ArrayUtilsTest.java:71:12:71:51 | toPrimitive(...) | provenance | | -| ArrayUtilsTest.java:71:12:71:51 | toPrimitive(...) : int[] [[]] : Object | ArrayUtilsTest.java:71:12:71:51 | toPrimitive(...) | provenance | | -| ArrayUtilsTest.java:71:35:71:50 | taintedBoxedInts : Integer[] | ArrayUtilsTest.java:71:12:71:51 | toPrimitive(...) : int[] [[]] : Object | provenance | MaD:54 | | ArrayUtilsTest.java:71:35:71:50 | taintedBoxedInts : Integer[] [[]] : Number | ArrayUtilsTest.java:71:12:71:51 | toPrimitive(...) : int[] [[]] : Number | provenance | MaD:54 | | ArrayUtilsTest.java:72:12:72:70 | toPrimitive(...) : int[] [[]] : Number | ArrayUtilsTest.java:72:12:72:70 | toPrimitive(...) | provenance | | | ArrayUtilsTest.java:72:53:72:69 | taint(...) : Number | ArrayUtilsTest.java:72:12:72:70 | toPrimitive(...) : int[] [[]] : Number | provenance | MaD:55 | @@ -3434,8 +3431,6 @@ nodes | ArrayUtilsTest.java:70:12:70:27 | taintedBoxedInts | semmle.label | taintedBoxedInts | | ArrayUtilsTest.java:71:12:71:51 | toPrimitive(...) | semmle.label | toPrimitive(...) | | ArrayUtilsTest.java:71:12:71:51 | toPrimitive(...) : int[] [[]] : Number | semmle.label | toPrimitive(...) : int[] [[]] : Number | -| ArrayUtilsTest.java:71:12:71:51 | toPrimitive(...) : int[] [[]] : Object | semmle.label | toPrimitive(...) : int[] [[]] : Object | -| ArrayUtilsTest.java:71:35:71:50 | taintedBoxedInts : Integer[] | semmle.label | taintedBoxedInts : Integer[] | | ArrayUtilsTest.java:71:35:71:50 | taintedBoxedInts : Integer[] [[]] : Number | semmle.label | taintedBoxedInts : Integer[] [[]] : Number | | ArrayUtilsTest.java:72:12:72:70 | toPrimitive(...) | semmle.label | toPrimitive(...) | | ArrayUtilsTest.java:72:12:72:70 | toPrimitive(...) : int[] [[]] : Number | semmle.label | toPrimitive(...) : int[] [[]] : Number | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 00392ecb043..c1b21928881 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -9,18 +9,13 @@ edges | conversions.swift:37:19:37:29 | call to sourceInt() | conversions.swift:37:12:37:30 | call to String.init(_:) | provenance | | | conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:40:12:40:12 | arr | provenance | | | conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:41:12:41:12 | arr [Collection element] | provenance | | -| conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:41:12:41:17 | ...[...] | provenance | | -| conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:42:20:42:20 | arr | provenance | | | conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:42:20:42:20 | arr [Collection element] | provenance | | -| conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:43:20:43:20 | arr | provenance | | | conversions.swift:39:12:39:30 | [...] [Collection element] | conversions.swift:43:20:43:20 | arr [Collection element] | provenance | | | conversions.swift:39:19:39:29 | call to sourceInt() | conversions.swift:39:12:39:30 | [...] [Collection element] | provenance | | | conversions.swift:41:12:41:12 | arr [Collection element] | conversions.swift:41:12:41:17 | ...[...] | provenance | | | conversions.swift:42:12:42:23 | call to Array.init(_:) [Collection element] | conversions.swift:42:12:42:23 | call to Array.init(_:) | provenance | | -| conversions.swift:42:20:42:20 | arr | conversions.swift:42:12:42:23 | call to Array.init(_:) [Collection element] | provenance | | | conversions.swift:42:20:42:20 | arr [Collection element] | conversions.swift:42:12:42:23 | call to Array.init(_:) [Collection element] | provenance | | | conversions.swift:43:12:43:23 | call to Array.init(_:) [Collection element] | conversions.swift:43:12:43:26 | ...[...] | provenance | | -| conversions.swift:43:20:43:20 | arr | conversions.swift:43:12:43:23 | call to Array.init(_:) [Collection element] | provenance | | | conversions.swift:43:20:43:20 | arr [Collection element] | conversions.swift:43:12:43:23 | call to Array.init(_:) [Collection element] | provenance | | | conversions.swift:44:12:44:39 | call to Array.init(_:) [Collection element] | conversions.swift:44:12:44:39 | call to Array.init(_:) | provenance | | | conversions.swift:44:20:44:33 | call to sourceString() | conversions.swift:44:20:44:35 | .utf8 | provenance | | @@ -106,32 +101,23 @@ edges | conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:185:31:185:31 | arr1 | provenance | | | conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:174:13:174:13 | arr2 | provenance | | | conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:176:13:176:13 | arr2 [Collection element] | provenance | | -| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:176:13:176:19 | ...[...] | provenance | | -| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:179:25:179:25 | arr2 | provenance | | | conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:179:25:179:25 | arr2 [Collection element] | provenance | | -| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:186:31:186:31 | arr2 | provenance | | | conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:186:31:186:31 | arr2 [Collection element] | provenance | | | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:172:14:172:26 | [...] [Collection element] | provenance | | | conversions.swift:176:13:176:13 | arr2 [Collection element] | conversions.swift:176:13:176:19 | ...[...] | provenance | | | conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | conversions.swift:180:13:180:13 | arr1b | provenance | | | conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | conversions.swift:182:13:182:13 | arr1b [Collection element] | provenance | | -| conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | conversions.swift:182:13:182:20 | ...[...] | provenance | | | conversions.swift:178:25:178:25 | arr1 | conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | provenance | | | conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | conversions.swift:181:13:181:13 | arr2b | provenance | | | conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | conversions.swift:183:13:183:13 | arr2b [Collection element] | provenance | | -| conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | conversions.swift:183:13:183:20 | ...[...] | provenance | | -| conversions.swift:179:25:179:25 | arr2 | conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | provenance | | | conversions.swift:179:25:179:25 | arr2 [Collection element] | conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | provenance | | | conversions.swift:182:13:182:13 | arr1b [Collection element] | conversions.swift:182:13:182:20 | ...[...] | provenance | | | conversions.swift:183:13:183:13 | arr2b [Collection element] | conversions.swift:183:13:183:20 | ...[...] | provenance | | | conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:187:13:187:13 | arr1c | provenance | | | conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:189:13:189:13 | arr1c [Collection element] | provenance | | -| conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:189:13:189:20 | ...[...] | provenance | | | conversions.swift:185:31:185:31 | arr1 | conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | provenance | | | conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:188:13:188:13 | arr2c | provenance | | | conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:190:13:190:13 | arr2c [Collection element] | provenance | | -| conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | conversions.swift:190:13:190:20 | ...[...] | provenance | | -| conversions.swift:186:31:186:31 | arr2 | conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | provenance | | | conversions.swift:186:31:186:31 | arr2 [Collection element] | conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | provenance | | | conversions.swift:189:13:189:13 | arr1c [Collection element] | conversions.swift:189:13:189:20 | ...[...] | provenance | | | conversions.swift:190:13:190:13 | arr2c [Collection element] | conversions.swift:190:13:190:20 | ...[...] | provenance | | @@ -277,11 +263,9 @@ nodes | conversions.swift:41:12:41:17 | ...[...] | semmle.label | ...[...] | | conversions.swift:42:12:42:23 | call to Array.init(_:) | semmle.label | call to Array.init(_:) | | conversions.swift:42:12:42:23 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | -| conversions.swift:42:20:42:20 | arr | semmle.label | arr | | conversions.swift:42:20:42:20 | arr [Collection element] | semmle.label | arr [Collection element] | | conversions.swift:43:12:43:23 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | | conversions.swift:43:12:43:26 | ...[...] | semmle.label | ...[...] | -| conversions.swift:43:20:43:20 | arr | semmle.label | arr | | conversions.swift:43:20:43:20 | arr [Collection element] | semmle.label | arr [Collection element] | | conversions.swift:44:12:44:39 | call to Array.init(_:) | semmle.label | call to Array.init(_:) | | conversions.swift:44:12:44:39 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | @@ -409,7 +393,6 @@ nodes | conversions.swift:178:19:178:29 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | | conversions.swift:178:25:178:25 | arr1 | semmle.label | arr1 | | conversions.swift:179:19:179:29 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | -| conversions.swift:179:25:179:25 | arr2 | semmle.label | arr2 | | conversions.swift:179:25:179:25 | arr2 [Collection element] | semmle.label | arr2 [Collection element] | | conversions.swift:180:13:180:13 | arr1b | semmle.label | arr1b | | conversions.swift:181:13:181:13 | arr2b | semmle.label | arr2b | @@ -420,7 +403,6 @@ nodes | conversions.swift:185:15:185:35 | call to ContiguousArray.init(_:) [Collection element] | semmle.label | call to ContiguousArray.init(_:) [Collection element] | | conversions.swift:185:31:185:31 | arr1 | semmle.label | arr1 | | conversions.swift:186:15:186:35 | call to ContiguousArray.init(_:) [Collection element] | semmle.label | call to ContiguousArray.init(_:) [Collection element] | -| conversions.swift:186:31:186:31 | arr2 | semmle.label | arr2 | | conversions.swift:186:31:186:31 | arr2 [Collection element] | semmle.label | arr2 [Collection element] | | conversions.swift:187:13:187:13 | arr1c | semmle.label | arr1c | | conversions.swift:188:13:188:13 | arr2c | semmle.label | arr2c | diff --git a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected index 835a6a5706e..cfd68d818ef 100644 --- a/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected +++ b/swift/ql/test/query-tests/Security/CWE-094/UnsafeJsEval.expected @@ -41,16 +41,14 @@ edges | UnsafeJsEval.swift:286:51:286:51 | stringBytes [Collection element] | UnsafeJsEval.swift:287:60:287:60 | stringBytes [Collection element] | provenance | | | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) | UnsafeJsEval.swift:291:17:291:17 | jsstr | provenance | | | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) | provenance | | -| UnsafeJsEval.swift:287:60:287:60 | stringBytes | UnsafeJsEval.swift:287:60:287:72 | .baseAddress | provenance | Config | -| UnsafeJsEval.swift:287:60:287:60 | stringBytes [Collection element] | UnsafeJsEval.swift:287:60:287:60 | stringBytes | provenance | | +| UnsafeJsEval.swift:287:60:287:60 | stringBytes [Collection element] | UnsafeJsEval.swift:287:60:287:72 | .baseAddress | provenance | Config | | UnsafeJsEval.swift:287:60:287:72 | .baseAddress | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) | provenance | | | UnsafeJsEval.swift:299:13:299:13 | string | UnsafeJsEval.swift:300:3:300:10 | .utf8CString | provenance | | | UnsafeJsEval.swift:300:3:300:10 | .utf8CString | UnsafeJsEval.swift:300:48:300:48 | stringBytes [Collection element] | provenance | | | UnsafeJsEval.swift:300:48:300:48 | stringBytes [Collection element] | UnsafeJsEval.swift:301:61:301:61 | stringBytes [Collection element] | provenance | | | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) | UnsafeJsEval.swift:305:17:305:17 | jsstr | provenance | | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) | provenance | | -| UnsafeJsEval.swift:301:61:301:61 | stringBytes | UnsafeJsEval.swift:301:61:301:73 | .baseAddress | provenance | Config | -| UnsafeJsEval.swift:301:61:301:61 | stringBytes [Collection element] | UnsafeJsEval.swift:301:61:301:61 | stringBytes | provenance | | +| UnsafeJsEval.swift:301:61:301:61 | stringBytes [Collection element] | UnsafeJsEval.swift:301:61:301:73 | .baseAddress | provenance | Config | | UnsafeJsEval.swift:301:61:301:73 | .baseAddress | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | provenance | | | UnsafeJsEval.swift:318:24:318:87 | call to String.init(contentsOf:) | UnsafeJsEval.swift:320:44:320:74 | ... .+(_:_:) ... | provenance | | nodes @@ -80,7 +78,6 @@ nodes | UnsafeJsEval.swift:286:51:286:51 | stringBytes [Collection element] | semmle.label | stringBytes [Collection element] | | UnsafeJsEval.swift:287:16:287:98 | call to JSStringRetain(_:) | semmle.label | call to JSStringRetain(_:) | | UnsafeJsEval.swift:287:31:287:97 | call to JSStringCreateWithCharacters(_:_:) | semmle.label | call to JSStringCreateWithCharacters(_:_:) | -| UnsafeJsEval.swift:287:60:287:60 | stringBytes | semmle.label | stringBytes | | UnsafeJsEval.swift:287:60:287:60 | stringBytes [Collection element] | semmle.label | stringBytes [Collection element] | | UnsafeJsEval.swift:287:60:287:72 | .baseAddress | semmle.label | .baseAddress | | UnsafeJsEval.swift:291:17:291:17 | jsstr | semmle.label | jsstr | @@ -89,7 +86,6 @@ nodes | UnsafeJsEval.swift:300:48:300:48 | stringBytes [Collection element] | semmle.label | stringBytes [Collection element] | | UnsafeJsEval.swift:301:16:301:85 | call to JSStringRetain(_:) | semmle.label | call to JSStringRetain(_:) | | UnsafeJsEval.swift:301:31:301:84 | call to JSStringCreateWithUTF8CString(_:) | semmle.label | call to JSStringCreateWithUTF8CString(_:) | -| UnsafeJsEval.swift:301:61:301:61 | stringBytes | semmle.label | stringBytes | | UnsafeJsEval.swift:301:61:301:61 | stringBytes [Collection element] | semmle.label | stringBytes [Collection element] | | UnsafeJsEval.swift:301:61:301:73 | .baseAddress | semmle.label | .baseAddress | | UnsafeJsEval.swift:305:17:305:17 | jsstr | semmle.label | jsstr | diff --git a/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected b/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected index 0d8a259fe90..544431cfb4f 100644 --- a/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected +++ b/swift/ql/test/query-tests/Security/CWE-321/HardcodedEncryptionKey.expected @@ -26,10 +26,7 @@ edges | cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:155:26:155:26 | keyString | provenance | | | cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:164:24:164:24 | keyString | provenance | | | cryptoswift.swift:94:18:94:36 | call to getConstantString() | cryptoswift.swift:166:24:166:24 | keyString | provenance | | -| file://:0:0:0:0 | [post] self | misc.swift:30:7:30:7 | self [Return] | provenance | | | file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self | provenance | | -| file://:0:0:0:0 | [post] self [encryptionKey] | file://:0:0:0:0 | [post] self | provenance | | -| file://:0:0:0:0 | [post] self [encryptionKey] | misc.swift:30:7:30:7 | self [Return] | provenance | | | file://:0:0:0:0 | [post] self [encryptionKey] | misc.swift:30:7:30:7 | self [Return] [encryptionKey] | provenance | | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [encryptionKey] | provenance | | | grdb.swift:21:20:21:20 | abc123 | grdb.swift:27:23:27:23 | constString | provenance | | @@ -45,11 +42,9 @@ edges | misc.swift:57:24:57:24 | abcdef123456 | misc.swift:57:19:57:38 | call to Data.init(_:) | provenance | | | misc.swift:66:2:66:2 | [post] config [encryptionKey] | misc.swift:66:2:66:2 | [post] config | provenance | | | misc.swift:66:25:66:25 | myConstKey | misc.swift:30:7:30:7 | value | provenance | | -| misc.swift:66:25:66:25 | myConstKey | misc.swift:66:2:66:2 | [post] config | provenance | | | misc.swift:66:25:66:25 | myConstKey | misc.swift:66:2:66:2 | [post] config [encryptionKey] | provenance | | | misc.swift:70:2:70:18 | [post] getter for .config [encryptionKey] | misc.swift:70:2:70:18 | [post] getter for .config | provenance | | | misc.swift:70:41:70:41 | myConstKey | misc.swift:30:7:30:7 | value | provenance | | -| misc.swift:70:41:70:41 | myConstKey | misc.swift:70:2:70:18 | [post] getter for .config | provenance | | | misc.swift:70:41:70:41 | myConstKey | misc.swift:70:2:70:18 | [post] getter for .config [encryptionKey] | provenance | | | misc.swift:73:14:73:20 | k1 | misc.swift:76:26:76:29 | .utf8 | provenance | | | misc.swift:73:28:73:34 | k2 | misc.swift:77:26:77:29 | .utf8 | provenance | | @@ -117,7 +112,6 @@ nodes | cryptoswift.swift:165:24:165:24 | key | semmle.label | key | | cryptoswift.swift:166:24:166:24 | keyString | semmle.label | keyString | | file://:0:0:0:0 | [post] self | semmle.label | [post] self | -| file://:0:0:0:0 | [post] self | semmle.label | [post] self | | file://:0:0:0:0 | [post] self [encryptionKey] | semmle.label | [post] self [encryptionKey] | | file://:0:0:0:0 | value | semmle.label | value | | grdb.swift:21:20:21:20 | abc123 | semmle.label | abc123 | @@ -128,7 +122,6 @@ nodes | grdb.swift:29:23:29:23 | constData | semmle.label | constData | | grdb.swift:31:26:31:26 | constString | semmle.label | constString | | grdb.swift:33:26:33:26 | constData | semmle.label | constData | -| misc.swift:30:7:30:7 | self [Return] | semmle.label | self [Return] | | misc.swift:30:7:30:7 | self [Return] [encryptionKey] | semmle.label | self [Return] [encryptionKey] | | misc.swift:30:7:30:7 | value | semmle.label | value | | misc.swift:57:19:57:38 | call to Data.init(_:) | semmle.label | call to Data.init(_:) | @@ -175,9 +168,7 @@ nodes | sqlite3_c_api.swift:49:36:49:36 | buffer | semmle.label | buffer | | sqlite3_c_api.swift:50:38:50:38 | buffer | semmle.label | buffer | subpaths -| misc.swift:66:25:66:25 | myConstKey | misc.swift:30:7:30:7 | value | misc.swift:30:7:30:7 | self [Return] | misc.swift:66:2:66:2 | [post] config | | misc.swift:66:25:66:25 | myConstKey | misc.swift:30:7:30:7 | value | misc.swift:30:7:30:7 | self [Return] [encryptionKey] | misc.swift:66:2:66:2 | [post] config [encryptionKey] | -| misc.swift:70:41:70:41 | myConstKey | misc.swift:30:7:30:7 | value | misc.swift:30:7:30:7 | self [Return] | misc.swift:70:2:70:18 | [post] getter for .config | | misc.swift:70:41:70:41 | myConstKey | misc.swift:30:7:30:7 | value | misc.swift:30:7:30:7 | self [Return] [encryptionKey] | misc.swift:70:2:70:18 | [post] getter for .config [encryptionKey] | #select | SQLite.swift:43:13:43:13 | hardcoded_key | SQLite.swift:43:13:43:13 | hardcoded_key | SQLite.swift:43:13:43:13 | hardcoded_key | The key 'hardcoded_key' has been initialized with hard-coded values from $@. | SQLite.swift:43:13:43:13 | hardcoded_key | hardcoded_key | diff --git a/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected index 267c16ae53b..f463e8d939b 100644 --- a/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected +++ b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected @@ -5,33 +5,26 @@ edges | InsecureTLS.swift:23:7:23:7 | value | file://:0:0:0:0 | value | provenance | | | InsecureTLS.swift:40:3:40:3 | [post] config [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:40:3:40:3 | [post] config | provenance | | | InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:19:7:19:7 | value | provenance | | -| InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:40:3:40:3 | [post] config | provenance | | | InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:40:3:40:3 | [post] config [tlsMinimumSupportedProtocolVersion] | provenance | | | InsecureTLS.swift:45:3:45:3 | [post] config [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:45:3:45:3 | [post] config | provenance | | | InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:19:7:19:7 | value | provenance | | -| InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:45:3:45:3 | [post] config | provenance | | | InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:45:3:45:3 | [post] config [tlsMinimumSupportedProtocolVersion] | provenance | | | InsecureTLS.swift:57:3:57:3 | [post] config [tlsMaximumSupportedProtocolVersion] | InsecureTLS.swift:57:3:57:3 | [post] config | provenance | | | InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:20:7:20:7 | value | provenance | | -| InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:57:3:57:3 | [post] config | provenance | | | InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:57:3:57:3 | [post] config [tlsMaximumSupportedProtocolVersion] | provenance | | | InsecureTLS.swift:64:3:64:3 | [post] config [tlsMinimumSupportedProtocol] | InsecureTLS.swift:64:3:64:3 | [post] config | provenance | | | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:22:7:22:7 | value | provenance | | -| InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:64:3:64:3 | [post] config | provenance | | | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:64:3:64:3 | [post] config [tlsMinimumSupportedProtocol] | provenance | | | InsecureTLS.swift:76:3:76:3 | [post] config [tlsMaximumSupportedProtocol] | InsecureTLS.swift:76:3:76:3 | [post] config | provenance | | | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:23:7:23:7 | value | provenance | | -| InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:76:3:76:3 | [post] config | provenance | | | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:76:3:76:3 | [post] config [tlsMaximumSupportedProtocol] | provenance | | | InsecureTLS.swift:102:10:102:33 | .TLSv10 | InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | provenance | | | InsecureTLS.swift:111:3:111:3 | [post] config [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:111:3:111:3 | [post] config | provenance | | | InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | InsecureTLS.swift:19:7:19:7 | value | provenance | | -| InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | InsecureTLS.swift:111:3:111:3 | [post] config | provenance | | | InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | InsecureTLS.swift:111:3:111:3 | [post] config [tlsMinimumSupportedProtocolVersion] | provenance | | | InsecureTLS.swift:121:55:121:66 | version | InsecureTLS.swift:122:47:122:47 | version | provenance | | | InsecureTLS.swift:122:3:122:3 | [post] config [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:122:3:122:3 | [post] config | provenance | | | InsecureTLS.swift:122:47:122:47 | version | InsecureTLS.swift:19:7:19:7 | value | provenance | | -| InsecureTLS.swift:122:47:122:47 | version | InsecureTLS.swift:122:3:122:3 | [post] config | provenance | | | InsecureTLS.swift:122:47:122:47 | version | InsecureTLS.swift:122:3:122:3 | [post] config [tlsMinimumSupportedProtocolVersion] | provenance | | | InsecureTLS.swift:127:25:127:48 | .TLSv11 | InsecureTLS.swift:121:55:121:66 | version | provenance | | | InsecureTLS.swift:158:7:158:7 | self [TLSVersion] | file://:0:0:0:0 | self [TLSVersion] | provenance | | @@ -43,11 +36,9 @@ edges | InsecureTLS.swift:165:47:165:47 | def [TLSVersion] | InsecureTLS.swift:158:7:158:7 | self [TLSVersion] | provenance | | | InsecureTLS.swift:165:47:165:47 | def [TLSVersion] | InsecureTLS.swift:165:47:165:51 | .TLSVersion | provenance | | | InsecureTLS.swift:165:47:165:51 | .TLSVersion | InsecureTLS.swift:19:7:19:7 | value | provenance | | -| InsecureTLS.swift:165:47:165:51 | .TLSVersion | InsecureTLS.swift:165:3:165:3 | [post] config | provenance | | | InsecureTLS.swift:165:47:165:51 | .TLSVersion | InsecureTLS.swift:165:3:165:3 | [post] config [tlsMinimumSupportedProtocolVersion] | provenance | | | InsecureTLS.swift:181:3:181:9 | [post] getter for .config [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:181:3:181:9 | [post] getter for .config | provenance | | | InsecureTLS.swift:181:53:181:76 | .TLSv10 | InsecureTLS.swift:19:7:19:7 | value | provenance | | -| InsecureTLS.swift:181:53:181:76 | .TLSv10 | InsecureTLS.swift:181:3:181:9 | [post] getter for .config | provenance | | | InsecureTLS.swift:181:53:181:76 | .TLSv10 | InsecureTLS.swift:181:3:181:9 | [post] getter for .config [tlsMinimumSupportedProtocolVersion] | provenance | | | InsecureTLS.swift:185:20:185:36 | withMinVersion | InsecureTLS.swift:187:42:187:42 | withMinVersion | provenance | | | InsecureTLS.swift:187:5:187:5 | [post] self [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:187:5:187:5 | [post] self | provenance | | @@ -58,27 +49,15 @@ edges | InsecureTLS.swift:202:24:202:31 | [post] getter for .tlsMinimumSupportedProtocolVersion | InsecureTLS.swift:202:24:202:24 | [post] config [tlsMinimumSupportedProtocolVersion] | provenance | | | InsecureTLS.swift:202:74:202:97 | .TLSv10 | InsecureTLS.swift:196:56:196:63 | value | provenance | | | InsecureTLS.swift:202:74:202:97 | .TLSv10 | InsecureTLS.swift:202:24:202:31 | [post] getter for .tlsMinimumSupportedProtocolVersion | provenance | | -| file://:0:0:0:0 | [post] self | InsecureTLS.swift:19:7:19:7 | self [Return] | provenance | | -| file://:0:0:0:0 | [post] self | InsecureTLS.swift:20:7:20:7 | self [Return] | provenance | | -| file://:0:0:0:0 | [post] self | InsecureTLS.swift:22:7:22:7 | self [Return] | provenance | | -| file://:0:0:0:0 | [post] self | InsecureTLS.swift:23:7:23:7 | self [Return] | provenance | | | file://:0:0:0:0 | [post] self [TLSVersion] | InsecureTLS.swift:158:7:158:7 | self [Return] [TLSVersion] | provenance | | -| file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocolVersion] | InsecureTLS.swift:20:7:20:7 | self [Return] | provenance | | | file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocolVersion] | InsecureTLS.swift:20:7:20:7 | self [Return] [tlsMaximumSupportedProtocolVersion] | provenance | | | file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocolVersion] | file://:0:0:0:0 | [post] self | provenance | | -| file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocolVersion] | file://:0:0:0:0 | [post] self | provenance | | -| file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocol] | InsecureTLS.swift:23:7:23:7 | self [Return] | provenance | | | file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocol] | InsecureTLS.swift:23:7:23:7 | self [Return] [tlsMaximumSupportedProtocol] | provenance | | | file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocol] | file://:0:0:0:0 | [post] self | provenance | | -| file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocol] | file://:0:0:0:0 | [post] self | provenance | | -| file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:19:7:19:7 | self [Return] | provenance | | | file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:19:7:19:7 | self [Return] [tlsMinimumSupportedProtocolVersion] | provenance | | | file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocolVersion] | file://:0:0:0:0 | [post] self | provenance | | -| file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocolVersion] | file://:0:0:0:0 | [post] self | provenance | | -| file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocol] | InsecureTLS.swift:22:7:22:7 | self [Return] | provenance | | | file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocol] | InsecureTLS.swift:22:7:22:7 | self [Return] [tlsMinimumSupportedProtocol] | provenance | | | file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocol] | file://:0:0:0:0 | [post] self | provenance | | -| file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocol] | file://:0:0:0:0 | [post] self | provenance | | | file://:0:0:0:0 | self [TLSVersion] | file://:0:0:0:0 | .TLSVersion | provenance | | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [TLSVersion] | provenance | | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocolVersion] | provenance | | @@ -86,16 +65,12 @@ edges | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocolVersion] | provenance | | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [tlsMinimumSupportedProtocol] | provenance | | nodes -| InsecureTLS.swift:19:7:19:7 | self [Return] | semmle.label | self [Return] | | InsecureTLS.swift:19:7:19:7 | self [Return] [tlsMinimumSupportedProtocolVersion] | semmle.label | self [Return] [tlsMinimumSupportedProtocolVersion] | | InsecureTLS.swift:19:7:19:7 | value | semmle.label | value | -| InsecureTLS.swift:20:7:20:7 | self [Return] | semmle.label | self [Return] | | InsecureTLS.swift:20:7:20:7 | self [Return] [tlsMaximumSupportedProtocolVersion] | semmle.label | self [Return] [tlsMaximumSupportedProtocolVersion] | | InsecureTLS.swift:20:7:20:7 | value | semmle.label | value | -| InsecureTLS.swift:22:7:22:7 | self [Return] | semmle.label | self [Return] | | InsecureTLS.swift:22:7:22:7 | self [Return] [tlsMinimumSupportedProtocol] | semmle.label | self [Return] [tlsMinimumSupportedProtocol] | | InsecureTLS.swift:22:7:22:7 | value | semmle.label | value | -| InsecureTLS.swift:23:7:23:7 | self [Return] | semmle.label | self [Return] | | InsecureTLS.swift:23:7:23:7 | self [Return] [tlsMaximumSupportedProtocol] | semmle.label | self [Return] [tlsMaximumSupportedProtocol] | | InsecureTLS.swift:23:7:23:7 | value | semmle.label | value | | InsecureTLS.swift:40:3:40:3 | [post] config | semmle.label | [post] config | @@ -150,10 +125,6 @@ nodes | file://:0:0:0:0 | [post] self | semmle.label | [post] self | | file://:0:0:0:0 | [post] self | semmle.label | [post] self | | file://:0:0:0:0 | [post] self | semmle.label | [post] self | -| file://:0:0:0:0 | [post] self | semmle.label | [post] self | -| file://:0:0:0:0 | [post] self | semmle.label | [post] self | -| file://:0:0:0:0 | [post] self | semmle.label | [post] self | -| file://:0:0:0:0 | [post] self | semmle.label | [post] self | | file://:0:0:0:0 | [post] self [TLSVersion] | semmle.label | [post] self [TLSVersion] | | file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocolVersion] | semmle.label | [post] self [tlsMaximumSupportedProtocolVersion] | | file://:0:0:0:0 | [post] self [tlsMaximumSupportedProtocol] | semmle.label | [post] self [tlsMaximumSupportedProtocol] | @@ -166,25 +137,16 @@ nodes | file://:0:0:0:0 | value | semmle.label | value | | file://:0:0:0:0 | value | semmle.label | value | subpaths -| InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] | InsecureTLS.swift:40:3:40:3 | [post] config | | InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:40:3:40:3 | [post] config [tlsMinimumSupportedProtocolVersion] | -| InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] | InsecureTLS.swift:45:3:45:3 | [post] config | | InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:45:3:45:3 | [post] config [tlsMinimumSupportedProtocolVersion] | -| InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:20:7:20:7 | value | InsecureTLS.swift:20:7:20:7 | self [Return] | InsecureTLS.swift:57:3:57:3 | [post] config | | InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:20:7:20:7 | value | InsecureTLS.swift:20:7:20:7 | self [Return] [tlsMaximumSupportedProtocolVersion] | InsecureTLS.swift:57:3:57:3 | [post] config [tlsMaximumSupportedProtocolVersion] | -| InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:22:7:22:7 | value | InsecureTLS.swift:22:7:22:7 | self [Return] | InsecureTLS.swift:64:3:64:3 | [post] config | | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:22:7:22:7 | value | InsecureTLS.swift:22:7:22:7 | self [Return] [tlsMinimumSupportedProtocol] | InsecureTLS.swift:64:3:64:3 | [post] config [tlsMinimumSupportedProtocol] | -| InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:23:7:23:7 | value | InsecureTLS.swift:23:7:23:7 | self [Return] | InsecureTLS.swift:76:3:76:3 | [post] config | | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:23:7:23:7 | value | InsecureTLS.swift:23:7:23:7 | self [Return] [tlsMaximumSupportedProtocol] | InsecureTLS.swift:76:3:76:3 | [post] config [tlsMaximumSupportedProtocol] | -| InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] | InsecureTLS.swift:111:3:111:3 | [post] config | | InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:111:3:111:3 | [post] config [tlsMinimumSupportedProtocolVersion] | -| InsecureTLS.swift:122:47:122:47 | version | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] | InsecureTLS.swift:122:3:122:3 | [post] config | | InsecureTLS.swift:122:47:122:47 | version | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:122:3:122:3 | [post] config [tlsMinimumSupportedProtocolVersion] | | InsecureTLS.swift:163:20:163:43 | .TLSv10 | InsecureTLS.swift:158:7:158:7 | value | InsecureTLS.swift:158:7:158:7 | self [Return] [TLSVersion] | InsecureTLS.swift:163:3:163:3 | [post] def [TLSVersion] | | InsecureTLS.swift:165:47:165:47 | def [TLSVersion] | InsecureTLS.swift:158:7:158:7 | self [TLSVersion] | file://:0:0:0:0 | .TLSVersion | InsecureTLS.swift:165:47:165:51 | .TLSVersion | -| InsecureTLS.swift:165:47:165:51 | .TLSVersion | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] | InsecureTLS.swift:165:3:165:3 | [post] config | | InsecureTLS.swift:165:47:165:51 | .TLSVersion | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:165:3:165:3 | [post] config [tlsMinimumSupportedProtocolVersion] | -| InsecureTLS.swift:181:53:181:76 | .TLSv10 | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] | InsecureTLS.swift:181:3:181:9 | [post] getter for .config | | InsecureTLS.swift:181:53:181:76 | .TLSv10 | InsecureTLS.swift:19:7:19:7 | value | InsecureTLS.swift:19:7:19:7 | self [Return] [tlsMinimumSupportedProtocolVersion] | InsecureTLS.swift:181:3:181:9 | [post] getter for .config [tlsMinimumSupportedProtocolVersion] | | InsecureTLS.swift:202:74:202:97 | .TLSv10 | InsecureTLS.swift:196:56:196:63 | value | InsecureTLS.swift:196:1:198:1 | version[return] | InsecureTLS.swift:202:24:202:31 | [post] getter for .tlsMinimumSupportedProtocolVersion | #select From d27b28d3714eeeac1f249c3fc4454b016ad32e7f Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 21 Aug 2024 13:57:01 +0200 Subject: [PATCH 091/404] C++: update test output This reveals that some tests were passing for the wrong reasons. See https://github.com/github/codeql/pull/17275 --- cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 299f1413878..8d4dc3351b4 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -4,4 +4,7 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (tai WARNING: module 'DataFlow' has been deprecated and may be removed in future (taint.ql:68,25-33) WARNING: module 'TaintTracking' has been deprecated and may be removed in future (taint.ql:73,20-33) testFailures +| taint.cpp:453:23:453:42 | // $ ir MISSING: ast | Missing result:ir= | +| vector.cpp:118:12:118:30 | // $ ir MISSING:ast | Missing result:ir= | +| vector.cpp:119:12:119:30 | // $ ir MISSING:ast | Missing result:ir= | failures From 8df7fbf6d660f67c2a7d5b0a380183d4ea1c8e81 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 23 Aug 2024 11:30:50 +0200 Subject: [PATCH 092/404] Swift: update test output The 'first' field is seen as a TaintInheritingContent, which means any read step for 'first' becomes a taint step too. This type of taint step does not permit an implicit read before it, because it wasn't contributed by a configuration. So there is no way for the taint to get out of the collection content before the taint step through '.first'. The test previously passed because an implicit read at once of the earlier sinks could follow use-use flow down to the receiver of .first, allowing it to escape the collection content. --- .../ql/test/library-tests/dataflow/taint/libraries/set.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/set.swift b/swift/ql/test/library-tests/dataflow/taint/libraries/set.swift index 76b41ff8b93..b7ca5b86cca 100644 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/set.swift +++ b/swift/ql/test/library-tests/dataflow/taint/libraries/set.swift @@ -28,7 +28,7 @@ func testSet(ix: Int) { sink(arg: taintedSet.max()!) // $ tainted=t1 sink(arg: taintedSet.firstIndex(of: source("t2"))!) sink(arg: taintedSet[taintedSet.firstIndex(of: source("t3"))!]) // $ tainted=t1 - sink(arg: taintedSet.first!) // $ tainted=t1 + sink(arg: taintedSet.first!) // $ MISSING: tainted=t1 for elem in taintedSet { sink(arg: elem) // $ tainted=t1 } @@ -100,7 +100,7 @@ func testSet(ix: Int) { sink(arg: taintedSet.sorted().randomElement()!) // $ tainted=t1 sink(arg: taintedSet.shuffled().randomElement()!) // $ tainted=t1 - sink(arg: taintedSet.lazy[taintedSet.firstIndex(of: source("t11"))!]) // $ tainted=t1 + sink(arg: taintedSet.lazy[taintedSet.firstIndex(of: source("t11"))!]) // $ MISSING: tainted=t1 var it = taintedSet.makeIterator() sink(arg: it.next()!) // $ tainted=t1 From 65189e09f54e0513e8266a43c362ef395db802b8 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 23 Aug 2024 11:52:22 +0200 Subject: [PATCH 093/404] Dataflow: Simplify using a SummaryCtx type. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 459 +++++++++--------- .../dataflow/internal/DataFlowImplCommon.qll | 18 - 2 files changed, 224 insertions(+), 253 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 379a618dbdf..98291d25ffc 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1419,10 +1419,6 @@ module MakeImpl Lang> { import Param /* Begin: Stage logic. */ - private module TypOption = Option; - - private class TypOption = TypOption::Option; - pragma[nomagic] private Typ getNodeTyp(NodeEx node) { PrevStage::revFlow(node) and result = getTyp(node.getDataFlowType()) @@ -1475,17 +1471,16 @@ module MakeImpl Lang> { */ pragma[nomagic] additional predicate fwdFlow( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap, ApApprox apa + NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa ) { - fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa) + fwdFlow1(node, state, cc, summaryCtx, _, t, ap, apa) } private predicate fwdFlow1( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa + NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t0, Typ t, Ap ap, + ApApprox apa ) { - fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and + fwdFlow0(node, state, cc, summaryCtx, t0, ap, apa) and PrevStage::revFlow(node, state, apa) and filter(node, state, t0, ap, t) and ( @@ -1500,25 +1495,22 @@ module MakeImpl Lang> { pragma[nomagic] private predicate typeStrengthen(Typ t0, Ap ap, Typ t) { - fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t + fwdFlow1(_, _, _, _, t0, t, ap, _) and t0 != t } pragma[nomagic] private predicate fwdFlow0( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap, ApApprox apa + NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa ) { sourceNode(node, state) and (if hasSourceCallCtx() then cc = ccSomeCall() else cc = ccNone()) and - argT instanceof TypOption::None and - argAp = apNone() and - summaryCtx = TParamNodeNone() and + summaryCtx = TSummaryCtxNone() and t = getNodeTyp(node) and ap instanceof ApNil and apa = getApprox(ap) or exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | - fwdFlow(mid, state0, cc, summaryCtx, argT, argAp, t0, ap, apa) and + fwdFlow(mid, state0, cc, summaryCtx, t0, ap, apa) and localCc = getLocalCc(cc) | localStep(mid, state0, node, state, true, _, localCc, _) and @@ -1530,20 +1522,18 @@ module MakeImpl Lang> { or fwdFlowJump(node, state, t, ap, apa) and cc = ccNone() and - summaryCtx = TParamNodeNone() and - argT instanceof TypOption::None and - argAp = apNone() + summaryCtx = TSummaryCtxNone() or // store exists(Content c, Typ t0, Ap ap0 | - fwdFlowStore(_, t0, ap0, c, t, node, state, cc, summaryCtx, argT, argAp) and + fwdFlowStore(_, t0, ap0, c, t, node, state, cc, summaryCtx) and ap = apCons(c, t0, ap0) and apa = getApprox(ap) ) or // read exists(Typ t0, Ap ap0, Content c | - fwdFlowRead(t0, ap0, c, _, node, state, cc, summaryCtx, argT, argAp) and + fwdFlowRead(t0, ap0, c, _, node, state, cc, summaryCtx) and fwdFlowConsCand(t0, ap0, c, t, ap) and apa = getApprox(ap) ) @@ -1553,13 +1543,9 @@ module MakeImpl Lang> { fwdFlowIn(node, apa, state, cc, t, ap, allowsFlowThrough) and if allowsFlowThrough = true then ( - summaryCtx = TParamNodeSome(node.asNode()) and - argT = TypOption::some(t) and - argAp = apSome(ap) + summaryCtx = TSummaryCtxSome(node, t, ap) ) else ( - summaryCtx = TParamNodeNone() and - argT instanceof TypOption::None and - argAp = apNone() and + summaryCtx = TSummaryCtxNone() and // When the call contexts of source and sink needs to match then there's // never any reason to enter a callable except to find a summary. See also // the comment in `PathNodeMid::isAtSink`. @@ -1568,36 +1554,71 @@ module MakeImpl Lang> { ) or // flow out of a callable - fwdFlowOut(_, _, node, state, cc, summaryCtx, argT, argAp, t, ap, apa) + fwdFlowOut(_, _, node, state, cc, summaryCtx, t, ap, apa) or // flow through a callable exists( DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa | - fwdFlowThrough(call, cc, state, ccc, summaryCtx, argT, argAp, t, ap, apa, ret, - innerArgApa) and + fwdFlowThrough(call, cc, state, ccc, summaryCtx, t, ap, apa, ret, innerArgApa) and flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa) and not inBarrier(node, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } + private newtype TSummaryCtx = + TSummaryCtxNone() or + TSummaryCtxSome(ParamNodeEx p, Typ t, Ap ap) { fwdFlowIn(p, _, _, _, t, ap, true) } + + /** + * A context for generating flow summaries. This represents flow entry through + * a specific parameter with an access path of a specific shape. + * + * Summaries are only created for parameters that may flow through. + */ + private class SummaryCtx extends TSummaryCtx { + abstract string toString(); + } + + /** A summary context from which no flow summary can be generated. */ + private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { + override string toString() { result = "" } + } + + /** A summary context from which a flow summary can be generated. */ + private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome { + private ParamNodeEx p; + private Typ t; + private Ap ap; + + SummaryCtxSome() { this = TSummaryCtxSome(p, t, ap) } + + ParamNodeEx getParamNode() { result = p } + + private string ppTyp() { result = t.toString() and result != "" } + + override string toString() { result = p + concat(" : " + this.ppTyp()) + " " + ap } + + Location getLocation() { result = p.getLocation() } + } + private predicate fwdFlowJump(NodeEx node, FlowState state, Typ t, Ap ap, ApApprox apa) { exists(NodeEx mid | - fwdFlow(mid, state, _, _, _, _, t, ap, apa) and + fwdFlow(mid, state, _, _, t, ap, apa) and jumpStepEx(mid, node) ) or exists(NodeEx mid | - fwdFlow(mid, state, _, _, _, _, _, ap, apa) and + fwdFlow(mid, state, _, _, _, ap, apa) and additionalJumpStep(mid, node, _) and t = getNodeTyp(node) and ap instanceof ApNil ) or exists(NodeEx mid, FlowState state0 | - fwdFlow(mid, state0, _, _, _, _, _, ap, apa) and + fwdFlow(mid, state0, _, _, _, ap, apa) and additionalJumpStateStep(mid, state0, node, state) and t = getNodeTyp(node) and ap instanceof ApNil @@ -1607,10 +1628,10 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowStore( NodeEx node1, Typ t1, Ap ap1, Content c, Typ t2, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, TypOption argT, ApOption argAp + SummaryCtx summaryCtx ) { exists(DataFlowType contentType, DataFlowType containerType, ApApprox apa1 | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t1, ap1, apa1) and + fwdFlow(node1, state, cc, summaryCtx, t1, ap1, apa1) and not outBarrier(node1, state) and not inBarrier(node2, state) and PrevStage::storeStepCand(node1, apa1, c, node2, contentType, containerType) and @@ -1626,7 +1647,7 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { - fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and + fwdFlowStore(_, t1, tail, c, t2, _, _, _, _) and cons = apCons(c, t1, tail) or exists(Typ t0 | @@ -1650,10 +1671,10 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowRead( Typ t, Ap ap, Content c, NodeEx node1, NodeEx node2, FlowState state, Cc cc, - ParamNodeOption summaryCtx, TypOption argT, ApOption argAp + SummaryCtx summaryCtx ) { exists(ApHeadContent apc | - fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and + fwdFlow(node1, state, cc, summaryCtx, t, ap, _) and not outBarrier(node1, state) and not inBarrier(node2, state) and apc = getHeadContent(ap) and @@ -1663,10 +1684,10 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowIntoArg( - ArgNodeEx arg, FlowState state, Cc outercc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap, boolean emptyAp, ApApprox apa, boolean cc + ArgNodeEx arg, FlowState state, Cc outercc, SummaryCtx summaryCtx, Typ t, Ap ap, + boolean emptyAp, ApApprox apa, boolean cc ) { - fwdFlow(arg, state, outercc, summaryCtx, argT, argAp, t, ap, apa) and + fwdFlow(arg, state, outercc, summaryCtx, t, ap, apa) and (if instanceofCcCall(outercc) then cc = true else cc = false) and if ap instanceof ApNil then emptyAp = true else emptyAp = false } @@ -1756,11 +1777,11 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowInCand( DataFlowCall call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, - ParamNodeEx p, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, - boolean emptyAp, ApApprox apa, boolean cc, boolean allowsFlowThrough + ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, boolean emptyAp, ApApprox apa, + boolean cc, boolean allowsFlowThrough ) { exists(boolean allowsFieldFlow | - fwdFlowIntoArg(arg, state, outercc, summaryCtx, argT, argAp, t, ap, emptyAp, apa, cc) and + fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, apa, cc) and ( inner = viableImplCallContextReducedInlineLate(call, arg, outercc) or @@ -1779,12 +1800,12 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowInCandTypeFlowDisabled( DataFlowCall call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, - ParamNodeEx p, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, - ApApprox apa, boolean cc, boolean allowsFlowThrough + ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, boolean cc, + boolean allowsFlowThrough ) { not enableTypeFlow() and - fwdFlowInCand(call, arg, state, outercc, inner, p, summaryCtx, argT, argAp, t, ap, _, - apa, cc, allowsFlowThrough) + fwdFlowInCand(call, arg, state, outercc, inner, p, summaryCtx, t, ap, _, apa, cc, + allowsFlowThrough) } pragma[nomagic] @@ -1793,7 +1814,7 @@ module MakeImpl Lang> { boolean emptyAp, ApApprox apa, boolean cc, boolean allowsFlowThrough ) { enableTypeFlow() and - fwdFlowInCand(call, arg, _, outercc, inner, p, _, _, _, _, _, emptyAp, apa, cc, + fwdFlowInCand(call, arg, _, outercc, inner, p, _, _, _, emptyAp, apa, cc, allowsFlowThrough) } @@ -1820,17 +1841,17 @@ module MakeImpl Lang> { pragma[inline] predicate fwdFlowIn( DataFlowCall call, ArgNodeEx arg, DataFlowCallable inner, ParamNodeEx p, - FlowState state, Cc outercc, CcCall innercc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap, ApApprox apa, boolean cc, boolean allowsFlowThrough + FlowState state, Cc outercc, CcCall innercc, SummaryCtx summaryCtx, Typ t, Ap ap, + ApApprox apa, boolean cc, boolean allowsFlowThrough ) { // type flow disabled: linear recursion - fwdFlowInCandTypeFlowDisabled(call, arg, state, outercc, inner, p, summaryCtx, argT, - argAp, t, ap, apa, cc, allowsFlowThrough) and + fwdFlowInCandTypeFlowDisabled(call, arg, state, outercc, inner, p, summaryCtx, t, ap, + apa, cc, allowsFlowThrough) and fwdFlowInValidEdgeTypeFlowDisabled(call, inner, innercc, pragma[only_bind_into](cc)) or // type flow enabled: non-linear recursion exists(boolean emptyAp | - fwdFlowIntoArg(arg, state, outercc, summaryCtx, argT, argAp, t, ap, emptyAp, apa, cc) and + fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, apa, cc) and fwdFlowInValidEdgeTypeFlowEnabled(call, arg, outercc, inner, p, innercc, emptyAp, apa, cc, allowsFlowThrough) ) @@ -1845,8 +1866,8 @@ module MakeImpl Lang> { boolean allowsFlowThrough ) { exists(boolean allowsFlowThrough0 | - FwdFlowIn::fwdFlowIn(_, _, _, p, state, _, innercc, _, _, _, t, - ap, apa, _, allowsFlowThrough0) and + FwdFlowIn::fwdFlowIn(_, _, _, p, state, _, innercc, _, t, ap, + apa, _, allowsFlowThrough0) and if PrevStage::parameterMayFlowThrough(p, apa) then allowsFlowThrough = allowsFlowThrough0 else allowsFlowThrough = false @@ -1891,12 +1912,12 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowIntoRet( - RetNodeEx ret, FlowState state, CcNoCall cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap, ApApprox apa + RetNodeEx ret, FlowState state, CcNoCall cc, SummaryCtx summaryCtx, Typ t, Ap ap, + ApApprox apa ) { instanceofCcNoCall(cc) and not outBarrier(ret, state) and - fwdFlow(ret, state, cc, summaryCtx, argT, argAp, t, ap, apa) + fwdFlow(ret, state, cc, summaryCtx, t, ap, apa) } pragma[nomagic] @@ -1904,7 +1925,7 @@ module MakeImpl Lang> { DataFlowCall call, RetNodeEx ret, CcNoCall innercc, DataFlowCallable inner, NodeEx out, ApApprox apa, boolean allowsFieldFlow ) { - fwdFlowIntoRet(ret, _, innercc, _, _, _, _, _, apa) and + fwdFlowIntoRet(ret, _, innercc, _, _, _, apa) and inner = ret.getEnclosingCallable() and ( call = viableImplCallContextReducedReverseInlineLate(inner, innercc) and @@ -1928,10 +1949,10 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowOut( DataFlowCall call, DataFlowCallable inner, NodeEx out, FlowState state, CcNoCall outercc, - ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa + SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa ) { exists(RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow | - fwdFlowIntoRet(ret, state, innercc, summaryCtx, argT, argAp, t, ap, apa) and + fwdFlowIntoRet(ret, state, innercc, summaryCtx, t, ap, apa) and fwdFlowOutValidEdge(call, ret, innercc, inner, out, outercc, apa, allowsFieldFlow) and not inBarrier(out, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -1950,14 +1971,14 @@ module MakeImpl Lang> { DataFlowCall call, DataFlowCallable c, ParamNodeEx p, FlowState state, CcCall innercc, Typ t, Ap ap, boolean cc ) { - FwdFlowIn::fwdFlowIn(call, _, c, p, state, _, innercc, _, _, _, - t, ap, _, cc, _) + FwdFlowIn::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, + _, cc, _) } pragma[nomagic] private predicate fwdFlow1Param(ParamNodeEx p, FlowState state, CcCall cc, Typ t0, Ap ap) { instanceofCcCall(cc) and - fwdFlow1(p, state, cc, _, _, _, t0, _, ap, _) + fwdFlow1(p, state, cc, _, t0, _, ap, _) } pragma[nomagic] @@ -1972,13 +1993,13 @@ module MakeImpl Lang> { private predicate dataFlowTakenCallEdgeOut0( DataFlowCall call, DataFlowCallable c, NodeEx node, FlowState state, Cc cc, Typ t, Ap ap ) { - fwdFlowOut(call, c, node, state, cc, _, _, _, t, ap, _) + fwdFlowOut(call, c, node, state, cc, _, t, ap, _) } pragma[nomagic] private predicate fwdFlow1Out(NodeEx node, FlowState state, Cc cc, Typ t0, Ap ap) { exists(ApApprox apa | - fwdFlow1(node, state, cc, _, _, _, t0, _, ap, apa) and + fwdFlow1(node, state, cc, _, t0, _, ap, apa) and PrevStage::callEdgeReturn(_, _, _, _, node, _, apa) ) } @@ -2019,43 +2040,39 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowRetFromArg( - RetNodeEx ret, FlowState state, CcCall ccc, ParamNodeEx summaryCtx, Typ argT, Ap argAp, - ApApprox argApa, Typ t, Ap ap, ApApprox apa + RetNodeEx ret, FlowState state, CcCall ccc, SummaryCtxSome summaryCtx, ApApprox argApa, + Typ t, Ap ap, ApApprox apa ) { - exists(ReturnKindExt kind | + exists(ReturnKindExt kind, ParamNodeEx p, Ap argAp | instanceofCcCall(ccc) and - fwdFlow(pragma[only_bind_into](ret), state, ccc, - TParamNodeSome(pragma[only_bind_into](summaryCtx.asNode())), TypOption::some(argT), - pragma[only_bind_into](apSome(argAp)), t, ap, pragma[only_bind_into](apa)) and + fwdFlow(pragma[only_bind_into](ret), state, ccc, summaryCtx, t, ap, + pragma[only_bind_into](apa)) and + summaryCtx = + TSummaryCtxSome(pragma[only_bind_into](p), _, pragma[only_bind_into](argAp)) and not outBarrier(ret, state) and kind = ret.getKind() and - parameterFlowThroughAllowed(summaryCtx, kind) and + parameterFlowThroughAllowed(p, kind) and argApa = getApprox(argAp) and - PrevStage::returnMayFlowThrough(ret, argApa, apa, kind) + PrevStage::returnMayFlowThrough(ret, pragma[only_bind_into](argApa), apa, kind) ) } pragma[inline] private predicate fwdFlowThrough0( DataFlowCall call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, - ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa, - RetNodeEx ret, ParamNodeEx innerSummaryCtx, Typ innerArgT, Ap innerArgAp, - ApApprox innerArgApa + SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, RetNodeEx ret, + SummaryCtxSome innerSummaryCtx, ApApprox innerArgApa ) { - fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgT, innerArgAp, innerArgApa, t, - ap, apa) and - fwdFlowIsEntered(call, arg, cc, ccc, summaryCtx, argT, argAp, innerSummaryCtx, innerArgT, - innerArgAp) + fwdFlowRetFromArg(ret, state, ccc, innerSummaryCtx, innerArgApa, t, ap, apa) and + fwdFlowIsEntered(call, arg, cc, ccc, summaryCtx, innerSummaryCtx) } pragma[nomagic] private predicate fwdFlowThrough( - DataFlowCall call, Cc cc, FlowState state, CcCall ccc, ParamNodeOption summaryCtx, - TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa, RetNodeEx ret, - ApApprox innerArgApa + DataFlowCall call, Cc cc, FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, + Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa ) { - fwdFlowThrough0(call, _, cc, state, ccc, summaryCtx, argT, argAp, t, ap, apa, ret, _, _, - _, innerArgApa) + fwdFlowThrough0(call, _, cc, state, ccc, summaryCtx, t, ap, apa, ret, _, innerArgApa) } private module FwdFlowThroughRestriction implements FwdFlowInInputSig { @@ -2064,22 +2081,33 @@ module MakeImpl Lang> { predicate parameterRestriction = PrevStage::parameterMayFlowThrough/2; } + pragma[nomagic] + private predicate fwdFlowIsEntered0( + DataFlowCall call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, + ParamNodeEx p, Typ t, Ap ap + ) { + FwdFlowIn::fwdFlowIn(call, arg, _, p, _, cc, innerCc, + summaryCtx, t, ap, _, _, true) + } + /** * Holds if an argument to `call` is reached in the flow covered by `fwdFlow` * and data might flow through the target callable and back out at `call`. */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, ArgNodeEx arg, Cc cc, CcCall innerCc, ParamNodeOption summaryCtx, - TypOption argT, ApOption argAp, ParamNodeEx p, Typ t, Ap ap + DataFlowCall call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, + SummaryCtxSome innerSummaryCtx ) { - FwdFlowIn::fwdFlowIn(call, arg, _, p, _, cc, innerCc, - summaryCtx, argT, argAp, t, ap, _, _, true) + exists(ParamNodeEx p, Typ t, Ap ap | + fwdFlowIsEntered0(call, arg, cc, innerCc, summaryCtx, p, t, ap) and + innerSummaryCtx = TSummaryCtxSome(p, t, ap) + ) } pragma[nomagic] private predicate storeStepFwd(NodeEx node1, Typ t1, Ap ap1, Content c, NodeEx node2, Ap ap2) { - fwdFlowStore(node1, t1, ap1, c, _, node2, _, _, _, _, _) and + fwdFlowStore(node1, t1, ap1, c, _, node2, _, _, _) and ap2 = apCons(c, t1, ap1) and readStepFwd(_, ap2, c, _, _) } @@ -2087,7 +2115,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate readStepFwd(NodeEx n1, Ap ap1, Content c, NodeEx n2, Ap ap2) { exists(Typ t1 | - fwdFlowRead(t1, ap1, c, n1, n2, _, _, _, _, _) and + fwdFlowRead(t1, ap1, c, n1, n2, _, _, _) and fwdFlowConsCand(t1, ap1, c, _, ap2) ) } @@ -2095,10 +2123,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate returnFlowsThrough0( DataFlowCall call, FlowState state, CcCall ccc, Ap ap, ApApprox apa, RetNodeEx ret, - ParamNodeEx innerSummaryCtx, Typ innerArgT, Ap innerArgAp, ApApprox innerArgApa + SummaryCtxSome innerSummaryCtx, ApApprox innerArgApa ) { - fwdFlowThrough0(call, _, _, state, ccc, _, _, _, _, ap, apa, ret, innerSummaryCtx, - innerArgT, innerArgAp, innerArgApa) + fwdFlowThrough0(call, _, _, state, ccc, _, _, ap, apa, ret, innerSummaryCtx, innerArgApa) } pragma[nomagic] @@ -2107,7 +2134,8 @@ module MakeImpl Lang> { Ap argAp, ApApprox argApa, Ap ap ) { exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow | - returnFlowsThrough0(call, state, ccc, ap, apa, ret, p, argT, argAp, argApa) and + returnFlowsThrough0(call, state, ccc, ap, apa, ret, TSummaryCtxSome(p, argT, argAp), + argApa) and flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, argApa, apa) and pos = ret.getReturnPosition() and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -2122,7 +2150,7 @@ module MakeImpl Lang> { returnFlowsThrough(_, _, _, _, pragma[only_bind_into](p), pragma[only_bind_into](argT), pragma[only_bind_into](argAp), pragma[only_bind_into](argApa), ap) and flowIntoCallApaTaken(call, _, pragma[only_bind_into](arg), p, allowsFieldFlow, argApa) and - fwdFlow(arg, _, _, _, _, _, pragma[only_bind_into](argT), pragma[only_bind_into](argAp), + fwdFlow(arg, _, _, _, pragma[only_bind_into](argT), pragma[only_bind_into](argAp), pragma[only_bind_into](argApa)) and if allowsFieldFlow = false then argAp instanceof ApNil else any() ) @@ -2134,7 +2162,7 @@ module MakeImpl Lang> { ) { exists(ApApprox apa, boolean allowsFieldFlow | flowIntoCallApaTaken(call, c, arg, p, allowsFieldFlow, apa) and - fwdFlow(arg, _, _, _, _, _, _, ap, apa) and + fwdFlow(arg, _, _, _, _, ap, apa) and if allowsFieldFlow = false then ap instanceof ApNil else any() ) } @@ -2146,7 +2174,7 @@ module MakeImpl Lang> { ) { exists(ApApprox apa, boolean allowsFieldFlow | PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow, apa) and - fwdFlow(ret, _, _, _, _, _, _, ap, apa) and + fwdFlow(ret, _, _, _, _, ap, apa) and pos = ret.getReturnPosition() and if allowsFieldFlow = false then ap instanceof ApNil else any() | @@ -2169,14 +2197,14 @@ module MakeImpl Lang> { NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { revFlow0(node, state, returnCtx, returnAp, ap) and - fwdFlow(node, state, _, _, _, _, _, ap, _) + fwdFlow(node, state, _, _, _, ap, _) } pragma[nomagic] private predicate revFlow0( NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { - fwdFlow(node, state, _, _, _, _, _, ap, _) and + fwdFlow(node, state, _, _, _, ap, _) and sinkNode(node, state) and ( if hasSinkCallCtx() @@ -2304,7 +2332,7 @@ module MakeImpl Lang> { predicate dataFlowNonCallEntry(DataFlowCallable c, boolean cc) { exists(NodeEx node, FlowState state, ApNil nil | - fwdFlow(node, state, _, _, _, _, _, nil, _) and + fwdFlow(node, state, _, _, _, nil, _) and sinkNode(node, state) and (if hasSinkCallCtx() then cc = true else cc = false) and c = node.getEnclosingCallable() @@ -2463,6 +2491,27 @@ module MakeImpl Lang> { ) } + pragma[nomagic] + private predicate nodeMayUseSummary0(NodeEx n, ParamNodeEx p, FlowState state, Ap ap) { + exists(Ap ap0 | + parameterMayFlowThrough(p, _) and + revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, ap0) and + fwdFlow(n, state, any(CcCall ccc), TSummaryCtxSome(p, _, ap), _, ap0, _) + ) + } + + /** + * Holds if `ap` is recorded as the summary context for flow reaching `node` + * and remains relevant for the following pruning stage. + */ + pragma[nomagic] + additional predicate nodeMayUseSummary(NodeEx n, FlowState state, Ap ap) { + exists(ParamNodeEx p | + parameterMayFlowThrough(p, ap) and + nodeMayUseSummary0(n, p, state, ap) + ) + } + pragma[nomagic] predicate returnMayFlowThrough(RetNodeEx ret, Ap argAp, Ap ap, ReturnKindExt kind) { exists(ParamNodeEx p, ReturnPosition pos | @@ -2539,11 +2588,8 @@ module MakeImpl Lang> { */ additional module Graph { private newtype TPathNode = - TPathNodeMid( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap - ) { - fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) and + TPathNodeMid(NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap) { + fwdFlow(node, state, cc, summaryCtx, t, ap, _) and revFlow(node, state, _, _, ap) } or TPathNodeSink(NodeEx node, FlowState state) { @@ -2651,13 +2697,11 @@ module MakeImpl Lang> { NodeEx node; FlowState state; Cc cc; - ParamNodeOption summaryCtx; - TypOption argT; - ApOption argAp; + SummaryCtx summaryCtx; Typ t; Ap ap; - PathNodeMid() { this = TPathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) } + PathNodeMid() { this = TPathNodeMid(node, state, cc, summaryCtx, t, ap) } override NodeEx getNodeEx() { result = node } @@ -2720,13 +2764,10 @@ module MakeImpl Lang> { private string ppCtx() { result = " <" + cc + ">" } private string ppSummaryCtx() { - summaryCtx instanceof TParamNodeNone and result = "" + summaryCtx instanceof SummaryCtxNone and result = "" or - exists(ParamNode p, Ap argAp0 | - summaryCtx = TParamNodeSome(p) and argAp = apSome(argAp0) - | - result = " <" + p + " : " + argT + " " + argAp0 + ">" - ) + summaryCtx instanceof SummaryCtxSome and + result = " <" + summaryCtx + ">" } override string toString() { result = node.toString() + this.ppType() + this.ppAp() } @@ -2743,7 +2784,7 @@ module MakeImpl Lang> { override predicate isSource() { sourceNode(node, state) and (if hasSourceCallCtx() then cc = ccSomeCall() else cc = ccNone()) and - summaryCtx = TParamNodeNone() and + summaryCtx = TSummaryCtxNone() and t = getNodeTyp(node) and ap instanceof ApNil } @@ -2762,7 +2803,7 @@ module MakeImpl Lang> { // which means that the summary context being empty holds if and // only if we are in the call context of the source. if Config::getAFeature() instanceof FeatureEqualSourceSinkCallContext - then summaryCtx = TParamNodeNone() + then summaryCtx = TSummaryCtxNone() else if Config::getAFeature() instanceof FeatureHasSinkCallContext then instanceofCcNoCall(cc) @@ -2804,12 +2845,11 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInStep( ArgNodeEx arg, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, - ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, - boolean allowsFlowThrough + SummaryCtx summaryCtx, Typ t, Ap ap, boolean allowsFlowThrough ) { exists(ApApprox apa, boolean allowsFlowThrough0 | FwdFlowIn::fwdFlowIn(_, arg, _, p, state, outercc, innercc, - summaryCtx, argT, argAp, t, ap, apa, _, allowsFlowThrough0) and + summaryCtx, t, ap, apa, _, allowsFlowThrough0) and if PrevStage::parameterMayFlowThrough(p, apa) then allowsFlowThrough = allowsFlowThrough0 else allowsFlowThrough = false @@ -2819,65 +2859,61 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThroughStep0( DataFlowCall call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, - ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, ApApprox apa, - RetNodeEx ret, ParamNodeEx innerSummaryCtx, Typ innerArgT, Ap innerArgAp, - ApApprox innerArgApa + SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, RetNodeEx ret, + SummaryCtxSome innerSummaryCtx, ApApprox innerArgApa ) { - fwdFlowThrough0(call, arg, cc, state, ccc, summaryCtx, argT, argAp, t, ap, apa, ret, - innerSummaryCtx, innerArgT, innerArgAp, innerArgApa) + fwdFlowThrough0(call, arg, cc, state, ccc, summaryCtx, t, ap, apa, ret, innerSummaryCtx, + innerArgApa) } - bindingset[node, state, cc, summaryCtx, argT, argAp, t, ap] + bindingset[node, state, cc, summaryCtx, t, ap] pragma[inline_late] private PathNodeImpl mkPathNode( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap + NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap ) { - result = TPathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) + result = TPathNodeMid(node, state, cc, summaryCtx, t, ap) } private PathNodeImpl typeStrengthenToPathNode( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t0, Ap ap + NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t0, Ap ap ) { exists(Typ t | - fwdFlow1(node, state, cc, summaryCtx, argT, argAp, t0, t, ap, _) and - result = TPathNodeMid(node, state, cc, summaryCtx, argT, argAp, t, ap) + fwdFlow1(node, state, cc, summaryCtx, t0, t, ap, _) and + result = TPathNodeMid(node, state, cc, summaryCtx, t, ap) ) } pragma[nomagic] private predicate fwdFlowThroughStep1( PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, DataFlowCall call, Cc cc, - FlowState state, CcCall ccc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, - Typ t, Ap ap, ApApprox apa, RetNodeEx ret, ApApprox innerArgApa + FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, + RetNodeEx ret, ApApprox innerArgApa ) { - exists(FlowState state0, ArgNodeEx arg, ParamNodeEx p, Typ innerArgT, Ap innerArgAp | - fwdFlowThroughStep0(call, arg, cc, state, ccc, summaryCtx, argT, argAp, t, ap, apa, - ret, p, innerArgT, innerArgAp, innerArgApa) and + exists( + FlowState state0, ArgNodeEx arg, SummaryCtxSome innerSummaryCtx, ParamNodeEx p, + Typ innerArgT, Ap innerArgAp + | + fwdFlowThroughStep0(call, arg, cc, state, ccc, summaryCtx, t, ap, apa, ret, + innerSummaryCtx, innerArgApa) and + innerSummaryCtx = TSummaryCtxSome(p, innerArgT, innerArgAp) and revFlow(arg, state0, _, _, _) and - pn1 = mkPathNode(arg, state0, cc, summaryCtx, argT, argAp, innerArgT, innerArgAp) and - pn2 = - typeStrengthenToPathNode(p, state0, ccc, TParamNodeSome(p.asNode()), - TypOption::some(innerArgT), apSome(innerArgAp), innerArgT, innerArgAp) and - pn3 = - mkPathNode(ret, state, ccc, TParamNodeSome(p.asNode()), TypOption::some(innerArgT), - apSome(innerArgAp), t, ap) + pn1 = mkPathNode(arg, state0, cc, summaryCtx, innerArgT, innerArgAp) and + pn2 = typeStrengthenToPathNode(p, state0, ccc, innerSummaryCtx, innerArgT, innerArgAp) and + pn3 = mkPathNode(ret, state, ccc, innerSummaryCtx, t, ap) ) } pragma[nomagic] private predicate fwdFlowThroughStep2( PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, NodeEx node, Cc cc, - FlowState state, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, - Ap ap + FlowState state, SummaryCtx summaryCtx, Typ t, Ap ap ) { exists( DataFlowCall call, CcCall ccc, RetNodeEx ret, boolean allowsFieldFlow, ApApprox innerArgApa, ApApprox apa | - fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, ccc, summaryCtx, argT, argAp, t, - ap, apa, ret, innerArgApa) and + fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, ccc, summaryCtx, t, ap, apa, ret, + innerArgApa) and flowThroughOutOfCall(call, ccc, ret, node, allowsFieldFlow, innerArgApa, apa) and not inBarrier(node, state) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -2885,11 +2921,11 @@ module MakeImpl Lang> { } private predicate localStep( - PathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, - TypOption argT, ApOption argAp, Typ t, Ap ap, string label, boolean isStoreStep + PathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, + Ap ap, string label, boolean isStoreStep ) { exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | - pn1 = TPathNodeMid(mid, state0, cc, summaryCtx, argT, argAp, t0, ap) and + pn1 = TPathNodeMid(mid, state0, cc, summaryCtx, t0, ap) and localCc = getLocalCc(cc) and isStoreStep = false | @@ -2902,8 +2938,8 @@ module MakeImpl Lang> { or // store exists(NodeEx mid, Content c, Typ t0, Ap ap0 | - pn1 = TPathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and - fwdFlowStore(mid, t0, ap0, c, t, node, state, cc, summaryCtx, argT, argAp) and + pn1 = TPathNodeMid(mid, state, cc, summaryCtx, t0, ap0) and + fwdFlowStore(mid, t0, ap0, c, t, node, state, cc, summaryCtx) and ap = apCons(c, t0, ap0) and label = "" and isStoreStep = true @@ -2911,8 +2947,8 @@ module MakeImpl Lang> { or // read exists(NodeEx mid, Typ t0, Ap ap0, Content c | - pn1 = TPathNodeMid(mid, state, cc, summaryCtx, argT, argAp, t0, ap0) and - fwdFlowRead(t0, ap0, c, mid, node, state, cc, summaryCtx, argT, argAp) and + pn1 = TPathNodeMid(mid, state, cc, summaryCtx, t0, ap0) and + fwdFlowRead(t0, ap0, c, mid, node, state, cc, summaryCtx) and fwdFlowConsCand(t0, ap0, c, t, ap) and label = "" and isStoreStep = false @@ -2921,11 +2957,11 @@ module MakeImpl Lang> { private predicate localStep(PathNodeImpl pn1, PathNodeImpl pn2, string label) { exists( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t0, Ap ap, boolean isStoreStep + NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t0, Ap ap, + boolean isStoreStep | - localStep(pn1, node, state, cc, summaryCtx, argT, argAp, t0, ap, label, isStoreStep) and - pn2 = typeStrengthenToPathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and + localStep(pn1, node, state, cc, summaryCtx, t0, ap, label, isStoreStep) and + pn2 = typeStrengthenToPathNode(node, state, cc, summaryCtx, t0, ap) and stepFilter(node, ap, isStoreStep) ) or @@ -2952,16 +2988,14 @@ module MakeImpl Lang> { } private predicate nonLocalStep( - PathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, - TypOption argT, ApOption argAp, Typ t, Ap ap, string label + PathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, + Ap ap, string label ) { // jump exists(NodeEx mid, FlowState state0, Typ t0 | - pn1 = TPathNodeMid(mid, state0, _, _, _, _, t0, ap) and + pn1 = TPathNodeMid(mid, state0, _, _, t0, ap) and cc = ccNone() and - summaryCtx = TParamNodeNone() and - argT instanceof TypOption::None and - argAp = apNone() + summaryCtx = TSummaryCtxNone() | jumpStepEx(mid, node) and state = state0 and @@ -2985,29 +3019,20 @@ module MakeImpl Lang> { or // flow into a callable exists( - ArgNodeEx arg, boolean allowsFlowThrough, Cc outercc, ParamNodeOption outerSummaryCtx, - TypOption outerArgT, ApOption outerArgAp + ArgNodeEx arg, boolean allowsFlowThrough, Cc outercc, SummaryCtx outerSummaryCtx | - pn1 = TPathNodeMid(arg, state, outercc, outerSummaryCtx, outerArgT, outerArgAp, t, ap) and - fwdFlowInStep(arg, node, state, outercc, cc, outerSummaryCtx, outerArgT, outerArgAp, - t, ap, allowsFlowThrough) and + pn1 = TPathNodeMid(arg, state, outercc, outerSummaryCtx, t, ap) and + fwdFlowInStep(arg, node, state, outercc, cc, outerSummaryCtx, t, ap, allowsFlowThrough) and label = "" and if allowsFlowThrough = true - then ( - summaryCtx = TParamNodeSome(node.asNode()) and - argT = TypOption::some(t) and - argAp = apSome(ap) - ) else ( - summaryCtx = TParamNodeNone() and - argT instanceof TypOption::None and - argAp = apNone() - ) + then summaryCtx = TSummaryCtxSome(node, t, ap) + else summaryCtx = TSummaryCtxNone() ) or // flow out of a callable exists(RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow, ApApprox apa | - pn1 = TPathNodeMid(ret, state, innercc, summaryCtx, argT, argAp, t, ap) and - fwdFlowIntoRet(ret, state, innercc, summaryCtx, argT, argAp, t, ap, apa) and + pn1 = TPathNodeMid(ret, state, innercc, summaryCtx, t, ap) and + fwdFlowIntoRet(ret, state, innercc, summaryCtx, t, ap, apa) and fwdFlowOutValidEdge(_, ret, innercc, _, node, cc, apa, allowsFieldFlow) and not inBarrier(node, state) and label = "" and @@ -3016,12 +3041,9 @@ module MakeImpl Lang> { } private predicate nonLocalStep(PathNodeImpl pn1, PathNodeImpl pn2, string label) { - exists( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t0, Ap ap - | - nonLocalStep(pn1, node, state, cc, summaryCtx, argT, argAp, t0, ap, label) and - pn2 = typeStrengthenToPathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and + exists(NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t0, Ap ap | + nonLocalStep(pn1, node, state, cc, summaryCtx, t0, ap, label) and + pn2 = typeStrengthenToPathNode(node, state, cc, summaryCtx, t0, ap) and stepFilter(node, ap, false) ) } @@ -3035,11 +3057,11 @@ module MakeImpl Lang> { PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out ) { exists( - NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t0, Ap ap, PathNodeImpl out0 + NodeEx node, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t0, Ap ap, + PathNodeImpl out0 | - fwdFlowThroughStep2(arg, par, ret, node, cc, state, summaryCtx, argT, argAp, t0, ap) and - out0 = typeStrengthenToPathNode(node, state, cc, summaryCtx, argT, argAp, t0, ap) and + fwdFlowThroughStep2(arg, par, ret, node, cc, state, summaryCtx, t0, ap) and + out0 = typeStrengthenToPathNode(node, state, cc, summaryCtx, t0, ap) and stepFilter(node, ap, false) | out = out0 or out = out0.(PathNodeMid).projectToSink(_) @@ -3298,14 +3320,13 @@ module MakeImpl Lang> { int tfnodes, int tftuples ) { fwd = true and - nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and + nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and - states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and + states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _)) and tuples = - count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, - ApOption argAp, Typ t, Ap ap | - fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _) + count(NodeEx n, FlowState state, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap | + fwdFlow(n, state, cc, summaryCtx, t, ap, _) ) and calledges = count(DataFlowCall call, DataFlowCallable c | @@ -3879,18 +3900,6 @@ module MakeImpl Lang> { private module Stage4 = MkStage::Stage; - /** - * Holds if `argApf` is recorded as the summary context for flow reaching `node` - * and remains relevant for the following pruning stage. - */ - private predicate flowCandSummaryCtx(NodeEx node, FlowState state, AccessPathFront argApf) { - exists(AccessPathFront apf | - Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and - Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, - apf, _) - ) - } - /** * Holds if a length 2 access path approximation with the head `c` is expected * to be expensive. @@ -3902,7 +3911,7 @@ module MakeImpl Lang> { strictcount(NodeEx n, FlowState state | Stage4::revFlow(n, state, any(AccessPathFrontHead apf | apf.getHead() = c)) or - flowCandSummaryCtx(n, state, any(AccessPathFrontHead apf | apf.getHead() = c)) + Stage4::nodeMayUseSummary(n, state, any(AccessPathFrontHead apf | apf.getHead() = c)) ) and accessPathApproxCostLimits(apLimit, tupleLimit) and apLimit < tails and @@ -4147,26 +4156,6 @@ module MakeImpl Lang> { private module Stage5 = MkStage::Stage; - pragma[nomagic] - private predicate nodeMayUseSummary0( - NodeEx n, ParamNodeEx p, FlowState state, AccessPathApprox apa - ) { - exists(AccessPathApprox apa0 | - Stage5::parameterMayFlowThrough(p, _) and - Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and - Stage5::fwdFlow(n, state, any(Stage5Param::CcCall ccc), TParamNodeSome(p.asNode()), _, - TAccessPathApproxSome(apa), _, apa0, _) - ) - } - - pragma[nomagic] - private predicate nodeMayUseSummary(NodeEx n, FlowState state, AccessPathApprox apa) { - exists(ParamNodeEx p | - Stage5::parameterMayFlowThrough(p, apa) and - nodeMayUseSummary0(n, p, state, apa) - ) - } - pragma[nomagic] private predicate stage5ConsCand(Content c, DataFlowType t, AccessPathFront apf, int len) { Stage5::consCand(c, t, any(AccessPathApprox ap | ap.getFront() = apf and ap.len() = len - 1)) @@ -4186,7 +4175,7 @@ module MakeImpl Lang> { private int countNodesUsingAccessPath(AccessPathApprox apa) { result = strictcount(NodeEx n, FlowState state | - Stage5::revFlow(n, state, apa) or nodeMayUseSummary(n, state, apa) + Stage5::revFlow(n, state, apa) or Stage5::nodeMayUseSummary(n, state, apa) ) } diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index 434fca9c995..8a82c7b570c 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -1569,11 +1569,6 @@ module MakeImplCommon Lang> { TDataFlowCallNone() or TDataFlowCallSome(DataFlowCall call) - cached - newtype TParamNodeOption = - TParamNodeNone() or - TParamNodeSome(ParamNode p) - cached newtype TReturnCtx = TReturnCtxNone() or @@ -2234,19 +2229,6 @@ module MakeImplCommon Lang> { } } - /** An optional `ParamNode`. */ - class ParamNodeOption extends TParamNodeOption { - string toString() { - this = TParamNodeNone() and - result = "(none)" - or - exists(ParamNode p | - this = TParamNodeSome(p) and - result = p.toString() - ) - } - } - /** * A return context used to calculate flow summaries in reverse flow. * From d84e745ce9bc457ac7ed4afaa1403afbd277bcd4 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Fri, 23 Aug 2024 14:24:51 +0200 Subject: [PATCH 094/404] Make ripunzip installer accessible from outside this repo. * The relative path to misc doesn't work when running from another repo * The buildifier dependency is not available from other repos, therefore we can't pull in //misc/bazel without further refactoring. Therefore, inline the runfiles snippet here. --- misc/ripunzip/BUILD.bazel | 2 +- misc/ripunzip/install.sh | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/misc/ripunzip/BUILD.bazel b/misc/ripunzip/BUILD.bazel index ea21e6b1c94..83317a74e01 100644 --- a/misc/ripunzip/BUILD.bazel +++ b/misc/ripunzip/BUILD.bazel @@ -9,5 +9,5 @@ sh_binary( srcs = ["install.sh"], args = ["$(rlocationpath :ripunzip)"], data = [":ripunzip"], - deps = ["//misc/bazel:sh_runfiles"], + deps = ["@bazel_tools//tools/bash/runfiles"], ) diff --git a/misc/ripunzip/install.sh b/misc/ripunzip/install.sh index 2fb4d48ed6c..45b69f84f78 100755 --- a/misc/ripunzip/install.sh +++ b/misc/ripunzip/install.sh @@ -2,7 +2,16 @@ set -eu -. misc/bazel/runfiles.sh +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- dest="${2:-$HOME/.local/bin}" From 7d500cf58c9fb1dfb8594dca221d02a95dee99d7 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 23 Aug 2024 15:08:10 +0100 Subject: [PATCH 095/404] Kotlin: Remove a redundant 'open' --- java/kotlin-extractor/src/main/kotlin/utils/Logger.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt index 955a34feb1f..44b2a71af8e 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt @@ -279,7 +279,7 @@ open class LoggerBase(val logCounter: LogCounter) { } } -open class Logger(val loggerBase: LoggerBase, open val dtw: DiagnosticTrapWriter) { +open class Logger(val loggerBase: LoggerBase, val dtw: DiagnosticTrapWriter) { fun flush() { dtw.flush() loggerBase.flush() From 6a7d8b53014c1a501c4b6619692a5b0685027506 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 23 Aug 2024 15:41:21 +0100 Subject: [PATCH 096/404] Kotlin: Restrict some TrapWriter types to DiagnosticTrapWriter We never use the greater generality, so this makes it easier to see what's happening. --- .../kotlin-extractor/src/main/kotlin/utils/Logger.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt index 955a34feb1f..3fdf5d29b83 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/Logger.kt @@ -220,26 +220,26 @@ open class LoggerBase(val logCounter: LogCounter) { logStream.write(logMessage.toJsonLine()) } - fun trace(tw: TrapWriter, msg: String) { + fun trace(dtw: DiagnosticTrapWriter, msg: String) { if (verbosity >= 4) { val logMessage = LogMessage("TRACE", msg) - tw.writeComment(logMessage.toText()) + dtw.writeComment(logMessage.toText()) logStream.write(logMessage.toJsonLine()) } } - fun debug(tw: TrapWriter, msg: String) { + fun debug(dtw: DiagnosticTrapWriter, msg: String) { if (verbosity >= 4) { val logMessage = LogMessage("DEBUG", msg) - tw.writeComment(logMessage.toText()) + dtw.writeComment(logMessage.toText()) logStream.write(logMessage.toJsonLine()) } } - fun info(tw: TrapWriter, msg: String) { + fun info(dtw: DiagnosticTrapWriter, msg: String) { if (verbosity >= 3) { val logMessage = LogMessage("INFO", msg) - tw.writeComment(logMessage.toText()) + dtw.writeComment(logMessage.toText()) logStream.write(logMessage.toJsonLine()) } } From 3ac8108c4a4d2d3627b47cd2a0f685173413e539 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Fri, 23 Aug 2024 17:26:05 +0200 Subject: [PATCH 097/404] Address review. --- .github/workflows/buildifier.yml | 2 +- .pre-commit-config.yaml | 2 +- misc/bazel/BUILD.bazel | 10 ---------- misc/bazel/buildifier/BUILD.bazel | 9 +++++++++ misc/ripunzip/BUILD.bazel | 2 +- misc/ripunzip/install.sh | 11 +---------- 6 files changed, 13 insertions(+), 23 deletions(-) create mode 100644 misc/bazel/buildifier/BUILD.bazel diff --git a/.github/workflows/buildifier.yml b/.github/workflows/buildifier.yml index b5d1e2244d5..f3fbf97854c 100644 --- a/.github/workflows/buildifier.yml +++ b/.github/workflows/buildifier.yml @@ -24,5 +24,5 @@ jobs: extra_args: > buildifier --all-files 2>&1 || ( - echo -e "In order to format all bazel files, please run:\n bazel run //misc/bazel:buildifier"; exit 1 + echo -e "In order to format all bazel files, please run:\n bazel run //misc/bazel/buildifier"; exit 1 ) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 62ac0d95779..45935401bee 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: name: Format bazel files files: \.(bazel|bzl) language: system - entry: bazel run //misc/bazel:buildifier + entry: bazel run //misc/bazel/buildifier pass_filenames: false # DISABLED: can be enabled by copying this config and installing `pre-commit` with `--config` on the copy diff --git a/misc/bazel/BUILD.bazel b/misc/bazel/BUILD.bazel index d5c15743903..c3670b75c94 100644 --- a/misc/bazel/BUILD.bazel +++ b/misc/bazel/BUILD.bazel @@ -1,13 +1,3 @@ -load("@buildifier_prebuilt//:rules.bzl", "buildifier") - -buildifier( - name = "buildifier", - exclude_patterns = [ - "./.git/*", - ], - lint_mode = "fix", -) - sh_library( name = "sh_runfiles", srcs = ["runfiles.sh"], diff --git a/misc/bazel/buildifier/BUILD.bazel b/misc/bazel/buildifier/BUILD.bazel new file mode 100644 index 00000000000..3ccdcda5f12 --- /dev/null +++ b/misc/bazel/buildifier/BUILD.bazel @@ -0,0 +1,9 @@ +load("@buildifier_prebuilt//:rules.bzl", "buildifier") + +buildifier( + name = "buildifier", + exclude_patterns = [ + "./.git/*", + ], + lint_mode = "fix", +) diff --git a/misc/ripunzip/BUILD.bazel b/misc/ripunzip/BUILD.bazel index 83317a74e01..ea21e6b1c94 100644 --- a/misc/ripunzip/BUILD.bazel +++ b/misc/ripunzip/BUILD.bazel @@ -9,5 +9,5 @@ sh_binary( srcs = ["install.sh"], args = ["$(rlocationpath :ripunzip)"], data = [":ripunzip"], - deps = ["@bazel_tools//tools/bash/runfiles"], + deps = ["//misc/bazel:sh_runfiles"], ) diff --git a/misc/ripunzip/install.sh b/misc/ripunzip/install.sh index 45b69f84f78..d9ee6dda1cb 100755 --- a/misc/ripunzip/install.sh +++ b/misc/ripunzip/install.sh @@ -2,16 +2,7 @@ set -eu -# --- begin runfiles.bash initialization v3 --- -# Copy-pasted from the Bazel Bash runfiles library v3. -set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash -source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ - source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ - source "$0.runfiles/$f" 2>/dev/null || \ - source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ - source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ - { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e -# --- end runfiles.bash initialization v3 --- +source misc/bazel/runfiles.sh 2>/dev/null || source external/ql~/misc/bazel/runfiles.sh dest="${2:-$HOME/.local/bin}" From c92c96fa788e57fcc47f9010ddfb75b3ff0f3374 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 12 Jul 2024 14:02:54 +0200 Subject: [PATCH 098/404] Data flow: Compute local big step relation per stage --- .../MemoryFreed/UseAfterFree.expected | 1 - .../semmle/tainted/ArithmeticTainted.expected | 2 - .../CWE-338/InsecureRandomness.expected | 2 - .../CWE-1004/CookieWithoutHttpOnly.expected | 55 -- .../CWE-74/DsnInjectionLocal.expected | 1 - .../frameworks/Twirp/RequestForgery.expected | 1 - .../frameworks/XNetHtml/ReflectedXss.expected | 4 - .../Security/CWE-078/StoredCommand.expected | 1 - .../Security/CWE-079/StoredXss.expected | 1 - .../django-orm/ReflectedXss.expected | 1 - .../CodeInjection/CodeInjection.expected | 3 - .../codeql/dataflow/internal/DataFlowImpl.qll | 504 +++++++++--------- .../dataflow/internal/DataFlowImplCommon.qll | 18 +- .../CWE-078/CommandInjection.expected | 14 - 14 files changed, 246 insertions(+), 362 deletions(-) diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected index 05fdfd7f035..891141f56f1 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected @@ -16,7 +16,6 @@ edges | test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:153:5:153:5 | a | provenance | | | test_free.cpp:233:14:233:15 | pointer to free output argument | test_free.cpp:234:9:234:11 | *... ++ | provenance | | | test_free.cpp:234:9:234:11 | *... ++ | test_free.cpp:236:9:236:10 | * ... | provenance | | -| test_free.cpp:238:15:238:17 | *... ++ | test_free.cpp:238:15:238:17 | *... ++ | provenance | | | test_free.cpp:238:15:238:17 | *... ++ | test_free.cpp:241:9:241:10 | * ... | provenance | | | test_free.cpp:239:14:239:15 | pointer to free output argument | test_free.cpp:238:15:238:17 | *... ++ | provenance | | | test_free.cpp:245:10:245:11 | pointer to free output argument | test_free.cpp:246:9:246:10 | * ... | provenance | | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected index b6e6310b779..c60b26aae40 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected @@ -22,11 +22,9 @@ edges | test.c:41:5:41:24 | ... = ... | test.c:44:7:44:10 | len2 | provenance | | | test.c:41:5:41:24 | ... = ... | test.c:44:7:44:12 | ... -- | provenance | | | test.c:44:7:44:12 | ... -- | test.c:44:7:44:10 | len2 | provenance | | -| test.c:44:7:44:12 | ... -- | test.c:44:7:44:12 | ... -- | provenance | | | test.c:51:5:51:24 | ... = ... | test.c:54:7:54:10 | len3 | provenance | | | test.c:51:5:51:24 | ... = ... | test.c:54:7:54:12 | ... -- | provenance | | | test.c:54:7:54:12 | ... -- | test.c:54:7:54:10 | len3 | provenance | | -| test.c:54:7:54:12 | ... -- | test.c:54:7:54:12 | ... -- | provenance | | nodes | test2.cpp:12:21:12:21 | v | semmle.label | v | | test2.cpp:14:11:14:11 | v | semmle.label | v | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected index ab87d7c7254..f1cb229f93a 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected @@ -12,13 +12,11 @@ edges | InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Byte | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | provenance | MaD:1 | | InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | provenance | MaD:3 | | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | provenance | | -| InsecureRandomness.cs:60:13:60:18 | access to local variable result : String | InsecureRandomness.cs:60:13:60:18 | access to local variable result : String | provenance | | | InsecureRandomness.cs:60:13:60:18 | access to local variable result : String | InsecureRandomness.cs:62:16:62:21 | access to local variable result : String | provenance | | | InsecureRandomness.cs:60:23:60:40 | access to array element : String | InsecureRandomness.cs:60:13:60:18 | access to local variable result : String | provenance | | | InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | InsecureRandomness.cs:60:23:60:40 | access to array element : String | provenance | Config | | InsecureRandomness.cs:62:16:62:21 | access to local variable result : String | InsecureRandomness.cs:62:16:62:32 | call to method ToString : String | provenance | MaD:4 | | InsecureRandomness.cs:62:16:62:32 | call to method ToString : String | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | provenance | | -| InsecureRandomness.cs:72:13:72:18 | access to local variable result : String | InsecureRandomness.cs:72:13:72:18 | access to local variable result : String | provenance | | | InsecureRandomness.cs:72:13:72:18 | access to local variable result : String | InsecureRandomness.cs:74:16:74:21 | access to local variable result : String | provenance | | | InsecureRandomness.cs:72:23:72:40 | access to indexer : String | InsecureRandomness.cs:72:13:72:18 | access to local variable result : String | provenance | | | InsecureRandomness.cs:72:31:72:39 | call to method Next : Int32 | InsecureRandomness.cs:72:23:72:40 | access to indexer : String | provenance | Config | diff --git a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected index ee50d6a6e07..467f08e74e6 100644 --- a/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected +++ b/go/ql/test/experimental/CWE-1004/CookieWithoutHttpOnly.expected @@ -3,8 +3,6 @@ edges | CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | | CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | CookieWithoutHttpOnly.go:15:21:15:21 | c | provenance | | | CookieWithoutHttpOnly.go:12:10:12:18 | "session" | CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | | CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:15:21:15:21 | c | provenance | | | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | | @@ -18,10 +16,6 @@ edges | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | | | CookieWithoutHttpOnly.go:20:13:20:21 | "session" | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:22:13:22:17 | false | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | | CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | | | CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | | | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | | @@ -40,10 +34,6 @@ edges | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | | | CookieWithoutHttpOnly.go:29:13:29:21 | "session" | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:31:13:31:16 | true | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | | CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | | | CookieWithoutHttpOnly.go:33:20:33:21 | &... | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | | | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | | @@ -62,10 +52,6 @@ edges | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | | | CookieWithoutHttpOnly.go:38:10:38:18 | "session" | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:41:15:41:18 | true | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | | CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | | | CookieWithoutHttpOnly.go:42:20:42:21 | &... | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | | | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | | @@ -84,10 +70,6 @@ edges | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | | | CookieWithoutHttpOnly.go:47:10:47:18 | "session" | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:50:15:50:19 | false | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | | CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | | | CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | | | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | | @@ -108,10 +90,6 @@ edges | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | | | CookieWithoutHttpOnly.go:57:13:57:21 | "session" | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:59:13:59:15 | val | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | | CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | | | CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | | | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | | @@ -132,10 +110,6 @@ edges | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | | | CookieWithoutHttpOnly.go:67:13:67:21 | "session" | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:69:13:69:15 | val | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | | CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | | | CookieWithoutHttpOnly.go:71:20:71:21 | &... | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | | | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | | @@ -156,10 +130,6 @@ edges | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | | | CookieWithoutHttpOnly.go:77:10:77:18 | "session" | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:80:15:80:17 | val | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | | CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | | | CookieWithoutHttpOnly.go:81:20:81:21 | &... | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | | | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | | @@ -180,10 +150,6 @@ edges | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | | | CookieWithoutHttpOnly.go:87:10:87:18 | "session" | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:90:15:90:17 | val | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | | CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | | | CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | | | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | | @@ -198,8 +164,6 @@ edges | CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | | CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | CookieWithoutHttpOnly.go:100:21:100:21 | c | provenance | | | CookieWithoutHttpOnly.go:99:15:99:19 | false | CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:100:20:100:21 | &... | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | | CookieWithoutHttpOnly.go:100:20:100:21 | &... | CookieWithoutHttpOnly.go:100:21:100:21 | c | provenance | | | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | | @@ -214,10 +178,6 @@ edges | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | | | CookieWithoutHttpOnly.go:106:10:106:13 | name | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:109:15:109:19 | false | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | | CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | | | CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | | | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | | @@ -237,10 +197,6 @@ edges | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | | | CookieWithoutHttpOnly.go:116:10:116:16 | session | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | provenance | Config | | CookieWithoutHttpOnly.go:119:15:119:19 | false | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | provenance | Config | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | -| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | | CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | | | CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | | | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | | @@ -292,8 +248,6 @@ edges | CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | provenance | | | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:134:2:134:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | | | CookieWithoutHttpOnly.go:135:2:135:8 | implicit dereference | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | | @@ -316,7 +270,6 @@ edges | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | Config | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:20:140:2 | &... | provenance | | | CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | provenance | | | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:137:20:140:2 | &... | provenance | | | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:137:20:140:2 | &... | provenance | | @@ -336,7 +289,6 @@ edges | CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | | | CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:146:2:146:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:149:2:149:8 | session | provenance | | | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | | | CookieWithoutHttpOnly.go:147:2:147:8 | session [pointer] | CookieWithoutHttpOnly.go:147:2:147:8 | implicit dereference | provenance | | @@ -348,7 +300,6 @@ edges | CookieWithoutHttpOnly.go:149:2:149:8 | session [pointer] | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:20:151:2 | &... | provenance | | | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:149:20:151:2 | &... | provenance | | | CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | provenance | | | CookieWithoutHttpOnly.go:157:14:157:17 | true | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | provenance | | @@ -371,8 +322,6 @@ edges | CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | provenance | | | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:158:2:158:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | | | CookieWithoutHttpOnly.go:159:2:159:8 | implicit dereference | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | | @@ -395,7 +344,6 @@ edges | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | Config | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:20:164:2 | &... | provenance | | | CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | provenance | | | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:161:20:164:2 | &... | provenance | | | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:161:20:164:2 | &... | provenance | | @@ -421,8 +369,6 @@ edges | CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:202:2:202:6 | store | provenance | | | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | provenance | | | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:170:2:170:8 | definition of session [pointer] | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | provenance | | -| CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | provenance | | | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | | | CookieWithoutHttpOnly.go:171:2:171:8 | implicit dereference | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | | @@ -445,7 +391,6 @@ edges | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference | provenance | Config | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | Config | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session | provenance | Config | -| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:20:176:2 | &... | provenance | | | CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | provenance | | | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:173:20:176:2 | &... | provenance | | | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:173:20:176:2 | &... | provenance | | diff --git a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected index a9d713d9392..7b433794a6c 100644 --- a/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected +++ b/go/ql/test/experimental/CWE-74/DsnInjectionLocal.expected @@ -11,7 +11,6 @@ edges | Dsn.go:62:2:62:4 | definition of cfg [pointer] | Dsn.go:67:102:67:104 | cfg [pointer] | provenance | | | Dsn.go:63:9:63:11 | cfg [pointer] | Dsn.go:63:9:63:11 | implicit dereference | provenance | | | Dsn.go:63:9:63:11 | implicit dereference | Dsn.go:62:2:62:4 | definition of cfg [pointer] | provenance | | -| Dsn.go:63:9:63:11 | implicit dereference | Dsn.go:63:9:63:11 | implicit dereference | provenance | | | Dsn.go:63:9:63:11 | implicit dereference | Dsn.go:67:102:67:108 | selection of dsn | provenance | | | Dsn.go:63:19:63:25 | selection of Args | Dsn.go:63:19:63:29 | slice expression | provenance | | | Dsn.go:63:19:63:29 | slice expression | Dsn.go:63:9:63:11 | implicit dereference | provenance | FunctionModel | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.expected b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.expected index ac8a66d1e2a..93ad219ccfc 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Twirp/RequestForgery.expected @@ -2,7 +2,6 @@ | server/main.go:30:38:30:48 | selection of Text | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | user-provided value | | server/main.go:30:38:30:48 | selection of Text | server/main.go:19:56:19:61 | definition of params | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | server/main.go:19:56:19:61 | definition of params | user-provided value | edges -| client/main.go:16:35:16:78 | &... | client/main.go:16:35:16:78 | &... | provenance | | | client/main.go:16:35:16:78 | &... | server/main.go:19:56:19:61 | definition of params | provenance | | | rpc/notes/service.twirp.go:473:6:473:13 | definition of typedReq | rpc/notes/service.twirp.go:477:44:477:51 | typedReq | provenance | | | rpc/notes/service.twirp.go:477:44:477:51 | typedReq | server/main.go:19:56:19:61 | definition of params | provenance | | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected index cc487a014a0..7cd78374940 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected @@ -50,8 +50,6 @@ edges | test.go:43:2:43:43 | ... := ...[0] | test.go:44:24:44:34 | taintedNode | provenance | | | test.go:43:31:43:42 | selection of Body | test.go:43:2:43:43 | ... := ...[0] | provenance | Src:MaD:15 MaD:3 | | test.go:44:24:44:34 | taintedNode | test.go:42:6:42:14 | definition of cleanNode | provenance | MaD:8 | -| test.go:45:22:45:31 | &... | test.go:45:22:45:31 | &... | provenance | | -| test.go:45:22:45:31 | &... | test.go:45:22:45:31 | &... | provenance | | | test.go:45:22:45:31 | &... | test.go:45:23:45:31 | cleanNode | provenance | | | test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | provenance | | | test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | provenance | | @@ -63,8 +61,6 @@ edges | test.go:48:2:48:44 | ... := ...[0] | test.go:49:26:49:37 | taintedNode2 | provenance | | | test.go:48:32:48:43 | selection of Body | test.go:48:2:48:44 | ... := ...[0] | provenance | Src:MaD:15 MaD:3 | | test.go:49:26:49:37 | taintedNode2 | test.go:47:6:47:15 | definition of cleanNode2 | provenance | MaD:9 | -| test.go:50:22:50:32 | &... | test.go:50:22:50:32 | &... | provenance | | -| test.go:50:22:50:32 | &... | test.go:50:22:50:32 | &... | provenance | | | test.go:50:22:50:32 | &... | test.go:50:23:50:32 | cleanNode2 | provenance | | | test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | provenance | | | test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | provenance | | diff --git a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected index b1c1822ca70..faba4f42251 100644 --- a/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected +++ b/go/ql/test/query-tests/Security/CWE-078/StoredCommand.expected @@ -3,7 +3,6 @@ edges | StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:13:2:13:5 | rows | provenance | | | StoredCommand.go:13:2:13:5 | rows | StoredCommand.go:13:12:13:19 | &... | provenance | FunctionModel | -| StoredCommand.go:13:12:13:19 | &... | StoredCommand.go:13:12:13:19 | &... | provenance | | | StoredCommand.go:13:12:13:19 | &... | StoredCommand.go:14:22:14:28 | cmdName | provenance | Sink:MaD:1 | models | 1 | Sink: os/exec; ; false; Command; ; ; Argument[0]; command-injection; manual | diff --git a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected index dfbfac29d86..efe98650a4e 100644 --- a/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/StoredXss.expected @@ -2,7 +2,6 @@ edges | StoredXss.go:13:21:13:31 | call to Name | StoredXss.go:13:21:13:36 | ...+... | provenance | | | stored.go:18:3:18:28 | ... := ...[0] | stored.go:25:14:25:17 | rows | provenance | | | stored.go:25:14:25:17 | rows | stored.go:25:29:25:33 | &... | provenance | FunctionModel | -| stored.go:25:29:25:33 | &... | stored.go:25:29:25:33 | &... | provenance | | | stored.go:25:29:25:33 | &... | stored.go:30:22:30:25 | name | provenance | | | stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | provenance | | nodes diff --git a/python/ql/test/library-tests/frameworks/django-orm/ReflectedXss.expected b/python/ql/test/library-tests/frameworks/django-orm/ReflectedXss.expected index fb9a00ca180..938e4d2c4e9 100644 --- a/python/ql/test/library-tests/frameworks/django-orm/ReflectedXss.expected +++ b/python/ql/test/library-tests/frameworks/django-orm/ReflectedXss.expected @@ -16,7 +16,6 @@ edges | testapp/orm_security_tests.py:42:13:42:18 | ControlFlowNode for person [Attribute name] | testapp/orm_security_tests.py:43:49:43:54 | ControlFlowNode for person [Attribute name] | provenance | | | testapp/orm_security_tests.py:42:23:42:42 | ControlFlowNode for Attribute() [List element, Attribute age] | testapp/orm_security_tests.py:42:13:42:18 | ControlFlowNode for person [Attribute age] | provenance | | | testapp/orm_security_tests.py:42:23:42:42 | ControlFlowNode for Attribute() [List element, Attribute name] | testapp/orm_security_tests.py:42:13:42:18 | ControlFlowNode for person [Attribute name] | provenance | | -| testapp/orm_security_tests.py:43:13:43:21 | ControlFlowNode for resp_text | testapp/orm_security_tests.py:43:13:43:21 | ControlFlowNode for resp_text | provenance | | | testapp/orm_security_tests.py:43:13:43:21 | ControlFlowNode for resp_text | testapp/orm_security_tests.py:44:29:44:37 | ControlFlowNode for resp_text | provenance | | | testapp/orm_security_tests.py:43:49:43:54 | ControlFlowNode for person [Attribute name] | testapp/orm_security_tests.py:43:49:43:59 | ControlFlowNode for Attribute | provenance | | | testapp/orm_security_tests.py:43:49:43:59 | ControlFlowNode for Attribute | testapp/orm_security_tests.py:43:13:43:21 | ControlFlowNode for resp_text | provenance | | diff --git a/ruby/ql/test/query-tests/security/cwe-094/CodeInjection/CodeInjection.expected b/ruby/ql/test/query-tests/security/cwe-094/CodeInjection/CodeInjection.expected index bec51d351fb..ca8345d92ee 100644 --- a/ruby/ql/test/query-tests/security/cwe-094/CodeInjection/CodeInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-094/CodeInjection/CodeInjection.expected @@ -17,7 +17,6 @@ edges | CodeInjection.rb:38:24:38:27 | code | CodeInjection.rb:38:10:38:28 | call to escape | provenance | MaD:21 | | CodeInjection.rb:38:24:38:27 | code | CodeInjection.rb:38:10:38:28 | call to escape | provenance | MaD:21 | | CodeInjection.rb:78:5:78:8 | code | CodeInjection.rb:80:16:80:19 | code | provenance | | -| CodeInjection.rb:78:5:78:8 | code | CodeInjection.rb:86:10:86:25 | ... + ... | provenance | | | CodeInjection.rb:78:5:78:8 | code | CodeInjection.rb:86:10:86:37 | ... + ... | provenance | | | CodeInjection.rb:78:5:78:8 | code | CodeInjection.rb:86:22:86:25 | code | provenance | | | CodeInjection.rb:78:5:78:8 | code | CodeInjection.rb:88:10:88:32 | "prefix_#{...}_suffix" | provenance | AdditionalTaintStep | @@ -27,7 +26,6 @@ edges | CodeInjection.rb:78:12:78:17 | call to params | CodeInjection.rb:78:12:78:24 | ...[...] | provenance | | | CodeInjection.rb:78:12:78:24 | ...[...] | CodeInjection.rb:78:5:78:8 | code | provenance | | | CodeInjection.rb:78:12:78:24 | ...[...] | CodeInjection.rb:78:5:78:8 | code | provenance | | -| CodeInjection.rb:86:10:86:25 | ... + ... | CodeInjection.rb:86:10:86:37 | ... + ... | provenance | | | CodeInjection.rb:86:10:86:25 | ... + ... [element] | CodeInjection.rb:86:10:86:37 | ... + ... [element] | provenance | | | CodeInjection.rb:86:10:86:37 | ... + ... [element] | CodeInjection.rb:86:10:86:37 | ... + ... | provenance | | | CodeInjection.rb:86:22:86:25 | code | CodeInjection.rb:86:10:86:25 | ... + ... [element] | provenance | | @@ -74,7 +72,6 @@ nodes | CodeInjection.rb:78:12:78:24 | ...[...] | semmle.label | ...[...] | | CodeInjection.rb:78:12:78:24 | ...[...] | semmle.label | ...[...] | | CodeInjection.rb:80:16:80:19 | code | semmle.label | code | -| CodeInjection.rb:86:10:86:25 | ... + ... | semmle.label | ... + ... | | CodeInjection.rb:86:10:86:25 | ... + ... [element] | semmle.label | ... + ... [element] | | CodeInjection.rb:86:10:86:37 | ... + ... | semmle.label | ... + ... | | CodeInjection.rb:86:10:86:37 | ... + ... [element] | semmle.label | ... + ... [element] | diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 379a618dbdf..8280f1a9da2 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1068,18 +1068,6 @@ module MakeImpl Lang> { if label1 = "" then result = label2 else result = label1 } - pragma[noinline] - private predicate localFlowStepNodeCand1(NodeEx node1, NodeEx node2, string model) { - Stage1::revFlow(node2) and - localFlowStepEx(node1, node2, model) - } - - pragma[noinline] - private predicate additionalLocalFlowStepNodeCand1(NodeEx node1, NodeEx node2, string model) { - Stage1::revFlow(node2) and - additionalLocalFlowStep(node1, node2, model) - } - pragma[nomagic] private predicate viableReturnPosOutNodeCand1(DataFlowCall call, ReturnPosition pos, NodeEx out) { Stage1::revFlow(out) and @@ -1376,8 +1364,6 @@ module MakeImpl Lang> { predicate instanceofCcNoCall(CcNoCall cc); - class LocalCc; - DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CcCall ctx); bindingset[call, ctx] @@ -1394,13 +1380,13 @@ module MakeImpl Lang> { CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call); bindingset[cc] - LocalCc getLocalCc(Cc cc); + LocalCallContext getLocalCc(Cc cc); bindingset[node1, state1] bindingset[node2, state2] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - Typ t, LocalCc lcc, string label + DataFlowType t, LocalCallContext lcc, string label ); bindingset[node, state, t0, ap] @@ -1503,6 +1489,18 @@ module MakeImpl Lang> { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } + bindingset[node1, state1] + bindingset[node2, state2] + additional predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + Typ t, LocalCallContext lcc, string label + ) { + exists(DataFlowType type | + Param::localStep(node1, state1, node2, state2, preservesValue, type, lcc, label) and + t = getTyp(type) + ) + } + pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -1517,7 +1515,7 @@ module MakeImpl Lang> { ap instanceof ApNil and apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | + exists(NodeEx mid, FlowState state0, Typ t0, LocalCallContext localCc | fwdFlow(mid, state0, cc, summaryCtx, argT, argAp, t0, ap, apa) and localCc = getLocalCc(cc) | @@ -2532,6 +2530,173 @@ module MakeImpl Lang> { callEdgeReturn(call, c, _, _, _, _, _) } + /** Provides a big-step relation for local flow steps. */ + additional module LocalFlowBigStep { + final private class NodeExFinal = NodeEx; + + /** + * A node where some checking is required, and hence the big-step relation + * is not allowed to step over. + */ + private class FlowCheckNode extends NodeExFinal { + FlowCheckNode() { + revFlow(this, _, _) and + ( + castNode(this.asNode()) or + clearsContentCached(this.asNode(), _) or + expectsContentCached(this.asNode(), _) or + neverSkipInPathGraph(this.asNode()) or + Config::neverSkip(this.asNode()) + ) + } + } + + private predicate additionalLocalStateStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, DataFlowType t, + LocalCallContext lcc, string label + ) { + exists(ApNil nil | + revFlow(node1, state1, pragma[only_bind_into](nil)) and + revFlow(node2, state2, pragma[only_bind_into](nil)) and + Param::localStep(node1, state1, node2, state2, false, t, lcc, label) and + state1 != state2 + ) + } + + /** + * Holds if `node` can be the first node in a maximal subsequence of local + * flow steps in a dataflow path. + */ + private predicate localFlowEntry(NodeEx node, FlowState state, Ap ap) { + revFlow(node, state, ap) and + ( + sourceNode(node, state) + or + jumpStepEx(_, node) + or + additionalJumpStep(_, node, _) + or + additionalJumpStateStep(_, _, node, state) + or + node instanceof ParamNodeEx + or + node.asNode() instanceof OutNodeExt + or + storeStepCand(_, _, _, node, _, _) + or + readStepCand(_, _, node) + or + node instanceof FlowCheckNode + or + exists(FlowState s | + additionalLocalStateStep(_, s, node, state, _, _, _) and + s != state + ) + ) + } + + /** + * Holds if `node` can be the last node in a maximal subsequence of local + * flow steps in a dataflow path. + */ + private predicate localFlowExit(NodeEx node, FlowState state, Ap ap) { + revFlow(node, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and + ( + exists(NodeEx next, Ap apNext | revFlow(next, pragma[only_bind_into](state), apNext) | + jumpStepEx(node, next) and + apNext = ap + or + additionalJumpStep(node, next, _) and + apNext = ap and + ap instanceof ApNil + or + callEdgeArgParam(_, _, node, next, _, ap) and + apNext = ap + or + callEdgeReturn(_, _, node, _, next, _, ap) and + apNext = ap + or + storeStepCand(node, _, _, next, _, _) + or + readStepCand(node, _, next) + ) + or + exists(NodeEx next, FlowState s | + revFlow(next, s, pragma[only_bind_into](ap)) and ap instanceof ApNil + | + additionalJumpStateStep(node, state, next, s) + or + additionalLocalStateStep(node, state, next, s) and + s != state + ) + or + node instanceof FlowCheckNode + or + sinkNode(node, state) and + ap instanceof ApNil + ) + } + + /** + * Holds if the local path from `node1` to `node2` is a prefix of a maximal + * subsequence of local flow steps in a dataflow path. + * + * This is the transitive closure of `[additional]localFlowStep` beginning + * at `localFlowEntry`. + */ + pragma[nomagic] + private predicate localFlowStepPlus( + NodeEx node1, FlowState state, NodeEx node2, boolean preservesValue, DataFlowType t, + LocalCallContext cc, string label + ) { + not inBarrier(node2, state) and + not outBarrier(node1, state) and + exists(NodeEx node0, boolean preservesValue0, DataFlowType t0, string label0, Ap ap | + Param::localStep(node0, state, node2, state, preservesValue0, t0, cc, label0) and + revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and + not outBarrier(node0, state) and + (preservesValue = true or ap instanceof ApNil) + | + node1 = node0 and + localFlowEntry(node1, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and + preservesValue = preservesValue0 and + label = label0 and + t = t0 and + node1 != node2 + or + exists(boolean preservesValue1, DataFlowType t1, string label1 | + localFlowStepPlus(node1, pragma[only_bind_into](state), node0, preservesValue1, t1, + cc, label1) and + not node0 instanceof FlowCheckNode and + preservesValue = preservesValue0.booleanAnd(preservesValue1) and + label = mergeLabels(label1, label0) and + if preservesValue0 = true then t = t1 else t = t0 + ) + ) + } + + /** + * Holds if `node1` can step to `node2` in one or more local steps and this + * path can occur as a maximal subsequence of local steps in a dataflow path. + */ + pragma[nomagic] + predicate localFlowBigStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + DataFlowType t, LocalCallContext callContext, string label + ) { + exists(Ap ap | + localFlowStepPlus(node1, state1, node2, preservesValue, t, callContext, label) and + localFlowExit(node2, state1, ap) and + state1 = state2 + | + preservesValue = true or ap instanceof ApNil + ) + or + additionalLocalStateStep(node1, state1, node2, state2, t, callContext, label) and + preservesValue = false + } + } + /** * INTERNAL: Only for debugging. * @@ -2888,7 +3053,7 @@ module MakeImpl Lang> { PathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, string label, boolean isStoreStep ) { - exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | + exists(NodeEx mid, FlowState state0, Typ t0, LocalCallContext localCc | pn1 = TPathNodeMid(mid, state0, cc, summaryCtx, argT, argAp, t0, ap) and localCc = getLocalCc(cc) and isStoreStep = false @@ -3358,10 +3523,13 @@ module MakeImpl Lang> { predicate instanceofCcNoCall(CcNoCall cc) { any() } - class LocalCc = Unit; - bindingset[cc] - LocalCc getLocalCc(Cc cc) { any() } + LocalCallContext getLocalCc(Cc cc) { + cc = ccSomeCall() and + result instanceof LocalCallContextSpecificCall + or + result instanceof LocalCallContextAny + } DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CcCall ctx) { none() } @@ -3417,29 +3585,63 @@ module MakeImpl Lang> { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } import CachedCallContextSensitivity - import NoLocalCallContext + import LocalCallContext + + pragma[noinline] + private predicate localFlowStepNodeCand1(NodeEx node1, NodeEx node2, string model) { + Stage1::revFlow(node2) and + localFlowStepEx(node1, node2, model) + } + + pragma[nomagic] + private predicate additionalLocalFlowStepNodeCand1(NodeEx node1, NodeEx node2, string model) { + Stage1::revFlow(node2) and + additionalLocalFlowStep(node1, node2, model) + } + + pragma[nomagic] + private predicate localStep( + NodeEx node1, NodeEx node2, boolean preservesValue, DataFlowType t, LocalCallContext lcc, + string label + ) { + ( + preservesValue = true and + localFlowStepNodeCand1(node1, node2, label) and + t = node1.getDataFlowType() + or + preservesValue = false and + additionalLocalFlowStepNodeCand1(node1, node2, label) and + t = node2.getDataFlowType() + ) and + lcc.relevantFor(node1.getEnclosingCallable()) and + not isUnreachableInCall1(node1, lcc) and + not isUnreachableInCall1(node2, lcc) + } + + pragma[nomagic] + private predicate localStateStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + DataFlowType t, LocalCallContext lcc, string label + ) { + preservesValue = false and + additionalLocalStateStep(node1, state1, node2, state2) and + label = "Config" and + t = node2.getDataFlowType() and + lcc.relevantFor(node1.getEnclosingCallable()) and + not isUnreachableInCall1(node1, lcc) and + not isUnreachableInCall1(node2, lcc) + } bindingset[node1, state1] bindingset[node2, state2] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - Typ t, LocalCc lcc, string label + DataFlowType t, LocalCallContext lcc, string label ) { - ( - preservesValue = true and - localFlowStepNodeCand1(node1, node2, label) and - state1 = state2 - or - preservesValue = false and - additionalLocalFlowStepNodeCand1(node1, node2, label) and - state1 = state2 - or - preservesValue = false and - additionalLocalStateStep(node1, state1, node2, state2) and - label = "Config" - ) and - exists(t) and - exists(lcc) + localStep(node1, node2, preservesValue, t, lcc, label) and + state1 = state2 + or + localStateStep(node1, state1, node2, state2, preservesValue, t, lcc, label) } pragma[nomagic] @@ -3476,192 +3678,6 @@ module MakeImpl Lang> { private module Stage2 = MkStage::Stage; - pragma[nomagic] - private predicate flowOutOfCallNodeCand2( - DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2, boolean allowsFieldFlow - ) { - flowOutOfCallNodeCand1(call, node1, kind, node2, allowsFieldFlow) and - Stage2::revFlow(node2) and - Stage2::revFlow(node1) - } - - pragma[nomagic] - private predicate flowIntoCallNodeCand2( - DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow - ) { - flowIntoCallNodeCand1(call, node1, node2, allowsFieldFlow) and - Stage2::revFlow(node2) and - Stage2::revFlow(node1) - } - - private module LocalFlowBigStep { - /** - * A node where some checking is required, and hence the big-step relation - * is not allowed to step over. - */ - private class FlowCheckNode extends NodeEx { - FlowCheckNode() { - castNode(this.asNode()) or - clearsContentCached(this.asNode(), _) or - expectsContentCached(this.asNode(), _) or - neverSkipInPathGraph(this.asNode()) or - Config::neverSkip(this.asNode()) - } - } - - /** - * Holds if `node` can be the first node in a maximal subsequence of local - * flow steps in a dataflow path. - */ - private predicate localFlowEntry(NodeEx node, FlowState state) { - Stage2::revFlow(node, state) and - ( - sourceNode(node, state) - or - jumpStepEx(_, node) - or - additionalJumpStep(_, node, _) - or - additionalJumpStateStep(_, _, node, state) - or - node instanceof ParamNodeEx - or - node.asNode() instanceof OutNodeExt - or - Stage2::storeStepCand(_, _, _, node, _, _) - or - Stage2::readStepCand(_, _, node) - or - node instanceof FlowCheckNode - or - exists(FlowState s | - additionalLocalStateStep(_, s, node, state) and - s != state - ) - ) - } - - /** - * Holds if `node` can be the last node in a maximal subsequence of local - * flow steps in a dataflow path. - */ - private predicate localFlowExit(NodeEx node, FlowState state) { - exists(NodeEx next | Stage2::revFlow(next, state) | - jumpStepEx(node, next) or - additionalJumpStep(node, next, _) or - flowIntoCallNodeCand2(_, node, next, _) or - flowOutOfCallNodeCand2(_, node, _, next, _) or - Stage2::storeStepCand(node, _, _, next, _, _) or - Stage2::readStepCand(node, _, next) - ) - or - exists(NodeEx next, FlowState s | Stage2::revFlow(next, s) | - additionalJumpStateStep(node, state, next, s) - or - additionalLocalStateStep(node, state, next, s) and - s != state - ) - or - Stage2::revFlow(node, state) and - node instanceof FlowCheckNode - or - sinkNode(node, state) - } - - pragma[noinline] - private predicate additionalLocalFlowStepNodeCand2( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, string label - ) { - additionalLocalFlowStepNodeCand1(node1, node2, label) and - state1 = state2 and - Stage2::revFlow(node1, pragma[only_bind_into](state1), false) and - Stage2::revFlow(node2, pragma[only_bind_into](state2), false) - or - additionalLocalStateStep(node1, state1, node2, state2) and - label = "Config" and - Stage2::revFlow(node1, state1, false) and - Stage2::revFlow(node2, state2, false) - } - - /** - * Holds if the local path from `node1` to `node2` is a prefix of a maximal - * subsequence of local flow steps in a dataflow path. - * - * This is the transitive closure of `[additional]localFlowStep` beginning - * at `localFlowEntry`. - */ - pragma[nomagic] - private predicate localFlowStepPlus( - NodeEx node1, FlowState state, NodeEx node2, boolean preservesValue, DataFlowType t, - LocalCallContext cc, string label - ) { - not isUnreachableInCall1(node2, cc) and - not inBarrier(node2, state) and - not outBarrier(node1, state) and - ( - localFlowEntry(node1, pragma[only_bind_into](state)) and - ( - localFlowStepNodeCand1(node1, node2, label) and - preservesValue = true and - t = node1.getDataFlowType() and // irrelevant dummy value - Stage2::revFlow(node2, pragma[only_bind_into](state)) - or - additionalLocalFlowStepNodeCand2(node1, state, node2, state, label) and - preservesValue = false and - t = node2.getDataFlowType() - ) and - node1 != node2 and - cc.relevantFor(node1.getEnclosingCallable()) and - not isUnreachableInCall1(node1, cc) and - not outBarrier(node1, state) - or - exists(NodeEx mid, string label1, string label2 | - localFlowStepPlus(node1, pragma[only_bind_into](state), mid, preservesValue, t, cc, - label1) and - localFlowStepNodeCand1(mid, node2, label2) and - not outBarrier(mid, state) and - not mid instanceof FlowCheckNode and - Stage2::revFlow(node2, pragma[only_bind_into](state)) and - label = mergeLabels(label1, label2) - ) - or - exists(NodeEx mid, string label1, string label2 | - localFlowStepPlus(node1, state, mid, _, _, cc, label1) and - additionalLocalFlowStepNodeCand2(mid, state, node2, state, label2) and - not outBarrier(mid, state) and - not mid instanceof FlowCheckNode and - preservesValue = false and - t = node2.getDataFlowType() and - label = mergeLabels(label1, label2) - ) - ) - } - - /** - * Holds if `node1` can step to `node2` in one or more local steps and this - * path can occur as a maximal subsequence of local steps in a dataflow path. - */ - pragma[nomagic] - predicate localFlowBigStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCallContext callContext, string label - ) { - localFlowStepPlus(node1, state1, node2, preservesValue, t, callContext, label) and - localFlowExit(node2, state1) and - state1 = state2 - or - additionalLocalFlowStepNodeCand2(node1, state1, node2, state2, label) and - state1 != state2 and - preservesValue = false and - t = node2.getDataFlowType() and - callContext.relevantFor(node1.getEnclosingCallable()) and - not isUnreachableInCall1(node1, callContext) and - not isUnreachableInCall1(node2, callContext) - } - } - - private import LocalFlowBigStep - pragma[nomagic] private predicate castingNodeEx(NodeEx node) { node.asNode() instanceof CastingNode or exists(node.asParamReturnNode()) @@ -3709,16 +3725,9 @@ module MakeImpl Lang> { } import CallContextSensitivity - import NoLocalCallContext + import LocalCallContext - predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - Typ t, LocalCc lcc, string label - ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, _, _, label) and - exists(t) and - exists(lcc) - } + predicate localStep = PrevStage::LocalFlowBigStep::localFlowBigStep/8; pragma[nomagic] private predicate expectsContentCand(NodeEx node, Ap ap) { @@ -3800,16 +3809,7 @@ module MakeImpl Lang> { import BooleanCallContext - pragma[nomagic] - predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - Typ t, LocalCc lcc, string label - ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _, label) and - PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and - PrevStage::revFlow(node2, pragma[only_bind_into](state2), _) and - exists(lcc) - } + predicate localStep = PrevStage::LocalFlowBigStep::localFlowBigStep/8; pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c) { @@ -4113,14 +4113,7 @@ module MakeImpl Lang> { import CallContextSensitivity import LocalCallContext - predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - Typ t, LocalCc lcc, string label - ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc, label) and - PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and - PrevStage::revFlow(node2, pragma[only_bind_into](state2), _) - } + predicate localStep = PrevStage::LocalFlowBigStep::localFlowBigStep/8; bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { @@ -4338,14 +4331,7 @@ module MakeImpl Lang> { import CallContextSensitivity import LocalCallContext - predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - Typ t, LocalCc lcc, string label - ) { - localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc, label) and - PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and - PrevStage::revFlow(node2, pragma[only_bind_into](state2), _) - } + predicate localStep = PrevStage::LocalFlowBigStep::localFlowBigStep/8; bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index 434fca9c995..5fe86520882 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -778,23 +778,7 @@ module MakeImplCommon Lang> { recordDataFlowCallSiteDispatch(call, c) } - module NoLocalCallContext { - class LocalCc = Unit; - - bindingset[cc] - LocalCc getLocalCc(CallContext cc) { any() } - - bindingset[call, c] - CallContextCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { - if recordDataFlowCallSiteDispatch(call, c) - then result = Input2::getSpecificCallContextCall(call, c) - else result = TSomeCall() - } - } - module LocalCallContext { - class LocalCc = LocalCallContext; - private UnreachableSet getUnreachable(CallContext ctx) { exists(UnreachableSetOption unreachable | ctx = TSpecificCall(_, _, unreachable) | result = unreachable.asSome() @@ -810,7 +794,7 @@ module MakeImplCommon Lang> { bindingset[cc] pragma[inline_late] - LocalCc getLocalCc(CallContext cc) { result = getLocalCallContext(cc) } + LocalCallContext getLocalCc(CallContext cc) { result = getLocalCallContext(cc) } bindingset[call, c] CallContextCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { diff --git a/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index f9c1f7bd175..0fe8ae7b868 100644 --- a/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -44,7 +44,6 @@ edges | CommandInjection.swift:105:12:105:12 | userControlledString | CommandInjection.swift:137:36:137:36 | userControlledString | provenance | | | CommandInjection.swift:105:12:105:12 | userControlledString | CommandInjection.swift:138:21:138:21 | userControlledString | provenance | | | CommandInjection.swift:105:12:105:12 | userControlledString | CommandInjection.swift:139:22:139:22 | userControlledString | provenance | | -| CommandInjection.swift:105:12:105:12 | userControlledString | CommandInjection.swift:140:24:140:24 | userControlledString | provenance | | | CommandInjection.swift:105:12:105:12 | userControlledString | CommandInjection.swift:150:42:150:42 | userControlledString | provenance | | | CommandInjection.swift:105:12:105:12 | userControlledString | CommandInjection.swift:151:75:151:75 | userControlledString | provenance | | | CommandInjection.swift:105:12:105:12 | userControlledString | CommandInjection.swift:154:35:154:35 | userControlledString | provenance | | @@ -65,7 +64,6 @@ edges | CommandInjection.swift:105:40:105:94 | call to String.init(contentsOf:) | CommandInjection.swift:137:36:137:36 | userControlledString | provenance | | | CommandInjection.swift:105:40:105:94 | call to String.init(contentsOf:) | CommandInjection.swift:138:21:138:21 | userControlledString | provenance | | | CommandInjection.swift:105:40:105:94 | call to String.init(contentsOf:) | CommandInjection.swift:139:22:139:22 | userControlledString | provenance | | -| CommandInjection.swift:105:40:105:94 | call to String.init(contentsOf:) | CommandInjection.swift:140:24:140:24 | userControlledString | provenance | | | CommandInjection.swift:105:40:105:94 | call to String.init(contentsOf:) | CommandInjection.swift:150:42:150:42 | userControlledString | provenance | | | CommandInjection.swift:105:40:105:94 | call to String.init(contentsOf:) | CommandInjection.swift:151:75:151:75 | userControlledString | provenance | | | CommandInjection.swift:105:40:105:94 | call to String.init(contentsOf:) | CommandInjection.swift:154:35:154:35 | userControlledString | provenance | | @@ -110,14 +108,6 @@ edges | CommandInjection.swift:138:21:138:21 | userControlledString | CommandInjection.swift:138:20:138:41 | [...] [Collection element] | provenance | | | CommandInjection.swift:139:21:139:42 | [...] [Collection element] | CommandInjection.swift:99:20:99:40 | arguments [Collection element] | provenance | | | CommandInjection.swift:139:22:139:22 | userControlledString | CommandInjection.swift:139:21:139:42 | [...] [Collection element] | provenance | | -| CommandInjection.swift:140:24:140:24 | userControlledString | CommandInjection.swift:150:42:150:42 | userControlledString | provenance | | -| CommandInjection.swift:140:24:140:24 | userControlledString | CommandInjection.swift:151:75:151:75 | userControlledString | provenance | | -| CommandInjection.swift:140:24:140:24 | userControlledString | CommandInjection.swift:154:35:154:35 | userControlledString | provenance | | -| CommandInjection.swift:140:24:140:24 | userControlledString | CommandInjection.swift:155:70:155:70 | userControlledString | provenance | | -| CommandInjection.swift:140:24:140:24 | userControlledString | CommandInjection.swift:160:53:160:53 | userControlledString | provenance | | -| CommandInjection.swift:140:24:140:24 | userControlledString | CommandInjection.swift:163:52:163:52 | userControlledString | provenance | | -| CommandInjection.swift:140:24:140:24 | userControlledString | CommandInjection.swift:164:33:164:33 | userControlledString | provenance | | -| CommandInjection.swift:140:24:140:24 | userControlledString | CommandInjection.swift:166:57:166:57 | userControlledString | provenance | | | CommandInjection.swift:151:67:151:95 | [...] [Collection element] | CommandInjection.swift:151:67:151:95 | [...] | provenance | | | CommandInjection.swift:151:75:151:75 | userControlledString | CommandInjection.swift:151:67:151:95 | [...] [Collection element] | provenance | | | CommandInjection.swift:154:23:154:55 | call to URL.init(string:) [some:0] | CommandInjection.swift:154:23:154:56 | ...! | provenance | | @@ -158,11 +148,8 @@ edges | CommandInjection.swift:205:19:205:19 | userControlledString | CommandInjection.swift:205:18:205:39 | [...] [Collection element] | provenance | | | CommandInjection.swift:207:3:207:3 | [post] getter for .p1 [arguments, Collection element] | CommandInjection.swift:207:3:207:3 | [post] getter for .p1 | provenance | | | CommandInjection.swift:207:18:207:18 | tainted1 [Collection element] | CommandInjection.swift:207:3:207:3 | [post] getter for .p1 [arguments, Collection element] | provenance | | -| CommandInjection.swift:207:18:207:18 | tainted1 [Collection element] | CommandInjection.swift:208:19:208:19 | tainted1 [Collection element] | provenance | | -| CommandInjection.swift:207:18:207:18 | tainted1 [Collection element] | CommandInjection.swift:209:18:209:18 | tainted1 [Collection element] | provenance | | | CommandInjection.swift:208:3:208:5 | [post] ...! [arguments, Collection element] | CommandInjection.swift:208:3:208:5 | [post] ...! | provenance | | | CommandInjection.swift:208:19:208:19 | tainted1 [Collection element] | CommandInjection.swift:208:3:208:5 | [post] ...! [arguments, Collection element] | provenance | | -| CommandInjection.swift:208:19:208:19 | tainted1 [Collection element] | CommandInjection.swift:209:18:209:18 | tainted1 [Collection element] | provenance | | | CommandInjection.swift:209:3:209:3 | [post] ...! [arguments, Collection element] | CommandInjection.swift:209:3:209:3 | [post] ...! | provenance | | | CommandInjection.swift:209:18:209:18 | tainted1 [Collection element] | CommandInjection.swift:209:3:209:3 | [post] ...! [arguments, Collection element] | provenance | | | CommandInjection.swift:211:30:211:51 | [...] [Collection element] | CommandInjection.swift:213:18:213:18 | tainted2 [Collection element] | provenance | | @@ -259,7 +246,6 @@ nodes | CommandInjection.swift:138:21:138:21 | userControlledString | semmle.label | userControlledString | | CommandInjection.swift:139:21:139:42 | [...] [Collection element] | semmle.label | [...] [Collection element] | | CommandInjection.swift:139:22:139:22 | userControlledString | semmle.label | userControlledString | -| CommandInjection.swift:140:24:140:24 | userControlledString | semmle.label | userControlledString | | CommandInjection.swift:150:42:150:42 | userControlledString | semmle.label | userControlledString | | CommandInjection.swift:151:67:151:95 | [...] | semmle.label | [...] | | CommandInjection.swift:151:67:151:95 | [...] [Collection element] | semmle.label | [...] [Collection element] | From 128053e2145ac2bd5d4536a09e02248fd8e54dcd Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 26 Aug 2024 08:41:37 +0200 Subject: [PATCH 099/404] C++: Add basic modeling of functions that don't throw --- .../code/cpp/models/implementations/Memcpy.qll | 3 ++- .../code/cpp/models/implementations/Memset.qll | 3 ++- .../cpp/models/implementations/NoexceptFunction.qll | 11 +++++++++++ .../code/cpp/models/interfaces/NonThrowing.qll | 13 +++++++++++++ .../CWE/CWE-570/IncorrectAllocationErrorHandling.ql | 10 +++++----- .../2024-08-26-non-throwing-functions.md | 4 ++++ .../IncorrectAllocationErrorHandling.expected | 1 + .../test/query-tests/Security/CWE/CWE-570/test.cpp | 2 +- 8 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll create mode 100644 cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll create mode 100644 cpp/ql/src/change-notes/2024-08-26-non-throwing-functions.md diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll index 2c47587f42e..0bf2dd31fe4 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll @@ -9,13 +9,14 @@ import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant * `__builtin___memcpy_chk`. */ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction, - AliasFunction + AliasFunction, NonThrowingFunction { MemcpyFunction() { // memcpy(dest, src, num) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll index 965ac8daf3b..ab2e0af99f3 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll @@ -8,9 +8,10 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect +import semmle.code.cpp.models.interfaces.NonThrowing private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction, - SideEffectFunction + SideEffectFunction, NonThrowingFunction { MemsetFunctionModel() { this.hasGlobalOrStdOrBslName("memset") diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll new file mode 100644 index 00000000000..b0f76ee6538 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/NoexceptFunction.qll @@ -0,0 +1,11 @@ +import semmle.code.cpp.models.interfaces.NonThrowing + +/** + * A function that is annotated with a `noexcept` specifier (or the equivalent + * `throw()` specifier) guaranteeing that the function can not throw exceptions. + * + * Note: The `throw` specifier was deprecated in C++11 and removed in C++17. + */ +class NoexceptFunction extends NonThrowingFunction { + NoexceptFunction() { this.isNoExcept() or this.isNoThrow() } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll new file mode 100644 index 00000000000..f3ec13b5bd5 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll @@ -0,0 +1,13 @@ +/** + * Provides an abstract class for modeling functions that never throws. + * + * See also `ThrowingFunction` for modeling functions that do throw. + */ + +import semmle.code.cpp.Function +import semmle.code.cpp.models.Models + +/** + * A function that is guaranteed to never throw. + */ +abstract class NonThrowingFunction extends Function { } diff --git a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql index 7f74c229ceb..73d9f2386a4 100644 --- a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql +++ b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql @@ -16,6 +16,8 @@ import cpp import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.controlflow.Guards +import semmle.code.cpp.models.interfaces.NonThrowing +import semmle.code.cpp.models.implementations.NoexceptFunction /** Gets the `Constructor` invoked when `newExpr` allocates memory. */ Constructor getConstructorForAllocation(NewOrNewArrayExpr newExpr) { @@ -44,9 +46,8 @@ predicate deleteMayThrow(DeleteOrDeleteArrayExpr deleteExpr) { * like it might throw an exception, and the function does not have a `noexcept` or `throw()` specifier. */ predicate functionMayThrow(Function f) { - (not exists(f.getBlock()) or stmtMayThrow(f.getBlock())) and - not f.isNoExcept() and - not f.isNoThrow() + not f instanceof NonThrowingFunction and + (not exists(f.getBlock()) or stmtMayThrow(f.getBlock())) } /** Holds if the evaluation of `stmt` may throw an exception. */ @@ -172,8 +173,7 @@ class ThrowingAllocator extends Function { not exists(Parameter p | p = this.getAParameter() | p.getUnspecifiedType().stripType() instanceof NoThrowType ) and - not this.isNoExcept() and - not this.isNoThrow() + not this instanceof NoexceptFunction ) } } diff --git a/cpp/ql/src/change-notes/2024-08-26-non-throwing-functions.md b/cpp/ql/src/change-notes/2024-08-26-non-throwing-functions.md new file mode 100644 index 00000000000..94acaaecc81 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-08-26-non-throwing-functions.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Add modeling of C functions that don't throw, thereby increasing the precision of the `cpp/incorrect-allocation-error-handling` ("Incorrect allocation-error handling") query. The query now produces additional true positives. \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.expected index 991ff2de8a4..53907bfeb40 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.expected @@ -17,3 +17,4 @@ | test.cpp:229:15:229:35 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:231:16:231:19 | { ... } | This catch block | | test.cpp:242:14:242:34 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:243:34:243:36 | { ... } | This catch block | | test.cpp:276:17:276:31 | new[] | This allocation cannot return null. $@ is unnecessary. | test.cpp:277:8:277:12 | ! ... | This check | +| test.cpp:288:19:288:47 | new[] | This allocation cannot throw. $@ is unnecessary. | test.cpp:291:30:293:5 | { ... } | This catch block | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-570/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-570/test.cpp index 977b6e878a2..9df901ca5a9 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-570/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-570/test.cpp @@ -282,7 +282,7 @@ namespace qhelp { } // BAD: the allocation won't throw an exception, but - // instead return a null pointer. [NOT DETECTED] + // instead return a null pointer. void bad2(std::size_t length) noexcept { try { int* dest = new(std::nothrow) int[length]; From e5d626f9079a65e5a658c662ac2d3a3c449f6701 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 26 Aug 2024 09:15:16 +0200 Subject: [PATCH 100/404] Data flow: Only recompute local big step in stage 6 --- .../codeql/dataflow/internal/DataFlowImpl.qll | 222 +++++++++++------- .../dataflow/internal/DataFlowImplCommon.qll | 18 +- 2 files changed, 157 insertions(+), 83 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 8280f1a9da2..9c50d245aa5 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1068,6 +1068,42 @@ module MakeImpl Lang> { if label1 = "" then result = label2 else result = label1 } + pragma[nomagic] + private predicate localStepNodeCand1( + NodeEx node1, NodeEx node2, boolean preservesValue, DataFlowType t, LocalCallContext lcc, + string label + ) { + Stage1::revFlow(node1) and + Stage1::revFlow(node2) and + ( + preservesValue = true and + localFlowStepEx(node1, node2, label) and + t = node1.getDataFlowType() + or + preservesValue = false and + additionalLocalFlowStep(node1, node2, label) and + t = node2.getDataFlowType() + ) and + lcc.relevantFor(node1.getEnclosingCallable()) and + not isUnreachableInCall1(node1, lcc) and + not isUnreachableInCall1(node2, lcc) + } + + pragma[nomagic] + private predicate localStateStepNodeCand1( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, DataFlowType t, + LocalCallContext lcc, string label + ) { + Stage1::revFlow(node1) and + Stage1::revFlow(node2) and + additionalLocalStateStep(node1, state1, node2, state2) and + label = "Config" and + t = node2.getDataFlowType() and + lcc.relevantFor(node1.getEnclosingCallable()) and + not isUnreachableInCall1(node1, lcc) and + not isUnreachableInCall1(node2, lcc) + } + pragma[nomagic] private predicate viableReturnPosOutNodeCand1(DataFlowCall call, ReturnPosition pos, NodeEx out) { Stage1::revFlow(out) and @@ -1364,6 +1400,8 @@ module MakeImpl Lang> { predicate instanceofCcNoCall(CcNoCall cc); + class LocalCc; + DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CcCall ctx); bindingset[call, ctx] @@ -1380,13 +1418,13 @@ module MakeImpl Lang> { CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call); bindingset[cc] - LocalCallContext getLocalCc(Cc cc); + LocalCc getLocalCc(Cc cc); bindingset[node1, state1] bindingset[node2, state2] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCallContext lcc, string label + Typ t, LocalCc lcc, string label ); bindingset[node, state, t0, ap] @@ -1489,18 +1527,6 @@ module MakeImpl Lang> { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } - bindingset[node1, state1] - bindingset[node2, state2] - additional predicate localStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - Typ t, LocalCallContext lcc, string label - ) { - exists(DataFlowType type | - Param::localStep(node1, state1, node2, state2, preservesValue, type, lcc, label) and - t = getTyp(type) - ) - } - pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -1515,7 +1541,7 @@ module MakeImpl Lang> { ap instanceof ApNil and apa = getApprox(ap) or - exists(NodeEx mid, FlowState state0, Typ t0, LocalCallContext localCc | + exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | fwdFlow(mid, state0, cc, summaryCtx, argT, argAp, t0, ap, apa) and localCc = getLocalCc(cc) | @@ -2530,8 +2556,24 @@ module MakeImpl Lang> { callEdgeReturn(call, c, _, _, _, _, _) } - /** Provides a big-step relation for local flow steps. */ - additional module LocalFlowBigStep { + /** Provides the input to `LocalFlowBigStep`. */ + signature module LocalFlowBigStepInputSig { + bindingset[node1, state1] + bindingset[node2, state2] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + DataFlowType t, LocalCallContext lcc, string label + ); + } + + /** + * Provides a big-step relation for local flow steps. + * + * The big-step releation is based on the `localStep` relation from the + * input module, restricted to nodes that are forwards and backwards + * reachable in this stage. + */ + additional module LocalFlowBigStep { final private class NodeExFinal = NodeEx; /** @@ -2558,7 +2600,7 @@ module MakeImpl Lang> { exists(ApNil nil | revFlow(node1, state1, pragma[only_bind_into](nil)) and revFlow(node2, state2, pragma[only_bind_into](nil)) and - Param::localStep(node1, state1, node2, state2, false, t, lcc, label) and + Input::localStep(node1, state1, node2, state2, false, t, lcc, label) and state1 != state2 ) } @@ -2652,7 +2694,7 @@ module MakeImpl Lang> { not inBarrier(node2, state) and not outBarrier(node1, state) and exists(NodeEx node0, boolean preservesValue0, DataFlowType t0, string label0, Ap ap | - Param::localStep(node0, state, node2, state, preservesValue0, t0, cc, label0) and + Input::localStep(node0, state, node2, state, preservesValue0, t0, cc, label0) and revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and not outBarrier(node0, state) and (preservesValue = true or ap instanceof ApNil) @@ -3053,7 +3095,7 @@ module MakeImpl Lang> { PathNodeImpl pn1, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, ApOption argAp, Typ t, Ap ap, string label, boolean isStoreStep ) { - exists(NodeEx mid, FlowState state0, Typ t0, LocalCallContext localCc | + exists(NodeEx mid, FlowState state0, Typ t0, LocalCc localCc | pn1 = TPathNodeMid(mid, state0, cc, summaryCtx, argT, argAp, t0, ap) and localCc = getLocalCc(cc) and isStoreStep = false @@ -3523,13 +3565,10 @@ module MakeImpl Lang> { predicate instanceofCcNoCall(CcNoCall cc) { any() } + class LocalCc = Unit; + bindingset[cc] - LocalCallContext getLocalCc(Cc cc) { - cc = ccSomeCall() and - result instanceof LocalCallContextSpecificCall - or - result instanceof LocalCallContextAny - } + LocalCc getLocalCc(Cc cc) { any() } DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CcCall ctx) { none() } @@ -3585,63 +3624,23 @@ module MakeImpl Lang> { ApOption apSome(Ap ap) { result = TBooleanSome(ap) } import CachedCallContextSensitivity - import LocalCallContext - - pragma[noinline] - private predicate localFlowStepNodeCand1(NodeEx node1, NodeEx node2, string model) { - Stage1::revFlow(node2) and - localFlowStepEx(node1, node2, model) - } - - pragma[nomagic] - private predicate additionalLocalFlowStepNodeCand1(NodeEx node1, NodeEx node2, string model) { - Stage1::revFlow(node2) and - additionalLocalFlowStep(node1, node2, model) - } - - pragma[nomagic] - private predicate localStep( - NodeEx node1, NodeEx node2, boolean preservesValue, DataFlowType t, LocalCallContext lcc, - string label - ) { - ( - preservesValue = true and - localFlowStepNodeCand1(node1, node2, label) and - t = node1.getDataFlowType() - or - preservesValue = false and - additionalLocalFlowStepNodeCand1(node1, node2, label) and - t = node2.getDataFlowType() - ) and - lcc.relevantFor(node1.getEnclosingCallable()) and - not isUnreachableInCall1(node1, lcc) and - not isUnreachableInCall1(node2, lcc) - } - - pragma[nomagic] - private predicate localStateStep( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCallContext lcc, string label - ) { - preservesValue = false and - additionalLocalStateStep(node1, state1, node2, state2) and - label = "Config" and - t = node2.getDataFlowType() and - lcc.relevantFor(node1.getEnclosingCallable()) and - not isUnreachableInCall1(node1, lcc) and - not isUnreachableInCall1(node2, lcc) - } + import NoLocalCallContext bindingset[node1, state1] bindingset[node2, state2] predicate localStep( NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, - DataFlowType t, LocalCallContext lcc, string label + Typ t, LocalCc lcc, string label ) { - localStep(node1, node2, preservesValue, t, lcc, label) and - state1 = state2 - or - localStateStep(node1, state1, node2, state2, preservesValue, t, lcc, label) + ( + localStepNodeCand1(node1, node2, preservesValue, _, _, label) and + state1 = state2 + or + localStateStepNodeCand1(node1, state1, node2, state2, _, _, label) and + preservesValue = false + ) and + exists(t) and + exists(lcc) } pragma[nomagic] @@ -3725,9 +3724,41 @@ module MakeImpl Lang> { } import CallContextSensitivity - import LocalCallContext + import NoLocalCallContext - predicate localStep = PrevStage::LocalFlowBigStep::localFlowBigStep/8; + private module BigStepInput implements PrevStage::LocalFlowBigStepInputSig { + bindingset[node1, state1] + bindingset[node2, state2] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + DataFlowType t, LocalCallContext lcc, string label + ) { + localStepNodeCand1(node1, node2, preservesValue, t, lcc, label) and + state1 = state2 + or + localStateStepNodeCand1(node1, state1, node2, state2, t, lcc, label) and + preservesValue = false + } + } + + additional predicate localFlowBigStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + DataFlowType t, LocalCallContext lcc, string label + ) { + PrevStage::LocalFlowBigStep::localFlowBigStep(node1, state1, node2, state2, + preservesValue, t, lcc, label) + } + + bindingset[node1, state1] + bindingset[node2, state2] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + Typ t, LocalCc lcc, string label + ) { + localFlowBigStep(node1, state1, node2, state2, preservesValue, _, _, label) and + exists(t) and + exists(lcc) + } pragma[nomagic] private predicate expectsContentCand(NodeEx node, Ap ap) { @@ -3809,7 +3840,16 @@ module MakeImpl Lang> { import BooleanCallContext - predicate localStep = PrevStage::LocalFlowBigStep::localFlowBigStep/8; + pragma[nomagic] + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + Typ t, LocalCc lcc, string label + ) { + Stage3Param::localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _, label) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and + PrevStage::revFlow(node2, pragma[only_bind_into](state2), _) and + exists(lcc) + } pragma[nomagic] private predicate clearSet(NodeEx node, ContentSet c) { @@ -4113,7 +4153,14 @@ module MakeImpl Lang> { import CallContextSensitivity import LocalCallContext - predicate localStep = PrevStage::LocalFlowBigStep::localFlowBigStep/8; + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + Typ t, LocalCc lcc, string label + ) { + Stage3Param::localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc, label) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and + PrevStage::revFlow(node2, pragma[only_bind_into](state2), _) + } bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { @@ -4331,7 +4378,18 @@ module MakeImpl Lang> { import CallContextSensitivity import LocalCallContext - predicate localStep = PrevStage::LocalFlowBigStep::localFlowBigStep/8; + private module BigStepInput implements PrevStage::LocalFlowBigStepInputSig { + predicate localStep( + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, + DataFlowType t, LocalCallContext lcc, string label + ) { + Stage3Param::localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc, label) and + PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and + PrevStage::revFlow(node2, pragma[only_bind_into](state2), _) + } + } + + predicate localStep = PrevStage::LocalFlowBigStep::localFlowBigStep/8; bindingset[node, state, t0, ap] predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) { diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index 5fe86520882..434fca9c995 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -778,7 +778,23 @@ module MakeImplCommon Lang> { recordDataFlowCallSiteDispatch(call, c) } + module NoLocalCallContext { + class LocalCc = Unit; + + bindingset[cc] + LocalCc getLocalCc(CallContext cc) { any() } + + bindingset[call, c] + CallContextCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { + if recordDataFlowCallSiteDispatch(call, c) + then result = Input2::getSpecificCallContextCall(call, c) + else result = TSomeCall() + } + } + module LocalCallContext { + class LocalCc = LocalCallContext; + private UnreachableSet getUnreachable(CallContext ctx) { exists(UnreachableSetOption unreachable | ctx = TSpecificCall(_, _, unreachable) | result = unreachable.asSome() @@ -794,7 +810,7 @@ module MakeImplCommon Lang> { bindingset[cc] pragma[inline_late] - LocalCallContext getLocalCc(CallContext cc) { result = getLocalCallContext(cc) } + LocalCc getLocalCc(CallContext cc) { result = getLocalCallContext(cc) } bindingset[call, c] CallContextCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { From 16c2cf24b310bec935167466d85c2c94d161e568 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 26 Aug 2024 11:53:31 +0200 Subject: [PATCH 101/404] C++: use inline annotation for missing flow --- cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp | 2 +- cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected | 3 --- cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index 1504142bdce..8e6199d35bd 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -450,7 +450,7 @@ void test_qualifiers() b.member = source(); sink(b); // $ ir MISSING: ast sink(b.member); // $ ast,ir - sink(b.getMember()); // $ ir MISSING: ast + sink(b.getMember()); // $ MISSING: ir ast c = new MyClass2(0); diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 8d4dc3351b4..299f1413878 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -4,7 +4,4 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (tai WARNING: module 'DataFlow' has been deprecated and may be removed in future (taint.ql:68,25-33) WARNING: module 'TaintTracking' has been deprecated and may be removed in future (taint.ql:73,20-33) testFailures -| taint.cpp:453:23:453:42 | // $ ir MISSING: ast | Missing result:ir= | -| vector.cpp:118:12:118:30 | // $ ir MISSING:ast | Missing result:ir= | -| vector.cpp:119:12:119:30 | // $ ir MISSING:ast | Missing result:ir= | failures diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index a5e0c428b71..7f4d3f22d8e 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -115,8 +115,8 @@ void test_vector_swap() { v3.swap(v4); sink(v1); - sink(v2); // $ ir MISSING:ast - sink(v3); // $ ir MISSING:ast + sink(v2); // $ MISSING:ir ast + sink(v3); // $ MISSING:ir ast sink(v4); } From d9dbcdba3481016956f20f7f99c7d88a87dfb832 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 26 Aug 2024 12:42:44 +0200 Subject: [PATCH 102/404] C++: Fix imports --- cpp/ql/lib/semmle/code/cpp/models/Models.qll | 1 + .../src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index 90a97777d8f..1e0b6cd33ed 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -42,6 +42,7 @@ private import implementations.Accept private import implementations.Poll private import implementations.Select private import implementations.MySql +private import implementations.NoexceptFunction private import implementations.ODBC private import implementations.SqLite3 private import implementations.PostgreSql diff --git a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql index 73d9f2386a4..92daf31b057 100644 --- a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql +++ b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql @@ -16,7 +16,6 @@ import cpp import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.controlflow.Guards -import semmle.code.cpp.models.interfaces.NonThrowing import semmle.code.cpp.models.implementations.NoexceptFunction /** Gets the `Constructor` invoked when `newExpr` allocates memory. */ From 34d83a6b0d3041cebddb55d59c4e53bae433baaf Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 26 Aug 2024 15:02:27 +0200 Subject: [PATCH 103/404] C#/Java: Address review comments. --- .../modelgenerator/debug/CaptureSummaryModelsPartialPath.ql | 2 +- .../modelgenerator/debug/CaptureSummaryModelsPartialPath.ql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql index 614fb7630b4..62d3ad7f9f4 100644 --- a/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql +++ b/csharp/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql @@ -22,6 +22,6 @@ from where PartialFlow::partialFlow(source, sink, _) and p = source.getNode() and - p.asParameter() = api.getParameter(0) + p.asParameter() = api.getAParameter() select sink.getNode(), source, sink, "There is flow from a $@ to $@.", source.getNode(), "parameter", sink.getNode(), "intermediate value" diff --git a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql index 2b8a6e220f8..1d9724abef8 100644 --- a/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql +++ b/java/ql/src/utils/modelgenerator/debug/CaptureSummaryModelsPartialPath.ql @@ -23,6 +23,6 @@ from where PartialFlow::partialFlow(source, sink, _) and p = source.getNode() and - p.asParameter() = api.getParameter(0) + p.asParameter() = api.getAParameter() select sink.getNode(), source, sink, "There is flow from a $@ to $@.", source.getNode(), "parameter", sink.getNode(), "intermediate value" From cbb58d00410b83400bf632da157d4cb0fbdcab46 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 26 Aug 2024 15:05:30 +0200 Subject: [PATCH 104/404] Dataflow: Add a getLocation rootdef. --- shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 98291d25ffc..7288d3e6e06 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1580,11 +1580,15 @@ module MakeImpl Lang> { */ private class SummaryCtx extends TSummaryCtx { abstract string toString(); + + abstract Location getLocation(); } /** A summary context from which no flow summary can be generated. */ private class SummaryCtxNone extends SummaryCtx, TSummaryCtxNone { override string toString() { result = "" } + + override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } } /** A summary context from which a flow summary can be generated. */ @@ -1601,7 +1605,7 @@ module MakeImpl Lang> { override string toString() { result = p + concat(" : " + this.ppTyp()) + " " + ap } - Location getLocation() { result = p.getLocation() } + override Location getLocation() { result = p.getLocation() } } private predicate fwdFlowJump(NodeEx node, FlowState state, Typ t, Ap ap, ApApprox apa) { From d8c8bcd3866fd97827f351ee9e56069417fe8746 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 26 Aug 2024 15:12:37 +0200 Subject: [PATCH 105/404] Dataflow: Tweak qldoc. --- shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 7288d3e6e06..da197490c1b 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1466,8 +1466,8 @@ module MakeImpl Lang> { * Holds if `node` is reachable with access path `ap` from a source. * * The call context `cc` records whether the node is reached through an - * argument in a call, and if so, `summaryCtx` and `argAp` record the - * corresponding parameter position and access path of that argument, respectively. + * argument in a call, and if so, `summaryCtx` records the + * corresponding parameter position and access path of that argument. */ pragma[nomagic] additional predicate fwdFlow( From 4381bae5d1481b161096986fb30b1e426205b369 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 26 Aug 2024 14:10:40 +0200 Subject: [PATCH 106/404] Shared: Fix bad join. --- .../dataflow/internal/ContentDataFlowImpl.qll | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll index a4d3e413625..1823a25155f 100644 --- a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll @@ -455,27 +455,42 @@ module MakeImplContentDataFlow Lang> { ) } + pragma[nomagic] + private predicate nodeAndState(Flow::PathNode n, Node node, State state) { + n.getNode() = node and n.getState() = state + } + + pragma[nomagic] + private predicate succNodeAndState( + Flow::PathNode pre, Node preNode, State preState, Flow::PathNode succ, Node succNode, + State succState + ) { + nodeAndState(pre, preNode, preState) and + nodeAndState(succ, succNode, succState) and + pre.getASuccessor() = succ + } + pragma[nomagic] private predicate nodeReachesStore( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode target, ContentSet c, AccessPath reads, AccessPath stores ) { - exists(Flow::PathNode mid | + exists(Flow::PathNode mid, State midState, Node midNode, State targetState, Node targetNode | nodeReaches(source, scReads, scStores, mid, reads, stores) and - storeStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and - mid.getASuccessor() = node + succNodeAndState(mid, midNode, midState, target, targetNode, targetState) and + storeStep(midNode, midState, c, targetNode, targetState) ) } pragma[nomagic] private predicate nodeReachesRead( - Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode node, + Flow::PathNode source, AccessPath scReads, AccessPath scStores, Flow::PathNode target, ContentSet c, AccessPath reads, AccessPath stores ) { - exists(Flow::PathNode mid | + exists(Flow::PathNode mid, State midState, Node midNode, State targetState, Node targetNode | nodeReaches(source, scReads, scStores, mid, reads, stores) and - readStep(mid.getNode(), mid.getState(), c, node.getNode(), node.getState()) and - mid.getASuccessor() = node + succNodeAndState(mid, midNode, midState, target, targetNode, targetState) and + readStep(midNode, midState, c, targetNode, targetState) ) } From 77bfe39ca7a4b85b9e322a9e13f0cecb21a773ee Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 26 Aug 2024 15:24:22 +0200 Subject: [PATCH 107/404] Shared: Address review comments. --- .../codeql/dataflow/internal/ContentDataFlowImpl.qll | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll index 1823a25155f..c63f36bdeda 100644 --- a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll @@ -455,18 +455,15 @@ module MakeImplContentDataFlow Lang> { ) } - pragma[nomagic] - private predicate nodeAndState(Flow::PathNode n, Node node, State state) { - n.getNode() = node and n.getState() = state - } - pragma[nomagic] private predicate succNodeAndState( Flow::PathNode pre, Node preNode, State preState, Flow::PathNode succ, Node succNode, State succState ) { - nodeAndState(pre, preNode, preState) and - nodeAndState(succ, succNode, succState) and + pre.getNode() = preNode and + pre.getState() = preState and + succ.getNode() = succNode and + succ.getState() = succState and pre.getASuccessor() = succ } From d19102c3998ddb24b09a1540a33d57c9c386eccc Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Mon, 26 Aug 2024 14:38:32 -0700 Subject: [PATCH 108/404] Separate into two groups --- .github/pull_request_template.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 520020522cc..9d6ec6cb4f5 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,7 +1,13 @@ ### Pull Request checklist -- [ ] Add a change note if necessary. See [the documentation](https://github.com/github/codeql/blob/main/docs/change-notes.md). +#### All query authors + +- [ ] Add a change note if necessary. See [the documentation](https://github.com/github/codeql/blob/main/docs/change-notes.md) in this repository. +- [ ] All new queries have appropriate `.qhelp`. See [the documentation](https://github.com/github/codeql/blob/mainπ /docs/query-help-style-guide.md) in this repository. +- [ ] QL tests are added if necessary. See [Testing custom queries](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/testing-custom-queries) in the GitHub documentation. +- [ ] New and changed queries have correct query metadata. See [the documentation](https://github.com/github/codeql/blob/main/docs/query-metadata-style-guide.md) in this repository. + +#### Internal query authors only + - [ ] If this PR makes significant changes to `.ql`, `.qll`, or `.qhelp` files, make sure that autofixes generated based on these changes are valid. See [the documentation](https://github.com/github/codeql-team/blob/main/docs/best-practices/validating-autofix-for-query-changes.md) (internal access required). -- [ ] All new queries has appropriate `.qhelp`. -- [ ] QL tests are added if necessary. -- [ ] Test your changes in [DCA](https://github.com/github/codeql-dca/) (internal access required). +- [ ] Test your changes [at scale](https://github.com/github/codeql-dca/) (internal access required). From 0738e01e7ed679f7084b7f84a28ca8e01a278bd2 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 27 Aug 2024 09:12:37 +0200 Subject: [PATCH 109/404] Bazel: fix logging bug in `git_lfs_probe.py` The case of an `HTTPError` was printed to stdout (and therefore globbed by bazel). While I'm at it, I also introduced a timeout to `urlopen` and improved the `no endpoints found` error message. --- misc/bazel/internal/git_lfs_probe.py | 47 +++++++++++++++------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/misc/bazel/internal/git_lfs_probe.py b/misc/bazel/internal/git_lfs_probe.py index 01b201c5486..22ca9855f54 100755 --- a/misc/bazel/internal/git_lfs_probe.py +++ b/misc/bazel/internal/git_lfs_probe.py @@ -16,13 +16,13 @@ import shutil import json import typing import urllib.request +import urllib.error from urllib.parse import urlparse import re import base64 from dataclasses import dataclass import argparse - def options(): p = argparse.ArgumentParser(description=__doc__) p.add_argument("--hash-only", action="store_true") @@ -30,6 +30,12 @@ def options(): return p.parse_args() +TIMEOUT = 20 + +def warn(message: str) -> None: + print(f"WARNING: {message}", file=sys.stderr) + + @dataclass class Endpoint: name: str @@ -41,6 +47,10 @@ class Endpoint: self.headers.update((k.capitalize(), v) for k, v in d) +class NoEndpointsFound(Exception): + pass + + opts = options() sources = [p.resolve() for p in opts.sources] source_dir = pathlib.Path(os.path.commonpath(src.parent for src in sources)) @@ -105,18 +115,12 @@ def get_endpoints() -> typing.Iterable[Endpoint]: "download", ] try: - res = subprocess.run(cmd, stdout=subprocess.PIPE, timeout=15) + res = subprocess.run(cmd, stdout=subprocess.PIPE, timeout=TIMEOUT) except subprocess.TimeoutExpired: - print( - f"WARNING: ssh timed out when connecting to {server}, ignoring {endpoint.name} endpoint", - file=sys.stderr, - ) + warn(f"ssh timed out when connecting to {server}, ignoring {endpoint.name} endpoint") continue if res.returncode != 0: - print( - f"WARNING: ssh failed when connecting to {server}, ignoring {endpoint.name} endpoint", - file=sys.stderr, - ) + warn(f"ssh failed when connecting to {server}, ignoring {endpoint.name} endpoint") continue ssh_resp = json.loads(res.stdout) endpoint.href = ssh_resp.get("href", endpoint) @@ -139,10 +143,7 @@ def get_endpoints() -> typing.Iterable[Endpoint]: input=f"protocol={url.scheme}\nhost={url.netloc}\npath={url.path[1:]}\n", ) if credentials is None: - print( - f"WARNING: no authorization method found, ignoring {data.name} endpoint", - file=sys.stderr, - ) + warn(f"no authorization method found, ignoring {endpoint.name} endpoint") continue credentials = dict(get_env(credentials)) auth = base64.b64encode( @@ -176,10 +177,10 @@ def get_locations(objects): data=json.dumps(data).encode("ascii"), ) try: - with urllib.request.urlopen(req) as resp: + with urllib.request.urlopen(req, timeout=TIMEOUT) as resp: data = json.load(resp) - except urllib.request.HTTPError as e: - print(f"WARNING: encountered HTTPError {e}, ignoring endpoint {e.name}") + except urllib.error.URLError as e: + warn(f"encountered {type(e).__name__} {e}, ignoring endpoint {endpoint.name}") continue assert len(data["objects"]) == len( indexes @@ -187,7 +188,7 @@ def get_locations(objects): for i, resp in zip(indexes, data["objects"]): ret[i] = f'{resp["oid"]} {resp["actions"]["download"]["href"]}' return ret - raise Exception(f"no valid endpoint found") + raise NoEndpointsFound def get_lfs_object(path): @@ -204,6 +205,10 @@ def get_lfs_object(path): return {"oid": sha256, "size": size} -objects = [get_lfs_object(src) for src in sources] -for resp in get_locations(objects): - print(resp) +try: + objects = [get_lfs_object(src) for src in sources] + for resp in get_locations(objects): + print(resp) +except NoEndpointsFound as e: + print(f"ERROR: no valid endpoints found", file=sys.stderr) + sys.exit(1) From 62219fae609730ea62f95fb11c5207e662f13d6d Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Tue, 27 Aug 2024 12:27:53 +0200 Subject: [PATCH 110/404] Bazel: switch to a 7.4.0 prerelease. --- .bazelversion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bazelversion b/.bazelversion index b26a34e4705..b9ad1fa3a7f 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -7.2.1 +5f5d70b6c4d2fb1a889479569107f1692239e8a7 From 123507e2dce45f1fbb2df51eb39634907b208ad5 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Tue, 27 Aug 2024 13:00:56 +0200 Subject: [PATCH 111/404] No need to disable the layering check anymore, this was fixed upstream. --- .github/workflows/cpp-swift-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cpp-swift-analysis.yml b/.github/workflows/cpp-swift-analysis.yml index b2ebbc7d7df..4b923f1b39c 100644 --- a/.github/workflows/cpp-swift-analysis.yml +++ b/.github/workflows/cpp-swift-analysis.yml @@ -37,7 +37,7 @@ jobs: with: languages: cpp config-file: ./.github/codeql/codeql-config.yml - + - name: "[Ubuntu] Remove GCC 13 from runner image" shell: bash run: | @@ -48,7 +48,7 @@ jobs: - name: "Build Swift extractor using Bazel" run: | bazel clean --expunge - bazel run //swift:create-extractor-pack --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results --spawn_strategy=local --features=-layering_check + bazel run //swift:create-extractor-pack --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results --spawn_strategy=local bazel shutdown - name: Perform CodeQL Analysis From 19606b1903494fb88c000d88ffe9a277a7cd8205 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Mon, 26 Aug 2024 12:41:47 +0200 Subject: [PATCH 112/404] Add *.actual to the gitignore file. This is also used by the integration tests. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a9a34f6bd4c..445faf8efaf 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,8 @@ .cache # qltest projects and artifacts +*.actual */ql/test/**/*.testproj -*/ql/test/**/*.actual */ql/test/**/go.sum # Visual studio temporaries, except a file used by QL4VS From 5fa30c33b833a305d33447fd77ea331c2f5f8795 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Fri, 23 Aug 2024 12:56:58 +0200 Subject: [PATCH 113/404] Remove legacy java files. --- java/ql/integration-tests/all-platforms/java/legacy | 0 java/ql/integration-tests/all-platforms/java/qlpack.yml | 5 ----- 2 files changed, 5 deletions(-) delete mode 100644 java/ql/integration-tests/all-platforms/java/legacy delete mode 100644 java/ql/integration-tests/all-platforms/java/qlpack.yml diff --git a/java/ql/integration-tests/all-platforms/java/legacy b/java/ql/integration-tests/all-platforms/java/legacy deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/java/ql/integration-tests/all-platforms/java/qlpack.yml b/java/ql/integration-tests/all-platforms/java/qlpack.yml deleted file mode 100644 index 4994af85a75..00000000000 --- a/java/ql/integration-tests/all-platforms/java/qlpack.yml +++ /dev/null @@ -1,5 +0,0 @@ -dependencies: - codeql/java-all: '*' - codeql/java-tests: '*' - codeql/java-queries: '*' -warnOnImplicitThis: true From c69df1a6e3eee9ad45759054aab369d0dea7d1bd Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Fri, 23 Aug 2024 14:14:04 +0200 Subject: [PATCH 114/404] Port java integration tests to pytest. Some notes: * These tests rely on a variety of fixtures * The previous maven-wrapper checks were checking for the version of maven installed by looking at the checked-in wrapper script. I dropped this behavior. * I replaced a lot of test queries that queried for a (subset of) source archive files with the source_archive fixture. In particular, tests that excluded properties files from being listed in the expected output now include them. It's much faster to generate this list via the fixture instead of using CodeQL for it. --- .../java/android-8-sample/.gitattributes | 6 - .../java/android-8-sample/.gitignore | 37 --- .../force_sequential_test_execution | 4 - .../gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../java/android-8-sample/gradlew | 240 ----------------- .../java/android-8-sample/gradlew.bat | 91 ------- .../android-8-sample/source_archive.expected | 27 ++ .../java/android-8-sample/test.expected | 20 -- .../java/android-8-sample/test.py | 10 +- .../java/android-8-sample/test.ql | 7 - .../force_sequential_test_execution | 4 - .../source_archive.expected | 26 ++ .../test.expected | 20 -- .../test.py | 9 +- .../test.ql | 7 - .../.gitattributes | 6 - .../force_sequential_test_execution | 4 - .../gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../gradlew | 240 ----------------- .../gradlew.bat | 91 ------- .../source_archive.expected | 26 ++ .../test.expected | 20 -- .../test.py | 9 +- .../test.ql | 7 - .../force_sequential_test_execution | 4 - .../source_archive.expected | 26 ++ .../android-sample-no-wrapper/test.expected | 20 -- .../java/android-sample-no-wrapper/test.py | 9 +- .../java/android-sample-no-wrapper/test.ql | 7 - .../force_sequential_test_execution | 4 - .../source_archive.expected | 29 ++ .../test.expected | 23 -- .../test.py | 10 +- .../test.ql | 7 - .../force_sequential_test_execution | 4 - .../gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../gradlew | 240 ----------------- .../gradlew.bat | 91 ------- .../source_archive.expected | 29 ++ .../test.expected | 23 -- .../test.py | 9 +- .../test.ql | 7 - .../force_sequential_test_execution | 4 - .../source_archive.expected | 29 ++ .../test.expected | 23 -- .../test.py | 10 +- .../test.ql | 7 - .../android-sample-old-style/.gitattributes | 6 - .../force_sequential_test_execution | 4 - .../gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../java/android-sample-old-style/gradlew | 240 ----------------- .../java/android-sample-old-style/gradlew.bat | 91 ------- .../source_archive.expected | 29 ++ .../android-sample-old-style/test.expected | 23 -- .../java/android-sample-old-style/test.py | 9 +- .../java/android-sample-old-style/test.ql | 7 - .../java/android-sample/.gitattributes | 6 - .../force_sequential_test_execution | 4 - .../gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../all-platforms/java/android-sample/gradlew | 240 ----------------- .../java/android-sample/gradlew.bat | 91 ------- .../android-sample/source_archive.expected | 26 ++ .../java/android-sample/test.expected | 20 -- .../all-platforms/java/android-sample/test.py | 9 +- .../all-platforms/java/android-sample/test.ql | 7 - .../all-platforms/java/ant-sample/test.py | 7 +- .../force_sequential_test_execution | 1 - .../test.py | 33 ++- .../java/buildless-erroneous/test.py | 10 +- .../.gitattributes | 9 - .../buildless-gradle-classifiers/.gitignore | 5 - .../force_sequential_test_execution | 3 - .../gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 - .../java/buildless-gradle-classifiers/gradlew | 249 ------------------ .../buildless-gradle-classifiers/gradlew.bat | 92 ------- .../source_archive.expected | 7 + .../test.expected | 1 - .../java/buildless-gradle-classifiers/test.py | 15 +- .../java/buildless-gradle-classifiers/test.ql | 5 - .../force_sequential_test_execution | 3 - .../source_archive.expected | 5 + .../buildless-gradle-timeout/test.expected | 5 - .../java/buildless-gradle-timeout/test.py | 16 +- .../java/buildless-gradle-timeout/test.ql | 7 - .../java/buildless-gradle/.gitattributes | 9 - .../java/buildless-gradle/.gitignore | 5 - .../force_sequential_test_execution | 3 - .../gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 - .../java/buildless-gradle/gradlew | 249 ------------------ .../java/buildless-gradle/gradlew.bat | 92 ------- .../buildless-gradle/source_archive.expected | 7 + .../java/buildless-gradle/test.expected | 1 - .../java/buildless-gradle/test.py | 15 +- .../java/buildless-gradle/test.ql | 5 - .../force_sequential_test_execution | 1 - .../buildless-inherit-trust-store/test.py | 35 ++- .../force_sequential_test_execution | 1 - .../source_archive.expected | 7 + .../test.expected | 10 - .../buildless-maven-executable-war/test.py | 15 +- .../buildless-maven-executable-war/test.ql | 9 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 14 + .../buildless-maven-multimodule/test.expected | 17 -- .../java/buildless-maven-multimodule/test.py | 15 +- .../java/buildless-maven-multimodule/test.ql | 9 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 8 + .../buildless-maven-timeout/test.expected | 11 - .../java/buildless-maven-timeout/test.py | 15 +- .../java/buildless-maven-timeout/test.ql | 9 - .../force_sequential_test_execution | 1 - .../test.py | 12 +- .../force_sequential_test_execution | 1 - .../buildless-maven/source_archive.expected | 7 + .../java/buildless-maven/test.expected | 10 - .../java/buildless-maven/test.py | 15 +- .../java/buildless-maven/test.ql | 9 - .../test.py | 9 +- .../buildless-proxy-gradle/.gitattributes | 9 - .../java/buildless-proxy-gradle/.gitignore | 5 - .../force_sequential_test_execution | 3 - .../gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 - .../java/buildless-proxy-gradle/gradlew | 249 ------------------ .../java/buildless-proxy-gradle/gradlew.bat | 92 ------- .../source_archive.expected | 7 + .../java/buildless-proxy-gradle/test.expected | 1 - .../java/buildless-proxy-gradle/test.py | 47 +--- .../java/buildless-proxy-gradle/test.ql | 5 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 8 + .../java/buildless-proxy-maven/test.expected | 11 - .../java/buildless-proxy-maven/test.py | 47 +--- .../java/buildless-proxy-maven/test.ql | 9 - .../force_sequential_test_execution | 3 - .../source_archive.expected | 29 ++ .../buildless-sibling-projects/test.expected | 8 - .../java/buildless-sibling-projects/test.py | 23 +- .../java/buildless-sibling-projects/test.ql | 5 - .../force_sequential_test_execution | 1 - .../buildless-snapshot-repository/test.py | 25 +- .../java/buildless/source_archive.expected | 6 + .../java/buildless/test.expected | 9 - .../all-platforms/java/buildless/test.py | 10 +- .../all-platforms/java/buildless/test.ql | 9 - .../.gitattributes | 6 - .../force_sequential_test_execution | 4 - .../gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../android-gradle-incompatibility/gradlew | 240 ----------------- .../gradlew.bat | 91 ------- .../android-gradle-incompatibility/test.py | 9 +- .../diagnostics/compilation-error/test.py | 9 +- .../java/diagnostics/dependency-error/test.py | 22 +- .../java-version-too-old/.gitattributes | 6 - .../java-version-too-old/.gitignore | 5 - .../force_sequential_test_execution | 3 - .../gradle/verification-metadata.xml | 7 - .../gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../diagnostics/java-version-too-old/gradlew | 185 ------------- .../java-version-too-old/gradlew.bat | 89 ------- .../skip-on-platform-osx-arm | 3 - .../diagnostics/java-version-too-old/test.py | 38 ++- .../diagnostics/maven-http-repository/test.py | 9 +- .../multiple-candidate-builds/test.py | 9 +- .../java/diagnostics/no-build-system/test.py | 9 +- .../diagnostics.expected | 2 +- .../no-gradle-test-classes/test.py | 9 +- .../force_sequential_test_execution | 3 - .../diagnostics/no-gradle-wrapper/test.py | 9 +- .../ecj-sample-noexit/source_archive.expected | 2 + .../java/ecj-sample-noexit/test.expected | 1 - .../java/ecj-sample-noexit/test.py | 10 +- .../java/ecj-sample-noexit/test.ql | 3 - .../java/ecj-sample/source_archive.expected | 2 + .../java/ecj-sample/test.expected | 1 - .../all-platforms/java/ecj-sample/test.py | 10 +- .../all-platforms/java/ecj-sample/test.ql | 3 - .../{Diagnostics.expected => Diag.expected} | 0 .../{Diagnostics.ql => Diag.ql} | 0 .../ecj-tolerate-enum-annotations/test.py | 16 +- .../.gitattributes | 9 - .../gradle-sample-kotlin-script/.gitignore | 5 - .../force_sequential_test_execution | 3 - .../gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../source_archive.expected | 9 + .../gradle-sample-kotlin-script/test.expected | 4 - .../java/gradle-sample-kotlin-script/test.py | 7 +- .../java/gradle-sample-kotlin-script/test.ql | 7 - .../java/gradle-sample/.gitattributes | 6 - .../java/gradle-sample/.gitignore | 5 - .../force_sequential_test_execution | 3 - .../gradle/verification-metadata.xml | 7 - .../gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .../all-platforms/java/gradle-sample/gradlew | 185 ------------- .../java/gradle-sample/gradlew.bat | 89 ------- .../gradle-sample/source_archive.expected | 9 + .../java/gradle-sample/test.expected | 5 - .../all-platforms/java/gradle-sample/test.py | 10 +- .../all-platforms/java/gradle-sample/test.ql | 7 - .../force_sequential_test_execution | 1 - .../all-platforms/java/java-web-jsp/test.py | 9 +- .../force_sequential_test_execution | 1 - .../maven-enforcer/source_archive.expected | 12 + .../java/maven-enforcer/test.expected | 15 -- .../all-platforms/java/maven-enforcer/test.py | 7 +- .../all-platforms/java/maven-enforcer/test.ql | 9 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 12 + .../test.expected | 15 -- .../maven-sample-extract-properties/test.py | 7 +- .../maven-sample-extract-properties/test.ql | 9 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 10 + .../test.expected | 7 - .../java/maven-sample-large-xml-files/test.py | 16 +- .../java/maven-sample-large-xml-files/test.ql | 7 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 17 ++ .../test.expected | 14 - .../java/maven-sample-small-xml-files/test.py | 16 +- .../java/maven-sample-small-xml-files/test.ql | 7 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 12 + .../maven-sample-xml-mode-all/test.expected | 9 - .../java/maven-sample-xml-mode-all/test.py | 7 +- .../java/maven-sample-xml-mode-all/test.ql | 7 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 10 + .../test.expected | 7 - .../java/maven-sample-xml-mode-byname/test.py | 7 +- .../java/maven-sample-xml-mode-byname/test.ql | 7 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 7 + .../test.expected | 4 - .../maven-sample-xml-mode-disabled/test.py | 7 +- .../maven-sample-xml-mode-disabled/test.ql | 7 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 10 + .../maven-sample-xml-mode-smart/test.expected | 7 - .../java/maven-sample-xml-mode-smart/test.py | 7 +- .../java/maven-sample-xml-mode-smart/test.ql | 7 - .../force_sequential_test_execution | 1 - .../java/maven-sample/source_archive.expected | 12 + .../java/maven-sample/test.expected | 15 -- .../all-platforms/java/maven-sample/test.py | 7 +- .../all-platforms/java/maven-sample/test.ql | 9 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 13 + .../maven-wrapper-script-only/test.expected | 16 -- .../java/maven-wrapper-script-only/test.py | 9 +- .../java/maven-wrapper-script-only/test.ql | 9 - .../force_sequential_test_execution | 1 - .../source_archive.expected | 13 + .../maven-wrapper-source-only/test.expected | 16 -- .../java/maven-wrapper-source-only/test.py | 9 +- .../java/maven-wrapper-source-only/test.ql | 9 - .../force_sequential_test_execution | 1 - .../maven-wrapper/source_archive.expected | 13 + .../java/maven-wrapper/test.expected | 16 -- .../all-platforms/java/maven-wrapper/test.py | 9 +- .../all-platforms/java/maven-wrapper/test.ql | 9 - .../java/multi-release-jar-java11/test.py | 35 ++- .../java/multi-release-jar-java17/test.py | 33 ++- .../force_sequential_test_execution | 3 - .../source_archive.expected | 10 + .../test.expected | 5 - .../test.py | 40 +-- .../test.ql | 7 - .../java/partial-gradle-sample/.gitignore | 5 - .../force_sequential_test_execution | 3 - .../source_archive.expected | 10 + .../java/partial-gradle-sample/test.expected | 5 - .../java/partial-gradle-sample/test.py | 9 +- .../java/partial-gradle-sample/test.ql | 7 - .../java/spring-boot-sample/.gitattributes | 6 - .../java/spring-boot-sample/.gitignore | 37 --- .../force_sequential_test_execution | 3 - .../gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 - .../java/spring-boot-sample/gradlew | 249 ------------------ .../java/spring-boot-sample/gradlew.bat | 92 ------- .../source_archive.expected | 11 + .../java/spring-boot-sample/test.expected | 4 - .../java/spring-boot-sample/test.py | 10 +- .../java/spring-boot-sample/test.ql | 7 - 297 files changed, 848 insertions(+), 5570 deletions(-) delete mode 100644 java/ql/integration-tests/all-platforms/java/android-8-sample/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/android-8-sample/.gitignore delete mode 100644 java/ql/integration-tests/all-platforms/java/android-8-sample/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/android-8-sample/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/android-8-sample/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/android-8-sample/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/android-8-sample/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/android-8-sample/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-8-sample/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-8-sample/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/android-sample-old-style/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/android-sample/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/android-sample/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/android-sample/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/.gitignore delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle/.gitignore delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/buildless-gradle/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-gradle/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-maven/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/.gitignore delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/buildless/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/buildless/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/gradlew.bat delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/.gitignore delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/verification-metadata.xml delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradlew.bat delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/skip-on-platform-osx-arm delete mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.ql create mode 100644 java/ql/integration-tests/all-platforms/java/ecj-sample/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/ecj-sample/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/ecj-sample/test.ql rename java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/{Diagnostics.expected => Diag.expected} (100%) rename java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/{Diagnostics.ql => Diag.ql} (100%) delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/.gitignore delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/gradle/wrapper/gradle-wrapper.properties create mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/.gitignore delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/gradle/verification-metadata.xml delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/gradle-sample/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/gradle-sample/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/java-web-jsp/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-enforcer/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-enforcer/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-enforcer/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-enforcer/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-sample/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/maven-wrapper/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/partial-gradle-sample/.gitignore delete mode 100644 java/ql/integration-tests/all-platforms/java/partial-gradle-sample/force_sequential_test_execution create mode 100644 java/ql/integration-tests/all-platforms/java/partial-gradle-sample/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.ql delete mode 100644 java/ql/integration-tests/all-platforms/java/spring-boot-sample/.gitattributes delete mode 100644 java/ql/integration-tests/all-platforms/java/spring-boot-sample/.gitignore delete mode 100644 java/ql/integration-tests/all-platforms/java/spring-boot-sample/force_sequential_test_execution delete mode 100644 java/ql/integration-tests/all-platforms/java/spring-boot-sample/gradle/wrapper/gradle-wrapper.jar delete mode 100644 java/ql/integration-tests/all-platforms/java/spring-boot-sample/gradle/wrapper/gradle-wrapper.properties delete mode 100755 java/ql/integration-tests/all-platforms/java/spring-boot-sample/gradlew delete mode 100644 java/ql/integration-tests/all-platforms/java/spring-boot-sample/gradlew.bat create mode 100644 java/ql/integration-tests/all-platforms/java/spring-boot-sample/source_archive.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.expected delete mode 100644 java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.ql diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/.gitattributes b/java/ql/integration-tests/all-platforms/java/android-8-sample/.gitattributes deleted file mode 100644 index 00a51aff5e5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-8-sample/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/.gitignore b/java/ql/integration-tests/all-platforms/java/android-8-sample/.gitignore deleted file mode 100644 index c2065bc2620..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-8-sample/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -HELP.md -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/android-8-sample/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-8-sample/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/android-8-sample/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090a2944b7473328c07c9755baa3196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60756 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 '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/gradlew.bat b/java/ql/integration-tests/all-platforms/java/android-8-sample/gradlew.bat deleted file mode 100644 index f127cfd49d4..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-8-sample/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/source_archive.expected b/java/ql/integration-tests/all-platforms/java/android-8-sample/source_archive.expected new file mode 100644 index 00000000000..8d61145f807 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/android-8-sample/source_archive.expected @@ -0,0 +1,27 @@ +.gradle/8.0/dependencies-accessors/gc.properties +.gradle/8.0/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +project/build/intermediates/app_metadata/release/app-metadata.properties +project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml +project/build/intermediates/incremental/lintVitalReportRelease/module.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalReportRelease/release.xml +project/build/intermediates/incremental/mergeReleaseAssets/merger.xml +project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml +project/build/intermediates/incremental/mergeReleaseShaders/merger.xml +project/build/intermediates/incremental/release/mergeReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml +project/build/intermediates/incremental/release/packageReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/release/packageReleaseResources/merger.xml +project/build/intermediates/merged_manifest/release/AndroidManifest.xml +project/build/intermediates/merged_manifests/release/AndroidManifest.xml +project/build/intermediates/packaged_manifests/release/AndroidManifest.xml +project/src/main/AndroidManifest.xml +project/src/main/java/com/github/androidsample/Main.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/test.expected b/java/ql/integration-tests/all-platforms/java/android-8-sample/test.expected deleted file mode 100644 index 64ce68113e7..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-8-sample/test.expected +++ /dev/null @@ -1,20 +0,0 @@ -#select -| project/src/main/java/com/github/androidsample/Main.java:0:0:0:0 | Main | -xmlFiles -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/module.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release.xml | -| project/build/intermediates/incremental/mergeReleaseAssets/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseAssets/merger.xml | -| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml | -| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml | -| project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml | -| project/build/intermediates/incremental/release/packageReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/release/packageReleaseResources/merger.xml | -| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml | -| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml | -| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml | -| project/src/main/AndroidManifest.xml:0:0:0:0 | project/src/main/AndroidManifest.xml | diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/test.py b/java/ql/integration-tests/all-platforms/java/android-8-sample/test.py index 3a0b27fe5ce..72e3c5d3fc4 100644 --- a/java/ql/integration-tests/all-platforms/java/android-8-sample/test.py +++ b/java/ql/integration-tests/all-platforms/java/android-8-sample/test.py @@ -1,10 +1,4 @@ -import sys - -from create_database_utils import * - # Put Java 11 on the path so as to challenge our version selection logic: Java 11 is unsuitable for Android Gradle Plugin 8+, # so it will be necessary to notice Java 17 available in the environment and actively select it. - -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, use_java_11, java, gradle_8_0, android_sdk): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/test.ql b/java/ql/integration-tests/all-platforms/java/android-8-sample/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-8-sample/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/source_archive.expected b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/source_archive.expected new file mode 100644 index 00000000000..70b1edf245a --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/source_archive.expected @@ -0,0 +1,26 @@ +.gradle/7.4/dependencies-accessors/gc.properties +.gradle/7.4/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java +project/build/intermediates/app_metadata/release/app-metadata.properties +project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml +project/build/intermediates/incremental/lintVitalReportRelease/module.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalReportRelease/release.xml +project/build/intermediates/incremental/mergeReleaseAssets/merger.xml +project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml +project/build/intermediates/incremental/mergeReleaseShaders/merger.xml +project/build/intermediates/incremental/release/mergeReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml +project/build/intermediates/merged_manifest/release/AndroidManifest.xml +project/build/intermediates/merged_manifests/release/AndroidManifest.xml +project/build/intermediates/packaged_manifests/release/AndroidManifest.xml +project/src/main/AndroidManifest.xml +project/src/main/java/com/github/androidsample/Main.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.expected b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.expected deleted file mode 100644 index 4f191ddaa1a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.expected +++ /dev/null @@ -1,20 +0,0 @@ -#select -| project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java:0:0:0:0 | BuildConfig | -| project/src/main/java/com/github/androidsample/Main.java:0:0:0:0 | Main | -xmlFiles -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/module.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release.xml | -| project/build/intermediates/incremental/mergeReleaseAssets/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseAssets/merger.xml | -| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml | -| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml | -| project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml | -| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml | -| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml | -| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml | -| project/src/main/AndroidManifest.xml:0:0:0:0 | project/src/main/AndroidManifest.xml | diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.py b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.py index 7f379da0a07..e3a791a59f3 100644 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.py +++ b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.py @@ -1,7 +1,2 @@ -import sys - -from create_database_utils import * - -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, use_java_11, java, android_sdk): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.ql b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/.gitattributes b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/.gitattributes deleted file mode 100644 index 00a51aff5e5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090a2944b7473328c07c9755baa3196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60756 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 '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/gradlew.bat b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/gradlew.bat deleted file mode 100644 index f127cfd49d4..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/source_archive.expected b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/source_archive.expected new file mode 100644 index 00000000000..70b1edf245a --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/source_archive.expected @@ -0,0 +1,26 @@ +.gradle/7.4/dependencies-accessors/gc.properties +.gradle/7.4/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java +project/build/intermediates/app_metadata/release/app-metadata.properties +project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml +project/build/intermediates/incremental/lintVitalReportRelease/module.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalReportRelease/release.xml +project/build/intermediates/incremental/mergeReleaseAssets/merger.xml +project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml +project/build/intermediates/incremental/mergeReleaseShaders/merger.xml +project/build/intermediates/incremental/release/mergeReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml +project/build/intermediates/merged_manifest/release/AndroidManifest.xml +project/build/intermediates/merged_manifests/release/AndroidManifest.xml +project/build/intermediates/packaged_manifests/release/AndroidManifest.xml +project/src/main/AndroidManifest.xml +project/src/main/java/com/github/androidsample/Main.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.expected b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.expected deleted file mode 100644 index 4f191ddaa1a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.expected +++ /dev/null @@ -1,20 +0,0 @@ -#select -| project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java:0:0:0:0 | BuildConfig | -| project/src/main/java/com/github/androidsample/Main.java:0:0:0:0 | Main | -xmlFiles -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/module.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release.xml | -| project/build/intermediates/incremental/mergeReleaseAssets/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseAssets/merger.xml | -| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml | -| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml | -| project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml | -| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml | -| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml | -| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml | -| project/src/main/AndroidManifest.xml:0:0:0:0 | project/src/main/AndroidManifest.xml | diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.py b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.py index 7f379da0a07..d3399e414e6 100644 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.py +++ b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.py @@ -1,7 +1,2 @@ -import sys - -from create_database_utils import * - -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, use_java_11, java, gradle_7_4, android_sdk): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.ql b/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/source_archive.expected b/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/source_archive.expected new file mode 100644 index 00000000000..70b1edf245a --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/source_archive.expected @@ -0,0 +1,26 @@ +.gradle/7.4/dependencies-accessors/gc.properties +.gradle/7.4/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java +project/build/intermediates/app_metadata/release/app-metadata.properties +project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml +project/build/intermediates/incremental/lintVitalReportRelease/module.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalReportRelease/release.xml +project/build/intermediates/incremental/mergeReleaseAssets/merger.xml +project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml +project/build/intermediates/incremental/mergeReleaseShaders/merger.xml +project/build/intermediates/incremental/release/mergeReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml +project/build/intermediates/merged_manifest/release/AndroidManifest.xml +project/build/intermediates/merged_manifests/release/AndroidManifest.xml +project/build/intermediates/packaged_manifests/release/AndroidManifest.xml +project/src/main/AndroidManifest.xml +project/src/main/java/com/github/androidsample/Main.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.expected b/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.expected deleted file mode 100644 index 4f191ddaa1a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.expected +++ /dev/null @@ -1,20 +0,0 @@ -#select -| project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java:0:0:0:0 | BuildConfig | -| project/src/main/java/com/github/androidsample/Main.java:0:0:0:0 | Main | -xmlFiles -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/module.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release.xml | -| project/build/intermediates/incremental/mergeReleaseAssets/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseAssets/merger.xml | -| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml | -| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml | -| project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml | -| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml | -| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml | -| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml | -| project/src/main/AndroidManifest.xml:0:0:0:0 | project/src/main/AndroidManifest.xml | diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.py b/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.py index 7f379da0a07..e3a791a59f3 100644 --- a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.py +++ b/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.py @@ -1,7 +1,2 @@ -import sys - -from create_database_utils import * - -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, use_java_11, java, android_sdk): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.ql b/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/source_archive.expected b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/source_archive.expected new file mode 100644 index 00000000000..a8f354b9e17 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/source_archive.expected @@ -0,0 +1,29 @@ +.gradle/7.0.2/dependencies-accessors/gc.properties +.gradle/7.0.2/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java +project/build/intermediates/app_metadata/release/app-metadata.properties +project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml +project/build/intermediates/incremental/lintVitalRelease/module.xml +project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalRelease/release.xml +project/build/intermediates/incremental/mergeReleaseAssets/merger.xml +project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml +project/build/intermediates/incremental/mergeReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/mergeReleaseResources/merger.xml +project/build/intermediates/incremental/mergeReleaseShaders/merger.xml +project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml +project/build/intermediates/merged_manifest/release/AndroidManifest.xml +project/build/intermediates/merged_manifests/release/AndroidManifest.xml +project/build/intermediates/packaged_manifests/release/AndroidManifest.xml +project/src/main/AndroidManifest.xml +project/src/main/java/com/github/androidsample/Main.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.expected b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.expected deleted file mode 100644 index f49910c2646..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.expected +++ /dev/null @@ -1,23 +0,0 @@ -#select -| project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java:0:0:0:0 | BuildConfig | -| project/src/main/java/com/github/androidsample/Main.java:0:0:0:0 | Main | -xmlFiles -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml | -| project/build/intermediates/incremental/lintVitalRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/module.xml | -| project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release.xml | -| project/build/intermediates/incremental/mergeReleaseAssets/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseAssets/merger.xml | -| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml | -| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml | -| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml | -| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml | -| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml | -| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml | -| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml | -| project/src/main/AndroidManifest.xml:0:0:0:0 | project/src/main/AndroidManifest.xml | diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py index 36702f6bb24..ca4ae04350f 100644 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py +++ b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py @@ -1,8 +1,2 @@ -from create_database_utils import * -from toolchains_test_utils import * - -try_use_java11() - -toolchains_file = actions_expose_all_toolchains() - -run_codeql_database_create([], lang="java", extra_env={"LGTM_INDEX_MAVEN_TOOLCHAINS_FILE": toolchains_file}) +def test(codeql, use_java_11, java, android_sdk, actions_toolchains_file): + codeql.database.create(_env={"LGTM_INDEX_MAVEN_TOOLCHAINS_FILE": str(actions_toolchains_file)}) diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.ql b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090a2944b7473328c07c9755baa3196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60756 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 '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/gradlew.bat b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/gradlew.bat deleted file mode 100644 index f127cfd49d4..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/source_archive.expected b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/source_archive.expected new file mode 100644 index 00000000000..2d3a437d507 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/source_archive.expected @@ -0,0 +1,29 @@ +.gradle/7.4/dependencies-accessors/gc.properties +.gradle/7.4/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java +project/build/intermediates/app_metadata/release/app-metadata.properties +project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml +project/build/intermediates/incremental/lintVitalRelease/module.xml +project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalRelease/release.xml +project/build/intermediates/incremental/mergeReleaseAssets/merger.xml +project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml +project/build/intermediates/incremental/mergeReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/mergeReleaseResources/merger.xml +project/build/intermediates/incremental/mergeReleaseShaders/merger.xml +project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml +project/build/intermediates/merged_manifest/release/AndroidManifest.xml +project/build/intermediates/merged_manifests/release/AndroidManifest.xml +project/build/intermediates/packaged_manifests/release/AndroidManifest.xml +project/src/main/AndroidManifest.xml +project/src/main/java/com/github/androidsample/Main.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.expected b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.expected deleted file mode 100644 index f49910c2646..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.expected +++ /dev/null @@ -1,23 +0,0 @@ -#select -| project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java:0:0:0:0 | BuildConfig | -| project/src/main/java/com/github/androidsample/Main.java:0:0:0:0 | Main | -xmlFiles -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml | -| project/build/intermediates/incremental/lintVitalRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/module.xml | -| project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release.xml | -| project/build/intermediates/incremental/mergeReleaseAssets/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseAssets/merger.xml | -| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml | -| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml | -| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml | -| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml | -| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml | -| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml | -| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml | -| project/src/main/AndroidManifest.xml:0:0:0:0 | project/src/main/AndroidManifest.xml | diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.py b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.py index 7f379da0a07..d3399e414e6 100644 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.py +++ b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.py @@ -1,7 +1,2 @@ -import sys - -from create_database_utils import * - -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, use_java_11, java, gradle_7_4, android_sdk): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.ql b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/source_archive.expected b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/source_archive.expected new file mode 100644 index 00000000000..a8f354b9e17 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/source_archive.expected @@ -0,0 +1,29 @@ +.gradle/7.0.2/dependencies-accessors/gc.properties +.gradle/7.0.2/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java +project/build/intermediates/app_metadata/release/app-metadata.properties +project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml +project/build/intermediates/incremental/lintVitalRelease/module.xml +project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalRelease/release.xml +project/build/intermediates/incremental/mergeReleaseAssets/merger.xml +project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml +project/build/intermediates/incremental/mergeReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/mergeReleaseResources/merger.xml +project/build/intermediates/incremental/mergeReleaseShaders/merger.xml +project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml +project/build/intermediates/merged_manifest/release/AndroidManifest.xml +project/build/intermediates/merged_manifests/release/AndroidManifest.xml +project/build/intermediates/packaged_manifests/release/AndroidManifest.xml +project/src/main/AndroidManifest.xml +project/src/main/java/com/github/androidsample/Main.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.expected b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.expected deleted file mode 100644 index f49910c2646..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.expected +++ /dev/null @@ -1,23 +0,0 @@ -#select -| project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java:0:0:0:0 | BuildConfig | -| project/src/main/java/com/github/androidsample/Main.java:0:0:0:0 | Main | -xmlFiles -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml | -| project/build/intermediates/incremental/lintVitalRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/module.xml | -| project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release.xml | -| project/build/intermediates/incremental/mergeReleaseAssets/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseAssets/merger.xml | -| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml | -| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml | -| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml | -| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml | -| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml | -| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml | -| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml | -| project/src/main/AndroidManifest.xml:0:0:0:0 | project/src/main/AndroidManifest.xml | diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.py b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.py index 36702f6bb24..ca4ae04350f 100644 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.py +++ b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.py @@ -1,8 +1,2 @@ -from create_database_utils import * -from toolchains_test_utils import * - -try_use_java11() - -toolchains_file = actions_expose_all_toolchains() - -run_codeql_database_create([], lang="java", extra_env={"LGTM_INDEX_MAVEN_TOOLCHAINS_FILE": toolchains_file}) +def test(codeql, use_java_11, java, android_sdk, actions_toolchains_file): + codeql.database.create(_env={"LGTM_INDEX_MAVEN_TOOLCHAINS_FILE": str(actions_toolchains_file)}) diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.ql b/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/.gitattributes b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/.gitattributes deleted file mode 100644 index 00a51aff5e5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090a2944b7473328c07c9755baa3196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60756 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 '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/gradlew.bat b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/gradlew.bat deleted file mode 100644 index f127cfd49d4..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/source_archive.expected b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/source_archive.expected new file mode 100644 index 00000000000..2d3a437d507 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/source_archive.expected @@ -0,0 +1,29 @@ +.gradle/7.4/dependencies-accessors/gc.properties +.gradle/7.4/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java +project/build/intermediates/app_metadata/release/app-metadata.properties +project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml +project/build/intermediates/incremental/lintVitalRelease/module.xml +project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalRelease/release.xml +project/build/intermediates/incremental/mergeReleaseAssets/merger.xml +project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml +project/build/intermediates/incremental/mergeReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/mergeReleaseResources/merger.xml +project/build/intermediates/incremental/mergeReleaseShaders/merger.xml +project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml +project/build/intermediates/merged_manifest/release/AndroidManifest.xml +project/build/intermediates/merged_manifests/release/AndroidManifest.xml +project/build/intermediates/packaged_manifests/release/AndroidManifest.xml +project/src/main/AndroidManifest.xml +project/src/main/java/com/github/androidsample/Main.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.expected b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.expected deleted file mode 100644 index f49910c2646..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.expected +++ /dev/null @@ -1,23 +0,0 @@ -#select -| project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java:0:0:0:0 | BuildConfig | -| project/src/main/java/com/github/androidsample/Main.java:0:0:0:0 | Main | -xmlFiles -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-testArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml | -| project/build/intermediates/incremental/lintVitalRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/module.xml | -| project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalRelease/release.xml | -| project/build/intermediates/incremental/mergeReleaseAssets/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseAssets/merger.xml | -| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml | -| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml | -| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml | -| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml | -| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml | -| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml | -| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml | -| project/src/main/AndroidManifest.xml:0:0:0:0 | project/src/main/AndroidManifest.xml | diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.py b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.py index 7f379da0a07..d3399e414e6 100644 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.py +++ b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.py @@ -1,7 +1,2 @@ -import sys - -from create_database_utils import * - -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, use_java_11, java, gradle_7_4, android_sdk): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.ql b/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/.gitattributes b/java/ql/integration-tests/all-platforms/java/android-sample/.gitattributes deleted file mode 100644 index 00a51aff5e5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/android-sample/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/android-sample/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090a2944b7473328c07c9755baa3196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60756 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 '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/gradlew.bat b/java/ql/integration-tests/all-platforms/java/android-sample/gradlew.bat deleted file mode 100644 index f127cfd49d4..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/source_archive.expected b/java/ql/integration-tests/all-platforms/java/android-sample/source_archive.expected new file mode 100644 index 00000000000..70b1edf245a --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/android-sample/source_archive.expected @@ -0,0 +1,26 @@ +.gradle/7.4/dependencies-accessors/gc.properties +.gradle/7.4/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java +project/build/intermediates/app_metadata/release/app-metadata.properties +project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml +project/build/intermediates/incremental/lintVitalReportRelease/module.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml +project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml +project/build/intermediates/incremental/lintVitalReportRelease/release.xml +project/build/intermediates/incremental/mergeReleaseAssets/merger.xml +project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml +project/build/intermediates/incremental/mergeReleaseShaders/merger.xml +project/build/intermediates/incremental/release/mergeReleaseResources/compile-file-map.properties +project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml +project/build/intermediates/merged_manifest/release/AndroidManifest.xml +project/build/intermediates/merged_manifests/release/AndroidManifest.xml +project/build/intermediates/packaged_manifests/release/AndroidManifest.xml +project/src/main/AndroidManifest.xml +project/src/main/java/com/github/androidsample/Main.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/test.expected b/java/ql/integration-tests/all-platforms/java/android-sample/test.expected deleted file mode 100644 index 4f191ddaa1a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample/test.expected +++ /dev/null @@ -1,20 +0,0 @@ -#select -| project/build/generated/source/buildConfig/release/com/github/androidsample/BuildConfig.java:0:0:0:0 | BuildConfig | -| project/src/main/java/com/github/androidsample/Main.java:0:0:0:0 | Main | -xmlFiles -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/module.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalAnalyzeRelease/release.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/module.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/module.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-dependencies.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release-mainArtifact-libraries.xml | -| project/build/intermediates/incremental/lintVitalReportRelease/release.xml:0:0:0:0 | project/build/intermediates/incremental/lintVitalReportRelease/release.xml | -| project/build/intermediates/incremental/mergeReleaseAssets/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseAssets/merger.xml | -| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml | -| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml | -| project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/release/mergeReleaseResources/merger.xml | -| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml | -| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml | -| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml | -| project/src/main/AndroidManifest.xml:0:0:0:0 | project/src/main/AndroidManifest.xml | diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/test.py b/java/ql/integration-tests/all-platforms/java/android-sample/test.py index 7f379da0a07..d3399e414e6 100644 --- a/java/ql/integration-tests/all-platforms/java/android-sample/test.py +++ b/java/ql/integration-tests/all-platforms/java/android-sample/test.py @@ -1,7 +1,2 @@ -import sys - -from create_database_utils import * - -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, use_java_11, java, gradle_7_4, android_sdk): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/test.ql b/java/ql/integration-tests/all-platforms/java/android-sample/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/android-sample/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/ant-sample/test.py b/java/ql/integration-tests/all-platforms/java/ant-sample/test.py index ab8845cbd73..eb49efe6a2a 100644 --- a/java/ql/integration-tests/all-platforms/java/ant-sample/test.py +++ b/java/ql/integration-tests/all-platforms/java/ant-sample/test.py @@ -1,5 +1,2 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create([], lang="java") +def test(codeql, java): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.py b/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.py index 6d0437d3ae2..6e0e201d9a2 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.py @@ -1,20 +1,19 @@ -import sys - -from create_database_utils import * -from buildless_test_utils import * import subprocess +import logging -# Each of these serves the "repo" and "repo2" directories on http://localhost:924[89] -repo_server_process = subprocess.Popen(["python3", "-m", "http.server", "9428"], cwd = "repo") -repo_server_process2 = subprocess.Popen(["python3", "-m", "http.server", "9429"], cwd = "repo2") -try: - run_codeql_database_create([], lang="java", extra_args=["--extractor-option=buildless=true"], extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"}) -finally: - try: - repo_server_process.kill() - except Exception as e: - print("Failed to kill server 1:", e, file = sys.stderr) - repo_server_process2.kill() - -check_buildless_fetches() +def test(codeql, java): + # Each of these serves the "repo" and "repo2" directories on http://localhost:924[89] + repo_server_process = subprocess.Popen(["python3", "-m", "http.server", "9428"], cwd="repo") + repo_server_process2 = subprocess.Popen(["python3", "-m", "http.server", "9429"], cwd="repo2") + try: + codeql.database.create( + extractor_option="buildless=true", + _env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"}, + ) + finally: + try: + repo_server_process.kill() + except Exception as e: + logging.error("Failed to kill server 1:", e) + repo_server_process2.kill() diff --git a/java/ql/integration-tests/all-platforms/java/buildless-erroneous/test.py b/java/ql/integration-tests/all-platforms/java/buildless-erroneous/test.py index 747dd6a82ad..834b1132cf1 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-erroneous/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-erroneous/test.py @@ -1,8 +1,2 @@ -import sys - -from create_database_utils import * -from diagnostics_test_utils import * - -run_codeql_database_create([], lang="java", extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true"}) - -check_diagnostics() +def test(codeql, java): + codeql.database.create(_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true"}) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/.gitattributes b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/.gitattributes deleted file mode 100644 index 097f9f98d9e..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/.gitattributes +++ /dev/null @@ -1,9 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# Linux start script should use lf -/gradlew text eol=lf - -# These are Windows script files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/.gitignore b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/.gitignore deleted file mode 100644 index 1b6985c0094..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Ignore Gradle project-specific cache directory -.gradle - -# Ignore Gradle build output directory -build diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63721 zcmb5Wb9gP!wgnp7wrv|bwr$&XvSZt}Z6`anZSUAlc9NHKf9JdJ;NJVr`=eI(_pMp0 zy1VAAG3FfAOI`{X1O)&90s;U4K;XLp008~hCjbEC_fbYfS%6kTR+JtXK>nW$ZR+`W ze|#J8f4A@M|F5BpfUJb5h>|j$jOe}0oE!`Zf6fM>CR?!y@zU(cL8NsKk`a z6tx5mAkdjD;J=LcJ;;Aw8p!v#ouk>mUDZF@ zK>yvw%+bKu+T{Nk@LZ;zkYy0HBKw06_IWcMHo*0HKpTsEFZhn5qCHH9j z)|XpN&{`!0a>Vl+PmdQc)Yg4A(AG-z!+@Q#eHr&g<9D?7E)_aEB?s_rx>UE9TUq|? z;(ggJt>9l?C|zoO@5)tu?EV0x_7T17q4fF-q3{yZ^ipUbKcRZ4Qftd!xO(#UGhb2y>?*@{xq%`(-`2T^vc=#< zx!+@4pRdk&*1ht2OWk^Z5IAQ0YTAXLkL{(D*$gENaD)7A%^XXrCchN&z2x+*>o2FwPFjWpeaL=!tzv#JOW#( z$B)Nel<+$bkH1KZv3&-}=SiG~w2sbDbAWarg%5>YbC|}*d9hBjBkR(@tyM0T)FO$# zPtRXukGPnOd)~z=?avu+4Co@wF}1T)-uh5jI<1$HLtyDrVak{gw`mcH@Q-@wg{v^c zRzu}hMKFHV<8w}o*yg6p@Sq%=gkd~;`_VGTS?L@yVu`xuGy+dH6YOwcP6ZE`_0rK% zAx5!FjDuss`FQ3eF|mhrWkjux(Pny^k$u_)dyCSEbAsecHsq#8B3n3kDU(zW5yE|( zgc>sFQywFj5}U*qtF9Y(bi*;>B7WJykcAXF86@)z|0-Vm@jt!EPoLA6>r)?@DIobIZ5Sx zsc@OC{b|3%vaMbyeM|O^UxEYlEMHK4r)V-{r)_yz`w1*xV0|lh-LQOP`OP`Pk1aW( z8DSlGN>Ts|n*xj+%If~+E_BxK)~5T#w6Q1WEKt{!Xtbd`J;`2a>8boRo;7u2M&iOop4qcy<)z023=oghSFV zST;?S;ye+dRQe>ygiJ6HCv4;~3DHtJ({fWeE~$H@mKn@Oh6Z(_sO>01JwH5oA4nvK zr5Sr^g+LC zLt(i&ecdmqsIJGNOSUyUpglvhhrY8lGkzO=0USEKNL%8zHshS>Qziu|`eyWP^5xL4 zRP122_dCJl>hZc~?58w~>`P_s18VoU|7(|Eit0-lZRgLTZKNq5{k zE?V=`7=R&ro(X%LTS*f+#H-mGo_j3dm@F_krAYegDLk6UV{`UKE;{YSsn$ z(yz{v1@p|p!0>g04!eRSrSVb>MQYPr8_MA|MpoGzqyd*$@4j|)cD_%^Hrd>SorF>@ zBX+V<@vEB5PRLGR(uP9&U&5=(HVc?6B58NJT_igiAH*q~Wb`dDZpJSKfy5#Aag4IX zj~uv74EQ_Q_1qaXWI!7Vf@ZrdUhZFE;L&P_Xr8l@GMkhc#=plV0+g(ki>+7fO%?Jb zl+bTy7q{w^pTb{>(Xf2q1BVdq?#f=!geqssXp z4pMu*q;iiHmA*IjOj4`4S&|8@gSw*^{|PT}Aw~}ZXU`6=vZB=GGeMm}V6W46|pU&58~P+?LUs%n@J}CSrICkeng6YJ^M? zS(W?K4nOtoBe4tvBXs@@`i?4G$S2W&;$z8VBSM;Mn9 zxcaEiQ9=vS|bIJ>*tf9AH~m&U%2+Dim<)E=}KORp+cZ^!@wI`h1NVBXu{@%hB2Cq(dXx_aQ9x3mr*fwL5!ZryQqi|KFJuzvP zK1)nrKZ7U+B{1ZmJub?4)Ln^J6k!i0t~VO#=q1{?T)%OV?MN}k5M{}vjyZu#M0_*u z8jwZKJ#Df~1jcLXZL7bnCEhB6IzQZ-GcoQJ!16I*39iazoVGugcKA{lhiHg4Ta2fD zk1Utyc5%QzZ$s3;p0N+N8VX{sd!~l*Ta3|t>lhI&G`sr6L~G5Lul`>m z{!^INm?J|&7X=;{XveF!(b*=?9NAp4y&r&N3(GKcW4rS(Ejk|Lzs1PrxPI_owB-`H zg3(Rruh^&)`TKA6+_!n>RdI6pw>Vt1_j&+bKIaMTYLiqhZ#y_=J8`TK{Jd<7l9&sY z^^`hmi7^14s16B6)1O;vJWOF$=$B5ONW;;2&|pUvJlmeUS&F;DbSHCrEb0QBDR|my zIs+pE0Y^`qJTyH-_mP=)Y+u^LHcuZhsM3+P||?+W#V!_6E-8boP#R-*na4!o-Q1 zVthtYhK{mDhF(&7Okzo9dTi03X(AE{8cH$JIg%MEQca`S zy@8{Fjft~~BdzWC(di#X{ny;!yYGK9b@=b|zcKZ{vv4D8i+`ilOPl;PJl{!&5-0!w z^fOl#|}vVg%=n)@_e1BrP)`A zKPgs`O0EO}Y2KWLuo`iGaKu1k#YR6BMySxQf2V++Wo{6EHmK>A~Q5o73yM z-RbxC7Qdh0Cz!nG+7BRZE>~FLI-?&W_rJUl-8FDIaXoNBL)@1hwKa^wOr1($*5h~T zF;%f^%<$p8Y_yu(JEg=c_O!aZ#)Gjh$n(hfJAp$C2he555W5zdrBqjFmo|VY+el;o z=*D_w|GXG|p0**hQ7~9-n|y5k%B}TAF0iarDM!q-jYbR^us(>&y;n^2l0C%@2B}KM zyeRT9)oMt97Agvc4sEKUEy%MpXr2vz*lb zh*L}}iG>-pqDRw7ud{=FvTD?}xjD)w{`KzjNom-$jS^;iw0+7nXSnt1R@G|VqoRhE%12nm+PH?9`(4rM0kfrZzIK9JU=^$YNyLvAIoxl#Q)xxDz!^0@zZ zSCs$nfcxK_vRYM34O<1}QHZ|hp4`ioX3x8(UV(FU$J@o%tw3t4k1QPmlEpZa2IujG&(roX_q*%e`Hq|);0;@k z0z=fZiFckp#JzW0p+2A+D$PC~IsakhJJkG(c;CqAgFfU0Z`u$PzG~-9I1oPHrCw&)@s^Dc~^)#HPW0Ra}J^=|h7Fs*<8|b13ZzG6MP*Q1dkoZ6&A^!}|hbjM{2HpqlSXv_UUg1U4gn z3Q)2VjU^ti1myodv+tjhSZp%D978m~p& z43uZUrraHs80Mq&vcetqfQpQP?m!CFj)44t8Z}k`E798wxg&~aCm+DBoI+nKq}&j^ zlPY3W$)K;KtEajks1`G?-@me7C>{PiiBu+41#yU_c(dITaqE?IQ(DBu+c^Ux!>pCj zLC|HJGU*v+!it1(;3e`6igkH(VA)-S+k(*yqxMgUah3$@C zz`7hEM47xr>j8^g`%*f=6S5n>z%Bt_Fg{Tvmr+MIsCx=0gsu_sF`q2hlkEmisz#Fy zj_0;zUWr;Gz}$BS%Y`meb(=$d%@Crs(OoJ|}m#<7=-A~PQbyN$x%2iXP2@e*nO0b7AwfH8cCUa*Wfu@b)D_>I*%uE4O3 z(lfnB`-Xf*LfC)E}e?%X2kK7DItK6Tf<+M^mX0Ijf_!IP>7c8IZX%8_#0060P{QMuV^B9i<^E`_Qf0pv9(P%_s8D`qvDE9LK9u-jB}J2S`(mCO&XHTS04Z5Ez*vl^T%!^$~EH8M-UdwhegL>3IQ*)(MtuH2Xt1p!fS4o~*rR?WLxlA!sjc2(O znjJn~wQ!Fp9s2e^IWP1C<4%sFF}T4omr}7+4asciyo3DntTgWIzhQpQirM$9{EbQd z3jz9vS@{aOqTQHI|l#aUV@2Q^Wko4T0T04Me4!2nsdrA8QY1%fnAYb~d2GDz@lAtfcHq(P7 zaMBAGo}+NcE-K*@9y;Vt3*(aCaMKXBB*BJcD_Qnxpt75r?GeAQ}*|>pYJE=uZb73 zC>sv)18)q#EGrTG6io*}JLuB_jP3AU1Uiu$D7r|2_zlIGb9 zjhst#ni)Y`$)!fc#reM*$~iaYoz~_Cy7J3ZTiPm)E?%`fbk`3Tu-F#`{i!l5pNEn5 zO-Tw-=TojYhzT{J=?SZj=Z8#|eoF>434b-DXiUsignxXNaR3 zm_}4iWU$gt2Mw5NvZ5(VpF`?X*f2UZDs1TEa1oZCif?Jdgr{>O~7}-$|BZ7I(IKW`{f;@|IZFX*R8&iT= zoWstN8&R;}@2Ka%d3vrLtR|O??ben;k8QbS-WB0VgiCz;<$pBmIZdN!aalyCSEm)crpS9dcD^Y@XT1a3+zpi-`D}e#HV<} z$Y(G&o~PvL-xSVD5D?JqF3?B9rxGWeb=oEGJ3vRp5xfBPlngh1O$yI95EL+T8{GC@ z98i1H9KhZGFl|;`)_=QpM6H?eDPpw~^(aFQWwyXZ8_EEE4#@QeT_URray*mEOGsGc z6|sdXtq!hVZo=d#+9^@lm&L5|q&-GDCyUx#YQiccq;spOBe3V+VKdjJA=IL=Zn%P} zNk=_8u}VhzFf{UYZV0`lUwcD&)9AFx0@Fc6LD9A6Rd1=ga>Mi0)_QxM2ddCVRmZ0d z+J=uXc(?5JLX3=)e)Jm$HS2yF`44IKhwRnm2*669_J=2LlwuF5$1tAo@ROSU@-y+;Foy2IEl2^V1N;fk~YR z?&EP8#t&m0B=?aJeuz~lHjAzRBX>&x=A;gIvb>MD{XEV zV%l-+9N-)i;YH%nKP?>f`=?#`>B(`*t`aiPLoQM(a6(qs4p5KFjDBN?8JGrf3z8>= zi7sD)c)Nm~x{e<^jy4nTx${P~cwz_*a>%0_;ULou3kHCAD7EYkw@l$8TN#LO9jC( z1BeFW`k+bu5e8Ns^a8dPcjEVHM;r6UX+cN=Uy7HU)j-myRU0wHd$A1fNI~`4;I~`zC)3ul#8#^rXVSO*m}Ag>c%_;nj=Nv$rCZ z*~L@C@OZg%Q^m)lc-kcX&a*a5`y&DaRxh6O*dfhLfF+fU5wKs(1v*!TkZidw*)YBP za@r`3+^IHRFeO%!ai%rxy;R;;V^Fr=OJlpBX;(b*3+SIw}7= zIq$*Thr(Zft-RlY)D3e8V;BmD&HOfX+E$H#Y@B3?UL5L~_fA-@*IB-!gItK7PIgG9 zgWuGZK_nuZjHVT_Fv(XxtU%)58;W39vzTI2n&)&4Dmq7&JX6G>XFaAR{7_3QB6zsT z?$L8c*WdN~nZGiscY%5KljQARN;`w$gho=p006z;n(qIQ*Zu<``TMO3n0{ARL@gYh zoRwS*|Niw~cR!?hE{m*y@F`1)vx-JRfqET=dJ5_(076st(=lFfjtKHoYg`k3oNmo_ zNbQEw8&sO5jAYmkD|Zaz_yUb0rC})U!rCHOl}JhbYIDLzLvrZVw0~JO`d*6f;X&?V=#T@ND*cv^I;`sFeq4 z##H5;gpZTb^0Hz@3C*~u0AqqNZ-r%rN3KD~%Gw`0XsIq$(^MEb<~H(2*5G^<2(*aI z%7}WB+TRlMIrEK#s0 z93xn*Ohb=kWFc)BNHG4I(~RPn-R8#0lqyBBz5OM6o5|>x9LK@%HaM}}Y5goCQRt2C z{j*2TtT4ne!Z}vh89mjwiSXG=%DURar~=kGNNaO_+Nkb+tRi~Rkf!7a$*QlavziD( z83s4GmQ^Wf*0Bd04f#0HX@ua_d8 z23~z*53ePD6@xwZ(vdl0DLc=>cPIOPOdca&MyR^jhhKrdQO?_jJh`xV3GKz&2lvP8 zEOwW6L*ufvK;TN{=S&R@pzV^U=QNk^Ec}5H z+2~JvEVA{`uMAr)?Kf|aW>33`)UL@bnfIUQc~L;TsTQ6>r-<^rB8uoNOJ>HWgqMI8 zSW}pZmp_;z_2O5_RD|fGyTxaxk53Hg_3Khc<8AUzV|ZeK{fp|Ne933=1&_^Dbv5^u zB9n=*)k*tjHDRJ@$bp9mrh}qFn*s}npMl5BMDC%Hs0M0g-hW~P*3CNG06G!MOPEQ_ zi}Qs-6M8aMt;sL$vlmVBR^+Ry<64jrm1EI1%#j?c?4b*7>)a{aDw#TfTYKq+SjEFA z(aJ&z_0?0JB83D-i3Vh+o|XV4UP+YJ$9Boid2^M2en@APw&wx7vU~t$r2V`F|7Qfo z>WKgI@eNBZ-+Og<{u2ZiG%>YvH2L3fNpV9J;WLJoBZda)01Rn;o@){01{7E#ke(7U zHK>S#qZ(N=aoae*4X!0A{)nu0R_sKpi1{)u>GVjC+b5Jyl6#AoQ-1_3UDovNSo`T> z?c-@7XX*2GMy?k?{g)7?Sv;SJkmxYPJPs!&QqB12ejq`Lee^-cDveVWL^CTUldb(G zjDGe(O4P=S{4fF=#~oAu>LG>wrU^z_?3yt24FOx>}{^lCGh8?vtvY$^hbZ)9I0E3r3NOlb9I?F-Yc=r$*~l`4N^xzlV~N zl~#oc>U)Yjl0BxV>O*Kr@lKT{Z09OXt2GlvE38nfs+DD7exl|&vT;)>VFXJVZp9Np zDK}aO;R3~ag$X*|hRVY3OPax|PG`@_ESc8E!mHRByJbZQRS38V2F__7MW~sgh!a>98Q2%lUNFO=^xU52|?D=IK#QjwBky-C>zOWlsiiM&1n z;!&1((Xn1$9K}xabq~222gYvx3hnZPg}VMF_GV~5ocE=-v>V=T&RsLBo&`)DOyIj* zLV{h)JU_y*7SdRtDajP_Y+rBkNN*1_TXiKwHH2&p51d(#zv~s#HwbNy?<+(=9WBvo zw2hkk2Dj%kTFhY+$T+W-b7@qD!bkfN#Z2ng@Pd=i3-i?xYfs5Z*1hO?kd7Sp^9`;Y zM2jeGg<-nJD1er@Pc_cSY7wo5dzQX44=%6rn}P_SRbpzsA{6B+!$3B0#;}qwO37G^ zL(V_5JK`XT?OHVk|{_$vQ|oNEpab*BO4F zUTNQ7RUhnRsU`TK#~`)$icsvKh~(pl=3p6m98@k3P#~upd=k*u20SNcb{l^1rUa)>qO997)pYRWMncC8A&&MHlbW?7i^7M`+B$hH~Y|J zd>FYOGQ;j>Zc2e7R{KK7)0>>nn_jYJy&o@sK!4G>-rLKM8Hv)f;hi1D2fAc$+six2 zyVZ@wZ6x|fJ!4KrpCJY=!Mq0;)X)OoS~{Lkh6u8J`eK%u0WtKh6B>GW_)PVc zl}-k`p09qwGtZ@VbYJC!>29V?Dr>>vk?)o(x?!z*9DJ||9qG-&G~#kXxbw{KKYy}J zQKa-dPt~M~E}V?PhW0R26xdA%1T*%ra6SguGu50YHngOTIv)@N|YttEXo#OZfgtP7;H?EeZZxo<}3YlYxtBq znJ!WFR^tmGf0Py}N?kZ(#=VtpC@%xJkDmfcCoBTxq zr_|5gP?u1@vJZbxPZ|G0AW4=tpb84gM2DpJU||(b8kMOV1S3|(yuwZJ&rIiFW(U;5 zUtAW`O6F6Zy+eZ1EDuP~AAHlSY-+A_eI5Gx)%*uro5tljy}kCZU*_d7)oJ>oQSZ3* zneTn`{gnNC&uJd)0aMBzAg021?YJ~b(fmkwZAd696a=0NzBAqBN54KuNDwa*no(^O z6p05bioXUR^uXjpTol*ppHp%1v9e)vkoUAUJyBx3lw0UO39b0?^{}yb!$yca(@DUn zCquRF?t=Zb9`Ed3AI6|L{eX~ijVH`VzSMheKoP7LSSf4g>md>`yi!TkoG5P>Ofp+n z(v~rW+(5L96L{vBb^g51B=(o)?%%xhvT*A5btOpw(TKh^g^4c zw>0%X!_0`{iN%RbVk+A^f{w-4-SSf*fu@FhruNL##F~sF24O~u zyYF<3el2b$$wZ_|uW#@Ak+VAGk#e|kS8nL1g>2B-SNMjMp^8;-FfeofY2fphFHO!{ z*!o4oTb{4e;S<|JEs<1_hPsmAlVNk?_5-Fp5KKU&d#FiNW~Y+pVFk@Cua1I{T+1|+ zHx6rFMor)7L)krbilqsWwy@T+g3DiH5MyVf8Wy}XbEaoFIDr~y;@r&I>FMW{ z?Q+(IgyebZ)-i4jNoXQhq4Muy9Fv+OxU;9_Jmn+<`mEC#%2Q_2bpcgzcinygNI!&^ z=V$)o2&Yz04~+&pPWWn`rrWxJ&}8khR)6B(--!9Q zubo}h+1T)>a@c)H^i``@<^j?|r4*{;tQf78(xn0g39IoZw0(CwY1f<%F>kEaJ zp9u|IeMY5mRdAlw*+gSN^5$Q)ShM<~E=(c8QM+T-Qk)FyKz#Sw0EJ*edYcuOtO#~Cx^(M7w5 z3)rl#L)rF|(Vun2LkFr!rg8Q@=r>9p>(t3Gf_auiJ2Xx9HmxYTa|=MH_SUlYL`mz9 zTTS$`%;D-|Jt}AP1&k7PcnfFNTH0A-*FmxstjBDiZX?}%u%Yq94$fUT&z6od+(Uk> zuqsld#G(b$G8tus=M!N#oPd|PVFX)?M?tCD0tS%2IGTfh}3YA3f&UM)W$_GNV8 zQo+a(ml2Km4o6O%gKTCSDNq+#zCTIQ1*`TIJh~k6Gp;htHBFnne))rlFdGqwC6dx2+La1&Mnko*352k0y z+tQcwndQlX`nc6nb$A9?<-o|r*%aWXV#=6PQic0Ok_D;q>wbv&j7cKc!w4~KF#-{6 z(S%6Za)WpGIWf7jZ3svNG5OLs0>vCL9{V7cgO%zevIVMH{WgP*^D9ws&OqA{yr|m| zKD4*07dGXshJHd#e%x%J+qmS^lS|0Bp?{drv;{@{l9ArPO&?Q5=?OO9=}h$oVe#3b z3Yofj&Cb}WC$PxmRRS)H%&$1-)z7jELS}!u!zQ?A^Y{Tv4QVt*vd@uj-^t2fYRzQj zfxGR>-q|o$3sGn^#VzZ!QQx?h9`njeJry}@x?|k0-GTTA4y3t2E`3DZ!A~D?GiJup z)8%PK2^9OVRlP(24P^4_<|D=H^7}WlWu#LgsdHzB%cPy|f8dD3|A^mh4WXxhLTVu_ z@abE{6Saz|Y{rXYPd4$tfPYo}ef(oQWZ=4Bct-=_9`#Qgp4ma$n$`tOwq#&E18$B; z@Bp)bn3&rEi0>fWWZ@7k5WazfoX`SCO4jQWwVuo+$PmSZn^Hz?O(-tW@*DGxuf)V1 zO_xm&;NVCaHD4dqt(-MlszI3F-p?0!-e$fbiCeuaw66h^TTDLWuaV<@C-`=Xe5WL) zwooG7h>4&*)p3pKMS3O!4>-4jQUN}iAMQ)2*70?hP~)TzzR?-f@?Aqy$$1Iy8VGG$ zMM?8;j!pUX7QQD$gRc_#+=raAS577ga-w?jd`vCiN5lu)dEUkkUPl9!?{$IJNxQys z*E4e$eF&n&+AMRQR2gcaFEjAy*r)G!s(P6D&TfoApMFC_*Ftx0|D0@E-=B7tezU@d zZ{hGiN;YLIoSeRS;9o%dEua4b%4R3;$SugDjP$x;Z!M!@QibuSBb)HY!3zJ7M;^jw zlx6AD50FD&p3JyP*>o+t9YWW8(7P2t!VQQ21pHJOcG_SXQD;(5aX#M6x##5H_Re>6lPyDCjxr*R(+HE%c&QN+b^tbT zXBJk?p)zhJj#I?&Y2n&~XiytG9!1ox;bw5Rbj~)7c(MFBb4>IiRATdhg zmiEFlj@S_hwYYI(ki{}&<;_7(Z0Qkfq>am z&LtL=2qc7rWguk3BtE4zL41@#S;NN*-jWw|7Kx7H7~_%7fPt;TIX}Ubo>;Rmj94V> zNB1=;-9AR7s`Pxn}t_6^3ahlq53e&!Lh85uG zec0vJY_6e`tg7LgfrJ3k!DjR)Bi#L@DHIrZ`sK=<5O0Ip!fxGf*OgGSpP@Hbbe&$9 z;ZI}8lEoC2_7;%L2=w?tb%1oL0V+=Z`7b=P&lNGY;yVBazXRYu;+cQDKvm*7NCxu&i;zub zAJh#11%?w>E2rf2e~C4+rAb-&$^vsdACs7 z@|Ra!OfVM(ke{vyiqh7puf&Yp6cd6{DptUteYfIRWG3pI+5< zBVBI_xkBAc<(pcb$!Y%dTW(b;B;2pOI-(QCsLv@U-D1XJ z(Gk8Q3l7Ws46Aktuj>|s{$6zA&xCPuXL-kB`CgYMs}4IeyG*P51IDwW?8UNQd+$i~ zlxOPtSi5L|gJcF@DwmJA5Ju8HEJ>o{{upwIpb!f{2(vLNBw`7xMbvcw<^{Fj@E~1( z?w`iIMieunS#>nXlmUcSMU+D3rX28f?s7z;X=se6bo8;5vM|O^(D6{A9*ChnGH!RG zP##3>LDC3jZPE4PH32AxrqPk|yIIrq~`aL-=}`okhNu9aT%q z1b)7iJ)CN=V#Ly84N_r7U^SH2FGdE5FpTO2 z630TF$P>GNMu8`rOytb(lB2};`;P4YNwW1<5d3Q~AX#P0aX}R2b2)`rgkp#zTxcGj zAV^cvFbhP|JgWrq_e`~exr~sIR$6p5V?o4Wym3kQ3HA+;Pr$bQ0(PmADVO%MKL!^q z?zAM8j1l4jrq|5X+V!8S*2Wl@=7*pPgciTVK6kS1Ge zMsd_u6DFK$jTnvVtE;qa+8(1sGBu~n&F%dh(&c(Zs4Fc#A=gG^^%^AyH}1^?|8quj zl@Z47h$){PlELJgYZCIHHL= z{U8O>Tw4x3<1{?$8>k-P<}1y9DmAZP_;(3Y*{Sk^H^A=_iSJ@+s5ktgwTXz_2$~W9>VVZsfwCm@s0sQ zeB50_yu@uS+e7QoPvdCwDz{prjo(AFwR%C?z`EL{1`|coJHQTk^nX=tvs1<0arUOJ z!^`*x&&BvTYmemyZ)2p~{%eYX=JVR?DYr(rNgqRMA5E1PR1Iw=prk=L2ldy3r3Vg@27IZx43+ywyzr-X*p*d@tZV+!U#~$-q=8c zgdSuh#r?b4GhEGNai)ayHQpk>5(%j5c@C1K3(W1pb~HeHpaqijJZa-e6vq_8t-^M^ zBJxq|MqZc?pjXPIH}70a5vt!IUh;l}<>VX<-Qcv^u@5(@@M2CHSe_hD$VG-eiV^V( zj7*9T0?di?P$FaD6oo?)<)QT>Npf6Og!GO^GmPV(Km0!=+dE&bk#SNI+C9RGQ|{~O*VC+tXK3!n`5 zHfl6>lwf_aEVV3`0T!aHNZLsj$paS$=LL(?b!Czaa5bbSuZ6#$_@LK<(7yrrl+80| z{tOFd=|ta2Z`^ssozD9BINn45NxUeCQis?-BKmU*Kt=FY-NJ+)8S1ecuFtN-M?&42 zl2$G>u!iNhAk*HoJ^4v^9#ORYp5t^wDj6|lx~5w45#E5wVqI1JQ~9l?nPp1YINf++ zMAdSif~_ETv@Er(EFBI^@L4BULFW>)NI+ejHFP*T}UhWNN`I)RRS8za? z*@`1>9ZB}An%aT5K=_2iQmfE;GcBVHLF!$`I99o5GO`O%O_zLr9AG18>&^HkG(;=V z%}c!OBQ~?MX(9h~tajX{=x)+!cbM7$YzTlmsPOdp2L-?GoW`@{lY9U3f;OUo*BwRB z8A+nv(br0-SH#VxGy#ZrgnGD(=@;HME;yd46EgWJ`EL%oXc&lFpc@Y}^>G(W>h_v_ zlN!`idhX+OjL+~T?19sroAFVGfa5tX-D49w$1g2g_-T|EpHL6}K_aX4$K=LTvwtlF zL*z}j{f+Uoe7{-px3_5iKPA<_7W=>Izkk)!l9ez2w%vi(?Y;i8AxRNLSOGDzNoqoI zP!1uAl}r=_871(G?y`i&)-7{u=%nxk7CZ_Qh#!|ITec zwQn`33GTUM`;D2POWnkqngqJhJRlM>CTONzTG}>^Q0wUunQyn|TAiHzyX2_%ATx%P z%7gW)%4rA9^)M<_%k@`Y?RbC<29sWU&5;@|9thf2#zf8z12$hRcZ!CSb>kUp=4N#y zl3hE#y6>kkA8VY2`W`g5Ip?2qC_BY$>R`iGQLhz2-S>x(RuWv)SPaGdl^)gGw7tjR zH@;jwk!jIaCgSg_*9iF|a);sRUTq30(8I(obh^|}S~}P4U^BIGYqcz;MPpC~Y@k_m zaw4WG1_vz2GdCAX!$_a%GHK**@IrHSkGoN>)e}>yzUTm52on`hYot7cB=oA-h1u|R ztH$11t?54Qg2L+i33FPFKKRm1aOjKST{l1*(nps`>sv%VqeVMWjl5+Gh+9);hIP8? zA@$?}Sc z3qIRpba+y5yf{R6G(u8Z^vkg0Fu&D-7?1s=QZU`Ub{-!Y`I?AGf1VNuc^L3v>)>i# z{DV9W$)>34wnzAXUiV^ZpYKw>UElrN_5Xj6{r_3| z$X5PK`e5$7>~9Dj7gK5ash(dvs`vwfk}&RD`>04;j62zoXESkFBklYaKm5seyiX(P zqQ-;XxlV*yg?Dhlx%xt!b0N3GHp@(p$A;8|%# zZ5m2KL|{on4nr>2_s9Yh=r5ScQ0;aMF)G$-9-Ca6%wA`Pa)i?NGFA|#Yi?{X-4ZO_ z^}%7%vkzvUHa$-^Y#aA+aiR5sa%S|Ebyn`EV<3Pc?ax_f>@sBZF1S;7y$CXd5t5=WGsTKBk8$OfH4v|0?0I=Yp}7c=WBSCg!{0n)XmiU;lfx)**zZaYqmDJelxk$)nZyx5`x$6R|fz(;u zEje5Dtm|a%zK!!tk3{i9$I2b{vXNFy%Bf{50X!x{98+BsDr_u9i>G5%*sqEX|06J0 z^IY{UcEbj6LDwuMh7cH`H@9sVt1l1#8kEQ(LyT@&+K}(ReE`ux8gb0r6L_#bDUo^P z3Ka2lRo52Hdtl_%+pwVs14=q`{d^L58PsU@AMf(hENumaxM{7iAT5sYmWh@hQCO^ zK&}ijo=`VqZ#a3vE?`7QW0ZREL17ZvDfdqKGD?0D4fg{7v%|Yj&_jcKJAB)>=*RS* zto8p6@k%;&^ZF>hvXm&$PCuEp{uqw3VPG$9VMdW5$w-fy2CNNT>E;>ejBgy-m_6`& z97L1p{%srn@O_JQgFpa_#f(_)eb#YS>o>q3(*uB;uZb605(iqM$=NK{nHY=+X2*G) zO3-_Xh%aG}fHWe*==58zBwp%&`mge<8uq8;xIxOd=P%9EK!34^E9sk|(Zq1QSz-JVeP12Fp)-`F|KY$LPwUE?rku zY@OJ)Z9A!ojfzfeyJ9;zv2EM7ZQB)AR5xGa-tMn^bl)FmoIiVyJ@!~@%{}qXXD&Ns zPnfe5U+&ohKefILu_1mPfLGuapX@btta5C#gPB2cjk5m4T}Nfi+Vfka!Yd(L?-c~5 z#ZK4VeQEXNPc4r$K00Fg>g#_W!YZ)cJ?JTS<&68_$#cZT-ME`}tcwqg3#``3M3UPvn+pi}(VNNx6y zFIMVb6OwYU(2`at$gHba*qrMVUl8xk5z-z~fb@Q3Y_+aXuEKH}L+>eW__!IAd@V}L zkw#s%H0v2k5-=vh$^vPCuAi22Luu3uKTf6fPo?*nvj$9(u)4$6tvF-%IM+3pt*cgs z_?wW}J7VAA{_~!?))?s6{M=KPpVhg4fNuU*|3THp@_(q!b*hdl{fjRVFWtu^1dV(f z6iOux9hi&+UK=|%M*~|aqFK{Urfl!TA}UWY#`w(0P!KMe1Si{8|o))Gy6d7;!JQYhgMYmXl?3FfOM2nQGN@~Ap6(G z3+d_5y@=nkpKAhRqf{qQ~k7Z$v&l&@m7Ppt#FSNzKPZM z8LhihcE6i=<(#87E|Wr~HKvVWhkll4iSK$^mUHaxgy8*K$_Zj;zJ`L$naPj+^3zTi z-3NTaaKnD5FPY-~?Tq6QHnmDDRxu0mh0D|zD~Y=vv_qig5r-cIbCpxlju&8Sya)@{ zsmv6XUSi)@(?PvItkiZEeN*)AE~I_?#+Ja-r8$(XiXei2d@Hi7Rx8+rZZb?ZLa{;@*EHeRQ-YDadz~M*YCM4&F-r;E#M+@CSJMJ0oU|PQ^ z=E!HBJDMQ2TN*Y(Ag(ynAL8%^v;=~q?s4plA_hig&5Z0x_^Oab!T)@6kRN$)qEJ6E zNuQjg|G7iwU(N8pI@_6==0CL;lRh1dQF#wePhmu@hADFd3B5KIH#dx(2A zp~K&;Xw}F_N6CU~0)QpQk7s$a+LcTOj1%=WXI(U=Dv!6 z{#<#-)2+gCyyv=Jw?Ab#PVkxPDeH|sAxyG`|Ys}A$PW4TdBv%zDz z^?lwrxWR<%Vzc8Sgt|?FL6ej_*e&rhqJZ3Y>k=X(^dytycR;XDU16}Pc9Vn0>_@H+ zQ;a`GSMEG64=JRAOg%~L)x*w{2re6DVprNp+FcNra4VdNjiaF0M^*>CdPkt(m150rCue?FVdL0nFL$V%5y6N z%eLr5%YN7D06k5ji5*p4v$UMM)G??Q%RB27IvH7vYr_^3>1D-M66#MN8tWGw>WED} z5AhlsanO=STFYFs)Il_0i)l)f<8qn|$DW7ZXhf5xI;m+7M5-%P63XFQrG9>DMqHc} zsgNU9nR`b}E^mL5=@7<1_R~j@q_2U^3h|+`7YH-?C=vme1C3m`Fe0HC>pjt6f_XMh zy~-i-8R46QNYneL4t@)<0VU7({aUO?aH`z4V2+kxgH5pYD5)wCh75JqQY)jIPN=U6 z+qi8cGiOtXG2tXm;_CfpH9ESCz#i5B(42}rBJJF$jh<1sbpj^8&L;gzGHb8M{of+} zzF^8VgML2O9nxBW7AvdEt90vp+#kZxWf@A)o9f9}vKJy9NDBjBW zSt=Hcs=YWCwnfY1UYx*+msp{g!w0HC<_SM!VL1(I2PE?CS}r(eh?{I)mQixmo5^p# zV?2R!R@3GV6hwTCrfHiK#3Orj>I!GS2kYhk1S;aFBD_}u2v;0HYFq}Iz1Z(I4oca4 zxquja8$+8JW_EagDHf$a1OTk5S97umGSDaj)gH=fLs9>_=XvVj^Xj9a#gLdk=&3tl zfmK9MNnIX9v{?%xdw7568 zNrZ|roYs(vC4pHB5RJ8>)^*OuyNC>x7ad)tB_}3SgQ96+-JT^Qi<`xi=)_=$Skwv~ zdqeT9Pa`LYvCAn&rMa2aCDV(TMI#PA5g#RtV|CWpgDYRA^|55LLN^uNh*gOU>Z=a06qJ;$C9z8;n-Pq=qZnc1zUwJ@t)L;&NN+E5m zRkQ(SeM8=l-aoAKGKD>!@?mWTW&~)uF2PYUJ;tB^my`r9n|Ly~0c%diYzqs9W#FTjy?h&X3TnH zXqA{QI82sdjPO->f=^K^f>N`+B`q9&rN0bOXO79S&a9XX8zund(kW7O76f4dcWhIu zER`XSMSFbSL>b;Rp#`CuGJ&p$s~G|76){d?xSA5wVg##_O0DrmyEYppyBr%fyWbbv zp`K84JwRNP$d-pJ!Qk|(RMr?*!wi1if-9G#0p>>1QXKXWFy)eB3ai)l3601q8!9JC zvU#ZWWDNKq9g6fYs?JQ)Q4C_cgTy3FhgKb8s&m)DdmL5zhNK#8wWg!J*7G7Qhe9VU zha?^AQTDpYcuN!B+#1dE*X{<#!M%zfUQbj=zLE{dW0XeQ7-oIsGY6RbkP2re@Q{}r_$iiH0xU%iN*ST`A)-EH6eaZB$GA#v)cLi z*MpA(3bYk$oBDKAzu^kJoSUsDd|856DApz={3u8sbQV@JnRkp2nC|)m;#T=DvIL-O zI4vh;g7824l}*`_p@MT4+d`JZ2%6NQh=N9bmgJ#q!hK@_<`HQq3}Z8Ij>3%~<*= zcv=!oT#5xmeGI92lqm9sGVE%#X$ls;St|F#u!?5Y7syhx6q#MVRa&lBmmn%$C0QzU z);*ldgwwCmzM3uglr}!Z2G+?& zf%Dpo&mD%2ZcNFiN-Z0f;c_Q;A%f@>26f?{d1kxIJD}LxsQkB47SAdwinfMILZdN3 zfj^HmTzS3Ku5BxY>ANutS8WPQ-G>v4^_Qndy==P3pDm+Xc?>rUHl-4+^%Sp5atOja z2oP}ftw-rqnb}+khR3CrRg^ibi6?QYk1*i^;kQGirQ=uB9Sd1NTfT-Rbv;hqnY4neE5H1YUrjS2m+2&@uXiAo- zrKUX|Ohg7(6F(AoP~tj;NZlV#xsfo-5reuQHB$&EIAhyZk;bL;k9ouDmJNBAun;H& zn;Of1z_Qj`x&M;5X;{s~iGzBQTY^kv-k{ksbE*Dl%Qf%N@hQCfY~iUw!=F-*$cpf2 z3wix|aLBV0b;W@z^%7S{>9Z^T^fLOI68_;l@+Qzaxo`nAI8emTV@rRhEKZ z?*z_{oGdI~R*#<2{bkz$G~^Qef}$*4OYTgtL$e9q!FY7EqxJ2`zk6SQc}M(k(_MaV zSLJnTXw&@djco1~a(vhBl^&w=$fa9{Sru>7g8SHahv$&Bl(D@(Zwxo_3r=;VH|uc5 zi1Ny)J!<(KN-EcQ(xlw%PNwK8U>4$9nVOhj(y0l9X^vP1TA>r_7WtSExIOsz`nDOP zs}d>Vxb2Vo2e5x8p(n~Y5ggAyvib>d)6?)|E@{FIz?G3PVGLf7-;BxaP;c?7ddH$z zA+{~k^V=bZuXafOv!RPsE1GrR3J2TH9uB=Z67gok+u`V#}BR86hB1xl}H4v`F+mRfr zYhortD%@IGfh!JB(NUNSDh+qDz?4ztEgCz&bIG-Wg7w-ua4ChgQR_c+z8dT3<1?uX z*G(DKy_LTl*Ea!%v!RhpCXW1WJO6F`bgS-SB;Xw9#! z<*K}=#wVu9$`Yo|e!z-CPYH!nj7s9dEPr-E`DXUBu0n!xX~&|%#G=BeM?X@shQQMf zMvr2!y7p_gD5-!Lnm|a@z8Of^EKboZsTMk%5VsJEm>VsJ4W7Kv{<|#4f-qDE$D-W>gWT%z-!qXnDHhOvLk=?^a1*|0j z{pW{M0{#1VcR5;F!!fIlLVNh_Gj zbnW(_j?0c2q$EHIi@fSMR{OUKBcLr{Y&$hrM8XhPByyZaXy|dd&{hYQRJ9@Fn%h3p7*VQolBIV@Eq`=y%5BU~3RPa^$a?ixp^cCg z+}Q*X+CW9~TL29@OOng(#OAOd!)e$d%sr}^KBJ-?-X&|4HTmtemxmp?cT3uA?md4% zT8yZ0U;6Rg6JHy3fJae{6TMGS?ZUX6+gGTT{Q{)SI85$5FD{g-eR%O0KMpWPY`4@O zx!hen1*8^E(*}{m^V_?}(b5k3hYo=T+$&M32+B`}81~KKZhY;2H{7O-M@vbCzuX0n zW-&HXeyr1%I3$@ns-V1~Lb@wIpkmx|8I~ob1Of7i6BTNysEwI}=!nU%q7(V_^+d*G z7G;07m(CRTJup!`cdYi93r^+LY+`M*>aMuHJm(A8_O8C#A*$!Xvddgpjx5)?_EB*q zgE8o5O>e~9IiSC@WtZpF{4Bj2J5eZ>uUzY%TgWF7wdDE!fSQIAWCP)V{;HsU3ap?4 znRsiiDbtN7i9hapO;(|Ew>Ip2TZSvK9Z^N21%J?OiA_&eP1{(Pu_=%JjKy|HOardq ze?zK^K zA%sjF64*Wufad%H<) z^|t>e*h+Z1#l=5wHexzt9HNDNXgM=-OPWKd^5p!~%SIl>Fo&7BvNpbf8{NXmH)o{r zO=aBJ;meX1^{O%q;kqdw*5k!Y7%t_30 zy{nGRVc&5qt?dBwLs+^Sfp;f`YVMSB#C>z^a9@fpZ!xb|b-JEz1LBX7ci)V@W+kvQ89KWA0T~Lj$aCcfW#nD5bt&Y_< z-q{4ZXDqVg?|0o)j1%l0^_it0WF*LCn-+)c!2y5yS7aZIN$>0LqNnkujV*YVes(v$ zY@_-!Q;!ZyJ}Bg|G-~w@or&u0RO?vlt5*9~yeoPV_UWrO2J54b4#{D(D>jF(R88u2 zo#B^@iF_%S>{iXSol8jpmsZuJ?+;epg>k=$d`?GSegAVp3n$`GVDvK${N*#L_1`44 z{w0fL{2%)0|E+qgZtjX}itZz^KJt4Y;*8uSK}Ft38+3>j|K(PxIXXR-t4VopXo#9# zt|F{LWr-?34y`$nLBVV_*UEgA6AUI65dYIbqpNq9cl&uLJ0~L}<=ESlOm?Y-S@L*d z<7vt}`)TW#f%Rp$Q}6@3=j$7Tze@_uZO@aMn<|si{?S}~maII`VTjs&?}jQ4_cut9$)PEqMukwoXobzaKx^MV z2fQwl+;LSZ$qy%Tys0oo^K=jOw$!YwCv^ei4NBVauL)tN%=wz9M{uf{IB(BxK|lT*pFkmNK_1tV`nb%jH=a0~VNq2RCKY(rG7jz!-D^k)Ec)yS%17pE#o6&eY+ z^qN(hQT$}5F(=4lgNQhlxj?nB4N6ntUY6(?+R#B?W3hY_a*)hnr4PA|vJ<6p`K3Z5Hy z{{8(|ux~NLUW=!?9Qe&WXMTAkQnLXg(g=I@(VG3{HE13OaUT|DljyWXPs2FE@?`iU z4GQlM&Q=T<4&v@Fe<+TuXiZQT3G~vZ&^POfmI1K2h6t4eD}Gk5XFGpbj1n_g*{qmD6Xy z`6Vv|lLZtLmrnv*{Q%xxtcWVj3K4M%$bdBk_a&ar{{GWyu#ljM;dII;*jP;QH z#+^o-A4np{@|Mz+LphTD0`FTyxYq#wY)*&Ls5o{0z9yg2K+K7ZN>j1>N&;r+Z`vI| zDzG1LJZ+sE?m?>x{5LJx^)g&pGEpY=fQ-4}{x=ru;}FL$inHemOg%|R*ZXPodU}Kh zFEd5#+8rGq$Y<_?k-}r5zgQ3jRV=ooHiF|@z_#D4pKVEmn5CGV(9VKCyG|sT9nc=U zEoT67R`C->KY8Wp-fEcjjFm^;Cg(ls|*ABVHq8clBE(;~K^b+S>6uj70g? z&{XQ5U&!Z$SO7zfP+y^8XBbiu*Cv-yJG|l-oe*!s5$@Lh_KpxYL2sx`B|V=dETN>5K+C+CU~a_3cI8{vbu$TNVdGf15*>D zz@f{zIlorkY>TRh7mKuAlN9A0>N>SV`X)+bEHms=mfYTMWt_AJtz_h+JMmrgH?mZt zm=lfdF`t^J*XLg7v+iS)XZROygK=CS@CvUaJo&w2W!Wb@aa?~Drtf`JV^cCMjngVZ zv&xaIBEo8EYWuML+vxCpjjY^s1-ahXJzAV6hTw%ZIy!FjI}aJ+{rE&u#>rs)vzuxz z+$5z=7W?zH2>Eb32dvgHYZtCAf!=OLY-pb4>Ae79rd68E2LkVPj-|jFeyqtBCCwiW zkB@kO_(3wFq)7qwV}bA=zD!*@UhT`geq}ITo%@O(Z5Y80nEX~;0-8kO{oB6|(4fQh z);73T!>3@{ZobPwRv*W?7m0Ml9GmJBCJd&6E?hdj9lV= z4flNfsc(J*DyPv?RCOx!MSvk(M952PJ-G|JeVxWVjN~SNS6n-_Ge3Q;TGE;EQvZg86%wZ`MB zSMQua(i*R8a75!6$QRO^(o7sGoomb+Y{OMy;m~Oa`;P9Yqo>?bJAhqXxLr7_3g_n>f#UVtxG!^F#1+y@os6x(sg z^28bsQ@8rw%Gxk-stAEPRbv^}5sLe=VMbkc@Jjimqjvmd!3E7+QnL>|(^3!R} zD-l1l7*Amu@j+PWLGHXXaFG0Ct2Q=}5YNUxEQHCAU7gA$sSC<5OGylNnQUa>>l%sM zyu}z6i&({U@x^hln**o6r2s-(C-L50tQvz|zHTqW!ir?w&V23tuYEDJVV#5pE|OJu z7^R!A$iM$YCe?8n67l*J-okwfZ+ZTkGvZ)tVPfR;|3gyFjF)8V zyXXN=!*bpyRg9#~Bg1+UDYCt0 ztp4&?t1X0q>uz;ann$OrZs{5*r`(oNvw=$7O#rD|Wuv*wIi)4b zGtq4%BX+kkagv3F9Id6~-c+1&?zny%w5j&nk9SQfo0k4LhdSU_kWGW7axkfpgR`8* z!?UTG*Zi_baA1^0eda8S|@&F z{)Rad0kiLjB|=}XFJhD(S3ssKlveFFmkN{Vl^_nb!o5M!RC=m)V&v2%e?ZoRC@h3> zJ(?pvToFd`*Zc@HFPL#=otWKwtuuQ_dT-Hr{S%pQX<6dqVJ8;f(o)4~VM_kEQkMR+ zs1SCVi~k>M`u1u2xc}>#D!V&6nOOh-E$O&SzYrjJdZpaDv1!R-QGA141WjQe2s0J~ zQ;AXG)F+K#K8_5HVqRoRM%^EduqOnS(j2)|ctA6Q^=|s_WJYU;Z%5bHp08HPL`YF2 zR)Ad1z{zh`=sDs^&V}J z%$Z$!jd7BY5AkT?j`eqMs%!Gm@T8)4w3GYEX~IwgE~`d|@T{WYHkudy(47brgHXx& zBL1yFG6!!!VOSmDxBpefy2{L_u5yTwja&HA!mYA#wg#bc-m%~8aRR|~AvMnind@zs zy>wkShe5&*un^zvSOdlVu%kHsEo>@puMQ`b1}(|)l~E{5)f7gC=E$fP(FC2=F<^|A zxeIm?{EE!3sO!Gr7e{w)Dx(uU#3WrFZ>ibmKSQ1tY?*-Nh1TDHLe+k*;{Rp!Bmd_m zb#^kh`Y*8l|9Cz2e{;RL%_lg{#^Ar+NH|3z*Zye>!alpt{z;4dFAw^^H!6ING*EFc z_yqhr8d!;%nHX9AKhFQZBGrSzfzYCi%C!(Q5*~hX>)0N`vbhZ@N|i;_972WSx*>LH z87?en(;2_`{_JHF`Sv6Wlps;dCcj+8IJ8ca6`DsOQCMb3n# z3)_w%FuJ3>fjeOOtWyq)ag|PmgQbC-s}KRHG~enBcIwqIiGW8R8jFeBNY9|YswRY5 zjGUxdGgUD26wOpwM#8a!Nuqg68*dG@VM~SbOroL_On0N6QdT9?)NeB3@0FCC?Z|E0 z6TPZj(AsPtwCw>*{eDEE}Gby>0q{*lI+g2e&(YQrsY&uGM{O~}(oM@YWmb*F zA0^rr5~UD^qmNljq$F#ARXRZ1igP`MQx4aS6*MS;Ot(1L5jF2NJ;de!NujUYg$dr# z=TEL_zTj2@>ZZN(NYCeVX2==~=aT)R30gETO{G&GM4XN<+!&W&(WcDP%oL8PyIVUC zs5AvMgh6qr-2?^unB@mXK*Dbil^y-GTC+>&N5HkzXtozVf93m~xOUHn8`HpX=$_v2 z61H;Z1qK9o;>->tb8y%#4H)765W4E>TQ1o0PFj)uTOPEvv&}%(_mG0ISmyhnQV33Z$#&yd{ zc{>8V8XK$3u8}04CmAQ#I@XvtmB*s4t8va?-IY4@CN>;)mLb_4!&P3XSw4pA_NzDb zORn!blT-aHk1%Jpi>T~oGLuh{DB)JIGZ9KOsciWs2N7mM1JWM+lna4vkDL?Q)z_Ct z`!mi0jtr+4*L&N7jk&LodVO#6?_qRGVaucqVB8*us6i3BTa^^EI0x%EREQSXV@f!lak6Wf1cNZ8>*artIJ(ADO*=<-an`3zB4d*oO*8D1K!f z*A@P1bZCNtU=p!742MrAj%&5v%Xp_dSX@4YCw%F|%Dk=u|1BOmo)HsVz)nD5USa zR~??e61sO(;PR)iaxK{M%QM_rIua9C^4ppVS$qCT9j2%?*em?`4Z;4@>I(c%M&#cH z>4}*;ej<4cKkbCAjjDsyKS8rIm90O)Jjgyxj5^venBx&7B!xLmzxW3jhj7sR(^3Fz z84EY|p1NauwXUr;FfZjdaAfh%ivyp+^!jBjJuAaKa!yCq=?T_)R!>16?{~p)FQ3LDoMyG%hL#pR!f@P%*;#90rs_y z@9}@r1BmM-SJ#DeuqCQk=J?ixDSwL*wh|G#us;dd{H}3*-Y7Tv5m=bQJMcH+_S`zVtf;!0kt*(zwJ zs+kedTm!A}cMiM!qv(c$o5K%}Yd0|nOd0iLjus&;s0Acvoi-PFrWm?+q9f^FslxGi z6ywB`QpL$rJzWDg(4)C4+!2cLE}UPCTBLa*_=c#*$b2PWrRN46$y~yST3a2$7hEH= zNjux+wna^AzQ=KEa_5#9Ph=G1{S0#hh1L3hQ`@HrVnCx{!fw_a0N5xV(iPdKZ-HOM za)LdgK}1ww*C_>V7hbQnTzjURJL`S%`6nTHcgS+dB6b_;PY1FsrdE8(2K6FN>37!62j_cBlui{jO^$dPkGHV>pXvW0EiOA zqW`YaSUBWg_v^Y5tPJfWLcLpsA8T zG)!x>pKMpt!lv3&KV!-um= zKCir6`bEL_LCFx4Z5bAFXW$g3Cq`?Q%)3q0r852XI*Der*JNuKUZ`C{cCuu8R8nkt z%pnF>R$uY8L+D!V{s^9>IC+bmt<05h**>49R*#vpM*4i0qRB2uPbg8{{s#9yC;Z18 zD7|4m<9qneQ84uX|J&f-g8a|nFKFt34@Bt{CU`v(SYbbn95Q67*)_Esl_;v291s=9 z+#2F2apZU4Tq=x+?V}CjwD(P=U~d<=mfEFuyPB`Ey82V9G#Sk8H_Ob_RnP3s?)S_3 zr%}Pb?;lt_)Nf>@zX~D~TBr;-LS<1I##8z`;0ZCvI_QbXNh8Iv)$LS=*gHr;}dgb=w5$3k2la1keIm|=7<-JD>)U%=Avl0Vj@+&vxn zt-)`vJxJr88D&!}2^{GPXc^nmRf#}nb$4MMkBA21GzB`-Or`-3lq^O^svO7Vs~FdM zv`NvzyG+0T!P8l_&8gH|pzE{N(gv_tgDU7SWeiI-iHC#0Ai%Ixn4&nt{5y3(GQs)i z&uA;~_0shP$0Wh0VooIeyC|lak__#KVJfxa7*mYmZ22@(<^W}FdKjd*U1CqSjNKW% z*z$5$=t^+;Ui=MoDW~A7;)Mj%ibX1_p4gu>RC}Z_pl`U*{_z@+HN?AF{_W z?M_X@o%w8fgFIJ$fIzBeK=v#*`mtY$HC3tqw7q^GCT!P$I%=2N4FY7j9nG8aIm$c9 zeKTxVKN!UJ{#W)zxW|Q^K!3s;(*7Gbn;e@pQBCDS(I|Y0euK#dSQ_W^)sv5pa%<^o zyu}3d?Lx`)3-n5Sy9r#`I{+t6x%I%G(iewGbvor&I^{lhu-!#}*Q3^itvY(^UWXgvthH52zLy&T+B)Pw;5>4D6>74 zO_EBS)>l!zLTVkX@NDqyN2cXTwsUVao7$HcqV2%t$YzdAC&T)dwzExa3*kt9d(}al zA~M}=%2NVNUjZiO7c>04YH)sRelXJYpWSn^aC$|Ji|E13a^-v2MB!Nc*b+=KY7MCm zqIteKfNkONq}uM;PB?vvgQvfKLPMB8u5+Am=d#>g+o&Ysb>dX9EC8q?D$pJH!MTAqa=DS5$cb+;hEvjwVfF{4;M{5U&^_+r zvZdu_rildI!*|*A$TzJ&apQWV@p{!W`=?t(o0{?9y&vM)V)ycGSlI3`;ps(vf2PUq zX745#`cmT*ra7XECC0gKkpu2eyhFEUb?;4@X7weEnLjXj_F~?OzL1U1L0|s6M+kIhmi%`n5vvDALMagi4`wMc=JV{XiO+^ z?s9i7;GgrRW{Mx)d7rj)?(;|b-`iBNPqdwtt%32se@?w4<^KU&585_kZ=`Wy^oLu9 z?DQAh5z%q;UkP48jgMFHTf#mj?#z|=w= z(q6~17Vn}P)J3M?O)x))%a5+>TFW3No~TgP;f}K$#icBh;rSS+R|}l鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ac72c34e8ac..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradlew b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradlew deleted file mode 100755 index 0adc8e1a532..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed 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 -# -# https://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. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradlew.bat b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradlew.bat deleted file mode 100644 index 93e3f59f135..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/source_archive.expected new file mode 100644 index 00000000000..1ee055eeb02 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/source_archive.expected @@ -0,0 +1,7 @@ +.gradle/8.3/dependencies-accessors/gc.properties +.gradle/8.3/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +src/main/java/com/fractestexample/Test.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.expected deleted file mode 100644 index 05792cb19fc..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.expected +++ /dev/null @@ -1 +0,0 @@ -| src/main/java/com/fractestexample/Test.java:0:0:0:0 | Test | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.py b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.py index bfff65b2fc2..bea3e5f552c 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.py @@ -1,8 +1,7 @@ -from create_database_utils import * -from diagnostics_test_utils import * -from buildless_test_utils import * - -run_codeql_database_create([], lang="java", extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"}) - -check_diagnostics() -check_buildless_fetches() +def test(codeql, java, gradle_8_3): + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", + } + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.ql deleted file mode 100644 index 8317a5a022f..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.ql +++ /dev/null @@ -1,5 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/source_archive.expected new file mode 100644 index 00000000000..e51c49f2057 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/source_archive.expected @@ -0,0 +1,5 @@ +gradle/verification-metadata.xml +gradle/wrapper/gradle-wrapper.properties +src/main/java/com/example/App.java +src/test/java/com/example/AppTest.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.expected deleted file mode 100644 index e7dd5838e6b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.expected +++ /dev/null @@ -1,5 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| gradle/verification-metadata.xml:0:0:0:0 | gradle/verification-metadata.xml | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.py b/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.py index 5e02cc11397..b0e307f15bb 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.py @@ -1,9 +1,7 @@ -import sys - -from create_database_utils import * -from diagnostics_test_utils import * - -# gradlew has been rigged to stall for a long time by trying to fetch from a black-hole IP. We should find the timeout logic fires and buildless aborts the Gradle run quickly. - -run_codeql_database_create([], lang="java", extra_args=["--build-mode=none"], extra_env={"CODEQL_EXTRACTOR_JAVA_BUILDLESS_CHILD_PROCESS_IDLE_TIMEOUT": "5"}) -check_diagnostics() +def test(codeql, java): + # gradlew has been rigged to stall for a long time by trying to fetch from a black-hole IP. + # We should find the timeout logic fires and buildless aborts the Gradle run quickly. + codeql.database.create( + build_mode="none", + _env={"CODEQL_EXTRACTOR_JAVA_BUILDLESS_CHILD_PROCESS_IDLE_TIMEOUT": "5"}, + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/.gitattributes b/java/ql/integration-tests/all-platforms/java/buildless-gradle/.gitattributes deleted file mode 100644 index 097f9f98d9e..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle/.gitattributes +++ /dev/null @@ -1,9 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# Linux start script should use lf -/gradlew text eol=lf - -# These are Windows script files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/.gitignore b/java/ql/integration-tests/all-platforms/java/buildless-gradle/.gitignore deleted file mode 100644 index 1b6985c0094..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Ignore Gradle project-specific cache directory -.gradle - -# Ignore Gradle build output directory -build diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-gradle/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ac72c34e8ac..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradlew b/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradlew deleted file mode 100755 index 0adc8e1a532..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed 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 -# -# https://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. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradlew.bat b/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradlew.bat deleted file mode 100644 index 93e3f59f135..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-gradle/source_archive.expected new file mode 100644 index 00000000000..1ee055eeb02 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-gradle/source_archive.expected @@ -0,0 +1,7 @@ +.gradle/8.3/dependencies-accessors/gc.properties +.gradle/8.3/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +src/main/java/com/fractestexample/Test.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.expected deleted file mode 100644 index 05792cb19fc..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.expected +++ /dev/null @@ -1 +0,0 @@ -| src/main/java/com/fractestexample/Test.java:0:0:0:0 | Test | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.py b/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.py index bfff65b2fc2..bea3e5f552c 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.py @@ -1,8 +1,7 @@ -from create_database_utils import * -from diagnostics_test_utils import * -from buildless_test_utils import * - -run_codeql_database_create([], lang="java", extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"}) - -check_diagnostics() -check_buildless_fetches() +def test(codeql, java, gradle_8_3): + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", + } + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.ql deleted file mode 100644 index 8317a5a022f..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.ql +++ /dev/null @@ -1,5 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.py b/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.py index 973a10c931c..b69070ddf81 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.py @@ -1,22 +1,21 @@ -import sys - -from create_database_utils import * -from buildless_test_utils import * -from diagnostics_test_utils import * import subprocess -import os.path +import os -# This serves the "repo" directory on https://locahost:4443 -repo_server_process = subprocess.Popen(["python3", "../server.py"], cwd = "repo") -mypath = os.path.abspath(os.path.dirname(__file__)) -certspath = os.path.join(mypath, "jdk8_shipped_cacerts_plus_cert_pem") -maven_certs_option = "-Djavax.net.ssl.trustStore=" + certspath +def test(codeql, java, cwd): + # This serves the "repo" directory on https://locahost:4443 + repo_server_process = subprocess.Popen(["python3", "../server.py"], cwd="repo") + certspath = cwd / "jdk8_shipped_cacerts_plus_cert_pem" + # If we override MAVEN_OPTS, we'll break cross-test maven isolation, so we need to append to it instead + maven_opts = os.environ["MAVEN_OPTS"] + f" -Djavax.net.ssl.trustStore={certspath}" -try: - run_codeql_database_create([], lang="java", extra_args=["--build-mode=none"], extra_env={"MAVEN_OPTS": maven_certs_option, "CODEQL_JAVA_EXTRACTOR_TRUST_STORE_PATH": certspath}) -finally: - repo_server_process.kill() - -check_buildless_fetches() -check_diagnostics() + try: + codeql.database.create( + extractor_option="buildless=true", + _env={ + "MAVEN_OPTS": maven_opts, + "CODEQL_JAVA_EXTRACTOR_TRUST_STORE_PATH": str(certspath), + }, + ) + finally: + repo_server_process.kill() diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/source_archive.expected new file mode 100644 index 00000000000..c6f2f49cf7d --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/source_archive.expected @@ -0,0 +1,7 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.expected deleted file mode 100644 index cbd09bcf554..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.expected +++ /dev/null @@ -1,10 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -propertiesFiles -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.py b/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.py index bfff65b2fc2..a92ac46584c 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.py @@ -1,8 +1,7 @@ -from create_database_utils import * -from diagnostics_test_utils import * -from buildless_test_utils import * - -run_codeql_database_create([], lang="java", extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"}) - -check_diagnostics() -check_buildless_fetches() +def test(codeql, java): + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", + } + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/source_archive.expected new file mode 100644 index 00000000000..06978379cfb --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/source_archive.expected @@ -0,0 +1,14 @@ +pom.xml +submod1/pom.xml +submod1/src/main/java/com/example/App.java +submod1/src/main/resources/my-app.properties +submod1/src/main/resources/page.xml +submod1/src/main/resources/struts.xml +submod1/src/test/java/com/example/AppTest.java +submod2/pom.xml +submod2/src/main/java/com/example/App2.java +submod2/src/main/resources/my-app.properties +submod2/src/main/resources/page.xml +submod2/src/main/resources/struts.xml +submod2/src/test/java/com/example/AppTest2.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.expected deleted file mode 100644 index ef6afbda3b0..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.expected +++ /dev/null @@ -1,17 +0,0 @@ -#select -| submod1/src/main/java/com/example/App.java:0:0:0:0 | App | -| submod1/src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -| submod2/src/main/java/com/example/App2.java:0:0:0:0 | App2 | -| submod2/src/test/java/com/example/AppTest2.java:0:0:0:0 | AppTest2 | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| submod1/pom.xml:0:0:0:0 | submod1/pom.xml | -| submod1/src/main/resources/page.xml:0:0:0:0 | submod1/src/main/resources/page.xml | -| submod1/src/main/resources/struts.xml:0:0:0:0 | submod1/src/main/resources/struts.xml | -| submod2/pom.xml:0:0:0:0 | submod2/pom.xml | -| submod2/src/main/resources/page.xml:0:0:0:0 | submod2/src/main/resources/page.xml | -| submod2/src/main/resources/struts.xml:0:0:0:0 | submod2/src/main/resources/struts.xml | -propertiesFiles -| submod1/src/main/resources/my-app.properties:0:0:0:0 | submod1/src/main/resources/my-app.properties | -| submod2/src/main/resources/my-app.properties:0:0:0:0 | submod2/src/main/resources/my-app.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.py b/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.py index bfff65b2fc2..a92ac46584c 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.py @@ -1,8 +1,7 @@ -from create_database_utils import * -from diagnostics_test_utils import * -from buildless_test_utils import * - -run_codeql_database_create([], lang="java", extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"}) - -check_diagnostics() -check_buildless_fetches() +def test(codeql, java): + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", + } + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/force_sequential_test_execution deleted file mode 100644 index 44bcad8d582..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -The wrapper downloading a Maven distribution multiple times in parallel is not safe. diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/source_archive.expected new file mode 100644 index 00000000000..f73dc023c39 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/source_archive.expected @@ -0,0 +1,8 @@ +.mvn/wrapper/maven-wrapper.properties +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.expected deleted file mode 100644 index 0728284fc94..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.expected +++ /dev/null @@ -1,11 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -propertiesFiles -| .mvn/wrapper/maven-wrapper.properties:0:0:0:0 | .mvn/wrapper/maven-wrapper.properties | -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.py b/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.py index 948d030eb9d..2c70d7dd91a 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.py @@ -1,9 +1,6 @@ -import sys - -from create_database_utils import * -from diagnostics_test_utils import * - -# mvnw has been rigged to stall for a long time by trying to fetch from a black-hole IP. We should find the timeout logic fires and buildless aborts the Maven run quickly. - -run_codeql_database_create([], lang="java", extra_args=["--build-mode=none"], extra_env={"CODEQL_EXTRACTOR_JAVA_BUILDLESS_CHILD_PROCESS_IDLE_TIMEOUT": "5"}) -check_diagnostics() +def test(codeql, java): + # mvnw has been rigged to stall for a long time by trying to fetch from a black-hole IP. We should find the timeout logic fires and buildless aborts the Maven run quickly. + codeql.database.create( + build_mode="none", + _env={"CODEQL_EXTRACTOR_JAVA_BUILDLESS_CHILD_PROCESS_IDLE_TIMEOUT": "5"}, + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/test.py b/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/test.py index 3f8deac940f..f7673ce3ad1 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/test.py @@ -1,8 +1,4 @@ -from create_database_utils import * -from diagnostics_test_utils import * -from buildless_test_utils import * - -run_codeql_database_create([], lang="java", extra_args=["--build-mode=none"]) - -check_diagnostics() -check_buildless_fetches() +def test(codeql, java): + codeql.database.create( + build_mode="none", + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-maven/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-maven/source_archive.expected new file mode 100644 index 00000000000..c6f2f49cf7d --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-maven/source_archive.expected @@ -0,0 +1,7 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-maven/test.expected deleted file mode 100644 index cbd09bcf554..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven/test.expected +++ /dev/null @@ -1,10 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -propertiesFiles -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/test.py b/java/ql/integration-tests/all-platforms/java/buildless-maven/test.py index bfff65b2fc2..a92ac46584c 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-maven/test.py @@ -1,8 +1,7 @@ -from create_database_utils import * -from diagnostics_test_utils import * -from buildless_test_utils import * - -run_codeql_database_create([], lang="java", extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"}) - -check_diagnostics() -check_buildless_fetches() +def test(codeql, java): + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", + } + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-maven/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-maven/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/test.py b/java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/test.py index a229dfff548..549f7b72e50 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/test.py @@ -1,5 +1,4 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create([], lang="java", extra_args=["--extractor-option=buildless=true"]) +def test(codeql, java): + codeql.database.create( + extractor_option="buildless=true", + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/.gitattributes b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/.gitattributes deleted file mode 100644 index 097f9f98d9e..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/.gitattributes +++ /dev/null @@ -1,9 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# Linux start script should use lf -/gradlew text eol=lf - -# These are Windows script files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/.gitignore b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/.gitignore deleted file mode 100644 index 1b6985c0094..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Ignore Gradle project-specific cache directory -.gradle - -# Ignore Gradle build output directory -build diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63721 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鯊%1Et zwk~hMkhq;MOw^Q5`7oC{CUUyTw9x>^%*FHx^qJw(LB+E0WBX@{Ghw;)6aA-KyYg8p z7XDveQOpEr;B4je@2~usI5BlFadedX^ma{b{ypd|RNYqo#~d*mj&y`^iojR}s%~vF z(H!u`yx68D1Tj(3(m;Q+Ma}s2n#;O~bcB1`lYk%Irx60&-nWIUBr2x&@}@76+*zJ5 ze&4?q8?m%L9c6h=J$WBzbiTf1Z-0Eb5$IZs>lvm$>1n_Mezp*qw_pr8<8$6f)5f<@ zyV#tzMCs51nTv_5ca`x`yfE5YA^*%O_H?;tWYdM_kHPubA%vy47i=9>Bq) zRQ&0UwLQHeswmB1yP)+BiR;S+Vc-5TX84KUA;8VY9}yEj0eESSO`7HQ4lO z4(CyA8y1G7_C;6kd4U3K-aNOK!sHE}KL_-^EDl(vB42P$2Km7$WGqNy=%fqB+ zSLdrlcbEH=T@W8V4(TgoXZ*G1_aq$K^@ek=TVhoKRjw;HyI&coln|uRr5mMOy2GXP zwr*F^Y|!Sjr2YQXX(Fp^*`Wk905K%$bd03R4(igl0&7IIm*#f`A!DCarW9$h$z`kYk9MjjqN&5-DsH@8xh63!fTNPxWsFQhNv z#|3RjnP$Thdb#Ys7M+v|>AHm0BVTw)EH}>x@_f4zca&3tXJhTZ8pO}aN?(dHo)44Z z_5j+YP=jMlFqwvf3lq!57-SAuRV2_gJ*wsR_!Y4Z(trO}0wmB9%f#jNDHPdQGHFR; zZXzS-$`;7DQ5vF~oSgP3bNV$6Z(rwo6W(U07b1n3UHqml>{=6&-4PALATsH@Bh^W? z)ob%oAPaiw{?9HfMzpGb)@Kys^J$CN{uf*HX?)z=g`J(uK1YO^8~s1(ZIbG%Et(|q z$D@_QqltVZu9Py4R0Ld8!U|#`5~^M=b>fnHthzKBRr=i+w@0Vr^l|W;=zFT#PJ?*a zbC}G#It}rQP^Ait^W&aa6B;+0gNvz4cWUMzpv(1gvfw-X4xJ2Sv;mt;zb2Tsn|kSS zo*U9N?I{=-;a-OybL4r;PolCfiaL=y@o9{%`>+&FI#D^uy#>)R@b^1ue&AKKwuI*` zx%+6r48EIX6nF4o;>)zhV_8(IEX})NGU6Vs(yslrx{5fII}o3SMHW7wGtK9oIO4OM&@@ECtXSICLcPXoS|{;=_yj>hh*%hP27yZwOmj4&Lh z*Nd@OMkd!aKReoqNOkp5cW*lC)&C$P?+H3*%8)6HcpBg&IhGP^77XPZpc%WKYLX$T zsSQ$|ntaVVOoRat$6lvZO(G-QM5s#N4j*|N_;8cc2v_k4n6zx9c1L4JL*83F-C1Cn zaJhd;>rHXB%%ZN=3_o3&Qd2YOxrK~&?1=UuN9QhL$~OY-Qyg&})#ez*8NpQW_*a&kD&ANjedxT0Ar z<6r{eaVz3`d~+N~vkMaV8{F?RBVemN(jD@S8qO~L{rUw#=2a$V(7rLE+kGUZ<%pdr z?$DP|Vg#gZ9S}w((O2NbxzQ^zTot=89!0^~hE{|c9q1hVzv0?YC5s42Yx($;hAp*E zyoGuRyphQY{Q2ee0Xx`1&lv(l-SeC$NEyS~8iil3_aNlnqF_G|;zt#F%1;J)jnPT& z@iU0S;wHJ2$f!juqEzPZeZkjcQ+Pa@eERSLKsWf=`{R@yv7AuRh&ALRTAy z8=g&nxsSJCe!QLchJ=}6|LshnXIK)SNd zRkJNiqHwKK{SO;N5m5wdL&qK`v|d?5<4!(FAsDxR>Ky#0#t$8XCMptvNo?|SY?d8b z`*8dVBlXTUanlh6n)!EHf2&PDG8sXNAt6~u-_1EjPI1|<=33T8 zEnA00E!`4Ave0d&VVh0e>)Dc}=FfAFxpsC1u9ATfQ`-Cu;mhc8Z>2;uyXtqpLb7(P zd2F9<3cXS} znMg?{&8_YFTGRQZEPU-XPq55%51}RJpw@LO_|)CFAt62-_!u_Uq$csc+7|3+TV_!h z+2a7Yh^5AA{q^m|=KSJL+w-EWDBc&I_I1vOr^}P8i?cKMhGy$CP0XKrQzCheG$}G# zuglf8*PAFO8%xop7KSwI8||liTaQ9NCAFarr~psQt)g*pC@9bORZ>m`_GA`_K@~&% zijH0z;T$fd;-Liw8%EKZas>BH8nYTqsK7F;>>@YsE=Rqo?_8}UO-S#|6~CAW0Oz1} z3F(1=+#wrBJh4H)9jTQ_$~@#9|Bc1Pd3rAIA_&vOpvvbgDJOM(yNPhJJq2%PCcMaI zrbe~toYzvkZYQ{ea(Wiyu#4WB#RRN%bMe=SOk!CbJZv^m?Flo5p{W8|0i3`hI3Np# zvCZqY%o258CI=SGb+A3yJe~JH^i{uU`#U#fvSC~rWTq+K`E%J@ zasU07&pB6A4w3b?d?q}2=0rA#SA7D`X+zg@&zm^iA*HVi z009#PUH<%lk4z~p^l0S{lCJk1Uxi=F4e_DwlfHA`X`rv(|JqWKAA5nH+u4Da+E_p+ zVmH@lg^n4ixs~*@gm_dgQ&eDmE1mnw5wBz9Yg?QdZwF|an67Xd*x!He)Gc8&2!urh z4_uXzbYz-aX)X1>&iUjGp;P1u8&7TID0bTH-jCL&Xk8b&;;6p2op_=y^m@Nq*0{#o!!A;wNAFG@0%Z9rHo zcJs?Th>Ny6+hI`+1XoU*ED$Yf@9f91m9Y=#N(HJP^Y@ZEYR6I?oM{>&Wq4|v0IB(p zqX#Z<_3X(&{H+{3Tr|sFy}~=bv+l=P;|sBz$wk-n^R`G3p0(p>p=5ahpaD7>r|>pm zv;V`_IR@tvZreIuv2EM7ZQHhO+qUgw#kOs%*ekY^n|=1#x9&c;Ro&I~{rG-#_3ZB1 z?|9}IFdbP}^DneP*T-JaoYHt~r@EfvnPE5EKUwIxjPbsr$% zfWW83pgWST7*B(o=kmo)74$8UU)v0{@4DI+ci&%=#90}!CZz|rnH+Mz=HN~97G3~@ z;v5(9_2%eca(9iu@J@aqaMS6*$TMw!S>H(b z4(*B!|H|8&EuB%mITr~O?vVEf%(Gr)6E=>H~1VR z&1YOXluJSG1!?TnT)_*YmJ*o_Q@om~(GdrhI{$Fsx_zrkupc#y{DK1WOUR>tk>ZE) ziOLoBkhZZ?0Uf}cm>GsA>Rd6V8@JF)J*EQlQ<=JD@m<)hyElXR0`pTku*3MU`HJn| zIf7$)RlK^pW-$87U;431;Ye4Ie+l~_B3*bH1>*yKzn23cH0u(i5pXV! z4K?{3oF7ZavmmtTq((wtml)m6i)8X6ot_mrE-QJCW}Yn!(3~aUHYG=^fA<^~`e3yc z-NWTb{gR;DOUcK#zPbN^D*e=2eR^_!(!RKkiwMW@@yYtEoOp4XjOGgzi`;=8 zi3`Ccw1%L*y(FDj=C7Ro-V?q)-%p?Ob2ZElu`eZ99n14-ZkEV#y5C+{Pq87Gu3&>g zFy~Wk7^6v*)4pF3@F@rE__k3ikx(hzN3@e*^0=KNA6|jC^B5nf(XaoQaZN?Xi}Rn3 z$8&m*KmWvPaUQ(V<#J+S&zO|8P-#!f%7G+n_%sXp9=J%Z4&9OkWXeuZN}ssgQ#Tcj z8p6ErJQJWZ+fXLCco=RN8D{W%+*kko*2-LEb))xcHwNl~Xmir>kmAxW?eW50Osw3# zki8Fl$#fvw*7rqd?%E?}ZX4`c5-R&w!Y0#EBbelVXSng+kUfeUiqofPehl}$ormli zg%r)}?%=?_pHb9`Cq9Z|B`L8b>(!+8HSX?`5+5mm81AFXfnAt1*R3F z%b2RPIacKAddx%JfQ8l{3U|vK@W7KB$CdLqn@wP^?azRks@x8z59#$Q*7q!KilY-P zHUbs(IFYRGG1{~@RF;Lqyho$~7^hNC`NL3kn^Td%A7dRgr_&`2k=t+}D-o9&C!y^? z6MsQ=tc3g0xkK(O%DzR9nbNB(r@L;1zQrs8mzx&4dz}?3KNYozOW5;=w18U6$G4U2 z#2^qRLT*Mo4bV1Oeo1PKQ2WQS2Y-hv&S|C7`xh6=Pj7MNLC5K-zokZ67S)C;(F0Dd zloDK2_o1$Fmza>EMj3X9je7e%Q`$39Dk~GoOj89-6q9|_WJlSl!!+*{R=tGp z8u|MuSwm^t7K^nUe+^0G3dkGZr3@(X+TL5eah)K^Tn zXEtHmR9UIaEYgD5Nhh(s*fcG_lh-mfy5iUF3xxpRZ0q3nZ=1qAtUa?(LnT9I&~uxX z`pV?+=|-Gl(kz?w!zIieXT}o}7@`QO>;u$Z!QB${a08_bW0_o@&9cjJUXzVyNGCm8 zm=W+$H!;_Kzp6WQqxUI;JlPY&`V}9C$8HZ^m?NvI*JT@~BM=()T()Ii#+*$y@lTZBkmMMda>7s#O(1YZR+zTG@&}!EXFG{ zEWPSDI5bFi;NT>Yj*FjH((=oe%t%xYmE~AGaOc4#9K_XsVpl<4SP@E!TgC0qpe1oi zNpxU2b0(lEMcoibQ-G^cxO?ySVW26HoBNa;n0}CWL*{k)oBu1>F18X061$SP{Gu67 z-v-Fa=Fl^u3lnGY^o5v)Bux}bNZ~ z5pL+7F_Esoun8^5>z8NFoIdb$sNS&xT8_|`GTe8zSXQzs4r^g0kZjg(b0bJvz`g<70u9Z3fQILX1Lj@;@+##bP|FAOl)U^9U>0rx zGi)M1(Hce)LAvQO-pW!MN$;#ZMX?VE(22lTlJrk#pB0FJNqVwC+*%${Gt#r_tH9I_ z;+#)#8cWAl?d@R+O+}@1A^hAR1s3UcW{G+>;X4utD2d9X(jF555}!TVN-hByV6t+A zdFR^aE@GNNgSxxixS2p=on4(+*+f<8xrwAObC)D5)4!z7)}mTpb7&ofF3u&9&wPS< zB62WHLGMhmrmOAgmJ+|c>qEWTD#jd~lHNgT0?t-p{T=~#EMcB| z=AoDKOL+qXCfk~F)-Rv**V}}gWFl>liXOl7Uec_8v)(S#av99PX1sQIVZ9eNLkhq$ zt|qu0b?GW_uo}TbU8!jYn8iJeIP)r@;!Ze_7mj{AUV$GEz6bDSDO=D!&C9!M@*S2! zfGyA|EPlXGMjkH6x7OMF?gKL7{GvGfED=Jte^p=91FpCu)#{whAMw`vSLa`K#atdN zThnL+7!ZNmP{rc=Z>%$meH;Qi1=m1E3Lq2D_O1-X5C;!I0L>zur@tPAC9*7Jeh)`;eec}1`nkRP(%iv-`N zZ@ip-g|7l6Hz%j%gcAM}6-nrC8oA$BkOTz^?dakvX?`^=ZkYh%vUE z9+&)K1UTK=ahYiaNn&G5nHUY5niLGus@p5E2@RwZufRvF{@$hW{;{3QhjvEHMvduO z#Wf-@oYU4ht?#uP{N3utVzV49mEc9>*TV_W2TVC`6+oI)zAjy$KJrr=*q##&kobiQ z1vNbya&OVjK`2pdRrM?LuK6BgrLN7H_3m z!qpNKg~87XgCwb#I=Q&0rI*l$wM!qTkXrx1ko5q-f;=R2fImRMwt5Qs{P*p^z@9ex z`2#v(qE&F%MXlHpdO#QEZyZftn4f05ab^f2vjxuFaat2}jke{j?5GrF=WYBR?gS(^ z9SBiNi}anzBDBRc+QqizTTQuJrzm^bNA~A{j%ugXP7McZqJ}65l10({wk++$=e8O{ zxWjG!Qp#5OmI#XRQQM?n6?1ztl6^D40hDJr?4$Wc&O_{*OfMfxe)V0=e{|N?J#fgE>j9jAajze$iN!*yeF%jJU#G1c@@rm zolGW!j?W6Q8pP=lkctNFdfgUMg92wlM4E$aks1??M$~WQfzzzXtS)wKrr2sJeCN4X zY(X^H_c^PzfcO8Bq(Q*p4c_v@F$Y8cHLrH$`pJ2}=#*8%JYdqsqnGqEdBQMpl!Ot04tUGSXTQdsX&GDtjbWD=prcCT9(+ z&UM%lW%Q3yrl1yiYs;LxzIy>2G}EPY6|sBhL&X&RAQrSAV4Tlh2nITR?{6xO9ujGu zr*)^E`>o!c=gT*_@6S&>0POxcXYNQd&HMw6<|#{eSute2C3{&h?Ah|cw56-AP^f8l zT^kvZY$YiH8j)sk7_=;gx)vx-PW`hbSBXJGCTkpt;ap(}G2GY=2bbjABU5)ty%G#x zAi07{Bjhv}>OD#5zh#$0w;-vvC@^}F! z#X$@)zIs1L^E;2xDAwEjaXhTBw2<{&JkF*`;c3<1U@A4MaLPe{M5DGGkL}#{cHL%* zYMG+-Fm0#qzPL#V)TvQVI|?_M>=zVJr9>(6ib*#z8q@mYKXDP`k&A4A};xMK0h=yrMp~JW{L?mE~ph&1Y1a#4%SO)@{ zK2juwynUOC)U*hVlJU17%llUxAJFuKZh3K0gU`aP)pc~bE~mM!i1mi!~LTf>1Wp< zuG+ahp^gH8g8-M$u{HUWh0m^9Rg@cQ{&DAO{PTMudV6c?ka7+AO& z746QylZ&Oj`1aqfu?l&zGtJnpEQOt;OAFq19MXTcI~`ZcoZmyMrIKDFRIDi`FH)w; z8+*8tdevMDv*VtQi|e}CnB_JWs>fhLOH-+Os2Lh!&)Oh2utl{*AwR)QVLS49iTp{6 z;|172Jl!Ml17unF+pd+Ff@jIE-{Oxv)5|pOm@CkHW?{l}b@1>Pe!l}VccX#xp@xgJ zyE<&ep$=*vT=}7vtvif0B?9xw_3Gej7mN*dOHdQPtW5kA5_zGD zpA4tV2*0E^OUimSsV#?Tg#oiQ>%4D@1F5@AHwT8Kgen$bSMHD3sXCkq8^(uo7CWk`mT zuslYq`6Yz;L%wJh$3l1%SZv#QnG3=NZ=BK4yzk#HAPbqXa92;3K5?0kn4TQ`%E%X} z&>Lbt!!QclYKd6+J7Nl@xv!uD%)*bY-;p`y^ZCC<%LEHUi$l5biu!sT3TGGSTPA21 zT8@B&a0lJHVn1I$I3I1I{W9fJAYc+8 zVj8>HvD}&O`TqU2AAb={?eT;0hyL(R{|h23=4fDSZKC32;wWxsVj`P z3J3{M$PwdH!ro*Cn!D&=jnFR>BNGR<<|I8CI@+@658Dy(lhqbhXfPTVecY@L8%`3Q z1Fux2w?2C3th60jI~%OC9BtpNF$QPqcG+Pz96qZJ71_`0o0w_q7|h&O>`6U+^BA&5 zXd5Zp1Xkw~>M%RixTm&OqpNl8Q+ue=92Op_>T~_9UON?ZM2c0aGm=^A4ejrXj3dV9 zhh_bCt-b9`uOX#cFLj!vhZ#lS8Tc47OH>*)y#{O9?AT~KR9LntM|#l#Dlm^8{nZdk zjMl#>ZM%#^nK2TPzLcKxqx24P7R1FPlBy7LSBrRvx>fE$9AJ;7{PQm~^LBX^k#6Zq zw*Z(zJC|`!6_)EFR}8|n8&&Rbj8y028~P~sFXBFRt+tmqH-S3<%N;C&WGH!f3{7cm zy_fCAb9@HqaXa1Y5vFbxWf%#zg6SI$C+Uz5=CTO}e|2fjWkZ;Dx|84Ow~bkI=LW+U zuq;KSv9VMboRvs9)}2PAO|b(JCEC_A0wq{uEj|3x@}*=bOd zwr{TgeCGG>HT<@Zeq8y}vTpwDg#UBvD)BEs@1KP$^3$sh&_joQPn{hjBXmLPJ{tC) z*HS`*2+VtJO{|e$mM^|qv1R*8i(m1`%)}g=SU#T#0KlTM2RSvYUc1fP+va|4;5}Bfz98UvDCpq7}+SMV&;nX zQw~N6qOX{P55{#LQkrZk(e5YGzr|(B;Q;ju;2a`q+S9bsEH@i1{_Y0;hWYn1-79jl z5c&bytD*k)GqrVcHn6t-7kinadiD>B{Tl`ZY@`g|b~pvHh5!gKP4({rp?D0aFd_cN zhHRo4dd5^S6ViN(>(28qZT6E>??aRhc($kP`>@<+lIKS5HdhjVU;>f7<4))E*5|g{ z&d1}D|vpuV^eRj5j|xx9nwaCxXFG?Qbjn~_WSy=N}P0W>MP zG-F%70lX5Xr$a)2i6?i|iMyM|;Jtf*hO?=Jxj12oz&>P=1#h~lf%#fc73M2_(SUM- zf&qnjS80|_Y0lDgl&I?*eMumUklLe_=Td!9G@eR*tcPOgIShJipp3{A10u(4eT~DY zHezEj8V+7m!knn7)W!-5QI3=IvC^as5+TW1@Ern@yX| z7Nn~xVx&fGSr+L%4iohtS3w^{-H1A_5=r&x8}R!YZvp<2T^YFvj8G_vm}5q;^UOJf ztl=X3iL;;^^a#`t{Ae-%5Oq{?M#s6Npj+L(n-*LMI-yMR{)qki!~{5z{&`-iL}lgW zxo+tnvICK=lImjV$Z|O_cYj_PlEYCzu-XBz&XC-JVxUh9;6*z4fuBG+H{voCC;`~GYV|hj%j_&I zDZCj>Q_0RCwFauYoVMiUSB+*Mx`tg)bWmM^SwMA+?lBg12QUF_x2b)b?qb88K-YUd z0dO}3k#QirBV<5%jL$#wlf!60dizu;tsp(7XLdI=eQs?P`tOZYMjVq&jE)qK*6B^$ zBe>VvH5TO>s>izhwJJ$<`a8fakTL!yM^Zfr2hV9`f}}VVUXK39p@G|xYRz{fTI+Yq z20d=)iwjuG9RB$%$^&8#(c0_j0t_C~^|n+c`Apu|x7~;#cS-s=X1|C*YxX3ailhg_|0`g!E&GZJEr?bh#Tpb8siR=JxWKc{#w7g zWznLwi;zLFmM1g8V5-P#RsM@iX>TK$xsWuujcsVR^7TQ@!+vCD<>Bk9tdCo7Mzgq5 zv8d>dK9x8C@Qoh01u@3h0X_`SZluTb@5o;{4{{eF!-4405x8X7hewZWpz z2qEi4UTiXTvsa(0X7kQH{3VMF>W|6;6iTrrYD2fMggFA&-CBEfSqPlQDxqsa>{e2M z(R5PJ7uOooFc|9GU0ELA%m4&4Ja#cQpNw8i8ACAoK6?-px+oBl_yKmenZut#Xumjz zk8p^OV2KY&?5MUwGrBOo?ki`Sxo#?-Q4gw*Sh0k`@ zFTaYK2;}%Zk-68`#5DXU$2#=%YL#S&MTN8bF+!J2VT6x^XBci6O)Q#JfW{YMz) zOBM>t2rSj)n#0a3cjvu}r|k3od6W(SN}V-cL?bi*Iz-8uOcCcsX0L>ZXjLqk zZu2uHq5B|Kt>e+=pPKu=1P@1r9WLgYFq_TNV1p9pu0erHGd!+bBp!qGi+~4A(RsYN@CyXNrC&hxGmW)u5m35OmWwX`I+0yByglO`}HC4nGE^_HUs^&A(uaM zKPj^=qI{&ayOq#z=p&pnx@@k&I1JI>cttJcu@Ihljt?6p^6{|ds`0MoQwp+I{3l6` zB<9S((RpLG^>=Kic`1LnhpW2=Gu!x`m~=y;A`Qk!-w`IN;S8S930#vBVMv2vCKi}u z6<-VPrU0AnE&vzwV(CFC0gnZYcpa-l5T0ZS$P6(?9AM;`Aj~XDvt;Jua=jIgF=Fm? zdp=M$>`phx%+Gu};;-&7T|B1AcC#L4@mW5SV_^1BRbo6;2PWe$r+npRV`yc;T1mo& z+~_?7rA+(Um&o@Tddl zL_hxvWk~a)yY}%j`Y+200D%9$bWHy&;(yj{jpi?Rtz{J66ANw)UyPOm;t6FzY3$hx zcn)Ir79nhFvNa7^a{SHN7XH*|Vlsx`CddPnA&Qvh8aNhEA;mPVv;Ah=k<*u!Zq^7 z<=xs*iQTQOMMcg|(NA_auh@x`3#_LFt=)}%SQppP{E>mu_LgquAWvh<>L7tf9+~rO znwUDS52u)OtY<~!d$;m9+87aO+&`#2ICl@Y>&F{jI=H(K+@3M1$rr=*H^dye#~TyD z!){#Pyfn+|ugUu}G;a~!&&0aqQ59U@UT3|_JuBlYUpT$2+11;}JBJ`{+lQN9T@QFY z5+`t;6(TS0F?OlBTE!@7D`8#URDNqx2t6`GZ{ZgXeS@v%-eJzZOHz18aS|svxII$a zZeFjrJ*$IwX$f-Rzr_G>xbu@euGl)B7pC&S+CmDJBg$BoV~jxSO#>y z33`bupN#LDoW0feZe0%q8un0rYN|eRAnwDHQ6e_)xBTbtoZtTA=Fvk){q}9Os~6mQ zKB80VI_&6iSq`LnK7*kfHZoeX6?WE}8yjuDn=2#JG$+;-TOA1%^=DnXx%w{b=w}tS zQbU3XxtOI8E(!%`64r2`zog;5<0b4i)xBmGP^jiDZ2%HNSxIf3@wKs~uk4%3Mxz;~ zts_S~E4>W+YwI<-*-$U8*^HKDEa8oLbmqGg?3vewnaNg%Mm)W=)lcC_J+1ov^u*N3 zXJ?!BrH-+wGYziJq2Y#vyry6Z>NPgkEk+Ke`^DvNRdb>Q2Nlr#v%O@<5hbflI6EKE z9dWc0-ORk^T}jP!nkJ1imyjdVX@GrjOs%cpgA8-c&FH&$(4od#x6Y&=LiJZPINVyW z0snY$8JW@>tc2}DlrD3StQmA0Twck~@>8dSix9CyQOALcREdxoM$Sw*l!}bXKq9&r zysMWR@%OY24@e`?+#xV2bk{T^C_xSo8v2ZI=lBI*l{RciPwuE>L5@uhz@{!l)rtVlWC>)6(G)1~n=Q|S!{E9~6*fdpa*n z!()-8EpTdj=zr_Lswi;#{TxbtH$8*G=UM`I+icz7sr_SdnHXrv=?iEOF1UL+*6O;% zPw>t^kbW9X@oEXx<97%lBm-9?O_7L!DeD)Me#rwE54t~UBu9VZ zl_I1tBB~>jm@bw0Aljz8! zXBB6ATG6iByKIxs!qr%pz%wgqbg(l{65DP4#v(vqhhL{0b#0C8mq`bnqZ1OwFV z7mlZZJFMACm>h9v^2J9+^_zc1=JjL#qM5ZHaThH&n zXPTsR8(+)cj&>Un{6v*z?@VTLr{TmZ@-fY%*o2G}*G}#!bmqpoo*Ay@U!JI^Q@7gj;Kg-HIrLj4}#ec4~D2~X6vo;ghep-@&yOivYP zC19L0D`jjKy1Yi-SGPAn94(768Tcf$urAf{)1)9W58P`6MA{YG%O?|07!g9(b`8PXG1B1Sh0?HQmeJtP0M$O$hI z{5G`&9XzYhh|y@qsF1GnHN|~^ru~HVf#)lOTSrv=S@DyR$UKQk zjdEPFDz{uHM&UM;=mG!xKvp;xAGHOBo~>_=WFTmh$chpC7c`~7?36h)7$fF~Ii}8q zF|YXxH-Z?d+Q+27Rs3X9S&K3N+)OBxMHn1u(vlrUC6ckBY@@jl+mgr#KQUKo#VeFm zFwNYgv0<%~Wn}KeLeD9e1$S>jhOq&(e*I@L<=I5b(?G(zpqI*WBqf|Zge0&aoDUsC zngMRA_Kt0>La+Erl=Uv_J^p(z=!?XHpenzn$%EA`JIq#yYF?JLDMYiPfM(&Csr#f{ zdd+LJL1by?xz|D8+(fgzRs~(N1k9DSyK@LJygwaYX8dZl0W!I&c^K?7)z{2is;OkE zd$VK-(uH#AUaZrp=1z;O*n=b?QJkxu`Xsw&7yrX0?(CX=I-C#T;yi8a<{E~?vr3W> zQrpPqOW2M+AnZ&p{hqmHZU-;Q(7?- zP8L|Q0RM~sB0w1w53f&Kd*y}ofx@c z5Y6B8qGel+uT1JMot$nT1!Tim6{>oZzJXdyA+4euOLME?5Fd_85Uk%#E*ln%y{u8Q z$|?|R@Hpb~yTVK-Yr_S#%NUy7EBfYGAg>b({J|5b+j-PBpPy$Ns`PaJin4JdRfOaS zE|<HjH%NuJgsd2wOlv>~y=np%=2)$M9LS|>P)zJ+Fei5vYo_N~B0XCn+GM76 z)Xz3tg*FRVFgIl9zpESgdpWAavvVViGlU8|UFY{{gVJskg*I!ZjWyk~OW-Td4(mZ6 zB&SQreAAMqwp}rjy`HsG({l2&q5Y52<@AULVAu~rWI$UbFuZs>Sc*x+XI<+ez%$U)|a^unjpiW0l0 zj1!K0(b6$8LOjzRqQ~K&dfbMIE=TF}XFAi)$+h}5SD3lo z%%Qd>p9se=VtQG{kQ;N`sI)G^u|DN#7{aoEd zkksYP%_X$Rq08);-s6o>CGJ<}v`qs%eYf+J%DQ^2k68C%nvikRsN?$ap--f+vCS`K z#&~)f7!N^;sdUXu54gl3L=LN>FB^tuK=y2e#|hWiWUls__n@L|>xH{%8lIJTd5`w? zSwZbnS;W~DawT4OwSJVdAylbY+u5S+ZH{4hAi2&}Iv~W(UvHg(1GTZRPz`@{SOqzy z(8g&Dz=$PfRV=6FgxN~zo+G8OoPI&d-thcGVR*_^(R8COTM@bq?fDwY{}WhsQS1AK zF6R1t8!RdFmfocpJ6?9Yv~;WYi~XPgs(|>{5})j!AR!voO7y9&cMPo#80A(`za@t>cx<0;qxM@S*m(jYP)dMXr*?q0E`oL;12}VAep179uEr8c<=D zr5?A*C{eJ`z9Ee;E$8)MECqatHkbHH z&Y+ho0B$31MIB-xm&;xyaFCtg<{m~M-QDbY)fQ>Q*Xibb~8ytxZQ?QMf9!%cV zU0_X1@b4d+Pg#R!`OJ~DOrQz3@cpiGy~XSKjZQQ|^4J1puvwKeScrH8o{bscBsowomu z^f12kTvje`yEI3eEXDHJ6L+O{Jv$HVj%IKb|J{IvD*l6IG8WUgDJ*UGz z3!C%>?=dlfSJ>4U88)V+`U-!9r^@AxJBx8R;)J4Fn@`~k>8>v0M9xp90OJElWP&R5 zM#v*vtT}*Gm1^)Bv!s72T3PB0yVIjJW)H7a)ilkAvoaH?)jjb`MP>2z{%Y?}83 zUIwBKn`-MSg)=?R)1Q0z3b>dHE^)D8LFs}6ASG1|daDly_^lOSy&zIIhm*HXm1?VS=_iacG);_I9c zUQH1>i#*?oPIwBMJkzi_*>HoUe}_4o>2(SHWzqQ=;TyhAHS;Enr7!#8;sdlty&(>d zl%5cjri8`2X^Ds`jnw7>A`X|bl=U8n+3LKLy(1dAu8`g@9=5iw$R0qk)w8Vh_Dt^U zIglK}sn^)W7aB(Q>HvrX=rxB z+*L)3DiqpQ_%~|m=44LcD4-bxO3OO*LPjsh%p(k?&jvLp0py57oMH|*IMa(<|{m1(0S|x)?R-mqJ=I;_YUZA>J z62v*eSK;5w!h8J+6Z2~oyGdZ68waWfy09?4fU&m7%u~zi?YPHPgK6LDwphgaYu%0j zurtw)AYOpYKgHBrkX189mlJ`q)w-f|6>IER{5Lk97%P~a-JyCRFjejW@L>n4vt6#hq;!|m;hNE||LK3nw1{bJOy+eBJjK=QqNjI;Q6;Rp5 z&035pZDUZ#%Oa;&_7x0T<7!RW`#YBOj}F380Bq?MjjEhrvlCATPdkCTTl+2efTX$k zH&0zR1n^`C3ef~^sXzJK-)52(T}uTG%OF8yDhT76L~|^+hZ2hiSM*QA9*D5odI1>& z9kV9jC~twA5MwyOx(lsGD_ggYmztXPD`2=_V|ks_FOx!_J8!zM zTzh^cc+=VNZ&(OdN=y4Juw)@8-85lwf_#VMN!Ed(eQiRiLB2^2e`4dp286h@v@`O%_b)Y~A; zv}r6U?zs&@uD_+(_4bwoy7*uozNvp?bXFoB8?l8yG0qsm1JYzIvB_OH4_2G*IIOwT zVl%HX1562vLVcxM_RG*~w_`FbIc!(T=3>r528#%mwwMK}uEhJ()3MEby zQQjzqjWkwfI~;Fuj(Lj=Ug0y`>~C7`w&wzjK(rPw+Hpd~EvQ-ufQOiB4OMpyUKJhw zqEt~jle9d7S~LI~$6Z->J~QJ{Vdn3!c}g9}*KG^Kzr^(7VI5Gk(mHLL{itj_hG?&K4Ws0+T4gLfi3eu$N=`s36geNC?c zm!~}vG6lx9Uf^5M;bWntF<-{p^bruy~f?sk9 zcETAPQZLoJ8JzMMg<-=ju4keY@SY%Wo?u9Gx=j&dfa6LIAB|IrbORLV1-H==Z1zCM zeZcOYpm5>U2fU7V*h;%n`8 zN95QhfD994={1*<2vKLCNF)feKOGk`R#K~G=;rfq}|)s20&MCa65 zUM?xF5!&e0lF%|U!#rD@I{~OsS_?=;s_MQ_b_s=PuWdC)q|UQ&ea)DMRh5>fpQjXe z%9#*x=7{iRCtBKT#H>#v%>77|{4_slZ)XCY{s3j_r{tdpvb#|r|sbS^dU1x70$eJMU!h{Y7Kd{dl}9&vxQl6Jt1a` zHQZrWyY0?!vqf@u-fxU_@+}u(%Wm>0I#KP48tiAPYY!TdW(o|KtVI|EUB9V`CBBNaBLVih7+yMVF|GSoIQD0Jfb{ z!OXq;(>Z?O`1gap(L~bUcp>Lc@Jl-})^=6P%<~~9ywY=$iu8pJ0m*hOPzr~q`23eX zgbs;VOxxENe0UMVeN*>uCn9Gk!4siN-e>x)pIKAbQz!G)TcqIJ0`JBBaX>1-4_XO_-HCS^vr2vjv#7KltDZdyQ{tlWh4$Gm zB>|O1cBDC)yG(sbnc*@w6e%e}r*|IhpXckx&;sQCwGdKH+3oSG-2)Bf#x`@<4ETAr z0My%7RFh6ZLiZ_;X6Mu1YmXx7C$lSZ^}1h;j`EZd6@%JNUe=btBE z%s=Xmo1Ps?8G`}9+6>iaB8bgjUdXT?=trMu|4yLX^m0Dg{m7rpKNJey|EwHI+nN1e zL^>qN%5Fg)dGs4DO~uwIdXImN)QJ*Jhpj7$fq_^`{3fwpztL@WBB}OwQ#Epo-mqMO zsM$UgpFiG&d#)lzEQ{3Q;)&zTw;SzGOah-Dpm{!q7<8*)Ti_;xvV2TYXa}=faXZy? z3y?~GY@kl)>G&EvEijk9y1S`*=zBJSB1iet>0;x1Ai)*`^{pj0JMs)KAM=@UyOGtO z3y0BouW$N&TnwU6!%zS%nIrnANvZF&vB1~P5_d`x-giHuG zPJ;>XkVoghm#kZXRf>qxxEix;2;D1CC~NrbO6NBX!`&_$iXwP~P*c($EVV|669kDO zKoTLZNF4Cskh!Jz5ga9uZ`3o%7Pv`d^;a=cXI|>y;zC3rYPFLQkF*nv(r>SQvD*## z(Vo%^9g`%XwS0t#94zPq;mYGLKu4LU3;txF26?V~A0xZbU4Lmy`)>SoQX^m7fd^*E z+%{R4eN!rIk~K)M&UEzxp9dbY;_I^c} zOc{wlIrN_P(PPqi51k_$>Lt|X6A^|CGYgKAmoI#Li?;Wq%q~q*L7ehZkUrMxW67Jl zhsb~+U?33QS>eqyN{(odAkbopo=Q$Az?L+NZW>j;#~@wCDX?=L5SI|OxI~7!Pli;e zELMFcZtJY3!|=Gr2L4>z8yQ-{To>(f80*#;6`4IAiqUw`=Pg$%C?#1 z_g@hIGerILSU>=P>z{gM|DS91A4cT@PEIB^hSop!uhMo#2G;+tQSpDO_6nOnPWSLU zS;a9m^DFMXR4?*X=}d7l;nXuHk&0|m`NQn%d?8|Ab3A9l9Jh5s120ibWBdB z$5YwsK3;wvp!Kn@)Qae{ef`0#NwlRpQ}k^r>yos_Ne1;xyKLO?4)t_G4eK~wkUS2A&@_;)K0-03XGBzU+5f+uMDxC z(s8!8!RvdC#@`~fx$r)TKdLD6fWEVdEYtV#{ncT-ZMX~eI#UeQ-+H(Z43vVn%Yj9X zLdu9>o%wnWdvzA-#d6Z~vzj-}V3FQ5;axDIZ;i(95IIU=GQ4WuU{tl-{gk!5{l4_d zvvb&uE{%!iFwpymz{wh?bKr1*qzeZb5f6e6m_ozRF&zux2mlK=v_(_s^R6b5lu?_W4W3#<$zeG~Pd)^!4tzhs}-Sx$FJP>)ZGF(hVTH|C3(U zs0PO&*h_ zNA-&qZpTP$$LtIgfiCn07}XDbK#HIXdmv8zdz4TY;ifNIH-0jy(gMSByG2EF~Th#eb_TueZC` zE?3I>UTMpKQ})=C;6p!?G)M6w^u*A57bD?2X`m3X^6;&4%i_m(uGJ3Z5h`nwxM<)H z$I5m?wN>O~8`BGnZ=y^p6;0+%_0K}Dcg|K;+fEi|qoBqvHj(M&aHGqNF48~XqhtU? z^ogwBzRlOfpAJ+Rw7IED8lRbTdBdyEK$gPUpUG}j-M42xDj_&qEAQEtbs>D#dRd7Y z<&TpSZ(quQDHiCFn&0xsrz~4`4tz!CdL8m~HxZM_agu@IrBpyeL1Ft}V$HX_ZqDPm z-f89)pjuEzGdq-PRu`b1m+qBGY{zr_>{6Ss>F|xHZlJj9dt5HD$u`1*WZe)qEIuDSR)%z+|n zatVlhQ?$w#XRS7xUrFE;Y8vMGhQS5*T{ZnY=q1P?w5g$OKJ#M&e??tAmPWHMj3xhS ziGxapy?kn@$~2%ZY;M8Bc@%$pkl%Rvj!?o%agBvpQ-Q61n9kznC4ttrRNQ4%GFR5u zyv%Yo9~yxQJWJSfj z?#HY$y=O~F|2pZs22pu|_&Ajd+D(Mt!nPUG{|1nlvP`=R#kKH zO*s$r_%ss5h1YO7k0bHJ2CXN)Yd6CHn~W!R=SqkWe=&nAZu(Q1G!xgcUilM@YVei@2@a`8he z9@pM`)VB*=e7-MWgLlXlc)t;fF&-AwM{E-EX}pViFn0I0CNw2bNEnN2dj!^4(^zS3 zobUm1uQnpqk_4q{pl*n06=TfK_C>UgurKFjRXsK_LEn};=79`TB12tv6KzwSu*-C8 z;=~ohDLZylHQ|Mpx-?yql>|e=vI1Z!epyUpAcDCp4T|*RV&X`Q$0ogNwy6mFALo^@ z9=&(9txO8V@E!@6^(W0{*~CT>+-MA~vnJULBxCTUW>X5>r7*eXYUT0B6+w@lzw%n> z_VjJ<2qf|(d6jYq2(x$(ZDf!yVkfnbvNmb5c|hhZ^2TV_LBz`9w!e_V*W_(MiA7|= z&EeIIkw*+$Xd!)j8<@_<}A5;~A_>3JT*kX^@}cDoLd>Qj<`Se^wdUa(j0dp+Tl8EptwBm{9OGsdFEq zM`!pjf(Lm(`$e3FLOjqA5LnN5o!}z{ zNf}rJuZh@yUtq&ErjHeGzX4(!luV!jB&;FAP|!R_QHYw#^Z1LwTePAKJ6X&IDNO#; z)#I@Xnnzyij~C@UH~X51JCgQeF0&hTXnuoElz#m{heZRexWc0k4<>0+ClX7%0 zEBqCCld1tD9Zwkr4{?Nor19#E5-YKfB8d?qgR82-Ow2^AuNevly2*tHA|sK!ybYkX zm-sLQH72P&{vEAW6+z~O5d0qd=xW~rua~5a?ymYFSD@8&gV)E5@RNNBAj^C99+Z5Z zR@Pq55mbCQbz+Mn$d_CMW<-+?TU960agEk1J<>d>0K=pF19yN))a~4>m^G&tc*xR+yMD*S=yip-q=H zIlredHpsJV8H(32@Zxc@bX6a21dUV95Th--8pE6C&3F>pk=yv$yd6@Haw;$v4+Fcb zRwn{Qo@0`7aPa2LQOP}j9v>sjOo5Kqvn|`FLizX zB+@-u4Lw|jsvz{p^>n8Vo8H2peIqJJnMN}A)q6%$Tmig7eu^}K2 zrh$X?T|ZMsoh{6pdw1G$_T<`Ds-G=jc;qcGdK4{?dN2-XxjDNbb(7pk|3JUVCU4y; z)?LXR>f+AAu)JEiti_Zy#z5{RgsC}R(@jl%9YZ>zu~hKQ*AxbvhC378-I@{~#%Y`Z zy=a=9YpewPIC+gkEUUwtUL7|RU7=!^Aa}Mk^6uxOgRGA#JXjWLsjFUnix|Mau{hDT z7mn*z1m5g`vP(#tjT0Zy4eAY(br&!RiiXE=ZI!{sE1#^#%x^Z7t1U)b<;%Y}Q9=5v z;wpDCEZ@OE36TWT=|gxigT@VaW9BvHS05;_P(#s z8zI4XFQys}q)<`tkX$WnSarn{3e!s}4(J!=Yf>+Y>cP3f;vr63f2{|S^`_pWc)^5_!R z*(x-fuBxL51@xe!lnDBKi}Br$c$BMZ3%f2Sa6kLabiBS{pq*yj;q|k(86x`PiC{p6 z_bxCW{>Q2BA8~Ggz&0jkrcU+-$ANBsOop*ms>34K9lNYil@}jC;?cYP(m^P}nR6FV zk(M%48Z&%2Rx$A&FhOEirEhY0(dn;-k(qkTU)sFQ`+-ih+s@A8g?r8Pw+}2;35WYf zi}VO`jS`p(tc)$X$a>-#WXoW!phhatC*$}|rk>|wUU71eUJG^$c6_jwX?iSHM@6__ zvV|6%U*$sSXJu9SX?2%M^kK|}a2QJ8AhF{fuXrHZxXsI~O zGKX45!K7p*MCPEQ=gp?eu&#AW*pR{lhQR##P_*{c_DjMGL|3T3-bSJ(o$|M{ytU}> zAV>wq*uE*qFo9KvnA^@juy{x<-u*#2NvkV={Ly}ysKYB-k`K3@K#^S1Bb$8Y#0L0# z`6IkSG&|Z$ODy|VLS+y5pFJx&8tvPmMd8c9FhCyiU8~k6FwkakUd^(_ml8`rnl>JS zZV){9G*)xBqPz^LDqRwyS6w86#D^~xP4($150M)SOZRe9sn=>V#aG0Iy(_^YcPpIz8QYM-#s+n% z@Jd?xQq?Xk6=<3xSY7XYP$$yd&Spu{A#uafiIfy8gRC`o0nk{ezEDjb=q_qRAlR1d zFq^*9Gn)yTG4b}R{!+3hWQ+u3GT~8nwl2S1lpw`s0X_qpxv)g+JIkVKl${sYf_nV~B>Em>M;RlqGb5WVil(89 zs=ld@|#;dq1*vQGz=7--Br-|l) zZ%Xh@v8>B7P?~}?Cg$q9_={59l%m~O&*a6TKsCMAzG&vD>k2WDzJ6!tc!V)+oxF;h zJH;apM=wO?r_+*#;ulohuP=E>^zon}a$NnlcQ{1$SO*i=jnGVcQa^>QOILc)e6;eNTI>os=eaJ{*^DE+~jc zS}TYeOykDmJ=6O%>m`i*>&pO_S;qMySJIyP=}4E&J%#1zju$RpVAkZbEl+p%?ZP^C z*$$2b4t%a(e+%>a>d_f_<JjxI#J1x;=hPd1zFPx=6T$;;X1TD*2(edZ3f46zaAoW>L53vS_J*N8TMB|n+;LD| zC=GkQPpyDY#Am4l49chDv*gojhRj_?63&&8#doW`INATAo(qY#{q}%nf@eTIXmtU< zdB<7YWfyCmBs|c)cK>1)v&M#!yNj#4d$~pVfDWQc_ke1?fw{T1Nce_b`v|Vp5ig(H zJvRD^+ps46^hLX;=e2!2e;w9y1D@!D$c@Jc&%%%IL=+xzw55&2?darw=9g~>P z9>?Kdc$r?6c$m%x2S$sdpPl>GQZ{rC9mPS63*qjCVa?OIBj!fW zm|g?>CVfGXNjOfcyqImXR_(tXS(F{FcoNzKvG5R$IgGaxC@)i(e+$ME}vPVIhd|mx2IIE+f zM?9opQHIVgBWu)^A|RzXw!^??S!x)SZOwZaJkGjc<_}2l^eSBm!eAJG9T>EC6I_sy z?bxzDIAn&K5*mX)$RQzDA?s)-no-XF(g*yl4%+GBf`##bDXJ==AQk*xmnatI;SsLp zP9XTHq5mmS=iWu~9ES>b%Q=1aMa|ya^vj$@qz9S!ih{T8_PD%Sf_QrNKwgrXw9ldm zHRVR98*{C?_XNpJn{abA!oix_mowRMu^2lV-LPi;0+?-F(>^5#OHX-fPED zCu^l7u3E%STI}c4{J2!)9SUlGP_@!d?5W^QJXOI-Ea`hFMKjR7TluLvzC-ozCPn1`Tpy z!vlv@_Z58ILX6>nDjTp-1LlFMx~-%GA`aJvG$?8*Ihn;mH37eK**rmOEwqegf-Ccx zrIX4;{c~RK>XuTXxYo5kMiWMy)!IC{*DHG@E$hx?RwP@+wuad(P1{@%tRkyJRqD)3 zMHHHZ4boqDn>-=DgR5VlhQTpfVy182Gk;A_S8A1-;U1RR>+$62>(MUx@Nox$vTjHq z%QR=j!6Gdyb5wu7y(YUktwMuW5<@jl?m4cv4BODiT5o8qVdC0MBqGr@-YBIwnpZAY znX9(_uQjP}JJ=!~Ve9#5I~rUnN|P_3D$LqZcvBnywYhjlMSFHm`;u9GPla{5QD7(7*6Tb3Svr8;(nuAd81q$*uq6HC_&~je*Ca7hP4sJp0av{M8480wF zxASi7Qv+~@2U%Nu1Ud;s-G4CTVWIPyx!sg&8ZG0Wq zG_}i3C(6_1>q3w!EH7$Kwq8uBp2F2N7}l65mk1p*9v0&+;th=_E-W)E;w}P(j⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ac72c34e8ac..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradlew b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradlew deleted file mode 100755 index 0adc8e1a532..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradlew +++ /dev/null @@ -1,249 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed 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 -# -# https://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. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradlew.bat b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradlew.bat deleted file mode 100644 index 93e3f59f135..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/source_archive.expected new file mode 100644 index 00000000000..1ee055eeb02 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/source_archive.expected @@ -0,0 +1,7 @@ +.gradle/8.3/dependencies-accessors/gc.properties +.gradle/8.3/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +src/main/java/com/fractestexample/Test.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.expected deleted file mode 100644 index 05792cb19fc..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.expected +++ /dev/null @@ -1 +0,0 @@ -| src/main/java/com/fractestexample/Test.java:0:0:0:0 | Test | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.py b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.py index ac3b64436ed..970c78f97ab 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.py @@ -1,40 +1,7 @@ -from create_database_utils import * -from diagnostics_test_utils import * -from buildless_test_utils import * -import mitm_proxy -import os -import shutil -import subprocess -import sys - -shutil.rmtree('certs', ignore_errors=True) -os.mkdir('certs') - -ca_cert_file = 'certs/ca-cert.pem' -ca_key_file = 'certs/ca-key.pem' -mitm_proxy.generateCA(ca_cert_file, ca_key_file) -with open(ca_cert_file, 'rb') as f: - cert_pem = f.read().decode('ascii') - -# This starts an HTTP proxy server on http://localhost:9430 -environment = os.environ.copy() -environment["PROXY_USER"] = "proxy" -environment["PROXY_PASSWORD"] = "password" - -proxy_server_process = subprocess.Popen( - [sys.executable, mitm_proxy.__file__, "9430", "certs/ca-cert.pem", "certs/ca-key.pem"], env=environment) - -try: - run_codeql_database_create([], lang="java", extra_env={ - "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", - "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", - "CODEQL_PROXY_HOST": "localhost", - "CODEQL_PROXY_PORT": "9430", - "CODEQL_PROXY_USER": "proxy", - "CODEQL_PROXY_PASSWORD": "password", - "CODEQL_PROXY_CA_CERTIFICATE": cert_pem - }) -finally: - proxy_server_process.kill() -check_diagnostics() -check_buildless_fetches() +def test(codeql, java, codeql_mitm_proxy, gradle_8_3): + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", + } + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.ql deleted file mode 100644 index 8317a5a022f..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.ql +++ /dev/null @@ -1,5 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/source_archive.expected new file mode 100644 index 00000000000..cdb0dca9421 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/source_archive.expected @@ -0,0 +1,8 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +test-db/log/ext/javac.properties +test-db/working/settings.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.expected deleted file mode 100644 index 9ab4eed832b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.expected +++ /dev/null @@ -1,11 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| test-db/working/settings.xml:0:0:0:0 | test-db/working/settings.xml | -propertiesFiles -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.py b/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.py index 648957a9920..c8919d321fa 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.py @@ -1,40 +1,7 @@ -from create_database_utils import * -from diagnostics_test_utils import * -from buildless_test_utils import * -import mitm_proxy -import os -import shutil -import subprocess -import sys - -shutil.rmtree('certs', ignore_errors=True) -os.mkdir('certs') - -ca_cert_file = 'certs/ca-cert.pem' -ca_key_file = 'certs/ca-key.pem' -mitm_proxy.generateCA(ca_cert_file, ca_key_file) -with open(ca_cert_file, 'rb') as f: - cert_pem = f.read().decode('ascii') - -# This starts an HTTP proxy server on http://localhost:9431 -environment = os.environ.copy() -environment["PROXY_USER"] = "proxy" -environment["PROXY_PASSWORD"] = "password" - -proxy_server_process = subprocess.Popen( - [sys.executable, mitm_proxy.__file__, "9431", "certs/ca-cert.pem", "certs/ca-key.pem"], env=environment) - -try: - run_codeql_database_create([], lang="java", extra_env={ - "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", - "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", - "CODEQL_PROXY_HOST": "localhost", - "CODEQL_PROXY_PORT": "9431", - "CODEQL_PROXY_USER": "proxy", - "CODEQL_PROXY_PASSWORD": "password", - "CODEQL_PROXY_CA_CERTIFICATE": cert_pem - }) -finally: - proxy_server_process.kill() -check_diagnostics() -check_buildless_fetches() +def test(codeql, java, codeql_mitm_proxy): + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", + } + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/source_archive.expected new file mode 100644 index 00000000000..d0e6787e268 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/source_archive.expected @@ -0,0 +1,29 @@ +gradle-sample/.gradle/6.6.1/gc.properties +gradle-sample/.gradle/buildOutputCleanup/cache.properties +gradle-sample/.gradle/configuration-cache/gc.properties +gradle-sample/.gradle/vcs-1/gc.properties +gradle-sample/gradle/verification-metadata.xml +gradle-sample/gradle/wrapper/gradle-wrapper.properties +gradle-sample/src/main/java/com/example/App.java +gradle-sample/src/test/java/com/example/AppTest.java +gradle-sample2/.gradle/6.6.1/gc.properties +gradle-sample2/.gradle/buildOutputCleanup/cache.properties +gradle-sample2/.gradle/configuration-cache/gc.properties +gradle-sample2/.gradle/vcs-1/gc.properties +gradle-sample2/gradle/verification-metadata.xml +gradle-sample2/gradle/wrapper/gradle-wrapper.properties +gradle-sample2/src/main/java/com/example/App2.java +gradle-sample2/src/test/java/com/example/AppTest2.java +maven-project-1/pom.xml +maven-project-1/src/main/java/com/example/App3.java +maven-project-1/src/main/resources/my-app.properties +maven-project-1/src/main/resources/page.xml +maven-project-1/src/main/resources/struts.xml +maven-project-1/src/test/java/com/example/AppTest3.java +maven-project-2/pom.xml +maven-project-2/src/main/java/com/example/App4.java +maven-project-2/src/main/resources/my-app.properties +maven-project-2/src/main/resources/page.xml +maven-project-2/src/main/resources/struts.xml +maven-project-2/src/test/java/com/example/AppTest4.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.expected b/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.expected deleted file mode 100644 index fe848a3dbf2..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.expected +++ /dev/null @@ -1,8 +0,0 @@ -| gradle-sample2/src/main/java/com/example/App2.java:0:0:0:0 | App2 | -| gradle-sample2/src/test/java/com/example/AppTest2.java:0:0:0:0 | AppTest2 | -| gradle-sample/src/main/java/com/example/App.java:0:0:0:0 | App | -| gradle-sample/src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -| maven-project-1/src/main/java/com/example/App3.java:0:0:0:0 | App3 | -| maven-project-1/src/test/java/com/example/AppTest3.java:0:0:0:0 | AppTest3 | -| maven-project-2/src/main/java/com/example/App4.java:0:0:0:0 | App4 | -| maven-project-2/src/test/java/com/example/AppTest4.java:0:0:0:0 | AppTest4 | diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.py b/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.py index 6971aa508db..1b7cae27c64 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.py @@ -1,14 +1,9 @@ -from create_database_utils import * -from diagnostics_test_utils import * -from buildless_test_utils import * -from toolchains_test_utils import * - -#The version of gradle used doesn't work on java 17 -try_use_java11() - -toolchains_file = actions_expose_all_toolchains() - -run_codeql_database_create([], lang="java", extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", "LGTM_INDEX_MAVEN_TOOLCHAINS_FILE": toolchains_file}) - -check_diagnostics() -check_buildless_fetches() +def test(codeql, use_java_11, java, actions_toolchains_file): + # The version of gradle used doesn't work on java 17 + codeql.database.create( + _env={ + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true", + "CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true", + "LGTM_INDEX_MAVEN_TOOLCHAINS_FILE": str(actions_toolchains_file), + } + ) diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.ql b/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.ql deleted file mode 100644 index 8317a5a022f..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.ql +++ /dev/null @@ -1,5 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.py b/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.py index cc9d91c7792..e5e38d725ae 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.py @@ -1,15 +1,16 @@ +import subprocess import sys -from create_database_utils import * -from buildless_test_utils import * -import subprocess -# This serves the "repo" directory on http://localhost:9427 -repo_server_process = subprocess.Popen(["python3", "-m", "http.server", "9427"], cwd = "repo") - -try: - run_codeql_database_create([], lang="java", extra_args=["--extractor-option=buildless=true"], extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"}) -finally: - repo_server_process.kill() - -check_buildless_fetches() +def test(codeql, java): + # This serves the "repo" directory on http://localhost:9427 + repo_server_process = subprocess.Popen( + [sys.executable, "-m", "http.server", "9427"], cwd="repo" + ) + try: + codeql.database.create( + extractor_option="buildless=true", + _env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_CLASSPATH_FROM_BUILD_FILES": "true"}, + ) + finally: + repo_server_process.kill() diff --git a/java/ql/integration-tests/all-platforms/java/buildless/source_archive.expected b/java/ql/integration-tests/all-platforms/java/buildless/source_archive.expected new file mode 100644 index 00000000000..b3923b0fd96 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/buildless/source_archive.expected @@ -0,0 +1,6 @@ +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless/test.expected b/java/ql/integration-tests/all-platforms/java/buildless/test.expected deleted file mode 100644 index 0213d624f7b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless/test.expected +++ /dev/null @@ -1,9 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -propertiesFiles -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/buildless/test.py b/java/ql/integration-tests/all-platforms/java/buildless/test.py index 747dd6a82ad..834b1132cf1 100644 --- a/java/ql/integration-tests/all-platforms/java/buildless/test.py +++ b/java/ql/integration-tests/all-platforms/java/buildless/test.py @@ -1,8 +1,2 @@ -import sys - -from create_database_utils import * -from diagnostics_test_utils import * - -run_codeql_database_create([], lang="java", extra_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true"}) - -check_diagnostics() +def test(codeql, java): + codeql.database.create(_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true"}) diff --git a/java/ql/integration-tests/all-platforms/java/buildless/test.ql b/java/ql/integration-tests/all-platforms/java/buildless/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/buildless/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/.gitattributes b/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/.gitattributes deleted file mode 100644 index 00a51aff5e5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/force_sequential_test_execution deleted file mode 100644 index 4947fd6fe51..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/force_sequential_test_execution +++ /dev/null @@ -1,4 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. -# Additionally, Android SDK on-demand downloading can fail when multiple tests try to download the same SDK in parallel. diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090a2944b7473328c07c9755baa3196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60756 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 '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/gradlew.bat b/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/gradlew.bat deleted file mode 100644 index f127cfd49d4..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/test.py b/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/test.py index 23fe1d32fd8..f58e84e77a2 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/test.py +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/test.py @@ -1,7 +1,2 @@ -import os -from create_database_utils import * -from diagnostics_test_utils import * - -run_codeql_database_create([], lang="java", runFunction = runUnsuccessfully, db = None) - -check_diagnostics() +def test(codeql, java, gradle_7_3, android_sdk): + codeql.database.create(_assert_failure=True) diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/test.py b/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/test.py index 23fe1d32fd8..a0c0737d3ac 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/test.py +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/test.py @@ -1,7 +1,2 @@ -import os -from create_database_utils import * -from diagnostics_test_utils import * - -run_codeql_database_create([], lang="java", runFunction = runUnsuccessfully, db = None) - -check_diagnostics() +def test(codeql, java): + codeql.database.create(_assert_failure=True) diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/test.py b/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/test.py index 1838af5db40..d285932b959 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/test.py +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/test.py @@ -1,18 +1,4 @@ -import os -import pathlib -import shutil -import re - -from create_database_utils import * -from diagnostics_test_utils import * - -# Ensure the intended dependency download failure is not cached: -try: - shutil.rmtree(pathlib.Path.home().joinpath(".m2", "repository", "junit", "junit-nonesuch")) -except FileNotFoundError: - pass - -run_codeql_database_create([], lang="java", runFunction = runUnsuccessfully, db = None) - -# Drop the specific output line here because it varies from version to version of Maven. -check_diagnostics(replacements = {"Relevant output line: [^\"]*": ""}) +def test(codeql, java, check_diagnostics): + codeql.database.create(_assert_failure=True) + # Drop the specific output line here because it varies from version to version of Maven. + check_diagnostics.replacements = [('Relevant output line: [^"]*', "")] diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/.gitattributes b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/.gitattributes deleted file mode 100644 index 00a51aff5e5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/.gitignore b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/.gitignore deleted file mode 100644 index 1b6985c0094..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Ignore Gradle project-specific cache directory -.gradle - -# Ignore Gradle build output directory -build diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/verification-metadata.xml b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/verification-metadata.xml deleted file mode 100644 index 14a69b8178b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/verification-metadata.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - true - false - - \ No newline at end of file diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59203 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

    K7UpUK$>l@ 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 E2O(~oYXATM diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 12d38de6a48..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradlew b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradlew deleted file mode 100755 index 4f906e0c811..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed 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 -# -# https://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. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradlew.bat b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradlew.bat deleted file mode 100644 index 107acd32c4e..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/skip-on-platform-osx-arm b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/skip-on-platform-osx-arm deleted file mode 100644 index 8b3140e546e..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/skip-on-platform-osx-arm +++ /dev/null @@ -1,3 +0,0 @@ -2023-11-08: - -There is no Java 8 build available for OSX Arm, therefore this test fails. diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/test.py b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/test.py index d087461cd89..accbd8facdd 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/test.py +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/test.py @@ -1,26 +1,20 @@ import os -from create_database_utils import * -from diagnostics_test_utils import * +import re +import runs_on -# Ensure we're using an old Java version that won't work with Gradle -for k in os.environ: - if k.upper() in ["JAVA_HOME_8_X64", "JAVA_HOME_8_ARM64"]: - os.environ["JAVA_HOME"] = os.environ[k] - sep = ";" if platform.system() == "Windows" else ":" - os.environ["PATH"] = "".join([os.path.join(os.environ["JAVA_HOME"], "bin"), sep, os.environ["PATH"]]) - break -# Ensure the autobuilder *doesn't* see newer Java versions, which it could switch to in order to build the project: -for k in os.environ: - if re.match(r"^JAVA_HOME_\d\d_", k): - del os.environ[k] +# There is no Java 8 build available for OSX Arm, therefore this test fails. +@runs_on.x86_64 +def test(codeql, use_java_8, java, cwd, gradle_6_6_1): + # Use a custom, empty toolchains.xml file so the autobuilder doesn't see any Java versions that may be + # in a system-level toolchains file + toolchains_path = cwd / "toolchains.xml" -# Use a custom, empty toolchains.xml file so the autobuilder doesn't see any Java versions that may be -# in a system-level toolchains file -toolchains_path = os.path.join(os.getcwd(), 'toolchains.xml') - -run_codeql_database_create([], lang="java", runFunction = runUnsuccessfully, db = None, extra_env={ - 'LGTM_INDEX_MAVEN_TOOLCHAINS_FILE': toolchains_path -}) - -check_diagnostics() + # Ensure the autobuilder *doesn't* see newer Java versions, which it could switch to in order to build the project: + for k in os.environ: + if re.match(r"^JAVA_HOME_\d\d_", k): + del os.environ[k] + codeql.database.create( + _assert_failure=True, + _env={"LGTM_INDEX_MAVEN_TOOLCHAINS_FILE": str(toolchains_path)}, + ) diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/test.py b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/test.py index 23fe1d32fd8..a0c0737d3ac 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/test.py +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/test.py @@ -1,7 +1,2 @@ -import os -from create_database_utils import * -from diagnostics_test_utils import * - -run_codeql_database_create([], lang="java", runFunction = runUnsuccessfully, db = None) - -check_diagnostics() +def test(codeql, java): + codeql.database.create(_assert_failure=True) diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/test.py b/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/test.py index 23fe1d32fd8..a0c0737d3ac 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/test.py +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/test.py @@ -1,7 +1,2 @@ -import os -from create_database_utils import * -from diagnostics_test_utils import * - -run_codeql_database_create([], lang="java", runFunction = runUnsuccessfully, db = None) - -check_diagnostics() +def test(codeql, java): + codeql.database.create(_assert_failure=True) diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/test.py b/java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/test.py index 23fe1d32fd8..a0c0737d3ac 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/test.py +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/test.py @@ -1,7 +1,2 @@ -import os -from create_database_utils import * -from diagnostics_test_utils import * - -run_codeql_database_create([], lang="java", runFunction = runUnsuccessfully, db = None) - -check_diagnostics() +def test(codeql, java): + codeql.database.create(_assert_failure=True) diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/diagnostics.expected b/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/diagnostics.expected index 30e328253da..e8f7e949c5e 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/diagnostics.expected +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/diagnostics.expected @@ -13,7 +13,7 @@ } } { - "markdownMessage": "Gradle project does not define a `testClasses` goal. [Supply a manual build command](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language) that builds the code that should be analyzed.\n\nRelevant output line: `org.gradle.execution.TaskSelectionException: Task 'testClasses' not found in root project 'no-gradle-test-classes'.`", + "markdownMessage": "Gradle project does not define a `testClasses` goal. [Supply a manual build command](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language) that builds the code that should be analyzed.\n\nRelevant output line: `org.gradle.execution.TaskSelectionException: Task 'testClasses' not found in root project 'test'.`", "severity": "error", "source": { "extractorName": "java", diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/test.py b/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/test.py index 23fe1d32fd8..a0c0737d3ac 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/test.py +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/test.py @@ -1,7 +1,2 @@ -import os -from create_database_utils import * -from diagnostics_test_utils import * - -run_codeql_database_create([], lang="java", runFunction = runUnsuccessfully, db = None) - -check_diagnostics() +def test(codeql, java): + codeql.database.create(_assert_failure=True) diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/test.py b/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/test.py index 23fe1d32fd8..a0c0737d3ac 100644 --- a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/test.py +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/test.py @@ -1,7 +1,2 @@ -import os -from create_database_utils import * -from diagnostics_test_utils import * - -run_codeql_database_create([], lang="java", runFunction = runUnsuccessfully, db = None) - -check_diagnostics() +def test(codeql, java): + codeql.database.create(_assert_failure=True) diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/source_archive.expected b/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/source_archive.expected new file mode 100644 index 00000000000..3d16d23ce76 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/source_archive.expected @@ -0,0 +1,2 @@ +Test.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.expected b/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.expected deleted file mode 100644 index 8f3e41e24f0..00000000000 --- a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.expected +++ /dev/null @@ -1 +0,0 @@ -| Test.java:1:14:1:17 | Test | diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.py b/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.py index 1478610427a..a9afd1055ef 100644 --- a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.py +++ b/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.py @@ -1,6 +1,4 @@ -import urllib.request -from create_database_utils import * - -urllib.request.urlretrieve("https://repo1.maven.org/maven2/org/eclipse/jdt/ecj/3.37.0/ecj-3.37.0.jar", "ecj.jar") - -run_codeql_database_create(["java -cp ecj.jar org.eclipse.jdt.internal.compiler.batch.Main -noExit Test.java"], lang="java") +def test(codeql, java, ecj): + codeql.database.create( + command=f"java -cp {ecj} org.eclipse.jdt.internal.compiler.batch.Main -noExit Test.java" + ) diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.ql b/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.ql deleted file mode 100644 index a61eb5e336a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.ql +++ /dev/null @@ -1,3 +0,0 @@ -import java - -select any(Class c | c.fromSource()) diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample/source_archive.expected b/java/ql/integration-tests/all-platforms/java/ecj-sample/source_archive.expected new file mode 100644 index 00000000000..3d16d23ce76 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/ecj-sample/source_archive.expected @@ -0,0 +1,2 @@ +Test.java +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample/test.expected b/java/ql/integration-tests/all-platforms/java/ecj-sample/test.expected deleted file mode 100644 index 8f3e41e24f0..00000000000 --- a/java/ql/integration-tests/all-platforms/java/ecj-sample/test.expected +++ /dev/null @@ -1 +0,0 @@ -| Test.java:1:14:1:17 | Test | diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample/test.py b/java/ql/integration-tests/all-platforms/java/ecj-sample/test.py index 9acadbdb6f1..d9948b5b54f 100644 --- a/java/ql/integration-tests/all-platforms/java/ecj-sample/test.py +++ b/java/ql/integration-tests/all-platforms/java/ecj-sample/test.py @@ -1,6 +1,4 @@ -import urllib.request -from create_database_utils import * - -urllib.request.urlretrieve("https://repo1.maven.org/maven2/org/eclipse/jdt/ecj/3.37.0/ecj-3.37.0.jar", "ecj.jar") - -run_codeql_database_create(["java -cp ecj.jar org.eclipse.jdt.internal.compiler.batch.Main Test.java"], lang="java") +def test(codeql, java, ecj): + codeql.database.create( + command=f"java -cp {ecj} org.eclipse.jdt.internal.compiler.batch.Main Test.java" + ) diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample/test.ql b/java/ql/integration-tests/all-platforms/java/ecj-sample/test.ql deleted file mode 100644 index a61eb5e336a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/ecj-sample/test.ql +++ /dev/null @@ -1,3 +0,0 @@ -import java - -select any(Class c | c.fromSource()) diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diagnostics.expected b/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diag.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diagnostics.expected rename to java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diag.expected diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diagnostics.ql b/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diag.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diagnostics.ql rename to java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diag.ql diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.py b/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.py index 40313e2654a..027ca32b433 100644 --- a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.py +++ b/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.py @@ -1,8 +1,8 @@ -import urllib.request -from create_database_utils import * - -urllib.request.urlretrieve("https://repo1.maven.org/maven2/org/eclipse/jdt/ecj/3.38.0/ecj-3.38.0.jar", "ecj.jar") - -# This tests the case where ECJ emits a RuntimeIn/VisibleAnnotations attribute that isn't the same size as the corresponding method argument list, in particular due to forgetting to include the synthetic parameters added to explicit enumeration constructors. - -run_codeql_database_create(["java -cp ecj.jar org.eclipse.jdt.internal.compiler.batch.Main Test.java -d out -source 8", "java -cp ecj.jar org.eclipse.jdt.internal.compiler.batch.Main Test2.java -cp out -source 8"], lang="java") +def test(codeql, java, ecj): + # This tests the case where ECJ emits a RuntimeIn/VisibleAnnotations attribute that isn't the same size as the corresponding method argument list, in particular due to forgetting to include the synthetic parameters added to explicit enumeration constructors. + codeql.database.create( + command=[ + f"java -cp {ecj} org.eclipse.jdt.internal.compiler.batch.Main Test.java -d out -source 8", + f"java -cp {ecj} org.eclipse.jdt.internal.compiler.batch.Main Test2.java -cp out -source 8", + ] + ) diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/.gitattributes b/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/.gitattributes deleted file mode 100644 index 097f9f98d9e..00000000000 --- a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/.gitattributes +++ /dev/null @@ -1,9 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# Linux start script should use lf -/gradlew text eol=lf - -# These are Windows script files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/.gitignore b/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/.gitignore deleted file mode 100644 index 1b6985c0094..00000000000 --- a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Ignore Gradle project-specific cache directory -.gradle - -# Ignore Gradle build output directory -build diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f090a2944b7473328c07c9755baa3196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60756 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 - - - true - false - - \ No newline at end of file diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/gradle-sample/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59203 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

    K7UpUK$>l@ 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 E2O(~oYXATM diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/all-platforms/java/gradle-sample/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 12d38de6a48..00000000000 --- a/java/ql/integration-tests/all-platforms/java/gradle-sample/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/gradlew b/java/ql/integration-tests/all-platforms/java/gradle-sample/gradlew deleted file mode 100755 index 4f906e0c811..00000000000 --- a/java/ql/integration-tests/all-platforms/java/gradle-sample/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed 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 -# -# https://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. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/gradlew.bat b/java/ql/integration-tests/all-platforms/java/gradle-sample/gradlew.bat deleted file mode 100644 index 107acd32c4e..00000000000 --- a/java/ql/integration-tests/all-platforms/java/gradle-sample/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/source_archive.expected b/java/ql/integration-tests/all-platforms/java/gradle-sample/source_archive.expected new file mode 100644 index 00000000000..ccdedc5ab73 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/gradle-sample/source_archive.expected @@ -0,0 +1,9 @@ +.gradle/6.6.1/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/configuration-cache/gc.properties +.gradle/vcs-1/gc.properties +gradle/wrapper/gradle-wrapper.properties +src/main/java/com/example/App.java +src/test/java/com/example/AppTest.java +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/test.expected b/java/ql/integration-tests/all-platforms/java/gradle-sample/test.expected deleted file mode 100644 index e7dd5838e6b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/gradle-sample/test.expected +++ /dev/null @@ -1,5 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| gradle/verification-metadata.xml:0:0:0:0 | gradle/verification-metadata.xml | diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/test.py b/java/ql/integration-tests/all-platforms/java/gradle-sample/test.py index 1cb6e142763..34670acfeea 100644 --- a/java/ql/integration-tests/all-platforms/java/gradle-sample/test.py +++ b/java/ql/integration-tests/all-platforms/java/gradle-sample/test.py @@ -1,8 +1,2 @@ -import sys - -from create_database_utils import * - -#The version of gradle used doesn't work on java 17 -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, use_java_11, java, gradle_6_6_1): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/test.ql b/java/ql/integration-tests/all-platforms/java/gradle-sample/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/gradle-sample/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/java-web-jsp/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/java-web-jsp/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/test.py b/java/ql/integration-tests/all-platforms/java/java-web-jsp/test.py index e87b8a1c009..a727946877a 100644 --- a/java/ql/integration-tests/all-platforms/java/java-web-jsp/test.py +++ b/java/ql/integration-tests/all-platforms/java/java-web-jsp/test.py @@ -1,5 +1,4 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create(["mvn clean package -P tomcat8Jsp"], lang="java", extra_env = {"CODEQL_EXTRACTOR_JAVA_JSP": "true"}) +def test(codeql, java): + codeql.database.create( + command="mvn clean package -P tomcat8Jsp", _env={"CODEQL_EXTRACTOR_JAVA_JSP": "true"} + ) diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-enforcer/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-enforcer/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-enforcer/source_archive.expected new file mode 100644 index 00000000000..016c614aec4 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-enforcer/source_archive.expected @@ -0,0 +1,12 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/page.xml +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.expected b/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.expected deleted file mode 100644 index fc706ca445a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.expected +++ /dev/null @@ -1,15 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/page.xml:0:0:0:0 | target/classes/page.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | -propertiesFiles -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| target/classes/my-app.properties:0:0:0:0 | target/classes/my-app.properties | -| target/maven-archiver/pom.properties:0:0:0:0 | target/maven-archiver/pom.properties | -| test-db/log/ext/javac-1.properties:0:0:0:0 | test-db/log/ext/javac-1.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.py b/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.py index ab8845cbd73..eb49efe6a2a 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.py @@ -1,5 +1,2 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create([], lang="java") +def test(codeql, java): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.ql b/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/source_archive.expected new file mode 100644 index 00000000000..016c614aec4 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/source_archive.expected @@ -0,0 +1,12 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/page.xml +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.expected deleted file mode 100644 index fc706ca445a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.expected +++ /dev/null @@ -1,15 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/page.xml:0:0:0:0 | target/classes/page.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | -propertiesFiles -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| target/classes/my-app.properties:0:0:0:0 | target/classes/my-app.properties | -| target/maven-archiver/pom.properties:0:0:0:0 | target/maven-archiver/pom.properties | -| test-db/log/ext/javac-1.properties:0:0:0:0 | test-db/log/ext/javac-1.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.py b/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.py index 6d5ed7563ef..a12444ef170 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.py @@ -1,5 +1,2 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create([], lang="java", extra_env = {"LGTM_INDEX_PROPERTIES_FILES": "true"}) +def test(codeql, java): + codeql.database.create(_env={"LGTM_INDEX_PROPERTIES_FILES": "true"}) diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.ql b/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/source_archive.expected new file mode 100644 index 00000000000..a4def4e92dc --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/source_archive.expected @@ -0,0 +1,10 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.expected deleted file mode 100644 index 7857752a01b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.expected +++ /dev/null @@ -1,7 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.py b/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.py index 65499f91e25..08a582b9d42 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.py @@ -1,10 +1,6 @@ -import sys - -from create_database_utils import * - -# Test that a build with 60 ~1MB XML docs extracts does not extract them, but we fall back to by-name mode instead: -for i in range(60): - with open("generated-%d.xml" % i, "w") as f: - f.write("" + ("a" * 1000000) + "") - -run_codeql_database_create([], lang="java") +def test(codeql, java): + # Test that a build with 60 ~1MB XML docs extracts does not extract them, but we fall back to by-name mode instead: + for i in range(60): + with open(f"generated-{i}.xml", "w") as f: + f.write("" + ("a" * 1000000) + "") + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.ql b/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/source_archive.expected new file mode 100644 index 00000000000..ccc5c6f2513 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/source_archive.expected @@ -0,0 +1,17 @@ +generated-0.xml +generated-1.xml +generated-2.xml +generated-3.xml +generated-4.xml +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/page.xml +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.expected deleted file mode 100644 index 82e6308469f..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.expected +++ /dev/null @@ -1,14 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| generated-0.xml:0:0:0:0 | generated-0.xml | -| generated-1.xml:0:0:0:0 | generated-1.xml | -| generated-2.xml:0:0:0:0 | generated-2.xml | -| generated-3.xml:0:0:0:0 | generated-3.xml | -| generated-4.xml:0:0:0:0 | generated-4.xml | -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/page.xml:0:0:0:0 | target/classes/page.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.py b/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.py index c951c4c6f0d..8795cbbaa09 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.py @@ -1,10 +1,6 @@ -import sys - -from create_database_utils import * - -# Test that a build with 5 ~1MB XML docs extracts them: -for i in range(5): - with open("generated-%d.xml" % i, "w") as f: - f.write("" + ("a" * 1000000) + "") - -run_codeql_database_create([], lang="java") +def test(codeql, java): + # Test that a build with 5 ~1MB XML docs extracts them: + for i in range(5): + with open(f"generated-{i}.xml", "w") as f: + f.write("" + ("a" * 1000000) + "") + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.ql b/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/source_archive.expected new file mode 100644 index 00000000000..016c614aec4 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/source_archive.expected @@ -0,0 +1,12 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/page.xml +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.expected deleted file mode 100644 index 05f39a55338..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.expected +++ /dev/null @@ -1,9 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/page.xml:0:0:0:0 | target/classes/page.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.py b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.py index 76966e04fb3..93ac0300499 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.py @@ -1,5 +1,2 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create([], lang="java", extra_env = {"LGTM_INDEX_XML_MODE": "all"}) +def test(codeql, java): + codeql.database.create(_env={"LGTM_INDEX_XML_MODE": "all"}) diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.ql b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/source_archive.expected new file mode 100644 index 00000000000..a4def4e92dc --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/source_archive.expected @@ -0,0 +1,10 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.expected deleted file mode 100644 index 7857752a01b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.expected +++ /dev/null @@ -1,7 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.py b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.py index 7d004ffb52f..64e5f7ba05a 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.py @@ -1,5 +1,2 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create([], lang="java", extra_env = {"LGTM_INDEX_XML_MODE": "byname"}) +def test(codeql, java): + codeql.database.create(_env={"LGTM_INDEX_XML_MODE": "byname"}) diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.ql b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/source_archive.expected new file mode 100644 index 00000000000..23eaad53231 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/source_archive.expected @@ -0,0 +1,7 @@ +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.expected deleted file mode 100644 index 2f2c7ce04f2..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.expected +++ /dev/null @@ -1,4 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.py b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.py index 376596d1f9c..aa6c911f94d 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.py @@ -1,5 +1,2 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create([], lang="java", extra_env = {"LGTM_INDEX_XML_MODE": "disabled"}) +def test(codeql, java): + codeql.database.create(_env={"LGTM_INDEX_XML_MODE": "disabled"}) diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.ql b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/source_archive.expected new file mode 100644 index 00000000000..a4def4e92dc --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/source_archive.expected @@ -0,0 +1,10 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.expected b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.expected deleted file mode 100644 index 7857752a01b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.expected +++ /dev/null @@ -1,7 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.py b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.py index 7169e99d71f..7736927eb8a 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.py @@ -1,5 +1,2 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create([], lang="java", extra_env = {"LGTM_INDEX_XML_MODE": "smart"}) +def test(codeql, java): + codeql.database.create(_env={"LGTM_INDEX_XML_MODE": "smart"}) diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.ql b/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-sample/force_sequential_test_execution deleted file mode 100644 index dd90439bca5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -# Concurrent Maven processes using ~/.m2/repository is not safe, so this test must run sequentially diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-sample/source_archive.expected new file mode 100644 index 00000000000..016c614aec4 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-sample/source_archive.expected @@ -0,0 +1,12 @@ +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/page.xml +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/test.expected b/java/ql/integration-tests/all-platforms/java/maven-sample/test.expected deleted file mode 100644 index fc706ca445a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample/test.expected +++ /dev/null @@ -1,15 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/page.xml:0:0:0:0 | target/classes/page.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | -propertiesFiles -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| target/classes/my-app.properties:0:0:0:0 | target/classes/my-app.properties | -| target/maven-archiver/pom.properties:0:0:0:0 | target/maven-archiver/pom.properties | -| test-db/log/ext/javac-1.properties:0:0:0:0 | test-db/log/ext/javac-1.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/test.py b/java/ql/integration-tests/all-platforms/java/maven-sample/test.py index ab8845cbd73..eb49efe6a2a 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-sample/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-sample/test.py @@ -1,5 +1,2 @@ -import sys - -from create_database_utils import * - -run_codeql_database_create([], lang="java") +def test(codeql, java): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/test.ql b/java/ql/integration-tests/all-platforms/java/maven-sample/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-sample/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/force_sequential_test_execution deleted file mode 100644 index 44bcad8d582..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -The wrapper downloading a Maven distribution multiple times in parallel is not safe. diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/source_archive.expected new file mode 100644 index 00000000000..63c4821feac --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/source_archive.expected @@ -0,0 +1,13 @@ +.mvn/wrapper/maven-wrapper.properties +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/page.xml +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.expected b/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.expected deleted file mode 100644 index dd77a3fab0a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.expected +++ /dev/null @@ -1,16 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/page.xml:0:0:0:0 | target/classes/page.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | -propertiesFiles -| .mvn/wrapper/maven-wrapper.properties:0:0:0:0 | .mvn/wrapper/maven-wrapper.properties | -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| target/classes/my-app.properties:0:0:0:0 | target/classes/my-app.properties | -| target/maven-archiver/pom.properties:0:0:0:0 | target/maven-archiver/pom.properties | -| test-db/log/ext/javac-1.properties:0:0:0:0 | test-db/log/ext/javac-1.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.py b/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.py index 5311b982c2b..eb49efe6a2a 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.py @@ -1,7 +1,2 @@ -import sys - -from create_database_utils import * -from maven_wrapper_test_utils import * - -run_codeql_database_create([], lang="java") -check_maven_wrapper_exists("3.9.4") +def test(codeql, java): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.ql b/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/force_sequential_test_execution deleted file mode 100644 index 44bcad8d582..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -The wrapper downloading a Maven distribution multiple times in parallel is not safe. diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/source_archive.expected new file mode 100644 index 00000000000..63c4821feac --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/source_archive.expected @@ -0,0 +1,13 @@ +.mvn/wrapper/maven-wrapper.properties +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/page.xml +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.expected b/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.expected deleted file mode 100644 index dd77a3fab0a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.expected +++ /dev/null @@ -1,16 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/page.xml:0:0:0:0 | target/classes/page.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | -propertiesFiles -| .mvn/wrapper/maven-wrapper.properties:0:0:0:0 | .mvn/wrapper/maven-wrapper.properties | -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| target/classes/my-app.properties:0:0:0:0 | target/classes/my-app.properties | -| target/maven-archiver/pom.properties:0:0:0:0 | target/maven-archiver/pom.properties | -| test-db/log/ext/javac-1.properties:0:0:0:0 | test-db/log/ext/javac-1.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.py b/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.py index 5311b982c2b..eb49efe6a2a 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.py @@ -1,7 +1,2 @@ -import sys - -from create_database_utils import * -from maven_wrapper_test_utils import * - -run_codeql_database_create([], lang="java") -check_maven_wrapper_exists("3.9.4") +def test(codeql, java): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.ql b/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/maven-wrapper/force_sequential_test_execution deleted file mode 100644 index 44bcad8d582..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper/force_sequential_test_execution +++ /dev/null @@ -1 +0,0 @@ -The wrapper downloading a Maven distribution multiple times in parallel is not safe. diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/source_archive.expected b/java/ql/integration-tests/all-platforms/java/maven-wrapper/source_archive.expected new file mode 100644 index 00000000000..63c4821feac --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/maven-wrapper/source_archive.expected @@ -0,0 +1,13 @@ +.mvn/wrapper/maven-wrapper.properties +pom.xml +src/main/java/com/example/App.java +src/main/resources/my-app.properties +src/main/resources/page.xml +src/main/resources/struts.xml +src/test/java/com/example/AppTest.java +target/classes/my-app.properties +target/classes/page.xml +target/classes/struts.xml +target/maven-archiver/pom.properties +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.expected b/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.expected deleted file mode 100644 index dd77a3fab0a..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.expected +++ /dev/null @@ -1,16 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| pom.xml:0:0:0:0 | pom.xml | -| src/main/resources/page.xml:0:0:0:0 | src/main/resources/page.xml | -| src/main/resources/struts.xml:0:0:0:0 | src/main/resources/struts.xml | -| target/classes/page.xml:0:0:0:0 | target/classes/page.xml | -| target/classes/struts.xml:0:0:0:0 | target/classes/struts.xml | -propertiesFiles -| .mvn/wrapper/maven-wrapper.properties:0:0:0:0 | .mvn/wrapper/maven-wrapper.properties | -| src/main/resources/my-app.properties:0:0:0:0 | src/main/resources/my-app.properties | -| target/classes/my-app.properties:0:0:0:0 | target/classes/my-app.properties | -| target/maven-archiver/pom.properties:0:0:0:0 | target/maven-archiver/pom.properties | -| test-db/log/ext/javac-1.properties:0:0:0:0 | test-db/log/ext/javac-1.properties | -| test-db/log/ext/javac.properties:0:0:0:0 | test-db/log/ext/javac.properties | diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.py b/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.py index 5311b982c2b..eb49efe6a2a 100644 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.py +++ b/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.py @@ -1,7 +1,2 @@ -import sys - -from create_database_utils import * -from maven_wrapper_test_utils import * - -run_codeql_database_create([], lang="java") -check_maven_wrapper_exists("3.9.4") +def test(codeql, java): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.ql b/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.ql deleted file mode 100644 index 25cd26fdd14..00000000000 --- a/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.ql +++ /dev/null @@ -1,9 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } - -query predicate propertiesFiles(File f) { f.getExtension() = "properties" } diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py b/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py index c4726143c50..d67602f8bcb 100644 --- a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py +++ b/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py @@ -1,15 +1,24 @@ -import sys +import commands -from create_database_utils import * -import subprocess -import os -try_use_java11() - -os.mkdir("mod1obj") -os.mkdir("mod2obj") - -subprocess.check_call(["javac", "mod1/module-info.java", "mod1/mod1pkg/Mod1Class.java", "-d", "mod1obj"]) -subprocess.check_call(["jar", "-c", "-f", "mod1.jar", "-C", "mod1obj", "mod1pkg/Mod1Class.class", "--release", "9", "-C", "mod1obj", "module-info.class"]) - -run_codeql_database_create(["javac mod2/mod2pkg/User.java mod2/module-info.java -d mod2obj -p mod1.jar"], lang="java") +def test(codeql, use_java_11, java): + commands.run(["javac", "mod1/module-info.java", "mod1/mod1pkg/Mod1Class.java", "-d", "mod1obj"]) + commands.run( + [ + "jar", + "-c", + "-f", + "mod1.jar", + "-C", + "mod1obj", + "mod1pkg/Mod1Class.class", + "--release", + "9", + "-C", + "mod1obj", + "module-info.class", + ] + ) + codeql.database.create( + command="javac mod2/mod2pkg/User.java mod2/module-info.java -d mod2obj -p mod1.jar" + ) diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py b/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py index c912a0cb27a..567cd51bef2 100644 --- a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py +++ b/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py @@ -1,13 +1,24 @@ -import sys +import commands -from create_database_utils import * -import subprocess -import os -os.mkdir("mod1obj") -os.mkdir("mod2obj") - -subprocess.check_call(["javac", "mod1/module-info.java", "mod1/mod1pkg/Mod1Class.java", "-d", "mod1obj"]) -subprocess.check_call(["jar", "-c", "-f", "mod1.jar", "-C", "mod1obj", "mod1pkg/Mod1Class.class", "--release", "9", "-C", "mod1obj", "module-info.class"]) - -run_codeql_database_create(["javac mod2/mod2pkg/User.java mod2/module-info.java -d mod2obj -p mod1.jar"], lang="java") +def test(codeql, java): + commands.run(["javac", "mod1/module-info.java", "mod1/mod1pkg/Mod1Class.java", "-d", "mod1obj"]) + commands.run( + [ + "jar", + "-c", + "-f", + "mod1.jar", + "-C", + "mod1obj", + "mod1pkg/Mod1Class.class", + "--release", + "9", + "-C", + "mod1obj", + "module-info.class", + ] + ) + codeql.database.create( + command="javac mod2/mod2pkg/User.java mod2/module-info.java -d mod2obj -p mod1.jar" + ) diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/source_archive.expected b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/source_archive.expected new file mode 100644 index 00000000000..67b20f5ad70 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/source_archive.expected @@ -0,0 +1,10 @@ +.gradle/6.6.1/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/configuration-cache/gc.properties +.gradle/vcs-1/gc.properties +gradle/verification-metadata.xml +gradle/wrapper/gradle-wrapper.properties +src/main/java/com/example/App.java +src/test/java/com/example/AppTest.java +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.expected b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.expected deleted file mode 100644 index e7dd5838e6b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.expected +++ /dev/null @@ -1,5 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| gradle/verification-metadata.xml:0:0:0:0 | gradle/verification-metadata.xml | diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.py b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.py index 846a89e8703..44576600a58 100644 --- a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.py +++ b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.py @@ -1,31 +1,17 @@ -import sys - -from create_database_utils import * -import shutil -import os.path import tempfile -import platform +import runs_on +import pathlib -#The version of gradle used doesn't work on java 17 -try_use_java11() -gradle_override_dir = tempfile.mkdtemp() -if platform.system() == "Windows": - with open(os.path.join(gradle_override_dir, "gradle.bat"), "w") as f: - f.write("@echo off\nexit /b 2\n") -else: - gradlepath = os.path.join(gradle_override_dir, "gradle") - with open(gradlepath, "w") as f: - f.write("#!/bin/bash\nexit 1\n") - os.chmod(gradlepath, 0o0755) +# The version of gradle used doesn't work on java 17 +def test(codeql, use_java_11, java, environment): + gradle_override_dir = pathlib.Path(tempfile.mkdtemp()) + if runs_on.windows: + (gradle_override_dir / "gradle.bat").write_text("@echo off\nexit /b 2\n") + else: + gradlepath = gradle_override_dir / "gradle" + gradlepath.write_text("#!/bin/bash\nexit 1\n") + gradlepath.chmod(0o0755) -oldpath = os.getenv("PATH") -os.environ["PATH"] = gradle_override_dir + os.pathsep + oldpath - -try: - run_codeql_database_create([], lang="java") -finally: - try: - shutil.rmtree(gradle_override_dir) - except Exception as e: - pass + environment.add_path(gradle_override_dir) + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.ql b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/.gitignore b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/.gitignore deleted file mode 100644 index 1b6985c0094..00000000000 --- a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Ignore Gradle project-specific cache directory -.gradle - -# Ignore Gradle build output directory -build diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/source_archive.expected b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/source_archive.expected new file mode 100644 index 00000000000..67b20f5ad70 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/source_archive.expected @@ -0,0 +1,10 @@ +.gradle/6.6.1/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/configuration-cache/gc.properties +.gradle/vcs-1/gc.properties +gradle/verification-metadata.xml +gradle/wrapper/gradle-wrapper.properties +src/main/java/com/example/App.java +src/test/java/com/example/AppTest.java +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.expected b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.expected deleted file mode 100644 index e7dd5838e6b..00000000000 --- a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.expected +++ /dev/null @@ -1,5 +0,0 @@ -#select -| src/main/java/com/example/App.java:0:0:0:0 | App | -| src/test/java/com/example/AppTest.java:0:0:0:0 | AppTest | -xmlFiles -| gradle/verification-metadata.xml:0:0:0:0 | gradle/verification-metadata.xml | diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.py b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.py index 1cb6e142763..31e476045b1 100644 --- a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.py +++ b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.py @@ -1,8 +1,5 @@ -import sys +# The version of gradle used doesn't work on java 17 -from create_database_utils import * -#The version of gradle used doesn't work on java 17 -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, use_java_11, java): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.ql b/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/.gitattributes b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/.gitattributes deleted file mode 100644 index 00a51aff5e5..00000000000 --- a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# -# https://help.github.com/articles/dealing-with-line-endings/ -# -# These are explicitly windows files and should use crlf -*.bat text eol=crlf - diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/.gitignore b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/.gitignore deleted file mode 100644 index c2065bc2620..00000000000 --- a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -HELP.md -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/force_sequential_test_execution b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/force_sequential_test_execution deleted file mode 100644 index b0e2500b259..00000000000 --- a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/force_sequential_test_execution +++ /dev/null @@ -1,3 +0,0 @@ -# We currently have a bug where gradle tests become flaky when executed in parallel -# - sometimes, gradle fails to connect to the gradle daemon. -# Therefore, force this test to run sequentially. diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e6441136f3d4ba8a0da8d277868979cfbc8ad796..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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

    NnX)EH+Nua)3Y(c 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 '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/gradlew.bat b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/gradlew.bat deleted file mode 100644 index 25da30dbdee..00000000000 --- a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/source_archive.expected b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/source_archive.expected new file mode 100644 index 00000000000..7c6e9b460fe --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/source_archive.expected @@ -0,0 +1,11 @@ +.gradle/8.7/dependencies-accessors/gc.properties +.gradle/8.7/gc.properties +.gradle/buildOutputCleanup/cache.properties +.gradle/vcs-1/gc.properties +build/resources/main/application.properties +gradle/wrapper/gradle-wrapper.properties +src/main/java/com/github/springbootsample/SpringBootSampleApplication.java +src/main/resources/application.properties +src/test/java/com/github/springbootsample/SpringBootSampleApplicationTests.java +test-db/log/ext/javac-1.properties +test-db/log/ext/javac.properties diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.expected b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.expected deleted file mode 100644 index f8e614cd984..00000000000 --- a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.expected +++ /dev/null @@ -1,4 +0,0 @@ -#select -| src/main/java/com/github/springbootsample/SpringBootSampleApplication.java:0:0:0:0 | SpringBootSampleApplication | -| src/test/java/com/github/springbootsample/SpringBootSampleApplicationTests.java:0:0:0:0 | SpringBootSampleApplicationTests | -xmlFiles diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.py b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.py index 1cb6e142763..a3d842b5390 100644 --- a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.py +++ b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.py @@ -1,8 +1,2 @@ -import sys - -from create_database_utils import * - -#The version of gradle used doesn't work on java 17 -try_use_java11() - -run_codeql_database_create([], lang="java") +def test(codeql, java, gradle_8_7): + codeql.database.create() diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.ql b/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.ql deleted file mode 100644 index c11b8fba707..00000000000 --- a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.ql +++ /dev/null @@ -1,7 +0,0 @@ -import java - -from File f -where f.isSourceFile() -select f - -query predicate xmlFiles(XmlFile x) { any() } From 1c3b9f7031c940ecef911f55003b12fcec788188 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Tue, 27 Aug 2024 13:13:55 +0200 Subject: [PATCH 115/404] Delete legacy test utils. --- .../buildless_test_utils.py | 37 ---- .../maven_wrapper_test_utils.py | 12 -- java/integration-tests-lib/mitm_proxy.py | 173 ------------------ .../toolchains_test_utils.py | 42 ----- 4 files changed, 264 deletions(-) delete mode 100644 java/integration-tests-lib/buildless_test_utils.py delete mode 100644 java/integration-tests-lib/maven_wrapper_test_utils.py delete mode 100644 java/integration-tests-lib/mitm_proxy.py delete mode 100644 java/integration-tests-lib/toolchains_test_utils.py diff --git a/java/integration-tests-lib/buildless_test_utils.py b/java/integration-tests-lib/buildless_test_utils.py deleted file mode 100644 index 27f43060dae..00000000000 --- a/java/integration-tests-lib/buildless_test_utils.py +++ /dev/null @@ -1,37 +0,0 @@ -import sys -import os.path -import glob - -def extract_fetched_jar_path(l): - if not l.startswith("["): - # Line continuation - return None - bits = l.split(" ", 3) # date time processid logline - if len(bits) >= 4 and bits[3].startswith("Fetch "): - return bits[3][6:].strip() - else: - return None - -def read_fetched_jars(fname): - with open(fname, "r") as f: - lines = [l for l in f] - return [l for l in map(extract_fetched_jar_path, lines) if l is not None] - -def check_buildless_fetches(): - - extractor_logs = glob.glob(os.path.join("test-db", "log", "javac-extractor-*.log")) - fetched_jars = map(read_fetched_jars, extractor_logs) - all_fetched_jars = tuple(sorted([item for sublist in fetched_jars for item in sublist])) - - try: - with open("buildless-fetches.expected", "r") as f: - expected_jar_fetches = tuple(l.strip() for l in f) - except FileNotFoundError: - expected_jar_fetches = tuple() - - if all_fetched_jars != expected_jar_fetches: - print("Expected jar fetch mismatch. Expected:\n%s\n\nActual:\n%s" % ("\n".join(expected_jar_fetches), "\n".join(all_fetched_jars)), file = sys.stderr) - with open("buildless-fetches.actual", "w") as f: - for j in all_fetched_jars: - f.write(j + "\n") - sys.exit(1) diff --git a/java/integration-tests-lib/maven_wrapper_test_utils.py b/java/integration-tests-lib/maven_wrapper_test_utils.py deleted file mode 100644 index fd3b727ff77..00000000000 --- a/java/integration-tests-lib/maven_wrapper_test_utils.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys -import os.path - -def check_maven_wrapper_exists(expected_version): - if not os.path.exists(".mvn/wrapper/maven-wrapper.jar"): - print("Maven wrapper jar file expected but not found", file = sys.stderr) - sys.exit(1) - with open(".mvn/wrapper/maven-wrapper.properties", "r") as f: - content = f.read() - if ("apache-maven-%s-" % expected_version) not in content: - print("Expected Maven wrapper to fetch version %s, but actual properties file said:\n\n%s" % (expected_version, content), file = sys.stderr) - sys.exit(1) diff --git a/java/integration-tests-lib/mitm_proxy.py b/java/integration-tests-lib/mitm_proxy.py deleted file mode 100644 index a7606380019..00000000000 --- a/java/integration-tests-lib/mitm_proxy.py +++ /dev/null @@ -1,173 +0,0 @@ -import http.server -import sys -import os -import socket -import ssl -import random -from datetime import datetime, timedelta, timezone -from cryptography.hazmat.primitives import hashes, serialization -from cryptography import utils, x509 -from cryptography.hazmat.primitives.asymmetric import rsa, dsa - -import select - - -def generateCA(ca_cert_file, ca_key_file): - ca_key = dsa.generate_private_key(4096) - name = x509.Name([ - x509.NameAttribute(x509.NameOID.COUNTRY_NAME, "US"), - x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, "GitHub"), - x509.NameAttribute(x509.NameOID.COMMON_NAME, "GitHub CodeQL Proxy")]) - ca_cert = x509.CertificateBuilder().subject_name(name).issuer_name(name) - ca_cert = ca_cert.public_key(ca_key.public_key()) - ca_cert = ca_cert.serial_number(random.randint(50000000, 100000000)) - ca_cert = ca_cert.not_valid_before(datetime.now(timezone.utc)) - ca_cert = ca_cert.not_valid_after( - datetime.now(timezone.utc) + timedelta(days=3650)) - ca_cert = ca_cert.add_extension(x509.BasicConstraints( - ca=True, path_length=None), critical=True) - ca_cert = ca_cert.add_extension( - x509.SubjectKeyIdentifier.from_public_key(ca_key.public_key()), critical=False) - ca_cert = ca_cert.sign(ca_key, hashes.SHA256()) - with open(ca_cert_file, 'wb') as f: - f.write(ca_cert.public_bytes(encoding=serialization.Encoding.PEM)) - with open(ca_key_file, 'wb') as f: - f.write(ca_key.private_bytes(encoding=serialization.Encoding.PEM, - format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption())) - - -def create_certificate(hostname): - pkey = rsa.generate_private_key(public_exponent=65537, key_size=2048) - subject = x509.Name( - [x509.NameAttribute(x509.NameOID.COMMON_NAME, hostname)]) - - cert = x509.CertificateBuilder() - cert = cert.subject_name(subject).issuer_name(ca_certificate.subject) - cert = cert.public_key(pkey.public_key()) - cert = cert.serial_number(random.randint(50000000, 100000000)) - cert = cert.not_valid_before(datetime.now(timezone.utc)).not_valid_after( - datetime.now(timezone.utc) + timedelta(days=3650)) - cert = cert.add_extension(x509.BasicConstraints( - ca=False, path_length=None), critical=True) - cert = cert.add_extension( - x509.SubjectAlternativeName([x509.DNSName(hostname), x509.DNSName(f"*.{hostname}")]), critical=False) - - cert = cert.sign(ca_key, hashes.SHA256()) - - return (cert, pkey) - - -class Handler(http.server.SimpleHTTPRequestHandler): - def check_auth(self): - username = os.getenv('PROXY_USER') - password = os.getenv('PROXY_PASSWORD') - if username is None or password is None: - return True - - authorization = self.headers.get( - 'Proxy-Authorization', self.headers.get('Authorization', '')) - authorization = authorization.split() - if len(authorization) == 2: - import base64 - import binascii - auth_type = authorization[0] - if auth_type.lower() == "basic": - try: - authorization = authorization[1].encode('ascii') - authorization = base64.decodebytes( - authorization).decode('ascii') - except (binascii.Error, UnicodeError): - pass - else: - authorization = authorization.split(':') - if len(authorization) == 2: - return username == authorization[0] and password == authorization[1] - return False - - def do_CONNECT(self): - if not self.check_auth(): - self.send_response( - http.HTTPStatus.PROXY_AUTHENTICATION_REQUIRED) - self.send_header('Proxy-Authenticate', 'Basic realm="Proxy"') - self.end_headers() - return - # split self.path into host and port - host, port = self.path.split(':') - port = int(port) - self.send_response(http.HTTPStatus.OK, 'Connection established') - self.send_header('Connection', 'close') - self.end_headers() - self.mitm(host, port) - - # man in the middle SSL connection - def mitm(self, host, port): - ssl_client_context = ssl.create_default_context( - purpose=ssl.Purpose.CLIENT_AUTH) - if not os.path.exists("certs/" + host + '.pem'): - cert, pkey = create_certificate(host) - with open("certs/" + host + '.pem', 'wb') as f: - f.write(pkey.private_bytes(encoding=serialization.Encoding.PEM, - format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption())) - f.write(cert.public_bytes(encoding=serialization.Encoding.PEM)) - - ssl_client_context.load_cert_chain("certs/" + host + '.pem') - ssl_client_context.load_verify_locations(ca_certificate_path) - # wrap self.connection in SSL - client = ssl_client_context.wrap_socket( - self.connection, server_side=True) - - # create socket to host:port - remote = socket.create_connection( - (host, port)) - # wrap socket in SSL - ssl_server_context = ssl.create_default_context( - purpose=ssl.Purpose.SERVER_AUTH) - remote = ssl_server_context.wrap_socket(remote, server_hostname=host) - - try: - while True: - ready, _, _ = select.select( - [client, remote], [], [], 2.0) - if not ready: - break - for src in ready: - if src is client: - dst = remote - else: - dst = client - src.setblocking(False) - dst.setblocking(True) - pending = 8192 - while pending: - try: - data = src.recv(pending) - except ssl.SSLWantReadError: - break - if not data: - return - pending = src.pending() - dst.sendall(data) - finally: - remote.close() - client.close() - - def do_GET(self): - raise NotImplementedError() - - -if __name__ == '__main__': - port = int(sys.argv[1]) - ca_certificate = None - ca_certificate_path = None - ca_key = None - if len(sys.argv) > 2: - ca_certificate_path = sys.argv[2] - with open(ca_certificate_path, 'rb') as f: - ca_certificate = x509.load_pem_x509_certificate(f.read()) - with open(sys.argv[3], 'rb') as f: - ca_key = serialization.load_pem_private_key( - f.read(), password=None) - - server_address = ('localhost', port) - httpd = http.server.HTTPServer(server_address, Handler) - httpd.serve_forever() diff --git a/java/integration-tests-lib/toolchains_test_utils.py b/java/integration-tests-lib/toolchains_test_utils.py deleted file mode 100644 index 938096dbb4b..00000000000 --- a/java/integration-tests-lib/toolchains_test_utils.py +++ /dev/null @@ -1,42 +0,0 @@ -import os.path -import sys -import tempfile - -def actions_expose_all_toolchains(): - - # On actions, expose all usable toolchains so that we can test version-selection logic. - - toolchains_dir = tempfile.mkdtemp(prefix="integration-tests-toolchains-") - toolchains_file = os.path.join(toolchains_dir, "toolchains.xml") - - def none_or_blank(s): - return s is None or s == "" - - with open(toolchains_file, "w") as f: - f.write('\n\n') - - for v in [8, 11, 17, 21]: - homedir = os.getenv("JAVA_HOME_%d_X64" % v) - if none_or_blank(homedir): - homedir = os.getenv("JAVA_HOME_%d_arm64" % v) - if none_or_blank(homedir) and v == 8 and not none_or_blank(os.getenv("JAVA_HOME_11_arm64")): - print("Mocking a toolchain entry using Java 11 install as a fake Java 8 entry, so this test behaves the same on x64 and arm64 runners", file = sys.stderr) - homedir = os.getenv("JAVA_HOME_11_arm64") - if homedir is not None and homedir != "": - f.write(""" - - jdk - - %d - oracle - - - %s - - - """ % (v, homedir)) - - f.write("") - - return toolchains_file - From fe6693739adb5aadff1140ef3464432520859fbc Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 15 Aug 2024 15:33:03 +0200 Subject: [PATCH 116/404] Java: Make more finegrained dataflow dispatch viable callable heuristic. --- java/ql/lib/semmle/code/java/Element.qll | 7 +++++ .../dataflow/internal/DataFlowDispatch.qll | 26 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/Element.qll b/java/ql/lib/semmle/code/java/Element.qll index 08689f05f94..aecdd51e144 100644 --- a/java/ql/lib/semmle/code/java/Element.qll +++ b/java/ql/lib/semmle/code/java/Element.qll @@ -36,6 +36,13 @@ class Element extends @element, Top { */ predicate fromSource() { this.getCompilationUnit().isSourceFile() } + /** + * Holds if this element is from source and classified as a stub implementation. + * An implementation is considered a stub, if the the path to the + * source file contains `/stubs/`. + */ + predicate isStub() { this.fromSource() and this.getFile().getAbsolutePath().matches("%/stubs/%") } + /** Gets the compilation unit that this element belongs to. */ CompilationUnit getCompilationUnit() { result = this.getFile() } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll index 6f27ea5b4b5..775d3c0067b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll @@ -40,11 +40,29 @@ private module DispatchImpl { else any() } - /** Gets a viable implementation of the target of the given `Call`. */ + /** + * Gets a viable implementation of the target of the given `Call`. + * The following heuristic is applied for finding the appropriate callable: + * 1. If an exact manual model exists, only dispatch to the summarized callable. + * 2. If a (non exact) manual model exists and/or if the source code is available, dispatch to both/either. + * 3. Only dispatch to a summarized callable (based on a generated model) if neither of the above apply. + */ DataFlowCallable viableCallable(DataFlowCall c) { - result.asCallable() = sourceDispatch(c.asCall()) - or - result.asSummarizedCallable().getACall() = c.asCall() + exists(Call call | call = c.asCall() | + result.asCallable() = sourceDispatch(call) + or + not ( + // Only use summarized callables with generated summaries in case + // we are not able to dispatch to a source declaration. + // Note that if applyGeneratedModel holds it implies that there doesn't + // exist a manual (exact) model. + exists(Callable callable | callable = sourceDispatch(call) | + callable.fromSource() and not callable.isStub() + ) and + result.asSummarizedCallable().applyGeneratedModel() + ) and + result.asSummarizedCallable().getACall() = call + ) } /** From 68880b20569fefcb9ae759535b0908d698582892 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 16 Aug 2024 11:39:49 +0200 Subject: [PATCH 117/404] Java: Update expected test output. Generated models are no longer applied as there exist a source implementation. --- .../test/library-tests/dataflow/external-models/steps.expected | 2 -- 1 file changed, 2 deletions(-) diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.expected b/java/ql/test/library-tests/dataflow/external-models/steps.expected index c9b2fd4d01e..3ef7da26182 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.expected +++ b/java/ql/test/library-tests/dataflow/external-models/steps.expected @@ -8,6 +8,4 @@ invalidModelRow | C.java:20:5:20:8 | this | C.java:20:5:20:22 | stepQualRes(...) | | C.java:21:5:21:17 | this <.method> | C.java:21:5:21:17 | stepQualRes(...) | | C.java:24:5:24:23 | this <.method> | C.java:24:17:24:22 | argOut [post update] | -| C.java:29:25:29:28 | arg1 | C.java:29:5:29:29 | stepArgResGenerated(...) | | C.java:34:38:34:41 | arg2 | C.java:34:5:34:42 | stepArgResGeneratedIgnored(...) | -| C.java:36:26:36:29 | arg1 | C.java:36:5:36:30 | this <.method> [post update] | From 6cb5e13a23ee165185d859c256ae22a29439acf0 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 16 Aug 2024 12:07:29 +0200 Subject: [PATCH 118/404] Java: Re-factor tests and update expected test output. --- .../dataflow/external-models/C.java | 59 ++++++++++++------- .../dataflow/external-models/steps.expected | 20 ++++--- .../dataflow/external-models/steps.ext.yml | 13 ++-- .../external-models/stubs/Library.java | 19 ++++++ 4 files changed, 75 insertions(+), 36 deletions(-) create mode 100644 java/ql/test/library-tests/dataflow/external-models/stubs/Library.java diff --git a/java/ql/test/library-tests/dataflow/external-models/C.java b/java/ql/test/library-tests/dataflow/external-models/C.java index b1c7f2dc85c..c0270dbe9f1 100644 --- a/java/ql/test/library-tests/dataflow/external-models/C.java +++ b/java/ql/test/library-tests/dataflow/external-models/C.java @@ -1,5 +1,7 @@ package my.qltest; +import my.qltest.external.Library; + public class C { void foo() { Object arg1 = new Object(); @@ -25,35 +27,50 @@ public class C { } void fooGenerated() { - Object arg1 = new Object(); - stepArgResGenerated(arg1); + Object arg = new Object(); - Object arg2 = new Object(); - // The summary for the first parameter is ignored, because it is generated and - // because there is hand written summary for the second parameter. - stepArgResGeneratedIgnored(arg1, arg2); - - stepArgQualGenerated(arg1); - // The summary for the first parameter is ignored, because it is generated and - // because there is hand written neutral summary model for this callable. - stepArgQualGeneratedIgnored(arg1); + // The (generated) summary is ignored because the source code is available. + stepArgResGenerated(arg); } - Object stepArgRes(Object x) { return null; } + // Library functionality is emulated by placing the source code in a "stubs" + // folder. This means that a generated summary will be applied, if there + // doesn't exist a manual summary or manual summary neutral. + void fooLibrary() { + Object arg1 = new Object(); - void stepArgArg(Object in, Object out) { } + Library lib = new Library(); - void stepArgQual(Object x) { } + lib.apiStepArgResGenerated(arg1); - Object stepQualRes() { return null; } + Object arg2 = new Object(); - void stepQualArg(Object out) { } + // The summary for the first parameter is ignored, because it is generated and + // because there is a manual summary for the second parameter. + lib.apiStepArgResGeneratedIgnored(arg1, arg2); - Object stepArgResGenerated(Object x) { return null; } + lib.apiStepArgQualGenerated(arg1); - Object stepArgResGeneratedIgnored(Object x, Object y) { return null; } + // The summary for the parameter is ignored, because it is generated and + // because there is a manual neutral summary model for this callable. + lib.apiStepArgQualGeneratedIgnored(arg1); + } - Object stepArgQualGenerated(Object x) { return null; } - - Object stepArgQualGeneratedIgnored(Object x) { return null; } + Object stepArgRes(Object x) { + return null; + } + + void stepArgArg(Object in, Object out) {} + + void stepArgQual(Object x) {} + + Object stepQualRes() { + return null; + } + + void stepQualArg(Object out) {} + + Object stepArgResGenerated(Object x) { + return null; + } } diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.expected b/java/ql/test/library-tests/dataflow/external-models/steps.expected index 3ef7da26182..e9cbb7ec99e 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.expected +++ b/java/ql/test/library-tests/dataflow/external-models/steps.expected @@ -1,11 +1,13 @@ invalidModelRow #select -| C.java:6:16:6:19 | arg1 | C.java:6:5:6:20 | stepArgRes(...) | -| C.java:10:16:10:21 | argIn1 | C.java:10:24:10:30 | argOut1 [post update] | -| C.java:13:16:13:21 | argIn2 | C.java:13:24:13:30 | argOut2 [post update] | -| C.java:16:17:16:20 | arg2 | C.java:16:5:16:21 | this <.method> [post update] | -| C.java:18:22:18:25 | arg3 | C.java:18:5:18:8 | this [post update] | -| C.java:20:5:20:8 | this | C.java:20:5:20:22 | stepQualRes(...) | -| C.java:21:5:21:17 | this <.method> | C.java:21:5:21:17 | stepQualRes(...) | -| C.java:24:5:24:23 | this <.method> | C.java:24:17:24:22 | argOut [post update] | -| C.java:34:38:34:41 | arg2 | C.java:34:5:34:42 | stepArgResGeneratedIgnored(...) | +| C.java:8:16:8:19 | arg1 | C.java:8:5:8:20 | stepArgRes(...) | +| C.java:12:16:12:21 | argIn1 | C.java:12:24:12:30 | argOut1 [post update] | +| C.java:15:16:15:21 | argIn2 | C.java:15:24:15:30 | argOut2 [post update] | +| C.java:18:17:18:20 | arg2 | C.java:18:5:18:21 | this <.method> [post update] | +| C.java:20:22:20:25 | arg3 | C.java:20:5:20:8 | this [post update] | +| C.java:22:5:22:8 | this | C.java:22:5:22:22 | stepQualRes(...) | +| C.java:23:5:23:17 | this <.method> | C.java:23:5:23:17 | stepQualRes(...) | +| C.java:26:5:26:23 | this <.method> | C.java:26:17:26:22 | argOut [post update] | +| C.java:44:32:44:35 | arg1 | C.java:44:5:44:36 | apiStepArgResGenerated(...) | +| C.java:50:45:50:48 | arg2 | C.java:50:5:50:49 | apiStepArgResGeneratedIgnored(...) | +| C.java:52:33:52:36 | arg1 | C.java:52:5:52:7 | lib [post update] | diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml index 831079dd40b..fbfcf0536ae 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml +++ b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml @@ -9,13 +9,14 @@ extensions: - ["my.qltest", "C", False, "stepQualRes", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["my.qltest", "C", False, "stepQualArg", "(Object)", "", "Argument[this]", "Argument[0]", "taint", "manual"] - ["my.qltest", "C", False, "stepArgResGenerated", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] - - ["my.qltest", "C", False, "stepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] - - ["my.qltest", "C", False, "stepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["my.qltest", "C", False, "stepArgQualGenerated", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] - - ["my.qltest", "C", False, "stepArgQualGeneratedIgnored", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["my.qltest.external", "Library", False, "apiStepArgResGenerated", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["my.qltest.external", "Library", False, "apiStepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["my.qltest.external", "Library", False, "apiStepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["my.qltest.external", "Library", False, "apiStepArgQualGenerated", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["my.qltest.external", "Library", False, "apiStepArgQualGeneratedIgnored", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] - addsTo: pack: codeql/java-all extensible: neutralModel data: - - ["my.qltest", "C", "stepArgQualGenerated", "(Object)", "summary", "df-generated"] - - ["my.qltest", "C", "stepArgQualGeneratedIgnored", "(Object)", "summary", "manual"] + - ["my.qltest.external", "Library", "apiStepArgQualGenerated", "(Object)", "summary", "df-generated"] + - ["my.qltest.external", "Library", "apiStepArgQualGeneratedIgnored", "(Object)", "summary", "manual"] diff --git a/java/ql/test/library-tests/dataflow/external-models/stubs/Library.java b/java/ql/test/library-tests/dataflow/external-models/stubs/Library.java new file mode 100644 index 00000000000..945d8671b39 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/external-models/stubs/Library.java @@ -0,0 +1,19 @@ +package my.qltest.external; + +public class Library { + public Object apiStepArgResGenerated(Object x) { + return null; + } + + public Object apiStepArgResGeneratedIgnored(Object x, Object y) { + return null; + } + + public Object apiStepArgQualGenerated(Object x) { + return null; + } + + public Object apiStepArgQualGeneratedIgnored(Object x) { + return null; + } +} From db51604f4611a6e1dcfe934754fe9c6bf2f457a8 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 19 Aug 2024 13:54:19 +0200 Subject: [PATCH 119/404] Java: Promote some generated models and add some manual neutrals. --- java/ql/lib/ext/java.net.model.yml | 1 + java/ql/lib/ext/java.nio.model.yml | 15 ++++++++++++++- java/ql/lib/ext/java.security.cert.model.yml | 8 ++++++++ java/ql/lib/ext/java.security.model.yml | 3 +++ java/ql/lib/ext/java.util.logging.model.yml | 3 +++ java/ql/lib/ext/javax.management.model.yml | 3 +++ 6 files changed, 32 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.net.model.yml b/java/ql/lib/ext/java.net.model.yml index f48acbeace1..5acfd7f4e10 100644 --- a/java/ql/lib/ext/java.net.model.yml +++ b/java/ql/lib/ext/java.net.model.yml @@ -48,6 +48,7 @@ extensions: - ["java.net", "URI", False, "URI", "(String,String,String)", "", "Argument[1]", "ReturnValue", "taint", "ai-manual"] - ["java.net", "URI", False, "URI", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.net", "URI", False, "create", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.net", "URI", False, "getPath", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] - ["java.net", "URI", False, "resolve", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - ["java.net", "URI", False, "resolve", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-manual"] - ["java.net", "URI", False, "toASCIIString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/java.nio.model.yml b/java/ql/lib/ext/java.nio.model.yml index 1548dc2c649..1848916b43b 100644 --- a/java/ql/lib/ext/java.nio.model.yml +++ b/java/ql/lib/ext/java.nio.model.yml @@ -5,7 +5,20 @@ extensions: data: - ["java.nio", "ByteBuffer", False, "array", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio", "ByteBuffer", False, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.nio", "ByteBuffer", False, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio", "ByteBuffer", True, "put", "(ByteBuffer)", "", "Argument[this]", "ReturnValue", "value", "df-manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte)", "", "Argument[this]", "ReturnValue", "value", "df-manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "df-manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte[])", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte[],int,int)", "", "Argument[0]", "Argument[this]", "taint", "df-manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte[],int,int)", "", "Argument[this]", "ReturnValue", "value", "df-manual"] + - ["java.nio", "ByteBuffer", True, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio", "ByteBuffer", True, "wrap", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] + - ["java.nio", "CharBuffer", True, "wrap", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] + - ["java.nio", "CharBuffer", True, "wrap", "(CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] + - ["java.nio", "CharBuffer", True, "wrap", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] + - ["java.nio", "CharBuffer", True, "wrap", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] + - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/java.security.cert.model.yml b/java/ql/lib/ext/java.security.cert.model.yml index 503ad06cabf..d85413b723d 100644 --- a/java/ql/lib/ext/java.security.cert.model.yml +++ b/java/ql/lib/ext/java.security.cert.model.yml @@ -4,6 +4,14 @@ extensions: extensible: sinkModel data: - ["java.security.cert", "X509CertSelector", False, "setSubjectPublicKey", "(byte[])", "", "Argument[0]", "credentials-key", "hq-generated"] + + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.security.cert", "X509Certificate", True, "getIssuerX500Principal", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] + - ["java.security.cert", "X509Certificate", True, "getSubjectX500Principal", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] + - addsTo: pack: codeql/java-all extensible: neutralModel diff --git a/java/ql/lib/ext/java.security.model.yml b/java/ql/lib/ext/java.security.model.yml index 6157c635fe6..27120072763 100644 --- a/java/ql/lib/ext/java.security.model.yml +++ b/java/ql/lib/ext/java.security.model.yml @@ -26,6 +26,9 @@ extensions: - ["java.security", "CodeSource", False, "getCertificates", "()", "", "Argument[this].SyntheticField[java.security.CodeSource.certificates].ArrayElement", "ReturnValue.ArrayElement", "value", "df-manual"] - ["java.security", "CodeSource", False, "getCodeSigners", "()", "", "Argument[this].SyntheticField[java.security.CodeSource.codeSigners].ArrayElement", "ReturnValue.ArrayElement", "value", "df-manual"] - ["java.security", "CodeSource", False, "getLocation", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] + - ["java.security", "Permission", True, "Permission", "(String)", "", "Argument[0]", "Argument[this]", "taint", "df-manual"] + - ["java.security", "Permission", True, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] + - addsTo: pack: codeql/java-all extensible: neutralModel diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml index 4bd8c6556c9..4913254bf2d 100644 --- a/java/ql/lib/ext/java.util.logging.model.yml +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -46,8 +46,11 @@ extensions: - ["java.util.logging", "Logger", False, "getLogger", "(String)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.logging.Logger.name]", "value", "manual"] - ["java.util.logging", "Logger", False, "getName", "()", "", "Argument[this].SyntheticField[java.util.logging.Logger.name]", "ReturnValue", "value", "manual"] - ["java.util.logging", "LogRecord", False, "LogRecord", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["java.util.logging", "LogRecord", True, "getMessage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] - addsTo: pack: codeql/java-all extensible: neutralModel data: + - ["java.util.logging", "Handler", "getEncoding", "()", "summary", "manual"] - ["java.util.logging", "Logger", "isLoggable", "(Level)", "summary", "manual"] + - ["java.util.logging", "LogRecord", "getParameters", "()", "summary", "manual"] diff --git a/java/ql/lib/ext/javax.management.model.yml b/java/ql/lib/ext/javax.management.model.yml index f1877228cf1..d973be3a69b 100644 --- a/java/ql/lib/ext/javax.management.model.yml +++ b/java/ql/lib/ext/javax.management.model.yml @@ -3,4 +3,7 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["javax.management", "Notification", True, "Notification", "(String,Object,long,String)", "", "Argument[3]", "Argument[this]", "taint", "df-manual"] + - ["javax.management", "Notification", True, "Notification", "(String,Object,long,long,String)", "", "Argument[4]", "Argument[this]", "taint", "df-manual"] + - ["javax.management", "Notification", True, "getMessage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] - ["javax.management", "ObjectName", True, "ObjectName", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-manual"] From d79aa294ec72a81268ea2fa487f787f4d06523e4 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 19 Aug 2024 13:58:12 +0200 Subject: [PATCH 120/404] Java: Move some neutrals into the model.yml file (they have previosly been ignored due to wrong file extension). --- java/ql/lib/ext/java.util.logging.model.yml | 4 ++++ java/ql/lib/ext/java.util.logging.yml | 8 -------- 2 files changed, 4 insertions(+), 8 deletions(-) delete mode 100644 java/ql/lib/ext/java.util.logging.yml diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml index 4913254bf2d..d13803d73bb 100644 --- a/java/ql/lib/ext/java.util.logging.model.yml +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -53,4 +53,8 @@ extensions: data: - ["java.util.logging", "Handler", "getEncoding", "()", "summary", "manual"] - ["java.util.logging", "Logger", "isLoggable", "(Level)", "summary", "manual"] + - ["java.util.logging", "LogRecord", "getResourceBundle", "()", "summary", "df-manual"] + # If needed, a pair of manual summary models using synthetics can be made for the two + # neutrals below. - ["java.util.logging", "LogRecord", "getParameters", "()", "summary", "manual"] + - ["java.util.logging", "LogRecord", "setParameters", "", "summary", "df-manual"] diff --git a/java/ql/lib/ext/java.util.logging.yml b/java/ql/lib/ext/java.util.logging.yml deleted file mode 100644 index c4bf4e77300..00000000000 --- a/java/ql/lib/ext/java.util.logging.yml +++ /dev/null @@ -1,8 +0,0 @@ -extensions: - - addsTo: - pack: codeql/java-all - extensible: neutralModel - data: - # summary neutrals - - ["java.util.logging", "LogRecord", "getResourceBundle", "()", "summary", "df-manual"] - - ["java.util.logging", "LogRecord", "setParameters", "", "summary", "df-manual"] From 7488cc0811dcc03a08e371db9ab09bffc9064af9 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 19 Aug 2024 15:17:27 +0200 Subject: [PATCH 121/404] Java: Updated expected test output. --- .../apache-commons-lang3/flow.expected | 646 +++++++++--------- 1 file changed, 323 insertions(+), 323 deletions(-) diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected index 5a5618355c0..5c7448f4222 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected @@ -1,14 +1,14 @@ models -| 1 | Summary: java.nio; CharBuffer; true; wrap; (char[]); ; Argument[0]; ReturnValue; taint; df-generated | -| 2 | Summary: java.io; Reader; true; read; ; ; Argument[this]; Argument[0]; taint; manual | -| 3 | Summary: java.io; StringReader; false; StringReader; ; ; Argument[0]; Argument[this]; taint; manual | -| 4 | Summary: java.lang; Appendable; true; append; ; ; Argument[0]; Argument[this]; taint; manual | -| 5 | Summary: java.lang; CharSequence; true; subSequence; ; ; Argument[this]; ReturnValue; taint; manual | -| 6 | Summary: java.lang; CharSequence; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | -| 7 | Summary: java.lang; Iterable; true; iterator; (); ; Argument[this].Element; ReturnValue.Element; value; manual | -| 8 | Summary: java.lang; String; false; toCharArray; ; ; Argument[this]; ReturnValue; taint; manual | -| 9 | Summary: java.lang; StringBuffer; true; StringBuffer; (String); ; Argument[0]; Argument[this]; taint; manual | -| 10 | Summary: java.lang; StringBuilder; true; StringBuilder; ; ; Argument[0]; Argument[this]; taint; manual | +| 1 | Summary: java.io; Reader; true; read; ; ; Argument[this]; Argument[0]; taint; manual | +| 2 | Summary: java.io; StringReader; false; StringReader; ; ; Argument[0]; Argument[this]; taint; manual | +| 3 | Summary: java.lang; Appendable; true; append; ; ; Argument[0]; Argument[this]; taint; manual | +| 4 | Summary: java.lang; CharSequence; true; subSequence; ; ; Argument[this]; ReturnValue; taint; manual | +| 5 | Summary: java.lang; CharSequence; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | +| 6 | Summary: java.lang; Iterable; true; iterator; (); ; Argument[this].Element; ReturnValue.Element; value; manual | +| 7 | Summary: java.lang; String; false; toCharArray; ; ; Argument[this]; ReturnValue; taint; manual | +| 8 | Summary: java.lang; StringBuffer; true; StringBuffer; (String); ; Argument[0]; Argument[this]; taint; manual | +| 9 | Summary: java.lang; StringBuilder; true; StringBuilder; ; ; Argument[0]; Argument[this]; taint; manual | +| 10 | Summary: java.nio; CharBuffer; true; wrap; (char[]); ; Argument[0]; ReturnValue; taint; df-manual | | 11 | Summary: java.util; Collection; true; add; ; ; Argument[0]; Argument[this].Element; value; manual | | 12 | Summary: java.util; Dictionary; true; put; (Object,Object); ; Argument[1]; Argument[this].MapValue; value; manual | | 13 | Summary: java.util; Iterator; true; next; ; ; Argument[this].Element; ReturnValue; value; manual | @@ -945,234 +945,234 @@ edges | RegExUtilsTest.java:27:57:27:63 | taint(...) : String | RegExUtilsTest.java:27:10:27:64 | replacePattern(...) | provenance | MaD:78 | | StrBuilderTest.java:17:28:17:50 | new StrBuilder(...) : StrBuilder | StrBuilderTest.java:17:58:17:62 | cons1 : StrBuilder | provenance | | | StrBuilderTest.java:17:43:17:49 | taint(...) : String | StrBuilderTest.java:17:28:17:50 | new StrBuilder(...) : StrBuilder | provenance | MaD:226 | -| StrBuilderTest.java:17:58:17:62 | cons1 : StrBuilder | StrBuilderTest.java:17:58:17:73 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:17:58:17:62 | cons1 : StrBuilder | StrBuilderTest.java:17:58:17:73 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:17:58:17:62 | cons1 : StrBuilder | StrBuilderTest.java:17:58:17:73 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:19:44:19:46 | sb1 [post update] : StrBuilder | StrBuilderTest.java:19:84:19:86 | sb1 : StrBuilder | provenance | | -| StrBuilderTest.java:19:55:19:61 | taint(...) : String | StrBuilderTest.java:19:55:19:75 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTest.java:19:55:19:61 | taint(...) : String | StrBuilderTest.java:19:55:19:75 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTest.java:19:55:19:75 | toCharArray(...) : char[] | StrBuilderTest.java:19:44:19:46 | sb1 [post update] : StrBuilder | provenance | MaD:228 | -| StrBuilderTest.java:19:84:19:86 | sb1 : StrBuilder | StrBuilderTest.java:19:84:19:97 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:19:84:19:86 | sb1 : StrBuilder | StrBuilderTest.java:19:84:19:97 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:19:84:19:86 | sb1 : StrBuilder | StrBuilderTest.java:19:84:19:97 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:20:44:20:46 | sb2 [post update] : StrBuilder | StrBuilderTest.java:20:90:20:92 | sb2 : StrBuilder | provenance | | -| StrBuilderTest.java:20:55:20:61 | taint(...) : String | StrBuilderTest.java:20:55:20:75 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTest.java:20:55:20:61 | taint(...) : String | StrBuilderTest.java:20:55:20:75 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTest.java:20:55:20:75 | toCharArray(...) : char[] | StrBuilderTest.java:20:44:20:46 | sb2 [post update] : StrBuilder | provenance | MaD:229 | -| StrBuilderTest.java:20:90:20:92 | sb2 : StrBuilder | StrBuilderTest.java:20:90:20:103 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:20:90:20:92 | sb2 : StrBuilder | StrBuilderTest.java:20:90:20:103 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:20:90:20:92 | sb2 : StrBuilder | StrBuilderTest.java:20:90:20:103 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:21:44:21:46 | sb3 [post update] : StrBuilder | StrBuilderTest.java:21:101:21:103 | sb3 : StrBuilder | provenance | | | StrBuilderTest.java:21:55:21:92 | wrap(...) : CharBuffer | StrBuilderTest.java:21:44:21:46 | sb3 [post update] : StrBuilder | provenance | MaD:241 | -| StrBuilderTest.java:21:71:21:77 | taint(...) : String | StrBuilderTest.java:21:71:21:91 | toCharArray(...) : char[] | provenance | MaD:8 | -| StrBuilderTest.java:21:71:21:91 | toCharArray(...) : char[] | StrBuilderTest.java:21:55:21:92 | wrap(...) : CharBuffer | provenance | MaD:1 | -| StrBuilderTest.java:21:101:21:103 | sb3 : StrBuilder | StrBuilderTest.java:21:101:21:114 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:21:71:21:77 | taint(...) : String | StrBuilderTest.java:21:71:21:91 | toCharArray(...) : char[] | provenance | MaD:7 | +| StrBuilderTest.java:21:71:21:91 | toCharArray(...) : char[] | StrBuilderTest.java:21:55:21:92 | wrap(...) : CharBuffer | provenance | MaD:10 | +| StrBuilderTest.java:21:101:21:103 | sb3 : StrBuilder | StrBuilderTest.java:21:101:21:114 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:21:101:21:103 | sb3 : StrBuilder | StrBuilderTest.java:21:101:21:114 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:22:44:22:46 | sb4 [post update] : StrBuilder | StrBuilderTest.java:22:107:22:109 | sb4 : StrBuilder | provenance | | | StrBuilderTest.java:22:55:22:92 | wrap(...) : CharBuffer | StrBuilderTest.java:22:44:22:46 | sb4 [post update] : StrBuilder | provenance | MaD:242 | -| StrBuilderTest.java:22:71:22:77 | taint(...) : String | StrBuilderTest.java:22:71:22:91 | toCharArray(...) : char[] | provenance | MaD:8 | -| StrBuilderTest.java:22:71:22:91 | toCharArray(...) : char[] | StrBuilderTest.java:22:55:22:92 | wrap(...) : CharBuffer | provenance | MaD:1 | -| StrBuilderTest.java:22:107:22:109 | sb4 : StrBuilder | StrBuilderTest.java:22:107:22:120 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:22:71:22:77 | taint(...) : String | StrBuilderTest.java:22:71:22:91 | toCharArray(...) : char[] | provenance | MaD:7 | +| StrBuilderTest.java:22:71:22:91 | toCharArray(...) : char[] | StrBuilderTest.java:22:55:22:92 | wrap(...) : CharBuffer | provenance | MaD:10 | +| StrBuilderTest.java:22:107:22:109 | sb4 : StrBuilder | StrBuilderTest.java:22:107:22:120 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:22:107:22:109 | sb4 : StrBuilder | StrBuilderTest.java:22:107:22:120 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:23:44:23:46 | sb5 [post update] : StrBuilder | StrBuilderTest.java:23:84:23:86 | sb5 : StrBuilder | provenance | | -| StrBuilderTest.java:23:55:23:75 | (...)... : String | StrBuilderTest.java:23:44:23:46 | sb5 [post update] : StrBuilder | provenance | MaD:4 | +| StrBuilderTest.java:23:55:23:75 | (...)... : String | StrBuilderTest.java:23:44:23:46 | sb5 [post update] : StrBuilder | provenance | MaD:3 | | StrBuilderTest.java:23:55:23:75 | (...)... : String | StrBuilderTest.java:23:44:23:46 | sb5 [post update] : StrBuilder | provenance | MaD:230 | | StrBuilderTest.java:23:69:23:75 | taint(...) : String | StrBuilderTest.java:23:55:23:75 | (...)... : String | provenance | | -| StrBuilderTest.java:23:84:23:86 | sb5 : StrBuilder | StrBuilderTest.java:23:84:23:97 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:23:84:23:86 | sb5 : StrBuilder | StrBuilderTest.java:23:84:23:97 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:23:84:23:86 | sb5 : StrBuilder | StrBuilderTest.java:23:84:23:97 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:24:44:24:46 | sb6 [post update] : StrBuilder | StrBuilderTest.java:24:90:24:92 | sb6 : StrBuilder | provenance | | -| StrBuilderTest.java:24:55:24:75 | (...)... : String | StrBuilderTest.java:24:44:24:46 | sb6 [post update] : StrBuilder | provenance | MaD:4 | +| StrBuilderTest.java:24:55:24:75 | (...)... : String | StrBuilderTest.java:24:44:24:46 | sb6 [post update] : StrBuilder | provenance | MaD:3 | | StrBuilderTest.java:24:55:24:75 | (...)... : String | StrBuilderTest.java:24:44:24:46 | sb6 [post update] : StrBuilder | provenance | MaD:231 | | StrBuilderTest.java:24:69:24:75 | taint(...) : String | StrBuilderTest.java:24:55:24:75 | (...)... : String | provenance | | -| StrBuilderTest.java:24:90:24:92 | sb6 : StrBuilder | StrBuilderTest.java:24:90:24:103 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:24:90:24:92 | sb6 : StrBuilder | StrBuilderTest.java:24:90:24:103 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:24:90:24:92 | sb6 : StrBuilder | StrBuilderTest.java:24:90:24:103 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:25:44:25:46 | sb7 [post update] : StrBuilder | StrBuilderTest.java:25:78:25:80 | sb7 : StrBuilder | provenance | | | StrBuilderTest.java:25:55:25:69 | (...)... : String | StrBuilderTest.java:25:44:25:46 | sb7 [post update] : StrBuilder | provenance | MaD:232 | | StrBuilderTest.java:25:63:25:69 | taint(...) : String | StrBuilderTest.java:25:55:25:69 | (...)... : String | provenance | | -| StrBuilderTest.java:25:78:25:80 | sb7 : StrBuilder | StrBuilderTest.java:25:78:25:91 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:25:78:25:80 | sb7 : StrBuilder | StrBuilderTest.java:25:78:25:91 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:25:78:25:80 | sb7 : StrBuilder | StrBuilderTest.java:25:78:25:91 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:27:50:27:54 | auxsb [post update] : StrBuilder | StrBuilderTest.java:28:59:28:63 | auxsb : StrBuilder | provenance | | | StrBuilderTest.java:27:63:27:69 | taint(...) : String | StrBuilderTest.java:27:50:27:54 | auxsb [post update] : StrBuilder | provenance | MaD:233 | | StrBuilderTest.java:28:48:28:50 | sb8 [post update] : StrBuilder | StrBuilderTest.java:28:72:28:74 | sb8 : StrBuilder | provenance | | | StrBuilderTest.java:28:59:28:63 | auxsb : StrBuilder | StrBuilderTest.java:28:48:28:50 | sb8 [post update] : StrBuilder | provenance | MaD:243 | -| StrBuilderTest.java:28:72:28:74 | sb8 : StrBuilder | StrBuilderTest.java:28:72:28:85 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:28:72:28:74 | sb8 : StrBuilder | StrBuilderTest.java:28:72:28:85 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:28:72:28:74 | sb8 : StrBuilder | StrBuilderTest.java:28:72:28:85 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:30:44:30:46 | sb9 [post update] : StrBuilder | StrBuilderTest.java:30:88:30:90 | sb9 : StrBuilder | provenance | | | StrBuilderTest.java:30:55:30:79 | new StringBuffer(...) : StringBuffer | StrBuilderTest.java:30:44:30:46 | sb9 [post update] : StrBuilder | provenance | MaD:237 | -| StrBuilderTest.java:30:72:30:78 | taint(...) : String | StrBuilderTest.java:30:55:30:79 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| StrBuilderTest.java:30:88:30:90 | sb9 : StrBuilder | StrBuilderTest.java:30:88:30:101 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:30:72:30:78 | taint(...) : String | StrBuilderTest.java:30:55:30:79 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| StrBuilderTest.java:30:88:30:90 | sb9 : StrBuilder | StrBuilderTest.java:30:88:30:101 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:30:88:30:90 | sb9 : StrBuilder | StrBuilderTest.java:30:88:30:101 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:31:45:31:48 | sb10 [post update] : StrBuilder | StrBuilderTest.java:31:96:31:99 | sb10 : StrBuilder | provenance | | | StrBuilderTest.java:31:57:31:81 | new StringBuffer(...) : StringBuffer | StrBuilderTest.java:31:45:31:48 | sb10 [post update] : StrBuilder | provenance | MaD:238 | -| StrBuilderTest.java:31:74:31:80 | taint(...) : String | StrBuilderTest.java:31:57:31:81 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| StrBuilderTest.java:31:96:31:99 | sb10 : StrBuilder | StrBuilderTest.java:31:96:31:110 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:31:74:31:80 | taint(...) : String | StrBuilderTest.java:31:57:31:81 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| StrBuilderTest.java:31:96:31:99 | sb10 : StrBuilder | StrBuilderTest.java:31:96:31:110 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:31:96:31:99 | sb10 : StrBuilder | StrBuilderTest.java:31:96:31:110 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:32:45:32:48 | sb11 [post update] : StrBuilder | StrBuilderTest.java:32:91:32:94 | sb11 : StrBuilder | provenance | | | StrBuilderTest.java:32:57:32:82 | new StringBuilder(...) : StringBuilder | StrBuilderTest.java:32:45:32:48 | sb11 [post update] : StrBuilder | provenance | MaD:239 | -| StrBuilderTest.java:32:75:32:81 | taint(...) : String | StrBuilderTest.java:32:57:32:82 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| StrBuilderTest.java:32:91:32:94 | sb11 : StrBuilder | StrBuilderTest.java:32:91:32:105 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:32:75:32:81 | taint(...) : String | StrBuilderTest.java:32:57:32:82 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| StrBuilderTest.java:32:91:32:94 | sb11 : StrBuilder | StrBuilderTest.java:32:91:32:105 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:32:91:32:94 | sb11 : StrBuilder | StrBuilderTest.java:32:91:32:105 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:33:45:33:48 | sb12 [post update] : StrBuilder | StrBuilderTest.java:33:97:33:100 | sb12 : StrBuilder | provenance | | | StrBuilderTest.java:33:57:33:82 | new StringBuilder(...) : StringBuilder | StrBuilderTest.java:33:45:33:48 | sb12 [post update] : StrBuilder | provenance | MaD:240 | -| StrBuilderTest.java:33:75:33:81 | taint(...) : String | StrBuilderTest.java:33:57:33:82 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| StrBuilderTest.java:33:97:33:100 | sb12 : StrBuilder | StrBuilderTest.java:33:97:33:111 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:33:75:33:81 | taint(...) : String | StrBuilderTest.java:33:57:33:82 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| StrBuilderTest.java:33:97:33:100 | sb12 : StrBuilder | StrBuilderTest.java:33:97:33:111 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:33:97:33:100 | sb12 : StrBuilder | StrBuilderTest.java:33:97:33:111 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:34:45:34:48 | sb13 [post update] : StrBuilder | StrBuilderTest.java:34:72:34:75 | sb13 : StrBuilder | provenance | | | StrBuilderTest.java:34:57:34:63 | taint(...) : String | StrBuilderTest.java:34:45:34:48 | sb13 [post update] : StrBuilder | provenance | MaD:233 | -| StrBuilderTest.java:34:72:34:75 | sb13 : StrBuilder | StrBuilderTest.java:34:72:34:86 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:34:72:34:75 | sb13 : StrBuilder | StrBuilderTest.java:34:72:34:86 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:34:72:34:75 | sb13 : StrBuilder | StrBuilderTest.java:34:72:34:86 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:35:45:35:48 | sb14 [post update] : StrBuilder | StrBuilderTest.java:35:78:35:81 | sb14 : StrBuilder | provenance | | | StrBuilderTest.java:35:57:35:63 | taint(...) : String | StrBuilderTest.java:35:45:35:48 | sb14 [post update] : StrBuilder | provenance | MaD:234 | -| StrBuilderTest.java:35:78:35:81 | sb14 : StrBuilder | StrBuilderTest.java:35:78:35:92 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:35:78:35:81 | sb14 : StrBuilder | StrBuilderTest.java:35:78:35:92 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:35:78:35:81 | sb14 : StrBuilder | StrBuilderTest.java:35:78:35:92 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:36:45:36:48 | sb15 [post update] : StrBuilder | StrBuilderTest.java:36:90:36:93 | sb15 : StrBuilder | provenance | | | StrBuilderTest.java:36:57:36:63 | taint(...) : String | StrBuilderTest.java:36:45:36:48 | sb15 [post update] : StrBuilder | provenance | MaD:235 | -| StrBuilderTest.java:36:90:36:93 | sb15 : StrBuilder | StrBuilderTest.java:36:90:36:104 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:36:90:36:93 | sb15 : StrBuilder | StrBuilderTest.java:36:90:36:104 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:36:90:36:93 | sb15 : StrBuilder | StrBuilderTest.java:36:90:36:104 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:37:45:37:48 | sb16 [post update] : StrBuilder | StrBuilderTest.java:37:97:37:100 | sb16 : StrBuilder | provenance | | | StrBuilderTest.java:37:45:37:89 | new ..[] { .. } : Object[] [[]] : String | StrBuilderTest.java:37:45:37:48 | sb16 [post update] : StrBuilder | provenance | MaD:236 | | StrBuilderTest.java:37:74:37:80 | taint(...) : String | StrBuilderTest.java:37:45:37:89 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| StrBuilderTest.java:37:97:37:100 | sb16 : StrBuilder | StrBuilderTest.java:37:97:37:111 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:37:97:37:100 | sb16 : StrBuilder | StrBuilderTest.java:37:97:37:111 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:37:97:37:100 | sb16 : StrBuilder | StrBuilderTest.java:37:97:37:111 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:40:13:40:23 | taintedList [post update] : ArrayList [] : String | StrBuilderTest.java:41:64:41:74 | taintedList : ArrayList [] : String | provenance | | | StrBuilderTest.java:40:13:40:23 | taintedList [post update] : ArrayList [] : String | StrBuilderTest.java:42:64:42:74 | taintedList : ArrayList [] : String | provenance | | | StrBuilderTest.java:40:29:40:35 | taint(...) : String | StrBuilderTest.java:40:13:40:23 | taintedList [post update] : ArrayList [] : String | provenance | MaD:11 | | StrBuilderTest.java:41:49:41:52 | sb17 [post update] : StrBuilder | StrBuilderTest.java:41:83:41:86 | sb17 : StrBuilder | provenance | | | StrBuilderTest.java:41:64:41:74 | taintedList : ArrayList [] : String | StrBuilderTest.java:41:49:41:52 | sb17 [post update] : StrBuilder | provenance | MaD:245 | -| StrBuilderTest.java:41:83:41:86 | sb17 : StrBuilder | StrBuilderTest.java:41:83:41:97 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:41:83:41:86 | sb17 : StrBuilder | StrBuilderTest.java:41:83:41:97 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:41:83:41:86 | sb17 : StrBuilder | StrBuilderTest.java:41:83:41:97 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:42:49:42:52 | sb18 [post update] : StrBuilder | StrBuilderTest.java:42:94:42:97 | sb18 : StrBuilder | provenance | | -| StrBuilderTest.java:42:64:42:74 | taintedList : ArrayList [] : String | StrBuilderTest.java:42:64:42:85 | iterator(...) : Iterator [] : String | provenance | MaD:7 | +| StrBuilderTest.java:42:64:42:74 | taintedList : ArrayList [] : String | StrBuilderTest.java:42:64:42:85 | iterator(...) : Iterator [] : String | provenance | MaD:6 | | StrBuilderTest.java:42:64:42:85 | iterator(...) : Iterator [] : String | StrBuilderTest.java:42:49:42:52 | sb18 [post update] : StrBuilder | provenance | MaD:246 | -| StrBuilderTest.java:42:94:42:97 | sb18 : StrBuilder | StrBuilderTest.java:42:94:42:108 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:42:94:42:97 | sb18 : StrBuilder | StrBuilderTest.java:42:94:42:108 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:42:94:42:97 | sb18 : StrBuilder | StrBuilderTest.java:42:94:42:108 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:44:45:44:48 | sb19 [post update] : StrBuilder | StrBuilderTest.java:44:84:44:87 | sb19 : StrBuilder | provenance | | | StrBuilderTest.java:44:45:44:76 | new ..[] { .. } : Object[] [[]] : String | StrBuilderTest.java:44:45:44:48 | sb19 [post update] : StrBuilder | provenance | MaD:247 | | StrBuilderTest.java:44:69:44:75 | taint(...) : String | StrBuilderTest.java:44:45:44:76 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| StrBuilderTest.java:44:84:44:87 | sb19 : StrBuilder | StrBuilderTest.java:44:84:44:98 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:44:84:44:87 | sb19 : StrBuilder | StrBuilderTest.java:44:84:44:98 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:44:84:44:87 | sb19 : StrBuilder | StrBuilderTest.java:44:84:44:98 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:45:45:45:48 | sb20 [post update] : StrBuilder | StrBuilderTest.java:45:84:45:87 | sb20 : StrBuilder | provenance | | | StrBuilderTest.java:45:45:45:76 | new ..[] { .. } : Object[] [[]] : String | StrBuilderTest.java:45:45:45:48 | sb20 [post update] : StrBuilder | provenance | MaD:247 | | StrBuilderTest.java:45:60:45:66 | taint(...) : String | StrBuilderTest.java:45:45:45:76 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| StrBuilderTest.java:45:84:45:87 | sb20 : StrBuilder | StrBuilderTest.java:45:84:45:98 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:45:84:45:87 | sb20 : StrBuilder | StrBuilderTest.java:45:84:45:98 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:45:84:45:87 | sb20 : StrBuilder | StrBuilderTest.java:45:84:45:98 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:46:45:46:48 | sb21 [post update] : StrBuilder | StrBuilderTest.java:46:97:46:100 | sb21 : StrBuilder | provenance | | | StrBuilderTest.java:46:74:46:80 | taint(...) : String | StrBuilderTest.java:46:45:46:48 | sb21 [post update] : StrBuilder | provenance | MaD:249 | -| StrBuilderTest.java:46:97:46:100 | sb21 : StrBuilder | StrBuilderTest.java:46:97:46:111 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:46:97:46:100 | sb21 : StrBuilder | StrBuilderTest.java:46:97:46:111 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:46:97:46:100 | sb21 : StrBuilder | StrBuilderTest.java:46:97:46:111 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:47:45:47:48 | sb22 [post update] : StrBuilder | StrBuilderTest.java:47:98:47:101 | sb22 : StrBuilder | provenance | | | StrBuilderTest.java:47:75:47:81 | taint(...) : String | StrBuilderTest.java:47:45:47:48 | sb22 [post update] : StrBuilder | provenance | MaD:251 | -| StrBuilderTest.java:47:98:47:101 | sb22 : StrBuilder | StrBuilderTest.java:47:98:47:112 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:47:98:47:101 | sb22 : StrBuilder | StrBuilderTest.java:47:98:47:112 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:47:98:47:101 | sb22 : StrBuilder | StrBuilderTest.java:47:98:47:112 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:48:45:48:48 | sb23 [post update] : StrBuilder | StrBuilderTest.java:48:88:48:91 | sb23 : StrBuilder | provenance | | -| StrBuilderTest.java:48:59:48:65 | taint(...) : String | StrBuilderTest.java:48:59:48:79 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTest.java:48:59:48:65 | taint(...) : String | StrBuilderTest.java:48:59:48:79 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTest.java:48:59:48:79 | toCharArray(...) : char[] | StrBuilderTest.java:48:45:48:48 | sb23 [post update] : StrBuilder | provenance | MaD:266 | -| StrBuilderTest.java:48:88:48:91 | sb23 : StrBuilder | StrBuilderTest.java:48:88:48:102 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:48:88:48:91 | sb23 : StrBuilder | StrBuilderTest.java:48:88:48:102 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:48:88:48:91 | sb23 : StrBuilder | StrBuilderTest.java:48:88:48:102 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:49:45:49:48 | sb24 [post update] : StrBuilder | StrBuilderTest.java:49:94:49:97 | sb24 : StrBuilder | provenance | | -| StrBuilderTest.java:49:59:49:65 | taint(...) : String | StrBuilderTest.java:49:59:49:79 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTest.java:49:59:49:65 | taint(...) : String | StrBuilderTest.java:49:59:49:79 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTest.java:49:59:49:79 | toCharArray(...) : char[] | StrBuilderTest.java:49:45:49:48 | sb24 [post update] : StrBuilder | provenance | MaD:267 | -| StrBuilderTest.java:49:94:49:97 | sb24 : StrBuilder | StrBuilderTest.java:49:94:49:108 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:49:94:49:97 | sb24 : StrBuilder | StrBuilderTest.java:49:94:49:108 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:49:94:49:97 | sb24 : StrBuilder | StrBuilderTest.java:49:94:49:108 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:50:45:50:48 | sb25 [post update] : StrBuilder | StrBuilderTest.java:50:82:50:85 | sb25 : StrBuilder | provenance | | | StrBuilderTest.java:50:59:50:73 | (...)... : String | StrBuilderTest.java:50:45:50:48 | sb25 [post update] : StrBuilder | provenance | MaD:268 | | StrBuilderTest.java:50:67:50:73 | taint(...) : String | StrBuilderTest.java:50:59:50:73 | (...)... : String | provenance | | -| StrBuilderTest.java:50:82:50:85 | sb25 : StrBuilder | StrBuilderTest.java:50:82:50:96 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:50:82:50:85 | sb25 : StrBuilder | StrBuilderTest.java:50:82:50:96 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:50:82:50:85 | sb25 : StrBuilder | StrBuilderTest.java:50:82:50:96 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:52:50:52:54 | auxsb [post update] : StrBuilder | StrBuilderTest.java:53:63:53:67 | auxsb : StrBuilder | provenance | | | StrBuilderTest.java:52:65:52:71 | taint(...) : String | StrBuilderTest.java:52:50:52:54 | auxsb [post update] : StrBuilder | provenance | MaD:269 | | StrBuilderTest.java:53:49:53:52 | sb26 [post update] : StrBuilder | StrBuilderTest.java:53:76:53:79 | sb26 : StrBuilder | provenance | | | StrBuilderTest.java:53:63:53:67 | auxsb : StrBuilder | StrBuilderTest.java:53:49:53:52 | sb26 [post update] : StrBuilder | provenance | MaD:277 | -| StrBuilderTest.java:53:76:53:79 | sb26 : StrBuilder | StrBuilderTest.java:53:76:53:90 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:53:76:53:79 | sb26 : StrBuilder | StrBuilderTest.java:53:76:53:90 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:53:76:53:79 | sb26 : StrBuilder | StrBuilderTest.java:53:76:53:90 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:55:45:55:48 | sb27 [post update] : StrBuilder | StrBuilderTest.java:55:92:55:95 | sb27 : StrBuilder | provenance | | | StrBuilderTest.java:55:59:55:83 | new StringBuffer(...) : StringBuffer | StrBuilderTest.java:55:45:55:48 | sb27 [post update] : StrBuilder | provenance | MaD:273 | -| StrBuilderTest.java:55:76:55:82 | taint(...) : String | StrBuilderTest.java:55:59:55:83 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| StrBuilderTest.java:55:92:55:95 | sb27 : StrBuilder | StrBuilderTest.java:55:92:55:106 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:55:76:55:82 | taint(...) : String | StrBuilderTest.java:55:59:55:83 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| StrBuilderTest.java:55:92:55:95 | sb27 : StrBuilder | StrBuilderTest.java:55:92:55:106 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:55:92:55:95 | sb27 : StrBuilder | StrBuilderTest.java:55:92:55:106 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:56:45:56:48 | sb28 [post update] : StrBuilder | StrBuilderTest.java:56:98:56:101 | sb28 : StrBuilder | provenance | | | StrBuilderTest.java:56:59:56:83 | new StringBuffer(...) : StringBuffer | StrBuilderTest.java:56:45:56:48 | sb28 [post update] : StrBuilder | provenance | MaD:274 | -| StrBuilderTest.java:56:76:56:82 | taint(...) : String | StrBuilderTest.java:56:59:56:83 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| StrBuilderTest.java:56:98:56:101 | sb28 : StrBuilder | StrBuilderTest.java:56:98:56:112 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:56:76:56:82 | taint(...) : String | StrBuilderTest.java:56:59:56:83 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| StrBuilderTest.java:56:98:56:101 | sb28 : StrBuilder | StrBuilderTest.java:56:98:56:112 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:56:98:56:101 | sb28 : StrBuilder | StrBuilderTest.java:56:98:56:112 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:57:45:57:48 | sb29 [post update] : StrBuilder | StrBuilderTest.java:57:93:57:96 | sb29 : StrBuilder | provenance | | | StrBuilderTest.java:57:59:57:84 | new StringBuilder(...) : StringBuilder | StrBuilderTest.java:57:45:57:48 | sb29 [post update] : StrBuilder | provenance | MaD:275 | -| StrBuilderTest.java:57:77:57:83 | taint(...) : String | StrBuilderTest.java:57:59:57:84 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| StrBuilderTest.java:57:93:57:96 | sb29 : StrBuilder | StrBuilderTest.java:57:93:57:107 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:57:77:57:83 | taint(...) : String | StrBuilderTest.java:57:59:57:84 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| StrBuilderTest.java:57:93:57:96 | sb29 : StrBuilder | StrBuilderTest.java:57:93:57:107 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:57:93:57:96 | sb29 : StrBuilder | StrBuilderTest.java:57:93:57:107 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:58:45:58:48 | sb30 [post update] : StrBuilder | StrBuilderTest.java:58:99:58:102 | sb30 : StrBuilder | provenance | | | StrBuilderTest.java:58:59:58:84 | new StringBuilder(...) : StringBuilder | StrBuilderTest.java:58:45:58:48 | sb30 [post update] : StrBuilder | provenance | MaD:276 | -| StrBuilderTest.java:58:77:58:83 | taint(...) : String | StrBuilderTest.java:58:59:58:84 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| StrBuilderTest.java:58:99:58:102 | sb30 : StrBuilder | StrBuilderTest.java:58:99:58:113 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:58:77:58:83 | taint(...) : String | StrBuilderTest.java:58:59:58:84 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| StrBuilderTest.java:58:99:58:102 | sb30 : StrBuilder | StrBuilderTest.java:58:99:58:113 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:58:99:58:102 | sb30 : StrBuilder | StrBuilderTest.java:58:99:58:113 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:59:45:59:48 | sb31 [post update] : StrBuilder | StrBuilderTest.java:59:74:59:77 | sb31 : StrBuilder | provenance | | | StrBuilderTest.java:59:59:59:65 | taint(...) : String | StrBuilderTest.java:59:45:59:48 | sb31 [post update] : StrBuilder | provenance | MaD:269 | -| StrBuilderTest.java:59:74:59:77 | sb31 : StrBuilder | StrBuilderTest.java:59:74:59:88 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:59:74:59:77 | sb31 : StrBuilder | StrBuilderTest.java:59:74:59:88 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:59:74:59:77 | sb31 : StrBuilder | StrBuilderTest.java:59:74:59:88 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:60:45:60:48 | sb32 [post update] : StrBuilder | StrBuilderTest.java:60:80:60:83 | sb32 : StrBuilder | provenance | | | StrBuilderTest.java:60:59:60:65 | taint(...) : String | StrBuilderTest.java:60:45:60:48 | sb32 [post update] : StrBuilder | provenance | MaD:270 | -| StrBuilderTest.java:60:80:60:83 | sb32 : StrBuilder | StrBuilderTest.java:60:80:60:94 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:60:80:60:83 | sb32 : StrBuilder | StrBuilderTest.java:60:80:60:94 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:60:80:60:83 | sb32 : StrBuilder | StrBuilderTest.java:60:80:60:94 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:61:45:61:48 | sb33 [post update] : StrBuilder | StrBuilderTest.java:61:92:61:95 | sb33 : StrBuilder | provenance | | | StrBuilderTest.java:61:59:61:65 | taint(...) : String | StrBuilderTest.java:61:45:61:48 | sb33 [post update] : StrBuilder | provenance | MaD:271 | -| StrBuilderTest.java:61:92:61:95 | sb33 : StrBuilder | StrBuilderTest.java:61:92:61:106 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:61:92:61:95 | sb33 : StrBuilder | StrBuilderTest.java:61:92:61:106 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:61:92:61:95 | sb33 : StrBuilder | StrBuilderTest.java:61:92:61:106 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:62:45:62:48 | sb34 [post update] : StrBuilder | StrBuilderTest.java:62:99:62:102 | sb34 : StrBuilder | provenance | | | StrBuilderTest.java:62:45:62:91 | new ..[] { .. } : Object[] [[]] : String | StrBuilderTest.java:62:45:62:48 | sb34 [post update] : StrBuilder | provenance | MaD:272 | | StrBuilderTest.java:62:76:62:82 | taint(...) : String | StrBuilderTest.java:62:45:62:91 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| StrBuilderTest.java:62:99:62:102 | sb34 : StrBuilder | StrBuilderTest.java:62:99:62:113 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:62:99:62:102 | sb34 : StrBuilder | StrBuilderTest.java:62:99:62:113 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:62:99:62:102 | sb34 : StrBuilder | StrBuilderTest.java:62:99:62:113 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:63:45:63:48 | sb35 [post update] : StrBuilder | StrBuilderTest.java:63:81:63:84 | sb35 : StrBuilder | provenance | | | StrBuilderTest.java:63:66:63:72 | taint(...) : String | StrBuilderTest.java:63:45:63:48 | sb35 [post update] : StrBuilder | provenance | MaD:256 | -| StrBuilderTest.java:63:81:63:84 | sb35 : StrBuilder | StrBuilderTest.java:63:81:63:95 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:63:81:63:84 | sb35 : StrBuilder | StrBuilderTest.java:63:81:63:95 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:63:81:63:84 | sb35 : StrBuilder | StrBuilderTest.java:63:81:63:95 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:64:45:64:48 | sb36 [post update] : StrBuilder | StrBuilderTest.java:64:84:64:87 | sb36 : StrBuilder | provenance | | | StrBuilderTest.java:64:66:64:72 | taint(...) : String | StrBuilderTest.java:64:45:64:48 | sb36 [post update] : StrBuilder | provenance | MaD:257 | -| StrBuilderTest.java:64:84:64:87 | sb36 : StrBuilder | StrBuilderTest.java:64:84:64:98 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:64:84:64:87 | sb36 : StrBuilder | StrBuilderTest.java:64:84:64:98 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:64:84:64:87 | sb36 : StrBuilder | StrBuilderTest.java:64:84:64:98 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:65:45:65:48 | sb37 [post update] : StrBuilder | StrBuilderTest.java:65:92:65:95 | sb37 : StrBuilder | provenance | | | StrBuilderTest.java:65:66:65:72 | taint(...) : String | StrBuilderTest.java:65:45:65:48 | sb37 [post update] : StrBuilder | provenance | MaD:258 | -| StrBuilderTest.java:65:92:65:95 | sb37 : StrBuilder | StrBuilderTest.java:65:92:65:106 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:65:92:65:95 | sb37 : StrBuilder | StrBuilderTest.java:65:92:65:106 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:65:92:65:95 | sb37 : StrBuilder | StrBuilderTest.java:65:92:65:106 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:66:45:66:48 | sb38 [post update] : StrBuilder | StrBuilderTest.java:66:85:66:88 | sb38 : StrBuilder | provenance | | | StrBuilderTest.java:66:70:66:76 | taint(...) : String | StrBuilderTest.java:66:45:66:48 | sb38 [post update] : StrBuilder | provenance | MaD:258 | -| StrBuilderTest.java:66:85:66:88 | sb38 : StrBuilder | StrBuilderTest.java:66:85:66:99 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:66:85:66:88 | sb38 : StrBuilder | StrBuilderTest.java:66:85:66:99 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:66:85:66:88 | sb38 : StrBuilder | StrBuilderTest.java:66:85:66:99 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:68:50:68:54 | auxsb [post update] : StrBuilder | StrBuilderTest.java:69:49:69:53 | auxsb : StrBuilder | provenance | | | StrBuilderTest.java:68:65:68:71 | taint(...) : String | StrBuilderTest.java:68:50:68:54 | auxsb [post update] : StrBuilder | provenance | MaD:269 | | StrBuilderTest.java:69:49:69:53 | auxsb : StrBuilder | StrBuilderTest.java:69:64:69:67 | sb39 [post update] : StrBuilder | provenance | MaD:259 | | StrBuilderTest.java:69:64:69:67 | sb39 [post update] : StrBuilder | StrBuilderTest.java:69:76:69:79 | sb39 : StrBuilder | provenance | | -| StrBuilderTest.java:69:76:69:79 | sb39 : StrBuilder | StrBuilderTest.java:69:76:69:90 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:69:76:69:79 | sb39 : StrBuilder | StrBuilderTest.java:69:76:69:90 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:69:76:69:79 | sb39 : StrBuilder | StrBuilderTest.java:69:76:69:90 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:73:13:73:23 | taintedList [post update] : ArrayList [] : String | StrBuilderTest.java:74:75:74:85 | taintedList : ArrayList [] : String | provenance | | | StrBuilderTest.java:73:13:73:23 | taintedList [post update] : ArrayList [] : String | StrBuilderTest.java:75:75:75:85 | taintedList : ArrayList [] : String | provenance | | | StrBuilderTest.java:73:29:73:35 | taint(...) : String | StrBuilderTest.java:73:13:73:23 | taintedList [post update] : ArrayList [] : String | provenance | MaD:11 | | StrBuilderTest.java:74:49:74:52 | sb40 [post update] : StrBuilder | StrBuilderTest.java:74:100:74:103 | sb40 : StrBuilder | provenance | | | StrBuilderTest.java:74:75:74:85 | taintedList : ArrayList [] : String | StrBuilderTest.java:74:49:74:52 | sb40 [post update] : StrBuilder | provenance | MaD:262 | -| StrBuilderTest.java:74:100:74:103 | sb40 : StrBuilder | StrBuilderTest.java:74:100:74:114 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:74:100:74:103 | sb40 : StrBuilder | StrBuilderTest.java:74:100:74:114 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:74:100:74:103 | sb40 : StrBuilder | StrBuilderTest.java:74:100:74:114 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:75:49:75:52 | sb41 [post update] : StrBuilder | StrBuilderTest.java:75:111:75:114 | sb41 : StrBuilder | provenance | | -| StrBuilderTest.java:75:75:75:85 | taintedList : ArrayList [] : String | StrBuilderTest.java:75:75:75:96 | iterator(...) : Iterator [] : String | provenance | MaD:7 | +| StrBuilderTest.java:75:75:75:85 | taintedList : ArrayList [] : String | StrBuilderTest.java:75:75:75:96 | iterator(...) : Iterator [] : String | provenance | MaD:6 | | StrBuilderTest.java:75:75:75:96 | iterator(...) : Iterator [] : String | StrBuilderTest.java:75:49:75:52 | sb41 [post update] : StrBuilder | provenance | MaD:263 | -| StrBuilderTest.java:75:111:75:114 | sb41 : StrBuilder | StrBuilderTest.java:75:111:75:125 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:75:111:75:114 | sb41 : StrBuilder | StrBuilderTest.java:75:111:75:125 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:75:111:75:114 | sb41 : StrBuilder | StrBuilderTest.java:75:111:75:125 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:77:49:77:52 | sb42 [post update] : StrBuilder | StrBuilderTest.java:77:105:77:108 | sb42 : StrBuilder | provenance | | | StrBuilderTest.java:77:90:77:96 | taint(...) : String | StrBuilderTest.java:77:49:77:52 | sb42 [post update] : StrBuilder | provenance | MaD:261 | -| StrBuilderTest.java:77:105:77:108 | sb42 : StrBuilder | StrBuilderTest.java:77:105:77:119 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:77:105:77:108 | sb42 : StrBuilder | StrBuilderTest.java:77:105:77:119 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:77:105:77:108 | sb42 : StrBuilder | StrBuilderTest.java:77:105:77:119 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:78:49:78:52 | sb43 [post update] : StrBuilder | StrBuilderTest.java:78:116:78:119 | sb43 : StrBuilder | provenance | | | StrBuilderTest.java:78:101:78:107 | taint(...) : String | StrBuilderTest.java:78:49:78:52 | sb43 [post update] : StrBuilder | provenance | MaD:261 | -| StrBuilderTest.java:78:116:78:119 | sb43 : StrBuilder | StrBuilderTest.java:78:116:78:130 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:78:116:78:119 | sb43 : StrBuilder | StrBuilderTest.java:78:116:78:130 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:78:116:78:119 | sb43 : StrBuilder | StrBuilderTest.java:78:116:78:130 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:79:37:79:60 | {...} : String[] [[]] : String | StrBuilderTest.java:81:75:81:86 | taintedArray : String[] [[]] : String | provenance | | | StrBuilderTest.java:79:52:79:58 | taint(...) : String | StrBuilderTest.java:79:37:79:60 | {...} : String[] [[]] : String | provenance | | | StrBuilderTest.java:81:49:81:52 | sb44 [post update] : StrBuilder | StrBuilderTest.java:81:101:81:104 | sb44 : StrBuilder | provenance | | | StrBuilderTest.java:81:75:81:86 | taintedArray : String[] [[]] : String | StrBuilderTest.java:81:49:81:52 | sb44 [post update] : StrBuilder | provenance | MaD:264 | -| StrBuilderTest.java:81:101:81:104 | sb44 : StrBuilder | StrBuilderTest.java:81:101:81:115 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:81:101:81:104 | sb44 : StrBuilder | StrBuilderTest.java:81:101:81:115 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:81:101:81:104 | sb44 : StrBuilder | StrBuilderTest.java:81:101:81:115 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:82:49:82:52 | sb45 [post update] : StrBuilder | StrBuilderTest.java:82:106:82:109 | sb45 : StrBuilder | provenance | | | StrBuilderTest.java:82:91:82:97 | taint(...) : String | StrBuilderTest.java:82:49:82:52 | sb45 [post update] : StrBuilder | provenance | MaD:261 | -| StrBuilderTest.java:82:106:82:109 | sb45 : StrBuilder | StrBuilderTest.java:82:106:82:120 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:82:106:82:109 | sb45 : StrBuilder | StrBuilderTest.java:82:106:82:120 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:82:106:82:109 | sb45 : StrBuilder | StrBuilderTest.java:82:106:82:120 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:85:49:85:52 | sb46 [post update] : StrBuilder | StrBuilderTest.java:87:13:87:16 | sb46 : StrBuilder | provenance | | | StrBuilderTest.java:85:61:85:67 | taint(...) : String | StrBuilderTest.java:85:49:85:52 | sb46 [post update] : StrBuilder | provenance | MaD:233 | | StrBuilderTest.java:87:13:87:16 | sb46 : StrBuilder | StrBuilderTest.java:87:13:87:27 | asReader(...) : Reader | provenance | MaD:278 | -| StrBuilderTest.java:87:13:87:27 | asReader(...) : Reader | StrBuilderTest.java:87:34:87:39 | target [post update] : char[] | provenance | MaD:2 | +| StrBuilderTest.java:87:13:87:27 | asReader(...) : Reader | StrBuilderTest.java:87:34:87:39 | target [post update] : char[] | provenance | MaD:1 | | StrBuilderTest.java:87:34:87:39 | target [post update] : char[] | StrBuilderTest.java:88:18:88:23 | target | provenance | | | StrBuilderTest.java:90:45:90:48 | sb47 [post update] : StrBuilder | StrBuilderTest.java:90:72:90:75 | sb47 : StrBuilder | provenance | | | StrBuilderTest.java:90:57:90:63 | taint(...) : String | StrBuilderTest.java:90:45:90:48 | sb47 [post update] : StrBuilder | provenance | MaD:233 | @@ -1194,23 +1194,23 @@ edges | StrBuilderTest.java:102:13:102:16 | sb51 : StrBuilder | StrBuilderTest.java:102:33:102:38 | target [post update] : char[] | provenance | MaD:288 | | StrBuilderTest.java:102:33:102:38 | target [post update] : char[] | StrBuilderTest.java:103:18:103:23 | target | provenance | | | StrBuilderTest.java:105:45:105:48 | sb52 [post update] : StrBuilder | StrBuilderTest.java:105:89:105:92 | sb52 : StrBuilder | provenance | | -| StrBuilderTest.java:105:60:105:66 | taint(...) : String | StrBuilderTest.java:105:60:105:80 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTest.java:105:60:105:66 | taint(...) : String | StrBuilderTest.java:105:60:105:80 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTest.java:105:60:105:80 | toCharArray(...) : char[] | StrBuilderTest.java:105:45:105:48 | sb52 [post update] : StrBuilder | provenance | MaD:290 | -| StrBuilderTest.java:105:89:105:92 | sb52 : StrBuilder | StrBuilderTest.java:105:89:105:103 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:105:89:105:92 | sb52 : StrBuilder | StrBuilderTest.java:105:89:105:103 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:105:89:105:92 | sb52 : StrBuilder | StrBuilderTest.java:105:89:105:103 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:106:45:106:48 | sb53 [post update] : StrBuilder | StrBuilderTest.java:106:95:106:98 | sb53 : StrBuilder | provenance | | -| StrBuilderTest.java:106:60:106:66 | taint(...) : String | StrBuilderTest.java:106:60:106:80 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTest.java:106:60:106:66 | taint(...) : String | StrBuilderTest.java:106:60:106:80 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTest.java:106:60:106:80 | toCharArray(...) : char[] | StrBuilderTest.java:106:45:106:48 | sb53 [post update] : StrBuilder | provenance | MaD:290 | -| StrBuilderTest.java:106:95:106:98 | sb53 : StrBuilder | StrBuilderTest.java:106:95:106:109 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:106:95:106:98 | sb53 : StrBuilder | StrBuilderTest.java:106:95:106:109 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:106:95:106:98 | sb53 : StrBuilder | StrBuilderTest.java:106:95:106:109 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:107:45:107:48 | sb54 [post update] : StrBuilder | StrBuilderTest.java:107:75:107:78 | sb54 : StrBuilder | provenance | | | StrBuilderTest.java:107:60:107:66 | taint(...) : String | StrBuilderTest.java:107:45:107:48 | sb54 [post update] : StrBuilder | provenance | MaD:290 | -| StrBuilderTest.java:107:75:107:78 | sb54 : StrBuilder | StrBuilderTest.java:107:75:107:89 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:107:75:107:78 | sb54 : StrBuilder | StrBuilderTest.java:107:75:107:89 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:107:75:107:78 | sb54 : StrBuilder | StrBuilderTest.java:107:75:107:89 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:108:45:108:48 | sb55 [post update] : StrBuilder | StrBuilderTest.java:108:83:108:86 | sb55 : StrBuilder | provenance | | | StrBuilderTest.java:108:60:108:74 | (...)... : String | StrBuilderTest.java:108:45:108:48 | sb55 [post update] : StrBuilder | provenance | MaD:290 | | StrBuilderTest.java:108:68:108:74 | taint(...) : String | StrBuilderTest.java:108:60:108:74 | (...)... : String | provenance | | -| StrBuilderTest.java:108:83:108:86 | sb55 : StrBuilder | StrBuilderTest.java:108:83:108:97 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:108:83:108:86 | sb55 : StrBuilder | StrBuilderTest.java:108:83:108:97 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:108:83:108:86 | sb55 : StrBuilder | StrBuilderTest.java:108:83:108:97 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:109:45:109:48 | sb56 [post update] : StrBuilder | StrBuilderTest.java:109:72:109:75 | sb56 : StrBuilder | provenance | | | StrBuilderTest.java:109:57:109:63 | taint(...) : String | StrBuilderTest.java:109:45:109:48 | sb56 [post update] : StrBuilder | provenance | MaD:233 | @@ -1219,41 +1219,41 @@ edges | StrBuilderTest.java:110:57:110:63 | taint(...) : String | StrBuilderTest.java:110:45:110:48 | sb57 [post update] : StrBuilder | provenance | MaD:233 | | StrBuilderTest.java:110:72:110:75 | sb57 : StrBuilder | StrBuilderTest.java:110:72:110:91 | midString(...) | provenance | MaD:292 | | StrBuilderTest.java:112:35:112:59 | new StringReader(...) : StringReader | StrBuilderTest.java:113:63:113:68 | reader : StringReader | provenance | | -| StrBuilderTest.java:112:52:112:58 | taint(...) : String | StrBuilderTest.java:112:35:112:59 | new StringReader(...) : StringReader | provenance | MaD:3 | +| StrBuilderTest.java:112:52:112:58 | taint(...) : String | StrBuilderTest.java:112:35:112:59 | new StringReader(...) : StringReader | provenance | MaD:2 | | StrBuilderTest.java:113:49:113:52 | sb58 [post update] : StrBuilder | StrBuilderTest.java:113:77:113:80 | sb58 : StrBuilder | provenance | | | StrBuilderTest.java:113:63:113:68 | reader : StringReader | StrBuilderTest.java:113:49:113:52 | sb58 [post update] : StrBuilder | provenance | MaD:294 | -| StrBuilderTest.java:113:77:113:80 | sb58 : StrBuilder | StrBuilderTest.java:113:77:113:91 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:113:77:113:80 | sb58 : StrBuilder | StrBuilderTest.java:113:77:113:91 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:113:77:113:80 | sb58 : StrBuilder | StrBuilderTest.java:113:77:113:91 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:115:45:115:48 | sb59 [post update] : StrBuilder | StrBuilderTest.java:115:79:115:82 | sb59 : StrBuilder | provenance | | | StrBuilderTest.java:115:64:115:70 | taint(...) : String | StrBuilderTest.java:115:45:115:48 | sb59 [post update] : StrBuilder | provenance | MaD:296 | -| StrBuilderTest.java:115:79:115:82 | sb59 : StrBuilder | StrBuilderTest.java:115:79:115:93 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:115:79:115:82 | sb59 : StrBuilder | StrBuilderTest.java:115:79:115:93 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:115:79:115:82 | sb59 : StrBuilder | StrBuilderTest.java:115:79:115:93 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:116:45:116:48 | sb60 [post update] : StrBuilder | StrBuilderTest.java:116:88:116:91 | sb60 : StrBuilder | provenance | | | StrBuilderTest.java:116:64:116:70 | taint(...) : String | StrBuilderTest.java:116:45:116:48 | sb60 [post update] : StrBuilder | provenance | MaD:297 | -| StrBuilderTest.java:116:88:116:91 | sb60 : StrBuilder | StrBuilderTest.java:116:88:116:102 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:116:88:116:91 | sb60 : StrBuilder | StrBuilderTest.java:116:88:116:102 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:116:88:116:91 | sb60 : StrBuilder | StrBuilderTest.java:116:88:116:102 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:117:45:117:48 | sb61 [post update] : StrBuilder | StrBuilderTest.java:117:94:117:97 | sb61 : StrBuilder | provenance | | | StrBuilderTest.java:117:79:117:85 | taint(...) : String | StrBuilderTest.java:117:45:117:48 | sb61 [post update] : StrBuilder | provenance | MaD:299 | -| StrBuilderTest.java:117:94:117:97 | sb61 : StrBuilder | StrBuilderTest.java:117:94:117:108 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:117:94:117:97 | sb61 : StrBuilder | StrBuilderTest.java:117:94:117:108 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:117:94:117:97 | sb61 : StrBuilder | StrBuilderTest.java:117:94:117:108 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:118:45:118:48 | sb62 [post update] : StrBuilder | StrBuilderTest.java:118:86:118:89 | sb62 : StrBuilder | provenance | | | StrBuilderTest.java:118:71:118:77 | taint(...) : String | StrBuilderTest.java:118:45:118:48 | sb62 [post update] : StrBuilder | provenance | MaD:299 | -| StrBuilderTest.java:118:86:118:89 | sb62 : StrBuilder | StrBuilderTest.java:118:86:118:100 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:118:86:118:89 | sb62 : StrBuilder | StrBuilderTest.java:118:86:118:100 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:118:86:118:89 | sb62 : StrBuilder | StrBuilderTest.java:118:86:118:100 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:120:45:120:48 | sb64 [post update] : StrBuilder | StrBuilderTest.java:120:96:120:99 | sb64 : StrBuilder | provenance | | | StrBuilderTest.java:120:81:120:87 | taint(...) : String | StrBuilderTest.java:120:45:120:48 | sb64 [post update] : StrBuilder | provenance | MaD:301 | -| StrBuilderTest.java:120:96:120:99 | sb64 : StrBuilder | StrBuilderTest.java:120:96:120:110 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:120:96:120:99 | sb64 : StrBuilder | StrBuilderTest.java:120:96:120:110 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:120:96:120:99 | sb64 : StrBuilder | StrBuilderTest.java:120:96:120:110 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:121:45:121:48 | sb65 [post update] : StrBuilder | StrBuilderTest.java:121:88:121:91 | sb65 : StrBuilder | provenance | | | StrBuilderTest.java:121:73:121:79 | taint(...) : String | StrBuilderTest.java:121:45:121:48 | sb65 [post update] : StrBuilder | provenance | MaD:301 | -| StrBuilderTest.java:121:88:121:91 | sb65 : StrBuilder | StrBuilderTest.java:121:88:121:102 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:121:88:121:91 | sb65 : StrBuilder | StrBuilderTest.java:121:88:121:102 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:121:88:121:91 | sb65 : StrBuilder | StrBuilderTest.java:121:88:121:102 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:123:45:123:48 | sb67 [post update] : StrBuilder | StrBuilderTest.java:123:72:123:75 | sb67 : StrBuilder | provenance | | | StrBuilderTest.java:123:57:123:63 | taint(...) : String | StrBuilderTest.java:123:45:123:48 | sb67 [post update] : StrBuilder | provenance | MaD:233 | | StrBuilderTest.java:123:72:123:75 | sb67 : StrBuilder | StrBuilderTest.java:123:72:123:90 | rightString(...) | provenance | MaD:303 | | StrBuilderTest.java:124:45:124:48 | sb68 [post update] : StrBuilder | StrBuilderTest.java:124:72:124:75 | sb68 : StrBuilder | provenance | | | StrBuilderTest.java:124:57:124:63 | taint(...) : String | StrBuilderTest.java:124:45:124:48 | sb68 [post update] : StrBuilder | provenance | MaD:233 | -| StrBuilderTest.java:124:72:124:75 | sb68 : StrBuilder | StrBuilderTest.java:124:72:124:93 | subSequence(...) | provenance | MaD:5 | +| StrBuilderTest.java:124:72:124:75 | sb68 : StrBuilder | StrBuilderTest.java:124:72:124:93 | subSequence(...) | provenance | MaD:4 | | StrBuilderTest.java:124:72:124:75 | sb68 : StrBuilder | StrBuilderTest.java:124:72:124:93 | subSequence(...) | provenance | MaD:308 | | StrBuilderTest.java:125:45:125:48 | sb69 [post update] : StrBuilder | StrBuilderTest.java:125:72:125:75 | sb69 : StrBuilder | provenance | | | StrBuilderTest.java:125:57:125:63 | taint(...) : String | StrBuilderTest.java:125:45:125:48 | sb69 [post update] : StrBuilder | provenance | MaD:233 | @@ -1275,18 +1275,18 @@ edges | StrBuilderTest.java:130:72:130:75 | sb74 : StrBuilder | StrBuilderTest.java:130:72:130:93 | toStringBuilder(...) | provenance | MaD:313 | | StrBuilderTest.java:135:14:135:58 | append(...) : StrBuilder | StrBuilderTest.java:135:14:135:82 | append(...) : StrBuilder | provenance | MaD:227 | | StrBuilderTest.java:135:14:135:58 | append(...) : StrBuilder | StrBuilderTest.java:135:14:135:82 | append(...) : StrBuilder | provenance | ValuePreservingMethod | -| StrBuilderTest.java:135:14:135:82 | append(...) : StrBuilder | StrBuilderTest.java:135:14:135:93 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:135:14:135:82 | append(...) : StrBuilder | StrBuilderTest.java:135:14:135:93 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:135:14:135:82 | append(...) : StrBuilder | StrBuilderTest.java:135:14:135:93 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:135:51:135:57 | taint(...) : String | StrBuilderTest.java:135:14:135:58 | append(...) : StrBuilder | provenance | MaD:233+MaD:227 | | StrBuilderTest.java:138:9:138:45 | append(...) [post update] : StrBuilder | StrBuilderTest.java:139:14:139:31 | fluentBackflowTest : StrBuilder | provenance | MaD:227 | | StrBuilderTest.java:138:9:138:45 | append(...) [post update] : StrBuilder | StrBuilderTest.java:139:14:139:31 | fluentBackflowTest : StrBuilder | provenance | ValuePreservingMethod | | StrBuilderTest.java:138:54:138:60 | taint(...) : String | StrBuilderTest.java:138:9:138:45 | append(...) [post update] : StrBuilder | provenance | MaD:233 | -| StrBuilderTest.java:139:14:139:31 | fluentBackflowTest : StrBuilder | StrBuilderTest.java:139:14:139:42 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:139:14:139:31 | fluentBackflowTest : StrBuilder | StrBuilderTest.java:139:14:139:42 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:139:14:139:31 | fluentBackflowTest : StrBuilder | StrBuilderTest.java:139:14:139:42 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:143:9:143:46 | append(...) [post update] : StrBuilder | StrBuilderTest.java:144:14:144:32 | fluentBackflowTest2 : StrBuilder | provenance | MaD:227 | | StrBuilderTest.java:143:9:143:46 | append(...) [post update] : StrBuilder | StrBuilderTest.java:144:14:144:32 | fluentBackflowTest2 : StrBuilder | provenance | ValuePreservingMethod | | StrBuilderTest.java:143:55:143:61 | taint(...) : String | StrBuilderTest.java:143:9:143:46 | append(...) [post update] : StrBuilder | provenance | MaD:233 | -| StrBuilderTest.java:144:14:144:32 | fluentBackflowTest2 : StrBuilder | StrBuilderTest.java:144:14:144:43 | toString(...) | provenance | MaD:6 | +| StrBuilderTest.java:144:14:144:32 | fluentBackflowTest2 : StrBuilder | StrBuilderTest.java:144:14:144:43 | toString(...) | provenance | MaD:5 | | StrBuilderTest.java:144:14:144:32 | fluentBackflowTest2 : StrBuilder | StrBuilderTest.java:144:14:144:43 | toString(...) | provenance | MaD:311 | | StrBuilderTest.java:147:43:147:65 | new StrBuilder(...) : StrBuilder | StrBuilderTest.java:148:14:148:33 | fluentAllMethodsTest : StrBuilder | provenance | | | StrBuilderTest.java:147:43:147:65 | new StrBuilder(...) : StrBuilder | StrBuilderTest.java:148:14:149:23 | append(...) : StrBuilder | provenance | ValuePreservingMethod | @@ -1672,234 +1672,234 @@ edges | StrBuilderTest.java:205:17:205:23 | taint(...) : String | StrBuilderTest.java:178:9:204:15 | trim(...) [post update] : StrBuilder | provenance | MaD:233 | | StrBuilderTextTest.java:17:28:17:50 | new StrBuilder(...) : StrBuilder | StrBuilderTextTest.java:17:58:17:62 | cons1 : StrBuilder | provenance | | | StrBuilderTextTest.java:17:43:17:49 | taint(...) : String | StrBuilderTextTest.java:17:28:17:50 | new StrBuilder(...) : StrBuilder | provenance | MaD:418 | -| StrBuilderTextTest.java:17:58:17:62 | cons1 : StrBuilder | StrBuilderTextTest.java:17:58:17:73 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:17:58:17:62 | cons1 : StrBuilder | StrBuilderTextTest.java:17:58:17:73 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:17:58:17:62 | cons1 : StrBuilder | StrBuilderTextTest.java:17:58:17:73 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:19:44:19:46 | sb1 [post update] : StrBuilder | StrBuilderTextTest.java:19:84:19:86 | sb1 : StrBuilder | provenance | | -| StrBuilderTextTest.java:19:55:19:61 | taint(...) : String | StrBuilderTextTest.java:19:55:19:75 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTextTest.java:19:55:19:61 | taint(...) : String | StrBuilderTextTest.java:19:55:19:75 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTextTest.java:19:55:19:75 | toCharArray(...) : char[] | StrBuilderTextTest.java:19:44:19:46 | sb1 [post update] : StrBuilder | provenance | MaD:420 | -| StrBuilderTextTest.java:19:84:19:86 | sb1 : StrBuilder | StrBuilderTextTest.java:19:84:19:97 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:19:84:19:86 | sb1 : StrBuilder | StrBuilderTextTest.java:19:84:19:97 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:19:84:19:86 | sb1 : StrBuilder | StrBuilderTextTest.java:19:84:19:97 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:20:44:20:46 | sb2 [post update] : StrBuilder | StrBuilderTextTest.java:20:90:20:92 | sb2 : StrBuilder | provenance | | -| StrBuilderTextTest.java:20:55:20:61 | taint(...) : String | StrBuilderTextTest.java:20:55:20:75 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTextTest.java:20:55:20:61 | taint(...) : String | StrBuilderTextTest.java:20:55:20:75 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTextTest.java:20:55:20:75 | toCharArray(...) : char[] | StrBuilderTextTest.java:20:44:20:46 | sb2 [post update] : StrBuilder | provenance | MaD:421 | -| StrBuilderTextTest.java:20:90:20:92 | sb2 : StrBuilder | StrBuilderTextTest.java:20:90:20:103 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:20:90:20:92 | sb2 : StrBuilder | StrBuilderTextTest.java:20:90:20:103 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:20:90:20:92 | sb2 : StrBuilder | StrBuilderTextTest.java:20:90:20:103 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:21:44:21:46 | sb3 [post update] : StrBuilder | StrBuilderTextTest.java:21:101:21:103 | sb3 : StrBuilder | provenance | | | StrBuilderTextTest.java:21:55:21:92 | wrap(...) : CharBuffer | StrBuilderTextTest.java:21:44:21:46 | sb3 [post update] : StrBuilder | provenance | MaD:433 | -| StrBuilderTextTest.java:21:71:21:77 | taint(...) : String | StrBuilderTextTest.java:21:71:21:91 | toCharArray(...) : char[] | provenance | MaD:8 | -| StrBuilderTextTest.java:21:71:21:91 | toCharArray(...) : char[] | StrBuilderTextTest.java:21:55:21:92 | wrap(...) : CharBuffer | provenance | MaD:1 | -| StrBuilderTextTest.java:21:101:21:103 | sb3 : StrBuilder | StrBuilderTextTest.java:21:101:21:114 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:21:71:21:77 | taint(...) : String | StrBuilderTextTest.java:21:71:21:91 | toCharArray(...) : char[] | provenance | MaD:7 | +| StrBuilderTextTest.java:21:71:21:91 | toCharArray(...) : char[] | StrBuilderTextTest.java:21:55:21:92 | wrap(...) : CharBuffer | provenance | MaD:10 | +| StrBuilderTextTest.java:21:101:21:103 | sb3 : StrBuilder | StrBuilderTextTest.java:21:101:21:114 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:21:101:21:103 | sb3 : StrBuilder | StrBuilderTextTest.java:21:101:21:114 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:22:44:22:46 | sb4 [post update] : StrBuilder | StrBuilderTextTest.java:22:107:22:109 | sb4 : StrBuilder | provenance | | | StrBuilderTextTest.java:22:55:22:92 | wrap(...) : CharBuffer | StrBuilderTextTest.java:22:44:22:46 | sb4 [post update] : StrBuilder | provenance | MaD:434 | -| StrBuilderTextTest.java:22:71:22:77 | taint(...) : String | StrBuilderTextTest.java:22:71:22:91 | toCharArray(...) : char[] | provenance | MaD:8 | -| StrBuilderTextTest.java:22:71:22:91 | toCharArray(...) : char[] | StrBuilderTextTest.java:22:55:22:92 | wrap(...) : CharBuffer | provenance | MaD:1 | -| StrBuilderTextTest.java:22:107:22:109 | sb4 : StrBuilder | StrBuilderTextTest.java:22:107:22:120 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:22:71:22:77 | taint(...) : String | StrBuilderTextTest.java:22:71:22:91 | toCharArray(...) : char[] | provenance | MaD:7 | +| StrBuilderTextTest.java:22:71:22:91 | toCharArray(...) : char[] | StrBuilderTextTest.java:22:55:22:92 | wrap(...) : CharBuffer | provenance | MaD:10 | +| StrBuilderTextTest.java:22:107:22:109 | sb4 : StrBuilder | StrBuilderTextTest.java:22:107:22:120 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:22:107:22:109 | sb4 : StrBuilder | StrBuilderTextTest.java:22:107:22:120 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:23:44:23:46 | sb5 [post update] : StrBuilder | StrBuilderTextTest.java:23:84:23:86 | sb5 : StrBuilder | provenance | | -| StrBuilderTextTest.java:23:55:23:75 | (...)... : String | StrBuilderTextTest.java:23:44:23:46 | sb5 [post update] : StrBuilder | provenance | MaD:4 | +| StrBuilderTextTest.java:23:55:23:75 | (...)... : String | StrBuilderTextTest.java:23:44:23:46 | sb5 [post update] : StrBuilder | provenance | MaD:3 | | StrBuilderTextTest.java:23:55:23:75 | (...)... : String | StrBuilderTextTest.java:23:44:23:46 | sb5 [post update] : StrBuilder | provenance | MaD:422 | | StrBuilderTextTest.java:23:69:23:75 | taint(...) : String | StrBuilderTextTest.java:23:55:23:75 | (...)... : String | provenance | | -| StrBuilderTextTest.java:23:84:23:86 | sb5 : StrBuilder | StrBuilderTextTest.java:23:84:23:97 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:23:84:23:86 | sb5 : StrBuilder | StrBuilderTextTest.java:23:84:23:97 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:23:84:23:86 | sb5 : StrBuilder | StrBuilderTextTest.java:23:84:23:97 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:24:44:24:46 | sb6 [post update] : StrBuilder | StrBuilderTextTest.java:24:90:24:92 | sb6 : StrBuilder | provenance | | -| StrBuilderTextTest.java:24:55:24:75 | (...)... : String | StrBuilderTextTest.java:24:44:24:46 | sb6 [post update] : StrBuilder | provenance | MaD:4 | +| StrBuilderTextTest.java:24:55:24:75 | (...)... : String | StrBuilderTextTest.java:24:44:24:46 | sb6 [post update] : StrBuilder | provenance | MaD:3 | | StrBuilderTextTest.java:24:55:24:75 | (...)... : String | StrBuilderTextTest.java:24:44:24:46 | sb6 [post update] : StrBuilder | provenance | MaD:423 | | StrBuilderTextTest.java:24:69:24:75 | taint(...) : String | StrBuilderTextTest.java:24:55:24:75 | (...)... : String | provenance | | -| StrBuilderTextTest.java:24:90:24:92 | sb6 : StrBuilder | StrBuilderTextTest.java:24:90:24:103 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:24:90:24:92 | sb6 : StrBuilder | StrBuilderTextTest.java:24:90:24:103 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:24:90:24:92 | sb6 : StrBuilder | StrBuilderTextTest.java:24:90:24:103 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:25:44:25:46 | sb7 [post update] : StrBuilder | StrBuilderTextTest.java:25:78:25:80 | sb7 : StrBuilder | provenance | | | StrBuilderTextTest.java:25:55:25:69 | (...)... : String | StrBuilderTextTest.java:25:44:25:46 | sb7 [post update] : StrBuilder | provenance | MaD:424 | | StrBuilderTextTest.java:25:63:25:69 | taint(...) : String | StrBuilderTextTest.java:25:55:25:69 | (...)... : String | provenance | | -| StrBuilderTextTest.java:25:78:25:80 | sb7 : StrBuilder | StrBuilderTextTest.java:25:78:25:91 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:25:78:25:80 | sb7 : StrBuilder | StrBuilderTextTest.java:25:78:25:91 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:25:78:25:80 | sb7 : StrBuilder | StrBuilderTextTest.java:25:78:25:91 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:27:50:27:54 | auxsb [post update] : StrBuilder | StrBuilderTextTest.java:28:59:28:63 | auxsb : StrBuilder | provenance | | | StrBuilderTextTest.java:27:63:27:69 | taint(...) : String | StrBuilderTextTest.java:27:50:27:54 | auxsb [post update] : StrBuilder | provenance | MaD:425 | | StrBuilderTextTest.java:28:48:28:50 | sb8 [post update] : StrBuilder | StrBuilderTextTest.java:28:72:28:74 | sb8 : StrBuilder | provenance | | | StrBuilderTextTest.java:28:59:28:63 | auxsb : StrBuilder | StrBuilderTextTest.java:28:48:28:50 | sb8 [post update] : StrBuilder | provenance | MaD:435 | -| StrBuilderTextTest.java:28:72:28:74 | sb8 : StrBuilder | StrBuilderTextTest.java:28:72:28:85 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:28:72:28:74 | sb8 : StrBuilder | StrBuilderTextTest.java:28:72:28:85 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:28:72:28:74 | sb8 : StrBuilder | StrBuilderTextTest.java:28:72:28:85 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:30:44:30:46 | sb9 [post update] : StrBuilder | StrBuilderTextTest.java:30:88:30:90 | sb9 : StrBuilder | provenance | | | StrBuilderTextTest.java:30:55:30:79 | new StringBuffer(...) : StringBuffer | StrBuilderTextTest.java:30:44:30:46 | sb9 [post update] : StrBuilder | provenance | MaD:429 | -| StrBuilderTextTest.java:30:72:30:78 | taint(...) : String | StrBuilderTextTest.java:30:55:30:79 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| StrBuilderTextTest.java:30:88:30:90 | sb9 : StrBuilder | StrBuilderTextTest.java:30:88:30:101 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:30:72:30:78 | taint(...) : String | StrBuilderTextTest.java:30:55:30:79 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| StrBuilderTextTest.java:30:88:30:90 | sb9 : StrBuilder | StrBuilderTextTest.java:30:88:30:101 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:30:88:30:90 | sb9 : StrBuilder | StrBuilderTextTest.java:30:88:30:101 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:31:45:31:48 | sb10 [post update] : StrBuilder | StrBuilderTextTest.java:31:96:31:99 | sb10 : StrBuilder | provenance | | | StrBuilderTextTest.java:31:57:31:81 | new StringBuffer(...) : StringBuffer | StrBuilderTextTest.java:31:45:31:48 | sb10 [post update] : StrBuilder | provenance | MaD:430 | -| StrBuilderTextTest.java:31:74:31:80 | taint(...) : String | StrBuilderTextTest.java:31:57:31:81 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| StrBuilderTextTest.java:31:96:31:99 | sb10 : StrBuilder | StrBuilderTextTest.java:31:96:31:110 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:31:74:31:80 | taint(...) : String | StrBuilderTextTest.java:31:57:31:81 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| StrBuilderTextTest.java:31:96:31:99 | sb10 : StrBuilder | StrBuilderTextTest.java:31:96:31:110 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:31:96:31:99 | sb10 : StrBuilder | StrBuilderTextTest.java:31:96:31:110 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:32:45:32:48 | sb11 [post update] : StrBuilder | StrBuilderTextTest.java:32:91:32:94 | sb11 : StrBuilder | provenance | | | StrBuilderTextTest.java:32:57:32:82 | new StringBuilder(...) : StringBuilder | StrBuilderTextTest.java:32:45:32:48 | sb11 [post update] : StrBuilder | provenance | MaD:431 | -| StrBuilderTextTest.java:32:75:32:81 | taint(...) : String | StrBuilderTextTest.java:32:57:32:82 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| StrBuilderTextTest.java:32:91:32:94 | sb11 : StrBuilder | StrBuilderTextTest.java:32:91:32:105 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:32:75:32:81 | taint(...) : String | StrBuilderTextTest.java:32:57:32:82 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| StrBuilderTextTest.java:32:91:32:94 | sb11 : StrBuilder | StrBuilderTextTest.java:32:91:32:105 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:32:91:32:94 | sb11 : StrBuilder | StrBuilderTextTest.java:32:91:32:105 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:33:45:33:48 | sb12 [post update] : StrBuilder | StrBuilderTextTest.java:33:97:33:100 | sb12 : StrBuilder | provenance | | | StrBuilderTextTest.java:33:57:33:82 | new StringBuilder(...) : StringBuilder | StrBuilderTextTest.java:33:45:33:48 | sb12 [post update] : StrBuilder | provenance | MaD:432 | -| StrBuilderTextTest.java:33:75:33:81 | taint(...) : String | StrBuilderTextTest.java:33:57:33:82 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| StrBuilderTextTest.java:33:97:33:100 | sb12 : StrBuilder | StrBuilderTextTest.java:33:97:33:111 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:33:75:33:81 | taint(...) : String | StrBuilderTextTest.java:33:57:33:82 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| StrBuilderTextTest.java:33:97:33:100 | sb12 : StrBuilder | StrBuilderTextTest.java:33:97:33:111 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:33:97:33:100 | sb12 : StrBuilder | StrBuilderTextTest.java:33:97:33:111 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:34:45:34:48 | sb13 [post update] : StrBuilder | StrBuilderTextTest.java:34:72:34:75 | sb13 : StrBuilder | provenance | | | StrBuilderTextTest.java:34:57:34:63 | taint(...) : String | StrBuilderTextTest.java:34:45:34:48 | sb13 [post update] : StrBuilder | provenance | MaD:425 | -| StrBuilderTextTest.java:34:72:34:75 | sb13 : StrBuilder | StrBuilderTextTest.java:34:72:34:86 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:34:72:34:75 | sb13 : StrBuilder | StrBuilderTextTest.java:34:72:34:86 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:34:72:34:75 | sb13 : StrBuilder | StrBuilderTextTest.java:34:72:34:86 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:35:45:35:48 | sb14 [post update] : StrBuilder | StrBuilderTextTest.java:35:78:35:81 | sb14 : StrBuilder | provenance | | | StrBuilderTextTest.java:35:57:35:63 | taint(...) : String | StrBuilderTextTest.java:35:45:35:48 | sb14 [post update] : StrBuilder | provenance | MaD:426 | -| StrBuilderTextTest.java:35:78:35:81 | sb14 : StrBuilder | StrBuilderTextTest.java:35:78:35:92 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:35:78:35:81 | sb14 : StrBuilder | StrBuilderTextTest.java:35:78:35:92 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:35:78:35:81 | sb14 : StrBuilder | StrBuilderTextTest.java:35:78:35:92 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:36:45:36:48 | sb15 [post update] : StrBuilder | StrBuilderTextTest.java:36:90:36:93 | sb15 : StrBuilder | provenance | | | StrBuilderTextTest.java:36:57:36:63 | taint(...) : String | StrBuilderTextTest.java:36:45:36:48 | sb15 [post update] : StrBuilder | provenance | MaD:427 | -| StrBuilderTextTest.java:36:90:36:93 | sb15 : StrBuilder | StrBuilderTextTest.java:36:90:36:104 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:36:90:36:93 | sb15 : StrBuilder | StrBuilderTextTest.java:36:90:36:104 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:36:90:36:93 | sb15 : StrBuilder | StrBuilderTextTest.java:36:90:36:104 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:37:45:37:48 | sb16 [post update] : StrBuilder | StrBuilderTextTest.java:37:97:37:100 | sb16 : StrBuilder | provenance | | | StrBuilderTextTest.java:37:45:37:89 | new ..[] { .. } : Object[] [[]] : String | StrBuilderTextTest.java:37:45:37:48 | sb16 [post update] : StrBuilder | provenance | MaD:428 | | StrBuilderTextTest.java:37:74:37:80 | taint(...) : String | StrBuilderTextTest.java:37:45:37:89 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| StrBuilderTextTest.java:37:97:37:100 | sb16 : StrBuilder | StrBuilderTextTest.java:37:97:37:111 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:37:97:37:100 | sb16 : StrBuilder | StrBuilderTextTest.java:37:97:37:111 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:37:97:37:100 | sb16 : StrBuilder | StrBuilderTextTest.java:37:97:37:111 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:40:13:40:23 | taintedList [post update] : ArrayList [] : String | StrBuilderTextTest.java:41:64:41:74 | taintedList : ArrayList [] : String | provenance | | | StrBuilderTextTest.java:40:13:40:23 | taintedList [post update] : ArrayList [] : String | StrBuilderTextTest.java:42:64:42:74 | taintedList : ArrayList [] : String | provenance | | | StrBuilderTextTest.java:40:29:40:35 | taint(...) : String | StrBuilderTextTest.java:40:13:40:23 | taintedList [post update] : ArrayList [] : String | provenance | MaD:11 | | StrBuilderTextTest.java:41:49:41:52 | sb17 [post update] : StrBuilder | StrBuilderTextTest.java:41:83:41:86 | sb17 : StrBuilder | provenance | | | StrBuilderTextTest.java:41:64:41:74 | taintedList : ArrayList [] : String | StrBuilderTextTest.java:41:49:41:52 | sb17 [post update] : StrBuilder | provenance | MaD:437 | -| StrBuilderTextTest.java:41:83:41:86 | sb17 : StrBuilder | StrBuilderTextTest.java:41:83:41:97 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:41:83:41:86 | sb17 : StrBuilder | StrBuilderTextTest.java:41:83:41:97 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:41:83:41:86 | sb17 : StrBuilder | StrBuilderTextTest.java:41:83:41:97 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:42:49:42:52 | sb18 [post update] : StrBuilder | StrBuilderTextTest.java:42:94:42:97 | sb18 : StrBuilder | provenance | | -| StrBuilderTextTest.java:42:64:42:74 | taintedList : ArrayList [] : String | StrBuilderTextTest.java:42:64:42:85 | iterator(...) : Iterator [] : String | provenance | MaD:7 | +| StrBuilderTextTest.java:42:64:42:74 | taintedList : ArrayList [] : String | StrBuilderTextTest.java:42:64:42:85 | iterator(...) : Iterator [] : String | provenance | MaD:6 | | StrBuilderTextTest.java:42:64:42:85 | iterator(...) : Iterator [] : String | StrBuilderTextTest.java:42:49:42:52 | sb18 [post update] : StrBuilder | provenance | MaD:438 | -| StrBuilderTextTest.java:42:94:42:97 | sb18 : StrBuilder | StrBuilderTextTest.java:42:94:42:108 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:42:94:42:97 | sb18 : StrBuilder | StrBuilderTextTest.java:42:94:42:108 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:42:94:42:97 | sb18 : StrBuilder | StrBuilderTextTest.java:42:94:42:108 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:44:45:44:48 | sb19 [post update] : StrBuilder | StrBuilderTextTest.java:44:84:44:87 | sb19 : StrBuilder | provenance | | | StrBuilderTextTest.java:44:45:44:76 | new ..[] { .. } : Object[] [[]] : String | StrBuilderTextTest.java:44:45:44:48 | sb19 [post update] : StrBuilder | provenance | MaD:439 | | StrBuilderTextTest.java:44:69:44:75 | taint(...) : String | StrBuilderTextTest.java:44:45:44:76 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| StrBuilderTextTest.java:44:84:44:87 | sb19 : StrBuilder | StrBuilderTextTest.java:44:84:44:98 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:44:84:44:87 | sb19 : StrBuilder | StrBuilderTextTest.java:44:84:44:98 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:44:84:44:87 | sb19 : StrBuilder | StrBuilderTextTest.java:44:84:44:98 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:45:45:45:48 | sb20 [post update] : StrBuilder | StrBuilderTextTest.java:45:84:45:87 | sb20 : StrBuilder | provenance | | | StrBuilderTextTest.java:45:45:45:76 | new ..[] { .. } : Object[] [[]] : String | StrBuilderTextTest.java:45:45:45:48 | sb20 [post update] : StrBuilder | provenance | MaD:439 | | StrBuilderTextTest.java:45:60:45:66 | taint(...) : String | StrBuilderTextTest.java:45:45:45:76 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| StrBuilderTextTest.java:45:84:45:87 | sb20 : StrBuilder | StrBuilderTextTest.java:45:84:45:98 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:45:84:45:87 | sb20 : StrBuilder | StrBuilderTextTest.java:45:84:45:98 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:45:84:45:87 | sb20 : StrBuilder | StrBuilderTextTest.java:45:84:45:98 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:46:45:46:48 | sb21 [post update] : StrBuilder | StrBuilderTextTest.java:46:97:46:100 | sb21 : StrBuilder | provenance | | | StrBuilderTextTest.java:46:74:46:80 | taint(...) : String | StrBuilderTextTest.java:46:45:46:48 | sb21 [post update] : StrBuilder | provenance | MaD:441 | -| StrBuilderTextTest.java:46:97:46:100 | sb21 : StrBuilder | StrBuilderTextTest.java:46:97:46:111 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:46:97:46:100 | sb21 : StrBuilder | StrBuilderTextTest.java:46:97:46:111 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:46:97:46:100 | sb21 : StrBuilder | StrBuilderTextTest.java:46:97:46:111 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:47:45:47:48 | sb22 [post update] : StrBuilder | StrBuilderTextTest.java:47:98:47:101 | sb22 : StrBuilder | provenance | | | StrBuilderTextTest.java:47:75:47:81 | taint(...) : String | StrBuilderTextTest.java:47:45:47:48 | sb22 [post update] : StrBuilder | provenance | MaD:443 | -| StrBuilderTextTest.java:47:98:47:101 | sb22 : StrBuilder | StrBuilderTextTest.java:47:98:47:112 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:47:98:47:101 | sb22 : StrBuilder | StrBuilderTextTest.java:47:98:47:112 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:47:98:47:101 | sb22 : StrBuilder | StrBuilderTextTest.java:47:98:47:112 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:48:45:48:48 | sb23 [post update] : StrBuilder | StrBuilderTextTest.java:48:88:48:91 | sb23 : StrBuilder | provenance | | -| StrBuilderTextTest.java:48:59:48:65 | taint(...) : String | StrBuilderTextTest.java:48:59:48:79 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTextTest.java:48:59:48:65 | taint(...) : String | StrBuilderTextTest.java:48:59:48:79 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTextTest.java:48:59:48:79 | toCharArray(...) : char[] | StrBuilderTextTest.java:48:45:48:48 | sb23 [post update] : StrBuilder | provenance | MaD:458 | -| StrBuilderTextTest.java:48:88:48:91 | sb23 : StrBuilder | StrBuilderTextTest.java:48:88:48:102 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:48:88:48:91 | sb23 : StrBuilder | StrBuilderTextTest.java:48:88:48:102 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:48:88:48:91 | sb23 : StrBuilder | StrBuilderTextTest.java:48:88:48:102 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:49:45:49:48 | sb24 [post update] : StrBuilder | StrBuilderTextTest.java:49:94:49:97 | sb24 : StrBuilder | provenance | | -| StrBuilderTextTest.java:49:59:49:65 | taint(...) : String | StrBuilderTextTest.java:49:59:49:79 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTextTest.java:49:59:49:65 | taint(...) : String | StrBuilderTextTest.java:49:59:49:79 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTextTest.java:49:59:49:79 | toCharArray(...) : char[] | StrBuilderTextTest.java:49:45:49:48 | sb24 [post update] : StrBuilder | provenance | MaD:459 | -| StrBuilderTextTest.java:49:94:49:97 | sb24 : StrBuilder | StrBuilderTextTest.java:49:94:49:108 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:49:94:49:97 | sb24 : StrBuilder | StrBuilderTextTest.java:49:94:49:108 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:49:94:49:97 | sb24 : StrBuilder | StrBuilderTextTest.java:49:94:49:108 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:50:45:50:48 | sb25 [post update] : StrBuilder | StrBuilderTextTest.java:50:82:50:85 | sb25 : StrBuilder | provenance | | | StrBuilderTextTest.java:50:59:50:73 | (...)... : String | StrBuilderTextTest.java:50:45:50:48 | sb25 [post update] : StrBuilder | provenance | MaD:460 | | StrBuilderTextTest.java:50:67:50:73 | taint(...) : String | StrBuilderTextTest.java:50:59:50:73 | (...)... : String | provenance | | -| StrBuilderTextTest.java:50:82:50:85 | sb25 : StrBuilder | StrBuilderTextTest.java:50:82:50:96 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:50:82:50:85 | sb25 : StrBuilder | StrBuilderTextTest.java:50:82:50:96 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:50:82:50:85 | sb25 : StrBuilder | StrBuilderTextTest.java:50:82:50:96 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:52:50:52:54 | auxsb [post update] : StrBuilder | StrBuilderTextTest.java:53:63:53:67 | auxsb : StrBuilder | provenance | | | StrBuilderTextTest.java:52:65:52:71 | taint(...) : String | StrBuilderTextTest.java:52:50:52:54 | auxsb [post update] : StrBuilder | provenance | MaD:461 | | StrBuilderTextTest.java:53:49:53:52 | sb26 [post update] : StrBuilder | StrBuilderTextTest.java:53:76:53:79 | sb26 : StrBuilder | provenance | | | StrBuilderTextTest.java:53:63:53:67 | auxsb : StrBuilder | StrBuilderTextTest.java:53:49:53:52 | sb26 [post update] : StrBuilder | provenance | MaD:469 | -| StrBuilderTextTest.java:53:76:53:79 | sb26 : StrBuilder | StrBuilderTextTest.java:53:76:53:90 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:53:76:53:79 | sb26 : StrBuilder | StrBuilderTextTest.java:53:76:53:90 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:53:76:53:79 | sb26 : StrBuilder | StrBuilderTextTest.java:53:76:53:90 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:55:45:55:48 | sb27 [post update] : StrBuilder | StrBuilderTextTest.java:55:92:55:95 | sb27 : StrBuilder | provenance | | | StrBuilderTextTest.java:55:59:55:83 | new StringBuffer(...) : StringBuffer | StrBuilderTextTest.java:55:45:55:48 | sb27 [post update] : StrBuilder | provenance | MaD:465 | -| StrBuilderTextTest.java:55:76:55:82 | taint(...) : String | StrBuilderTextTest.java:55:59:55:83 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| StrBuilderTextTest.java:55:92:55:95 | sb27 : StrBuilder | StrBuilderTextTest.java:55:92:55:106 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:55:76:55:82 | taint(...) : String | StrBuilderTextTest.java:55:59:55:83 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| StrBuilderTextTest.java:55:92:55:95 | sb27 : StrBuilder | StrBuilderTextTest.java:55:92:55:106 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:55:92:55:95 | sb27 : StrBuilder | StrBuilderTextTest.java:55:92:55:106 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:56:45:56:48 | sb28 [post update] : StrBuilder | StrBuilderTextTest.java:56:98:56:101 | sb28 : StrBuilder | provenance | | | StrBuilderTextTest.java:56:59:56:83 | new StringBuffer(...) : StringBuffer | StrBuilderTextTest.java:56:45:56:48 | sb28 [post update] : StrBuilder | provenance | MaD:466 | -| StrBuilderTextTest.java:56:76:56:82 | taint(...) : String | StrBuilderTextTest.java:56:59:56:83 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| StrBuilderTextTest.java:56:98:56:101 | sb28 : StrBuilder | StrBuilderTextTest.java:56:98:56:112 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:56:76:56:82 | taint(...) : String | StrBuilderTextTest.java:56:59:56:83 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| StrBuilderTextTest.java:56:98:56:101 | sb28 : StrBuilder | StrBuilderTextTest.java:56:98:56:112 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:56:98:56:101 | sb28 : StrBuilder | StrBuilderTextTest.java:56:98:56:112 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:57:45:57:48 | sb29 [post update] : StrBuilder | StrBuilderTextTest.java:57:93:57:96 | sb29 : StrBuilder | provenance | | | StrBuilderTextTest.java:57:59:57:84 | new StringBuilder(...) : StringBuilder | StrBuilderTextTest.java:57:45:57:48 | sb29 [post update] : StrBuilder | provenance | MaD:467 | -| StrBuilderTextTest.java:57:77:57:83 | taint(...) : String | StrBuilderTextTest.java:57:59:57:84 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| StrBuilderTextTest.java:57:93:57:96 | sb29 : StrBuilder | StrBuilderTextTest.java:57:93:57:107 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:57:77:57:83 | taint(...) : String | StrBuilderTextTest.java:57:59:57:84 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| StrBuilderTextTest.java:57:93:57:96 | sb29 : StrBuilder | StrBuilderTextTest.java:57:93:57:107 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:57:93:57:96 | sb29 : StrBuilder | StrBuilderTextTest.java:57:93:57:107 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:58:45:58:48 | sb30 [post update] : StrBuilder | StrBuilderTextTest.java:58:99:58:102 | sb30 : StrBuilder | provenance | | | StrBuilderTextTest.java:58:59:58:84 | new StringBuilder(...) : StringBuilder | StrBuilderTextTest.java:58:45:58:48 | sb30 [post update] : StrBuilder | provenance | MaD:468 | -| StrBuilderTextTest.java:58:77:58:83 | taint(...) : String | StrBuilderTextTest.java:58:59:58:84 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| StrBuilderTextTest.java:58:99:58:102 | sb30 : StrBuilder | StrBuilderTextTest.java:58:99:58:113 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:58:77:58:83 | taint(...) : String | StrBuilderTextTest.java:58:59:58:84 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| StrBuilderTextTest.java:58:99:58:102 | sb30 : StrBuilder | StrBuilderTextTest.java:58:99:58:113 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:58:99:58:102 | sb30 : StrBuilder | StrBuilderTextTest.java:58:99:58:113 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:59:45:59:48 | sb31 [post update] : StrBuilder | StrBuilderTextTest.java:59:74:59:77 | sb31 : StrBuilder | provenance | | | StrBuilderTextTest.java:59:59:59:65 | taint(...) : String | StrBuilderTextTest.java:59:45:59:48 | sb31 [post update] : StrBuilder | provenance | MaD:461 | -| StrBuilderTextTest.java:59:74:59:77 | sb31 : StrBuilder | StrBuilderTextTest.java:59:74:59:88 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:59:74:59:77 | sb31 : StrBuilder | StrBuilderTextTest.java:59:74:59:88 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:59:74:59:77 | sb31 : StrBuilder | StrBuilderTextTest.java:59:74:59:88 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:60:45:60:48 | sb32 [post update] : StrBuilder | StrBuilderTextTest.java:60:80:60:83 | sb32 : StrBuilder | provenance | | | StrBuilderTextTest.java:60:59:60:65 | taint(...) : String | StrBuilderTextTest.java:60:45:60:48 | sb32 [post update] : StrBuilder | provenance | MaD:462 | -| StrBuilderTextTest.java:60:80:60:83 | sb32 : StrBuilder | StrBuilderTextTest.java:60:80:60:94 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:60:80:60:83 | sb32 : StrBuilder | StrBuilderTextTest.java:60:80:60:94 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:60:80:60:83 | sb32 : StrBuilder | StrBuilderTextTest.java:60:80:60:94 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:61:45:61:48 | sb33 [post update] : StrBuilder | StrBuilderTextTest.java:61:92:61:95 | sb33 : StrBuilder | provenance | | | StrBuilderTextTest.java:61:59:61:65 | taint(...) : String | StrBuilderTextTest.java:61:45:61:48 | sb33 [post update] : StrBuilder | provenance | MaD:463 | -| StrBuilderTextTest.java:61:92:61:95 | sb33 : StrBuilder | StrBuilderTextTest.java:61:92:61:106 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:61:92:61:95 | sb33 : StrBuilder | StrBuilderTextTest.java:61:92:61:106 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:61:92:61:95 | sb33 : StrBuilder | StrBuilderTextTest.java:61:92:61:106 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:62:45:62:48 | sb34 [post update] : StrBuilder | StrBuilderTextTest.java:62:99:62:102 | sb34 : StrBuilder | provenance | | | StrBuilderTextTest.java:62:45:62:91 | new ..[] { .. } : Object[] [[]] : String | StrBuilderTextTest.java:62:45:62:48 | sb34 [post update] : StrBuilder | provenance | MaD:464 | | StrBuilderTextTest.java:62:76:62:82 | taint(...) : String | StrBuilderTextTest.java:62:45:62:91 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| StrBuilderTextTest.java:62:99:62:102 | sb34 : StrBuilder | StrBuilderTextTest.java:62:99:62:113 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:62:99:62:102 | sb34 : StrBuilder | StrBuilderTextTest.java:62:99:62:113 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:62:99:62:102 | sb34 : StrBuilder | StrBuilderTextTest.java:62:99:62:113 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:63:45:63:48 | sb35 [post update] : StrBuilder | StrBuilderTextTest.java:63:81:63:84 | sb35 : StrBuilder | provenance | | | StrBuilderTextTest.java:63:66:63:72 | taint(...) : String | StrBuilderTextTest.java:63:45:63:48 | sb35 [post update] : StrBuilder | provenance | MaD:448 | -| StrBuilderTextTest.java:63:81:63:84 | sb35 : StrBuilder | StrBuilderTextTest.java:63:81:63:95 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:63:81:63:84 | sb35 : StrBuilder | StrBuilderTextTest.java:63:81:63:95 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:63:81:63:84 | sb35 : StrBuilder | StrBuilderTextTest.java:63:81:63:95 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:64:45:64:48 | sb36 [post update] : StrBuilder | StrBuilderTextTest.java:64:84:64:87 | sb36 : StrBuilder | provenance | | | StrBuilderTextTest.java:64:66:64:72 | taint(...) : String | StrBuilderTextTest.java:64:45:64:48 | sb36 [post update] : StrBuilder | provenance | MaD:449 | -| StrBuilderTextTest.java:64:84:64:87 | sb36 : StrBuilder | StrBuilderTextTest.java:64:84:64:98 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:64:84:64:87 | sb36 : StrBuilder | StrBuilderTextTest.java:64:84:64:98 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:64:84:64:87 | sb36 : StrBuilder | StrBuilderTextTest.java:64:84:64:98 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:65:45:65:48 | sb37 [post update] : StrBuilder | StrBuilderTextTest.java:65:92:65:95 | sb37 : StrBuilder | provenance | | | StrBuilderTextTest.java:65:66:65:72 | taint(...) : String | StrBuilderTextTest.java:65:45:65:48 | sb37 [post update] : StrBuilder | provenance | MaD:450 | -| StrBuilderTextTest.java:65:92:65:95 | sb37 : StrBuilder | StrBuilderTextTest.java:65:92:65:106 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:65:92:65:95 | sb37 : StrBuilder | StrBuilderTextTest.java:65:92:65:106 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:65:92:65:95 | sb37 : StrBuilder | StrBuilderTextTest.java:65:92:65:106 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:66:45:66:48 | sb38 [post update] : StrBuilder | StrBuilderTextTest.java:66:85:66:88 | sb38 : StrBuilder | provenance | | | StrBuilderTextTest.java:66:70:66:76 | taint(...) : String | StrBuilderTextTest.java:66:45:66:48 | sb38 [post update] : StrBuilder | provenance | MaD:450 | -| StrBuilderTextTest.java:66:85:66:88 | sb38 : StrBuilder | StrBuilderTextTest.java:66:85:66:99 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:66:85:66:88 | sb38 : StrBuilder | StrBuilderTextTest.java:66:85:66:99 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:66:85:66:88 | sb38 : StrBuilder | StrBuilderTextTest.java:66:85:66:99 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:68:50:68:54 | auxsb [post update] : StrBuilder | StrBuilderTextTest.java:69:49:69:53 | auxsb : StrBuilder | provenance | | | StrBuilderTextTest.java:68:65:68:71 | taint(...) : String | StrBuilderTextTest.java:68:50:68:54 | auxsb [post update] : StrBuilder | provenance | MaD:461 | | StrBuilderTextTest.java:69:49:69:53 | auxsb : StrBuilder | StrBuilderTextTest.java:69:64:69:67 | sb39 [post update] : StrBuilder | provenance | MaD:451 | | StrBuilderTextTest.java:69:64:69:67 | sb39 [post update] : StrBuilder | StrBuilderTextTest.java:69:76:69:79 | sb39 : StrBuilder | provenance | | -| StrBuilderTextTest.java:69:76:69:79 | sb39 : StrBuilder | StrBuilderTextTest.java:69:76:69:90 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:69:76:69:79 | sb39 : StrBuilder | StrBuilderTextTest.java:69:76:69:90 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:69:76:69:79 | sb39 : StrBuilder | StrBuilderTextTest.java:69:76:69:90 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:73:13:73:23 | taintedList [post update] : ArrayList [] : String | StrBuilderTextTest.java:74:75:74:85 | taintedList : ArrayList [] : String | provenance | | | StrBuilderTextTest.java:73:13:73:23 | taintedList [post update] : ArrayList [] : String | StrBuilderTextTest.java:75:75:75:85 | taintedList : ArrayList [] : String | provenance | | | StrBuilderTextTest.java:73:29:73:35 | taint(...) : String | StrBuilderTextTest.java:73:13:73:23 | taintedList [post update] : ArrayList [] : String | provenance | MaD:11 | | StrBuilderTextTest.java:74:49:74:52 | sb40 [post update] : StrBuilder | StrBuilderTextTest.java:74:100:74:103 | sb40 : StrBuilder | provenance | | | StrBuilderTextTest.java:74:75:74:85 | taintedList : ArrayList [] : String | StrBuilderTextTest.java:74:49:74:52 | sb40 [post update] : StrBuilder | provenance | MaD:454 | -| StrBuilderTextTest.java:74:100:74:103 | sb40 : StrBuilder | StrBuilderTextTest.java:74:100:74:114 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:74:100:74:103 | sb40 : StrBuilder | StrBuilderTextTest.java:74:100:74:114 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:74:100:74:103 | sb40 : StrBuilder | StrBuilderTextTest.java:74:100:74:114 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:75:49:75:52 | sb41 [post update] : StrBuilder | StrBuilderTextTest.java:75:111:75:114 | sb41 : StrBuilder | provenance | | -| StrBuilderTextTest.java:75:75:75:85 | taintedList : ArrayList [] : String | StrBuilderTextTest.java:75:75:75:96 | iterator(...) : Iterator [] : String | provenance | MaD:7 | +| StrBuilderTextTest.java:75:75:75:85 | taintedList : ArrayList [] : String | StrBuilderTextTest.java:75:75:75:96 | iterator(...) : Iterator [] : String | provenance | MaD:6 | | StrBuilderTextTest.java:75:75:75:96 | iterator(...) : Iterator [] : String | StrBuilderTextTest.java:75:49:75:52 | sb41 [post update] : StrBuilder | provenance | MaD:455 | -| StrBuilderTextTest.java:75:111:75:114 | sb41 : StrBuilder | StrBuilderTextTest.java:75:111:75:125 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:75:111:75:114 | sb41 : StrBuilder | StrBuilderTextTest.java:75:111:75:125 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:75:111:75:114 | sb41 : StrBuilder | StrBuilderTextTest.java:75:111:75:125 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:77:49:77:52 | sb42 [post update] : StrBuilder | StrBuilderTextTest.java:77:105:77:108 | sb42 : StrBuilder | provenance | | | StrBuilderTextTest.java:77:90:77:96 | taint(...) : String | StrBuilderTextTest.java:77:49:77:52 | sb42 [post update] : StrBuilder | provenance | MaD:453 | -| StrBuilderTextTest.java:77:105:77:108 | sb42 : StrBuilder | StrBuilderTextTest.java:77:105:77:119 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:77:105:77:108 | sb42 : StrBuilder | StrBuilderTextTest.java:77:105:77:119 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:77:105:77:108 | sb42 : StrBuilder | StrBuilderTextTest.java:77:105:77:119 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:78:49:78:52 | sb43 [post update] : StrBuilder | StrBuilderTextTest.java:78:116:78:119 | sb43 : StrBuilder | provenance | | | StrBuilderTextTest.java:78:101:78:107 | taint(...) : String | StrBuilderTextTest.java:78:49:78:52 | sb43 [post update] : StrBuilder | provenance | MaD:453 | -| StrBuilderTextTest.java:78:116:78:119 | sb43 : StrBuilder | StrBuilderTextTest.java:78:116:78:130 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:78:116:78:119 | sb43 : StrBuilder | StrBuilderTextTest.java:78:116:78:130 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:78:116:78:119 | sb43 : StrBuilder | StrBuilderTextTest.java:78:116:78:130 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:79:37:79:60 | {...} : String[] [[]] : String | StrBuilderTextTest.java:81:75:81:86 | taintedArray : String[] [[]] : String | provenance | | | StrBuilderTextTest.java:79:52:79:58 | taint(...) : String | StrBuilderTextTest.java:79:37:79:60 | {...} : String[] [[]] : String | provenance | | | StrBuilderTextTest.java:81:49:81:52 | sb44 [post update] : StrBuilder | StrBuilderTextTest.java:81:101:81:104 | sb44 : StrBuilder | provenance | | | StrBuilderTextTest.java:81:75:81:86 | taintedArray : String[] [[]] : String | StrBuilderTextTest.java:81:49:81:52 | sb44 [post update] : StrBuilder | provenance | MaD:456 | -| StrBuilderTextTest.java:81:101:81:104 | sb44 : StrBuilder | StrBuilderTextTest.java:81:101:81:115 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:81:101:81:104 | sb44 : StrBuilder | StrBuilderTextTest.java:81:101:81:115 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:81:101:81:104 | sb44 : StrBuilder | StrBuilderTextTest.java:81:101:81:115 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:82:49:82:52 | sb45 [post update] : StrBuilder | StrBuilderTextTest.java:82:106:82:109 | sb45 : StrBuilder | provenance | | | StrBuilderTextTest.java:82:91:82:97 | taint(...) : String | StrBuilderTextTest.java:82:49:82:52 | sb45 [post update] : StrBuilder | provenance | MaD:453 | -| StrBuilderTextTest.java:82:106:82:109 | sb45 : StrBuilder | StrBuilderTextTest.java:82:106:82:120 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:82:106:82:109 | sb45 : StrBuilder | StrBuilderTextTest.java:82:106:82:120 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:82:106:82:109 | sb45 : StrBuilder | StrBuilderTextTest.java:82:106:82:120 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:85:49:85:52 | sb46 [post update] : StrBuilder | StrBuilderTextTest.java:87:13:87:16 | sb46 : StrBuilder | provenance | | | StrBuilderTextTest.java:85:61:85:67 | taint(...) : String | StrBuilderTextTest.java:85:49:85:52 | sb46 [post update] : StrBuilder | provenance | MaD:425 | | StrBuilderTextTest.java:87:13:87:16 | sb46 : StrBuilder | StrBuilderTextTest.java:87:13:87:27 | asReader(...) : Reader | provenance | MaD:470 | -| StrBuilderTextTest.java:87:13:87:27 | asReader(...) : Reader | StrBuilderTextTest.java:87:34:87:39 | target [post update] : char[] | provenance | MaD:2 | +| StrBuilderTextTest.java:87:13:87:27 | asReader(...) : Reader | StrBuilderTextTest.java:87:34:87:39 | target [post update] : char[] | provenance | MaD:1 | | StrBuilderTextTest.java:87:34:87:39 | target [post update] : char[] | StrBuilderTextTest.java:88:18:88:23 | target | provenance | | | StrBuilderTextTest.java:90:45:90:48 | sb47 [post update] : StrBuilder | StrBuilderTextTest.java:90:72:90:75 | sb47 : StrBuilder | provenance | | | StrBuilderTextTest.java:90:57:90:63 | taint(...) : String | StrBuilderTextTest.java:90:45:90:48 | sb47 [post update] : StrBuilder | provenance | MaD:425 | @@ -1921,23 +1921,23 @@ edges | StrBuilderTextTest.java:102:13:102:16 | sb51 : StrBuilder | StrBuilderTextTest.java:102:33:102:38 | target [post update] : char[] | provenance | MaD:480 | | StrBuilderTextTest.java:102:33:102:38 | target [post update] : char[] | StrBuilderTextTest.java:103:18:103:23 | target | provenance | | | StrBuilderTextTest.java:105:45:105:48 | sb52 [post update] : StrBuilder | StrBuilderTextTest.java:105:89:105:92 | sb52 : StrBuilder | provenance | | -| StrBuilderTextTest.java:105:60:105:66 | taint(...) : String | StrBuilderTextTest.java:105:60:105:80 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTextTest.java:105:60:105:66 | taint(...) : String | StrBuilderTextTest.java:105:60:105:80 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTextTest.java:105:60:105:80 | toCharArray(...) : char[] | StrBuilderTextTest.java:105:45:105:48 | sb52 [post update] : StrBuilder | provenance | MaD:482 | -| StrBuilderTextTest.java:105:89:105:92 | sb52 : StrBuilder | StrBuilderTextTest.java:105:89:105:103 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:105:89:105:92 | sb52 : StrBuilder | StrBuilderTextTest.java:105:89:105:103 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:105:89:105:92 | sb52 : StrBuilder | StrBuilderTextTest.java:105:89:105:103 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:106:45:106:48 | sb53 [post update] : StrBuilder | StrBuilderTextTest.java:106:95:106:98 | sb53 : StrBuilder | provenance | | -| StrBuilderTextTest.java:106:60:106:66 | taint(...) : String | StrBuilderTextTest.java:106:60:106:80 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrBuilderTextTest.java:106:60:106:66 | taint(...) : String | StrBuilderTextTest.java:106:60:106:80 | toCharArray(...) : char[] | provenance | MaD:7 | | StrBuilderTextTest.java:106:60:106:80 | toCharArray(...) : char[] | StrBuilderTextTest.java:106:45:106:48 | sb53 [post update] : StrBuilder | provenance | MaD:482 | -| StrBuilderTextTest.java:106:95:106:98 | sb53 : StrBuilder | StrBuilderTextTest.java:106:95:106:109 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:106:95:106:98 | sb53 : StrBuilder | StrBuilderTextTest.java:106:95:106:109 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:106:95:106:98 | sb53 : StrBuilder | StrBuilderTextTest.java:106:95:106:109 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:107:45:107:48 | sb54 [post update] : StrBuilder | StrBuilderTextTest.java:107:75:107:78 | sb54 : StrBuilder | provenance | | | StrBuilderTextTest.java:107:60:107:66 | taint(...) : String | StrBuilderTextTest.java:107:45:107:48 | sb54 [post update] : StrBuilder | provenance | MaD:482 | -| StrBuilderTextTest.java:107:75:107:78 | sb54 : StrBuilder | StrBuilderTextTest.java:107:75:107:89 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:107:75:107:78 | sb54 : StrBuilder | StrBuilderTextTest.java:107:75:107:89 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:107:75:107:78 | sb54 : StrBuilder | StrBuilderTextTest.java:107:75:107:89 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:108:45:108:48 | sb55 [post update] : StrBuilder | StrBuilderTextTest.java:108:83:108:86 | sb55 : StrBuilder | provenance | | | StrBuilderTextTest.java:108:60:108:74 | (...)... : String | StrBuilderTextTest.java:108:45:108:48 | sb55 [post update] : StrBuilder | provenance | MaD:482 | | StrBuilderTextTest.java:108:68:108:74 | taint(...) : String | StrBuilderTextTest.java:108:60:108:74 | (...)... : String | provenance | | -| StrBuilderTextTest.java:108:83:108:86 | sb55 : StrBuilder | StrBuilderTextTest.java:108:83:108:97 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:108:83:108:86 | sb55 : StrBuilder | StrBuilderTextTest.java:108:83:108:97 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:108:83:108:86 | sb55 : StrBuilder | StrBuilderTextTest.java:108:83:108:97 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:109:45:109:48 | sb56 [post update] : StrBuilder | StrBuilderTextTest.java:109:72:109:75 | sb56 : StrBuilder | provenance | | | StrBuilderTextTest.java:109:57:109:63 | taint(...) : String | StrBuilderTextTest.java:109:45:109:48 | sb56 [post update] : StrBuilder | provenance | MaD:425 | @@ -1946,41 +1946,41 @@ edges | StrBuilderTextTest.java:110:57:110:63 | taint(...) : String | StrBuilderTextTest.java:110:45:110:48 | sb57 [post update] : StrBuilder | provenance | MaD:425 | | StrBuilderTextTest.java:110:72:110:75 | sb57 : StrBuilder | StrBuilderTextTest.java:110:72:110:91 | midString(...) | provenance | MaD:484 | | StrBuilderTextTest.java:112:35:112:59 | new StringReader(...) : StringReader | StrBuilderTextTest.java:113:63:113:68 | reader : StringReader | provenance | | -| StrBuilderTextTest.java:112:52:112:58 | taint(...) : String | StrBuilderTextTest.java:112:35:112:59 | new StringReader(...) : StringReader | provenance | MaD:3 | +| StrBuilderTextTest.java:112:52:112:58 | taint(...) : String | StrBuilderTextTest.java:112:35:112:59 | new StringReader(...) : StringReader | provenance | MaD:2 | | StrBuilderTextTest.java:113:49:113:52 | sb58 [post update] : StrBuilder | StrBuilderTextTest.java:113:77:113:80 | sb58 : StrBuilder | provenance | | | StrBuilderTextTest.java:113:63:113:68 | reader : StringReader | StrBuilderTextTest.java:113:49:113:52 | sb58 [post update] : StrBuilder | provenance | MaD:486 | -| StrBuilderTextTest.java:113:77:113:80 | sb58 : StrBuilder | StrBuilderTextTest.java:113:77:113:91 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:113:77:113:80 | sb58 : StrBuilder | StrBuilderTextTest.java:113:77:113:91 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:113:77:113:80 | sb58 : StrBuilder | StrBuilderTextTest.java:113:77:113:91 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:115:45:115:48 | sb59 [post update] : StrBuilder | StrBuilderTextTest.java:115:79:115:82 | sb59 : StrBuilder | provenance | | | StrBuilderTextTest.java:115:64:115:70 | taint(...) : String | StrBuilderTextTest.java:115:45:115:48 | sb59 [post update] : StrBuilder | provenance | MaD:488 | -| StrBuilderTextTest.java:115:79:115:82 | sb59 : StrBuilder | StrBuilderTextTest.java:115:79:115:93 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:115:79:115:82 | sb59 : StrBuilder | StrBuilderTextTest.java:115:79:115:93 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:115:79:115:82 | sb59 : StrBuilder | StrBuilderTextTest.java:115:79:115:93 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:116:45:116:48 | sb60 [post update] : StrBuilder | StrBuilderTextTest.java:116:88:116:91 | sb60 : StrBuilder | provenance | | | StrBuilderTextTest.java:116:64:116:70 | taint(...) : String | StrBuilderTextTest.java:116:45:116:48 | sb60 [post update] : StrBuilder | provenance | MaD:489 | -| StrBuilderTextTest.java:116:88:116:91 | sb60 : StrBuilder | StrBuilderTextTest.java:116:88:116:102 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:116:88:116:91 | sb60 : StrBuilder | StrBuilderTextTest.java:116:88:116:102 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:116:88:116:91 | sb60 : StrBuilder | StrBuilderTextTest.java:116:88:116:102 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:117:45:117:48 | sb61 [post update] : StrBuilder | StrBuilderTextTest.java:117:94:117:97 | sb61 : StrBuilder | provenance | | | StrBuilderTextTest.java:117:79:117:85 | taint(...) : String | StrBuilderTextTest.java:117:45:117:48 | sb61 [post update] : StrBuilder | provenance | MaD:491 | -| StrBuilderTextTest.java:117:94:117:97 | sb61 : StrBuilder | StrBuilderTextTest.java:117:94:117:108 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:117:94:117:97 | sb61 : StrBuilder | StrBuilderTextTest.java:117:94:117:108 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:117:94:117:97 | sb61 : StrBuilder | StrBuilderTextTest.java:117:94:117:108 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:118:45:118:48 | sb62 [post update] : StrBuilder | StrBuilderTextTest.java:118:86:118:89 | sb62 : StrBuilder | provenance | | | StrBuilderTextTest.java:118:71:118:77 | taint(...) : String | StrBuilderTextTest.java:118:45:118:48 | sb62 [post update] : StrBuilder | provenance | MaD:491 | -| StrBuilderTextTest.java:118:86:118:89 | sb62 : StrBuilder | StrBuilderTextTest.java:118:86:118:100 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:118:86:118:89 | sb62 : StrBuilder | StrBuilderTextTest.java:118:86:118:100 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:118:86:118:89 | sb62 : StrBuilder | StrBuilderTextTest.java:118:86:118:100 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:120:45:120:48 | sb64 [post update] : StrBuilder | StrBuilderTextTest.java:120:96:120:99 | sb64 : StrBuilder | provenance | | | StrBuilderTextTest.java:120:81:120:87 | taint(...) : String | StrBuilderTextTest.java:120:45:120:48 | sb64 [post update] : StrBuilder | provenance | MaD:493 | -| StrBuilderTextTest.java:120:96:120:99 | sb64 : StrBuilder | StrBuilderTextTest.java:120:96:120:110 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:120:96:120:99 | sb64 : StrBuilder | StrBuilderTextTest.java:120:96:120:110 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:120:96:120:99 | sb64 : StrBuilder | StrBuilderTextTest.java:120:96:120:110 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:121:45:121:48 | sb65 [post update] : StrBuilder | StrBuilderTextTest.java:121:88:121:91 | sb65 : StrBuilder | provenance | | | StrBuilderTextTest.java:121:73:121:79 | taint(...) : String | StrBuilderTextTest.java:121:45:121:48 | sb65 [post update] : StrBuilder | provenance | MaD:493 | -| StrBuilderTextTest.java:121:88:121:91 | sb65 : StrBuilder | StrBuilderTextTest.java:121:88:121:102 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:121:88:121:91 | sb65 : StrBuilder | StrBuilderTextTest.java:121:88:121:102 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:121:88:121:91 | sb65 : StrBuilder | StrBuilderTextTest.java:121:88:121:102 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:123:45:123:48 | sb67 [post update] : StrBuilder | StrBuilderTextTest.java:123:72:123:75 | sb67 : StrBuilder | provenance | | | StrBuilderTextTest.java:123:57:123:63 | taint(...) : String | StrBuilderTextTest.java:123:45:123:48 | sb67 [post update] : StrBuilder | provenance | MaD:425 | | StrBuilderTextTest.java:123:72:123:75 | sb67 : StrBuilder | StrBuilderTextTest.java:123:72:123:90 | rightString(...) | provenance | MaD:495 | | StrBuilderTextTest.java:124:45:124:48 | sb68 [post update] : StrBuilder | StrBuilderTextTest.java:124:72:124:75 | sb68 : StrBuilder | provenance | | | StrBuilderTextTest.java:124:57:124:63 | taint(...) : String | StrBuilderTextTest.java:124:45:124:48 | sb68 [post update] : StrBuilder | provenance | MaD:425 | -| StrBuilderTextTest.java:124:72:124:75 | sb68 : StrBuilder | StrBuilderTextTest.java:124:72:124:93 | subSequence(...) | provenance | MaD:5 | +| StrBuilderTextTest.java:124:72:124:75 | sb68 : StrBuilder | StrBuilderTextTest.java:124:72:124:93 | subSequence(...) | provenance | MaD:4 | | StrBuilderTextTest.java:124:72:124:75 | sb68 : StrBuilder | StrBuilderTextTest.java:124:72:124:93 | subSequence(...) | provenance | MaD:500 | | StrBuilderTextTest.java:125:45:125:48 | sb69 [post update] : StrBuilder | StrBuilderTextTest.java:125:72:125:75 | sb69 : StrBuilder | provenance | | | StrBuilderTextTest.java:125:57:125:63 | taint(...) : String | StrBuilderTextTest.java:125:45:125:48 | sb69 [post update] : StrBuilder | provenance | MaD:425 | @@ -2001,16 +2001,16 @@ edges | StrBuilderTextTest.java:130:57:130:63 | taint(...) : String | StrBuilderTextTest.java:130:45:130:48 | sb74 [post update] : StrBuilder | provenance | MaD:425 | | StrBuilderTextTest.java:130:72:130:75 | sb74 : StrBuilder | StrBuilderTextTest.java:130:72:130:93 | toStringBuilder(...) | provenance | MaD:505 | | StrBuilderTextTest.java:135:14:135:58 | append(...) : StrBuilder | StrBuilderTextTest.java:135:14:135:82 | append(...) : StrBuilder | provenance | MaD:419 | -| StrBuilderTextTest.java:135:14:135:82 | append(...) : StrBuilder | StrBuilderTextTest.java:135:14:135:93 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:135:14:135:82 | append(...) : StrBuilder | StrBuilderTextTest.java:135:14:135:93 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:135:14:135:82 | append(...) : StrBuilder | StrBuilderTextTest.java:135:14:135:93 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:135:51:135:57 | taint(...) : String | StrBuilderTextTest.java:135:14:135:58 | append(...) : StrBuilder | provenance | MaD:425+MaD:419 | | StrBuilderTextTest.java:138:9:138:45 | append(...) [post update] : StrBuilder | StrBuilderTextTest.java:139:14:139:31 | fluentBackflowTest : StrBuilder | provenance | MaD:419 | | StrBuilderTextTest.java:138:54:138:60 | taint(...) : String | StrBuilderTextTest.java:138:9:138:45 | append(...) [post update] : StrBuilder | provenance | MaD:425 | -| StrBuilderTextTest.java:139:14:139:31 | fluentBackflowTest : StrBuilder | StrBuilderTextTest.java:139:14:139:42 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:139:14:139:31 | fluentBackflowTest : StrBuilder | StrBuilderTextTest.java:139:14:139:42 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:139:14:139:31 | fluentBackflowTest : StrBuilder | StrBuilderTextTest.java:139:14:139:42 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:143:9:143:46 | append(...) [post update] : StrBuilder | StrBuilderTextTest.java:144:14:144:32 | fluentBackflowTest2 : StrBuilder | provenance | MaD:419 | | StrBuilderTextTest.java:143:55:143:61 | taint(...) : String | StrBuilderTextTest.java:143:9:143:46 | append(...) [post update] : StrBuilder | provenance | MaD:425 | -| StrBuilderTextTest.java:144:14:144:32 | fluentBackflowTest2 : StrBuilder | StrBuilderTextTest.java:144:14:144:43 | toString(...) | provenance | MaD:6 | +| StrBuilderTextTest.java:144:14:144:32 | fluentBackflowTest2 : StrBuilder | StrBuilderTextTest.java:144:14:144:43 | toString(...) | provenance | MaD:5 | | StrBuilderTextTest.java:144:14:144:32 | fluentBackflowTest2 : StrBuilder | StrBuilderTextTest.java:144:14:144:43 | toString(...) | provenance | MaD:503 | | StrBuilderTextTest.java:147:43:147:65 | new StrBuilder(...) : StrBuilder | StrBuilderTextTest.java:148:14:148:33 | fluentAllMethodsTest : StrBuilder | provenance | | | StrBuilderTextTest.java:147:58:147:64 | taint(...) : String | StrBuilderTextTest.java:147:43:147:65 | new StrBuilder(...) : StrBuilder | provenance | MaD:418 | @@ -2150,10 +2150,10 @@ edges | StrSubstitutorTest.java:51:12:51:25 | untaintedSubst : StrSubstitutor | StrSubstitutorTest.java:51:12:51:48 | replace(...) | provenance | MaD:319 | | StrSubstitutorTest.java:51:35:51:41 | taint(...) : String | StrSubstitutorTest.java:51:12:51:48 | replace(...) | provenance | MaD:332 | | StrSubstitutorTest.java:52:12:52:25 | untaintedSubst : StrSubstitutor | StrSubstitutorTest.java:52:12:52:56 | replace(...) | provenance | MaD:319 | -| StrSubstitutorTest.java:52:35:52:41 | taint(...) : String | StrSubstitutorTest.java:52:35:52:55 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrSubstitutorTest.java:52:35:52:41 | taint(...) : String | StrSubstitutorTest.java:52:35:52:55 | toCharArray(...) : char[] | provenance | MaD:7 | | StrSubstitutorTest.java:52:35:52:55 | toCharArray(...) : char[] | StrSubstitutorTest.java:52:12:52:56 | replace(...) | provenance | MaD:320 | | StrSubstitutorTest.java:53:12:53:25 | untaintedSubst : StrSubstitutor | StrSubstitutorTest.java:53:12:53:62 | replace(...) | provenance | MaD:319 | -| StrSubstitutorTest.java:53:35:53:41 | taint(...) : String | StrSubstitutorTest.java:53:35:53:55 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrSubstitutorTest.java:53:35:53:41 | taint(...) : String | StrSubstitutorTest.java:53:35:53:55 | toCharArray(...) : char[] | provenance | MaD:7 | | StrSubstitutorTest.java:53:35:53:55 | toCharArray(...) : char[] | StrSubstitutorTest.java:53:12:53:62 | replace(...) | provenance | MaD:321 | | StrSubstitutorTest.java:54:12:54:25 | untaintedSubst : StrSubstitutor | StrSubstitutorTest.java:54:12:54:56 | replace(...) | provenance | MaD:319 | | StrSubstitutorTest.java:54:35:54:55 | (...)... : String | StrSubstitutorTest.java:54:12:54:56 | replace(...) | provenance | MaD:322 | @@ -2169,16 +2169,16 @@ edges | StrSubstitutorTest.java:57:50:57:56 | taint(...) : String | StrSubstitutorTest.java:57:35:57:57 | new StrBuilder(...) : StrBuilder | provenance | MaD:226 | | StrSubstitutorTest.java:58:12:58:25 | untaintedSubst : StrSubstitutor | StrSubstitutorTest.java:58:12:58:61 | replace(...) | provenance | MaD:319 | | StrSubstitutorTest.java:58:35:58:60 | new StringBuilder(...) : StringBuilder | StrSubstitutorTest.java:58:12:58:61 | replace(...) | provenance | MaD:322 | -| StrSubstitutorTest.java:58:53:58:59 | taint(...) : String | StrSubstitutorTest.java:58:35:58:60 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | +| StrSubstitutorTest.java:58:53:58:59 | taint(...) : String | StrSubstitutorTest.java:58:35:58:60 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | | StrSubstitutorTest.java:59:12:59:25 | untaintedSubst : StrSubstitutor | StrSubstitutorTest.java:59:12:59:67 | replace(...) | provenance | MaD:319 | | StrSubstitutorTest.java:59:35:59:60 | new StringBuilder(...) : StringBuilder | StrSubstitutorTest.java:59:12:59:67 | replace(...) | provenance | MaD:323 | -| StrSubstitutorTest.java:59:53:59:59 | taint(...) : String | StrSubstitutorTest.java:59:35:59:60 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | +| StrSubstitutorTest.java:59:53:59:59 | taint(...) : String | StrSubstitutorTest.java:59:35:59:60 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | | StrSubstitutorTest.java:60:12:60:25 | untaintedSubst : StrSubstitutor | StrSubstitutorTest.java:60:12:60:60 | replace(...) | provenance | MaD:319 | | StrSubstitutorTest.java:60:35:60:59 | new StringBuffer(...) : StringBuffer | StrSubstitutorTest.java:60:12:60:60 | replace(...) | provenance | MaD:333 | -| StrSubstitutorTest.java:60:52:60:58 | taint(...) : String | StrSubstitutorTest.java:60:35:60:59 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | +| StrSubstitutorTest.java:60:52:60:58 | taint(...) : String | StrSubstitutorTest.java:60:35:60:59 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | | StrSubstitutorTest.java:61:12:61:25 | untaintedSubst : StrSubstitutor | StrSubstitutorTest.java:61:12:61:66 | replace(...) | provenance | MaD:319 | | StrSubstitutorTest.java:61:35:61:59 | new StringBuffer(...) : StringBuffer | StrSubstitutorTest.java:61:12:61:66 | replace(...) | provenance | MaD:334 | -| StrSubstitutorTest.java:61:52:61:58 | taint(...) : String | StrSubstitutorTest.java:61:35:61:59 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | +| StrSubstitutorTest.java:61:52:61:58 | taint(...) : String | StrSubstitutorTest.java:61:35:61:59 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | | StrSubstitutorTest.java:64:35:64:41 | taint(...) : String | StrSubstitutorTest.java:64:12:64:73 | replace(...) | provenance | MaD:325 | | StrSubstitutorTest.java:65:35:65:41 | taint(...) : String | StrSubstitutorTest.java:65:12:65:83 | replace(...) | provenance | MaD:327 | | StrSubstitutorTest.java:66:44:66:53 | taintedMap : HashMap [] : String | StrSubstitutorTest.java:66:12:66:54 | replace(...) | provenance | MaD:326 | @@ -2190,41 +2190,41 @@ edges | StrSubstitutorTest.java:71:44:71:55 | taintedProps : Properties [] : String | StrSubstitutorTest.java:71:12:71:56 | replace(...) | provenance | MaD:330 | | StrSubstitutorTest.java:74:50:74:61 | taintedSubst : StrSubstitutor | StrSubstitutorTest.java:74:73:74:83 | strBuilder1 [post update] : StrBuilder | provenance | MaD:341 | | StrSubstitutorTest.java:74:73:74:83 | strBuilder1 [post update] : StrBuilder | StrSubstitutorTest.java:74:92:74:102 | strBuilder1 : StrBuilder | provenance | | -| StrSubstitutorTest.java:74:92:74:102 | strBuilder1 : StrBuilder | StrSubstitutorTest.java:74:92:74:113 | toString(...) | provenance | MaD:6 | +| StrSubstitutorTest.java:74:92:74:102 | strBuilder1 : StrBuilder | StrSubstitutorTest.java:74:92:74:113 | toString(...) | provenance | MaD:5 | | StrSubstitutorTest.java:74:92:74:102 | strBuilder1 : StrBuilder | StrSubstitutorTest.java:74:92:74:113 | toString(...) | provenance | MaD:311 | | StrSubstitutorTest.java:75:50:75:61 | taintedSubst : StrSubstitutor | StrSubstitutorTest.java:75:73:75:83 | strBuilder2 [post update] : StrBuilder | provenance | MaD:342 | | StrSubstitutorTest.java:75:73:75:83 | strBuilder2 [post update] : StrBuilder | StrSubstitutorTest.java:75:98:75:108 | strBuilder2 : StrBuilder | provenance | | -| StrSubstitutorTest.java:75:98:75:108 | strBuilder2 : StrBuilder | StrSubstitutorTest.java:75:98:75:119 | toString(...) | provenance | MaD:6 | +| StrSubstitutorTest.java:75:98:75:108 | strBuilder2 : StrBuilder | StrSubstitutorTest.java:75:98:75:119 | toString(...) | provenance | MaD:5 | | StrSubstitutorTest.java:75:98:75:108 | strBuilder2 : StrBuilder | StrSubstitutorTest.java:75:98:75:119 | toString(...) | provenance | MaD:311 | | StrSubstitutorTest.java:76:59:76:70 | taintedSubst : StrSubstitutor | StrSubstitutorTest.java:76:82:76:95 | stringBuilder1 [post update] : StringBuilder | provenance | MaD:339 | | StrSubstitutorTest.java:76:82:76:95 | stringBuilder1 [post update] : StringBuilder | StrSubstitutorTest.java:76:104:76:117 | stringBuilder1 : StringBuilder | provenance | | -| StrSubstitutorTest.java:76:104:76:117 | stringBuilder1 : StringBuilder | StrSubstitutorTest.java:76:104:76:128 | toString(...) | provenance | MaD:6 | +| StrSubstitutorTest.java:76:104:76:117 | stringBuilder1 : StringBuilder | StrSubstitutorTest.java:76:104:76:128 | toString(...) | provenance | MaD:5 | | StrSubstitutorTest.java:77:59:77:70 | taintedSubst : StrSubstitutor | StrSubstitutorTest.java:77:82:77:95 | stringBuilder2 [post update] : StringBuilder | provenance | MaD:340 | | StrSubstitutorTest.java:77:82:77:95 | stringBuilder2 [post update] : StringBuilder | StrSubstitutorTest.java:77:110:77:123 | stringBuilder2 : StringBuilder | provenance | | -| StrSubstitutorTest.java:77:110:77:123 | stringBuilder2 : StringBuilder | StrSubstitutorTest.java:77:110:77:134 | toString(...) | provenance | MaD:6 | +| StrSubstitutorTest.java:77:110:77:123 | stringBuilder2 : StringBuilder | StrSubstitutorTest.java:77:110:77:134 | toString(...) | provenance | MaD:5 | | StrSubstitutorTest.java:78:56:78:67 | taintedSubst : StrSubstitutor | StrSubstitutorTest.java:78:79:78:91 | stringBuffer1 [post update] : StringBuffer | provenance | MaD:337 | | StrSubstitutorTest.java:78:79:78:91 | stringBuffer1 [post update] : StringBuffer | StrSubstitutorTest.java:78:100:78:112 | stringBuffer1 : StringBuffer | provenance | | -| StrSubstitutorTest.java:78:100:78:112 | stringBuffer1 : StringBuffer | StrSubstitutorTest.java:78:100:78:123 | toString(...) | provenance | MaD:6 | +| StrSubstitutorTest.java:78:100:78:112 | stringBuffer1 : StringBuffer | StrSubstitutorTest.java:78:100:78:123 | toString(...) | provenance | MaD:5 | | StrSubstitutorTest.java:79:56:79:67 | taintedSubst : StrSubstitutor | StrSubstitutorTest.java:79:79:79:91 | stringBuffer2 [post update] : StringBuffer | provenance | MaD:338 | | StrSubstitutorTest.java:79:79:79:91 | stringBuffer2 [post update] : StringBuffer | StrSubstitutorTest.java:79:106:79:118 | stringBuffer2 : StringBuffer | provenance | | -| StrSubstitutorTest.java:79:106:79:118 | stringBuffer2 : StringBuffer | StrSubstitutorTest.java:79:106:79:129 | toString(...) | provenance | MaD:6 | +| StrSubstitutorTest.java:79:106:79:118 | stringBuffer2 : StringBuffer | StrSubstitutorTest.java:79:106:79:129 | toString(...) | provenance | MaD:5 | | StrTokenizerTest.java:12:11:12:49 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTest.java:12:10:12:61 | toString(...) | provenance | MaD:356 | -| StrTokenizerTest.java:12:28:12:34 | taint(...) : String | StrTokenizerTest.java:12:28:12:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTest.java:12:28:12:34 | taint(...) : String | StrTokenizerTest.java:12:28:12:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTest.java:12:28:12:48 | toCharArray(...) : char[] | StrTokenizerTest.java:12:11:12:49 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:344 | | StrTokenizerTest.java:13:11:13:54 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTest.java:13:10:13:66 | toString(...) | provenance | MaD:356 | -| StrTokenizerTest.java:13:28:13:34 | taint(...) : String | StrTokenizerTest.java:13:28:13:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTest.java:13:28:13:34 | taint(...) : String | StrTokenizerTest.java:13:28:13:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTest.java:13:28:13:48 | toCharArray(...) : char[] | StrTokenizerTest.java:13:11:13:54 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:344 | | StrTokenizerTest.java:14:11:14:59 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTest.java:14:10:14:71 | toString(...) | provenance | MaD:356 | -| StrTokenizerTest.java:14:28:14:34 | taint(...) : String | StrTokenizerTest.java:14:28:14:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTest.java:14:28:14:34 | taint(...) : String | StrTokenizerTest.java:14:28:14:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTest.java:14:28:14:48 | toCharArray(...) : char[] | StrTokenizerTest.java:14:11:14:59 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:344 | | StrTokenizerTest.java:15:11:15:54 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTest.java:15:10:15:66 | toString(...) | provenance | MaD:356 | -| StrTokenizerTest.java:15:28:15:34 | taint(...) : String | StrTokenizerTest.java:15:28:15:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTest.java:15:28:15:34 | taint(...) : String | StrTokenizerTest.java:15:28:15:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTest.java:15:28:15:48 | toCharArray(...) : char[] | StrTokenizerTest.java:15:11:15:54 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:344 | | StrTokenizerTest.java:16:11:16:67 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTest.java:16:10:16:79 | toString(...) | provenance | MaD:356 | -| StrTokenizerTest.java:16:28:16:34 | taint(...) : String | StrTokenizerTest.java:16:28:16:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTest.java:16:28:16:34 | taint(...) : String | StrTokenizerTest.java:16:28:16:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTest.java:16:28:16:48 | toCharArray(...) : char[] | StrTokenizerTest.java:16:11:16:67 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:344 | | StrTokenizerTest.java:17:11:17:85 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTest.java:17:10:17:97 | toString(...) | provenance | MaD:356 | -| StrTokenizerTest.java:17:28:17:34 | taint(...) : String | StrTokenizerTest.java:17:28:17:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTest.java:17:28:17:34 | taint(...) : String | StrTokenizerTest.java:17:28:17:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTest.java:17:28:17:48 | toCharArray(...) : char[] | StrTokenizerTest.java:17:11:17:85 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:344 | | StrTokenizerTest.java:18:11:18:35 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTest.java:18:10:18:47 | toString(...) | provenance | MaD:356 | | StrTokenizerTest.java:18:28:18:34 | taint(...) : String | StrTokenizerTest.java:18:11:18:35 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:344 | @@ -2239,12 +2239,12 @@ edges | StrTokenizerTest.java:23:11:23:71 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTest.java:23:10:23:83 | toString(...) | provenance | MaD:356 | | StrTokenizerTest.java:23:28:23:34 | taint(...) : String | StrTokenizerTest.java:23:11:23:71 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:344 | | StrTokenizerTest.java:26:10:26:59 | getCSVInstance(...) : StrTokenizer | StrTokenizerTest.java:26:10:26:70 | toString(...) | provenance | MaD:356 | -| StrTokenizerTest.java:26:38:26:44 | taint(...) : String | StrTokenizerTest.java:26:38:26:58 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTest.java:26:38:26:44 | taint(...) : String | StrTokenizerTest.java:26:38:26:58 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTest.java:26:38:26:58 | toCharArray(...) : char[] | StrTokenizerTest.java:26:10:26:59 | getCSVInstance(...) : StrTokenizer | provenance | MaD:346 | | StrTokenizerTest.java:27:10:27:45 | getCSVInstance(...) : StrTokenizer | StrTokenizerTest.java:27:10:27:56 | toString(...) | provenance | MaD:356 | | StrTokenizerTest.java:27:38:27:44 | taint(...) : String | StrTokenizerTest.java:27:10:27:45 | getCSVInstance(...) : StrTokenizer | provenance | MaD:346 | | StrTokenizerTest.java:28:10:28:59 | getTSVInstance(...) : StrTokenizer | StrTokenizerTest.java:28:10:28:70 | toString(...) | provenance | MaD:356 | -| StrTokenizerTest.java:28:38:28:44 | taint(...) : String | StrTokenizerTest.java:28:38:28:58 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTest.java:28:38:28:44 | taint(...) : String | StrTokenizerTest.java:28:38:28:58 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTest.java:28:38:28:58 | toCharArray(...) : char[] | StrTokenizerTest.java:28:10:28:59 | getTSVInstance(...) : StrTokenizer | provenance | MaD:348 | | StrTokenizerTest.java:29:10:29:45 | getTSVInstance(...) : StrTokenizer | StrTokenizerTest.java:29:10:29:56 | toString(...) | provenance | MaD:356 | | StrTokenizerTest.java:29:38:29:44 | taint(...) : String | StrTokenizerTest.java:29:10:29:45 | getTSVInstance(...) : StrTokenizer | provenance | MaD:348 | @@ -2268,27 +2268,27 @@ edges | StrTokenizerTest.java:39:11:39:35 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTest.java:39:10:39:52 | previousToken(...) | provenance | MaD:354 | | StrTokenizerTest.java:39:28:39:34 | taint(...) : String | StrTokenizerTest.java:39:11:39:35 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:344 | | StrTokenizerTest.java:42:10:42:58 | reset(...) : StrTokenizer | StrTokenizerTest.java:42:10:42:69 | toString(...) | provenance | MaD:356 | -| StrTokenizerTest.java:42:37:42:43 | taint(...) : String | StrTokenizerTest.java:42:37:42:57 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTest.java:42:37:42:43 | taint(...) : String | StrTokenizerTest.java:42:37:42:57 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTest.java:42:37:42:57 | toCharArray(...) : char[] | StrTokenizerTest.java:42:10:42:58 | reset(...) : StrTokenizer | provenance | MaD:355 | | StrTokenizerTest.java:43:10:43:44 | reset(...) : StrTokenizer | StrTokenizerTest.java:43:10:43:55 | toString(...) | provenance | MaD:356 | | StrTokenizerTest.java:43:37:43:43 | taint(...) : String | StrTokenizerTest.java:43:10:43:44 | reset(...) : StrTokenizer | provenance | MaD:355 | | StrTokenizerTextTest.java:12:11:12:49 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTextTest.java:12:10:12:61 | toString(...) | provenance | MaD:519 | -| StrTokenizerTextTest.java:12:28:12:34 | taint(...) : String | StrTokenizerTextTest.java:12:28:12:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTextTest.java:12:28:12:34 | taint(...) : String | StrTokenizerTextTest.java:12:28:12:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTextTest.java:12:28:12:48 | toCharArray(...) : char[] | StrTokenizerTextTest.java:12:11:12:49 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:507 | | StrTokenizerTextTest.java:13:11:13:54 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTextTest.java:13:10:13:66 | toString(...) | provenance | MaD:519 | -| StrTokenizerTextTest.java:13:28:13:34 | taint(...) : String | StrTokenizerTextTest.java:13:28:13:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTextTest.java:13:28:13:34 | taint(...) : String | StrTokenizerTextTest.java:13:28:13:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTextTest.java:13:28:13:48 | toCharArray(...) : char[] | StrTokenizerTextTest.java:13:11:13:54 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:507 | | StrTokenizerTextTest.java:14:11:14:59 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTextTest.java:14:10:14:71 | toString(...) | provenance | MaD:519 | -| StrTokenizerTextTest.java:14:28:14:34 | taint(...) : String | StrTokenizerTextTest.java:14:28:14:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTextTest.java:14:28:14:34 | taint(...) : String | StrTokenizerTextTest.java:14:28:14:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTextTest.java:14:28:14:48 | toCharArray(...) : char[] | StrTokenizerTextTest.java:14:11:14:59 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:507 | | StrTokenizerTextTest.java:15:11:15:54 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTextTest.java:15:10:15:66 | toString(...) | provenance | MaD:519 | -| StrTokenizerTextTest.java:15:28:15:34 | taint(...) : String | StrTokenizerTextTest.java:15:28:15:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTextTest.java:15:28:15:34 | taint(...) : String | StrTokenizerTextTest.java:15:28:15:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTextTest.java:15:28:15:48 | toCharArray(...) : char[] | StrTokenizerTextTest.java:15:11:15:54 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:507 | | StrTokenizerTextTest.java:16:11:16:67 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTextTest.java:16:10:16:79 | toString(...) | provenance | MaD:519 | -| StrTokenizerTextTest.java:16:28:16:34 | taint(...) : String | StrTokenizerTextTest.java:16:28:16:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTextTest.java:16:28:16:34 | taint(...) : String | StrTokenizerTextTest.java:16:28:16:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTextTest.java:16:28:16:48 | toCharArray(...) : char[] | StrTokenizerTextTest.java:16:11:16:67 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:507 | | StrTokenizerTextTest.java:17:11:17:85 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTextTest.java:17:10:17:97 | toString(...) | provenance | MaD:519 | -| StrTokenizerTextTest.java:17:28:17:34 | taint(...) : String | StrTokenizerTextTest.java:17:28:17:48 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTextTest.java:17:28:17:34 | taint(...) : String | StrTokenizerTextTest.java:17:28:17:48 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTextTest.java:17:28:17:48 | toCharArray(...) : char[] | StrTokenizerTextTest.java:17:11:17:85 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:507 | | StrTokenizerTextTest.java:18:11:18:35 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTextTest.java:18:10:18:47 | toString(...) | provenance | MaD:519 | | StrTokenizerTextTest.java:18:28:18:34 | taint(...) : String | StrTokenizerTextTest.java:18:11:18:35 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:507 | @@ -2303,12 +2303,12 @@ edges | StrTokenizerTextTest.java:23:11:23:71 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTextTest.java:23:10:23:83 | toString(...) | provenance | MaD:519 | | StrTokenizerTextTest.java:23:28:23:34 | taint(...) : String | StrTokenizerTextTest.java:23:11:23:71 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:507 | | StrTokenizerTextTest.java:26:10:26:59 | getCSVInstance(...) : StrTokenizer | StrTokenizerTextTest.java:26:10:26:70 | toString(...) | provenance | MaD:519 | -| StrTokenizerTextTest.java:26:38:26:44 | taint(...) : String | StrTokenizerTextTest.java:26:38:26:58 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTextTest.java:26:38:26:44 | taint(...) : String | StrTokenizerTextTest.java:26:38:26:58 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTextTest.java:26:38:26:58 | toCharArray(...) : char[] | StrTokenizerTextTest.java:26:10:26:59 | getCSVInstance(...) : StrTokenizer | provenance | MaD:509 | | StrTokenizerTextTest.java:27:10:27:45 | getCSVInstance(...) : StrTokenizer | StrTokenizerTextTest.java:27:10:27:56 | toString(...) | provenance | MaD:519 | | StrTokenizerTextTest.java:27:38:27:44 | taint(...) : String | StrTokenizerTextTest.java:27:10:27:45 | getCSVInstance(...) : StrTokenizer | provenance | MaD:509 | | StrTokenizerTextTest.java:28:10:28:59 | getTSVInstance(...) : StrTokenizer | StrTokenizerTextTest.java:28:10:28:70 | toString(...) | provenance | MaD:519 | -| StrTokenizerTextTest.java:28:38:28:44 | taint(...) : String | StrTokenizerTextTest.java:28:38:28:58 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTextTest.java:28:38:28:44 | taint(...) : String | StrTokenizerTextTest.java:28:38:28:58 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTextTest.java:28:38:28:58 | toCharArray(...) : char[] | StrTokenizerTextTest.java:28:10:28:59 | getTSVInstance(...) : StrTokenizer | provenance | MaD:511 | | StrTokenizerTextTest.java:29:10:29:45 | getTSVInstance(...) : StrTokenizer | StrTokenizerTextTest.java:29:10:29:56 | toString(...) | provenance | MaD:519 | | StrTokenizerTextTest.java:29:38:29:44 | taint(...) : String | StrTokenizerTextTest.java:29:10:29:45 | getTSVInstance(...) : StrTokenizer | provenance | MaD:511 | @@ -2332,7 +2332,7 @@ edges | StrTokenizerTextTest.java:39:11:39:35 | new StrTokenizer(...) : StrTokenizer | StrTokenizerTextTest.java:39:10:39:52 | previousToken(...) | provenance | MaD:517 | | StrTokenizerTextTest.java:39:28:39:34 | taint(...) : String | StrTokenizerTextTest.java:39:11:39:35 | new StrTokenizer(...) : StrTokenizer | provenance | MaD:507 | | StrTokenizerTextTest.java:42:10:42:58 | reset(...) : StrTokenizer | StrTokenizerTextTest.java:42:10:42:69 | toString(...) | provenance | MaD:519 | -| StrTokenizerTextTest.java:42:37:42:43 | taint(...) : String | StrTokenizerTextTest.java:42:37:42:57 | toCharArray(...) : char[] | provenance | MaD:8 | +| StrTokenizerTextTest.java:42:37:42:43 | taint(...) : String | StrTokenizerTextTest.java:42:37:42:57 | toCharArray(...) : char[] | provenance | MaD:7 | | StrTokenizerTextTest.java:42:37:42:57 | toCharArray(...) : char[] | StrTokenizerTextTest.java:42:10:42:58 | reset(...) : StrTokenizer | provenance | MaD:518 | | StrTokenizerTextTest.java:43:10:43:44 | reset(...) : StrTokenizer | StrTokenizerTextTest.java:43:10:43:55 | toString(...) | provenance | MaD:519 | | StrTokenizerTextTest.java:43:37:43:43 | taint(...) : String | StrTokenizerTextTest.java:43:10:43:44 | reset(...) : StrTokenizer | provenance | MaD:518 | @@ -2445,10 +2445,10 @@ edges | StringSubstitutorTextTest.java:52:12:52:25 | untaintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:52:12:52:48 | replace(...) | provenance | MaD:522 | | StringSubstitutorTextTest.java:52:35:52:41 | taint(...) : String | StringSubstitutorTextTest.java:52:12:52:48 | replace(...) | provenance | MaD:535 | | StringSubstitutorTextTest.java:53:12:53:25 | untaintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:53:12:53:56 | replace(...) | provenance | MaD:522 | -| StringSubstitutorTextTest.java:53:35:53:41 | taint(...) : String | StringSubstitutorTextTest.java:53:35:53:55 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringSubstitutorTextTest.java:53:35:53:41 | taint(...) : String | StringSubstitutorTextTest.java:53:35:53:55 | toCharArray(...) : char[] | provenance | MaD:7 | | StringSubstitutorTextTest.java:53:35:53:55 | toCharArray(...) : char[] | StringSubstitutorTextTest.java:53:12:53:56 | replace(...) | provenance | MaD:523 | | StringSubstitutorTextTest.java:54:12:54:25 | untaintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:54:12:54:62 | replace(...) | provenance | MaD:522 | -| StringSubstitutorTextTest.java:54:35:54:41 | taint(...) : String | StringSubstitutorTextTest.java:54:35:54:55 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringSubstitutorTextTest.java:54:35:54:41 | taint(...) : String | StringSubstitutorTextTest.java:54:35:54:55 | toCharArray(...) : char[] | provenance | MaD:7 | | StringSubstitutorTextTest.java:54:35:54:55 | toCharArray(...) : char[] | StringSubstitutorTextTest.java:54:12:54:62 | replace(...) | provenance | MaD:524 | | StringSubstitutorTextTest.java:55:12:55:25 | untaintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:55:12:55:56 | replace(...) | provenance | MaD:522 | | StringSubstitutorTextTest.java:55:35:55:55 | (...)... : String | StringSubstitutorTextTest.java:55:12:55:56 | replace(...) | provenance | MaD:525 | @@ -2464,16 +2464,16 @@ edges | StringSubstitutorTextTest.java:58:57:58:63 | taint(...) : String | StringSubstitutorTextTest.java:58:35:58:64 | new TextStringBuilder(...) : TextStringBuilder | provenance | MaD:561 | | StringSubstitutorTextTest.java:59:12:59:25 | untaintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:59:12:59:61 | replace(...) | provenance | MaD:522 | | StringSubstitutorTextTest.java:59:35:59:60 | new StringBuilder(...) : StringBuilder | StringSubstitutorTextTest.java:59:12:59:61 | replace(...) | provenance | MaD:525 | -| StringSubstitutorTextTest.java:59:53:59:59 | taint(...) : String | StringSubstitutorTextTest.java:59:35:59:60 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | +| StringSubstitutorTextTest.java:59:53:59:59 | taint(...) : String | StringSubstitutorTextTest.java:59:35:59:60 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | | StringSubstitutorTextTest.java:60:12:60:25 | untaintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:60:12:60:67 | replace(...) | provenance | MaD:522 | | StringSubstitutorTextTest.java:60:35:60:60 | new StringBuilder(...) : StringBuilder | StringSubstitutorTextTest.java:60:12:60:67 | replace(...) | provenance | MaD:526 | -| StringSubstitutorTextTest.java:60:53:60:59 | taint(...) : String | StringSubstitutorTextTest.java:60:35:60:60 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | +| StringSubstitutorTextTest.java:60:53:60:59 | taint(...) : String | StringSubstitutorTextTest.java:60:35:60:60 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | | StringSubstitutorTextTest.java:61:12:61:25 | untaintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:61:12:61:60 | replace(...) | provenance | MaD:522 | | StringSubstitutorTextTest.java:61:35:61:59 | new StringBuffer(...) : StringBuffer | StringSubstitutorTextTest.java:61:12:61:60 | replace(...) | provenance | MaD:536 | -| StringSubstitutorTextTest.java:61:52:61:58 | taint(...) : String | StringSubstitutorTextTest.java:61:35:61:59 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | +| StringSubstitutorTextTest.java:61:52:61:58 | taint(...) : String | StringSubstitutorTextTest.java:61:35:61:59 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | | StringSubstitutorTextTest.java:62:12:62:25 | untaintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:62:12:62:66 | replace(...) | provenance | MaD:522 | | StringSubstitutorTextTest.java:62:35:62:59 | new StringBuffer(...) : StringBuffer | StringSubstitutorTextTest.java:62:12:62:66 | replace(...) | provenance | MaD:537 | -| StringSubstitutorTextTest.java:62:52:62:58 | taint(...) : String | StringSubstitutorTextTest.java:62:35:62:59 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | +| StringSubstitutorTextTest.java:62:52:62:58 | taint(...) : String | StringSubstitutorTextTest.java:62:35:62:59 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | | StringSubstitutorTextTest.java:65:38:65:44 | taint(...) : String | StringSubstitutorTextTest.java:65:12:65:76 | replace(...) | provenance | MaD:528 | | StringSubstitutorTextTest.java:66:38:66:44 | taint(...) : String | StringSubstitutorTextTest.java:66:12:66:86 | replace(...) | provenance | MaD:530 | | StringSubstitutorTextTest.java:67:47:67:56 | taintedMap : HashMap [] : String | StringSubstitutorTextTest.java:67:12:67:57 | replace(...) | provenance | MaD:529 | @@ -2485,41 +2485,41 @@ edges | StringSubstitutorTextTest.java:72:47:72:58 | taintedProps : Properties [] : String | StringSubstitutorTextTest.java:72:12:72:59 | replace(...) | provenance | MaD:533 | | StringSubstitutorTextTest.java:75:64:75:75 | taintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:75:87:75:97 | strBuilder1 [post update] : TextStringBuilder | provenance | MaD:544 | | StringSubstitutorTextTest.java:75:87:75:97 | strBuilder1 [post update] : TextStringBuilder | StringSubstitutorTextTest.java:75:106:75:116 | strBuilder1 : TextStringBuilder | provenance | | -| StringSubstitutorTextTest.java:75:106:75:116 | strBuilder1 : TextStringBuilder | StringSubstitutorTextTest.java:75:106:75:127 | toString(...) | provenance | MaD:6 | +| StringSubstitutorTextTest.java:75:106:75:116 | strBuilder1 : TextStringBuilder | StringSubstitutorTextTest.java:75:106:75:127 | toString(...) | provenance | MaD:5 | | StringSubstitutorTextTest.java:75:106:75:116 | strBuilder1 : TextStringBuilder | StringSubstitutorTextTest.java:75:106:75:127 | toString(...) | provenance | MaD:646 | | StringSubstitutorTextTest.java:76:64:76:75 | taintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:76:87:76:97 | strBuilder2 [post update] : TextStringBuilder | provenance | MaD:545 | | StringSubstitutorTextTest.java:76:87:76:97 | strBuilder2 [post update] : TextStringBuilder | StringSubstitutorTextTest.java:76:112:76:122 | strBuilder2 : TextStringBuilder | provenance | | -| StringSubstitutorTextTest.java:76:112:76:122 | strBuilder2 : TextStringBuilder | StringSubstitutorTextTest.java:76:112:76:133 | toString(...) | provenance | MaD:6 | +| StringSubstitutorTextTest.java:76:112:76:122 | strBuilder2 : TextStringBuilder | StringSubstitutorTextTest.java:76:112:76:133 | toString(...) | provenance | MaD:5 | | StringSubstitutorTextTest.java:76:112:76:122 | strBuilder2 : TextStringBuilder | StringSubstitutorTextTest.java:76:112:76:133 | toString(...) | provenance | MaD:646 | | StringSubstitutorTextTest.java:77:59:77:70 | taintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:77:82:77:95 | stringBuilder1 [post update] : StringBuilder | provenance | MaD:542 | | StringSubstitutorTextTest.java:77:82:77:95 | stringBuilder1 [post update] : StringBuilder | StringSubstitutorTextTest.java:77:104:77:117 | stringBuilder1 : StringBuilder | provenance | | -| StringSubstitutorTextTest.java:77:104:77:117 | stringBuilder1 : StringBuilder | StringSubstitutorTextTest.java:77:104:77:128 | toString(...) | provenance | MaD:6 | +| StringSubstitutorTextTest.java:77:104:77:117 | stringBuilder1 : StringBuilder | StringSubstitutorTextTest.java:77:104:77:128 | toString(...) | provenance | MaD:5 | | StringSubstitutorTextTest.java:78:59:78:70 | taintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:78:82:78:95 | stringBuilder2 [post update] : StringBuilder | provenance | MaD:543 | | StringSubstitutorTextTest.java:78:82:78:95 | stringBuilder2 [post update] : StringBuilder | StringSubstitutorTextTest.java:78:110:78:123 | stringBuilder2 : StringBuilder | provenance | | -| StringSubstitutorTextTest.java:78:110:78:123 | stringBuilder2 : StringBuilder | StringSubstitutorTextTest.java:78:110:78:134 | toString(...) | provenance | MaD:6 | +| StringSubstitutorTextTest.java:78:110:78:123 | stringBuilder2 : StringBuilder | StringSubstitutorTextTest.java:78:110:78:134 | toString(...) | provenance | MaD:5 | | StringSubstitutorTextTest.java:79:56:79:67 | taintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:79:79:79:91 | stringBuffer1 [post update] : StringBuffer | provenance | MaD:540 | | StringSubstitutorTextTest.java:79:79:79:91 | stringBuffer1 [post update] : StringBuffer | StringSubstitutorTextTest.java:79:100:79:112 | stringBuffer1 : StringBuffer | provenance | | -| StringSubstitutorTextTest.java:79:100:79:112 | stringBuffer1 : StringBuffer | StringSubstitutorTextTest.java:79:100:79:123 | toString(...) | provenance | MaD:6 | +| StringSubstitutorTextTest.java:79:100:79:112 | stringBuffer1 : StringBuffer | StringSubstitutorTextTest.java:79:100:79:123 | toString(...) | provenance | MaD:5 | | StringSubstitutorTextTest.java:80:56:80:67 | taintedSubst : StringSubstitutor | StringSubstitutorTextTest.java:80:79:80:91 | stringBuffer2 [post update] : StringBuffer | provenance | MaD:541 | | StringSubstitutorTextTest.java:80:79:80:91 | stringBuffer2 [post update] : StringBuffer | StringSubstitutorTextTest.java:80:106:80:118 | stringBuffer2 : StringBuffer | provenance | | -| StringSubstitutorTextTest.java:80:106:80:118 | stringBuffer2 : StringBuffer | StringSubstitutorTextTest.java:80:106:80:129 | toString(...) | provenance | MaD:6 | +| StringSubstitutorTextTest.java:80:106:80:118 | stringBuffer2 : StringBuffer | StringSubstitutorTextTest.java:80:106:80:129 | toString(...) | provenance | MaD:5 | | StringTokenizerTest.java:12:11:12:52 | new StringTokenizer(...) : StringTokenizer | StringTokenizerTest.java:12:10:12:64 | toString(...) | provenance | MaD:559 | -| StringTokenizerTest.java:12:31:12:37 | taint(...) : String | StringTokenizerTest.java:12:31:12:51 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringTokenizerTest.java:12:31:12:37 | taint(...) : String | StringTokenizerTest.java:12:31:12:51 | toCharArray(...) : char[] | provenance | MaD:7 | | StringTokenizerTest.java:12:31:12:51 | toCharArray(...) : char[] | StringTokenizerTest.java:12:11:12:52 | new StringTokenizer(...) : StringTokenizer | provenance | MaD:547 | | StringTokenizerTest.java:13:11:13:57 | new StringTokenizer(...) : StringTokenizer | StringTokenizerTest.java:13:10:13:69 | toString(...) | provenance | MaD:559 | -| StringTokenizerTest.java:13:31:13:37 | taint(...) : String | StringTokenizerTest.java:13:31:13:51 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringTokenizerTest.java:13:31:13:37 | taint(...) : String | StringTokenizerTest.java:13:31:13:51 | toCharArray(...) : char[] | provenance | MaD:7 | | StringTokenizerTest.java:13:31:13:51 | toCharArray(...) : char[] | StringTokenizerTest.java:13:11:13:57 | new StringTokenizer(...) : StringTokenizer | provenance | MaD:547 | | StringTokenizerTest.java:14:11:14:62 | new StringTokenizer(...) : StringTokenizer | StringTokenizerTest.java:14:10:14:74 | toString(...) | provenance | MaD:559 | -| StringTokenizerTest.java:14:31:14:37 | taint(...) : String | StringTokenizerTest.java:14:31:14:51 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringTokenizerTest.java:14:31:14:37 | taint(...) : String | StringTokenizerTest.java:14:31:14:51 | toCharArray(...) : char[] | provenance | MaD:7 | | StringTokenizerTest.java:14:31:14:51 | toCharArray(...) : char[] | StringTokenizerTest.java:14:11:14:62 | new StringTokenizer(...) : StringTokenizer | provenance | MaD:547 | | StringTokenizerTest.java:15:11:15:57 | new StringTokenizer(...) : StringTokenizer | StringTokenizerTest.java:15:10:15:69 | toString(...) | provenance | MaD:559 | -| StringTokenizerTest.java:15:31:15:37 | taint(...) : String | StringTokenizerTest.java:15:31:15:51 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringTokenizerTest.java:15:31:15:37 | taint(...) : String | StringTokenizerTest.java:15:31:15:51 | toCharArray(...) : char[] | provenance | MaD:7 | | StringTokenizerTest.java:15:31:15:51 | toCharArray(...) : char[] | StringTokenizerTest.java:15:11:15:57 | new StringTokenizer(...) : StringTokenizer | provenance | MaD:547 | | StringTokenizerTest.java:16:11:16:73 | new StringTokenizer(...) : StringTokenizer | StringTokenizerTest.java:16:10:16:85 | toString(...) | provenance | MaD:559 | -| StringTokenizerTest.java:16:31:16:37 | taint(...) : String | StringTokenizerTest.java:16:31:16:51 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringTokenizerTest.java:16:31:16:37 | taint(...) : String | StringTokenizerTest.java:16:31:16:51 | toCharArray(...) : char[] | provenance | MaD:7 | | StringTokenizerTest.java:16:31:16:51 | toCharArray(...) : char[] | StringTokenizerTest.java:16:11:16:73 | new StringTokenizer(...) : StringTokenizer | provenance | MaD:547 | | StringTokenizerTest.java:17:11:17:94 | new StringTokenizer(...) : StringTokenizer | StringTokenizerTest.java:17:10:17:106 | toString(...) | provenance | MaD:559 | -| StringTokenizerTest.java:17:31:17:37 | taint(...) : String | StringTokenizerTest.java:17:31:17:51 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringTokenizerTest.java:17:31:17:37 | taint(...) : String | StringTokenizerTest.java:17:31:17:51 | toCharArray(...) : char[] | provenance | MaD:7 | | StringTokenizerTest.java:17:31:17:51 | toCharArray(...) : char[] | StringTokenizerTest.java:17:11:17:94 | new StringTokenizer(...) : StringTokenizer | provenance | MaD:547 | | StringTokenizerTest.java:18:11:18:38 | new StringTokenizer(...) : StringTokenizer | StringTokenizerTest.java:18:10:18:50 | toString(...) | provenance | MaD:559 | | StringTokenizerTest.java:18:31:18:37 | taint(...) : String | StringTokenizerTest.java:18:11:18:38 | new StringTokenizer(...) : StringTokenizer | provenance | MaD:547 | @@ -2534,12 +2534,12 @@ edges | StringTokenizerTest.java:23:11:23:80 | new StringTokenizer(...) : StringTokenizer | StringTokenizerTest.java:23:10:23:92 | toString(...) | provenance | MaD:559 | | StringTokenizerTest.java:23:31:23:37 | taint(...) : String | StringTokenizerTest.java:23:11:23:80 | new StringTokenizer(...) : StringTokenizer | provenance | MaD:547 | | StringTokenizerTest.java:26:10:26:62 | getCSVInstance(...) : StringTokenizer | StringTokenizerTest.java:26:10:26:73 | toString(...) | provenance | MaD:559 | -| StringTokenizerTest.java:26:41:26:47 | taint(...) : String | StringTokenizerTest.java:26:41:26:61 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringTokenizerTest.java:26:41:26:47 | taint(...) : String | StringTokenizerTest.java:26:41:26:61 | toCharArray(...) : char[] | provenance | MaD:7 | | StringTokenizerTest.java:26:41:26:61 | toCharArray(...) : char[] | StringTokenizerTest.java:26:10:26:62 | getCSVInstance(...) : StringTokenizer | provenance | MaD:549 | | StringTokenizerTest.java:27:10:27:48 | getCSVInstance(...) : StringTokenizer | StringTokenizerTest.java:27:10:27:59 | toString(...) | provenance | MaD:559 | | StringTokenizerTest.java:27:41:27:47 | taint(...) : String | StringTokenizerTest.java:27:10:27:48 | getCSVInstance(...) : StringTokenizer | provenance | MaD:549 | | StringTokenizerTest.java:28:10:28:62 | getTSVInstance(...) : StringTokenizer | StringTokenizerTest.java:28:10:28:73 | toString(...) | provenance | MaD:559 | -| StringTokenizerTest.java:28:41:28:47 | taint(...) : String | StringTokenizerTest.java:28:41:28:61 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringTokenizerTest.java:28:41:28:47 | taint(...) : String | StringTokenizerTest.java:28:41:28:61 | toCharArray(...) : char[] | provenance | MaD:7 | | StringTokenizerTest.java:28:41:28:61 | toCharArray(...) : char[] | StringTokenizerTest.java:28:10:28:62 | getTSVInstance(...) : StringTokenizer | provenance | MaD:551 | | StringTokenizerTest.java:29:10:29:48 | getTSVInstance(...) : StringTokenizer | StringTokenizerTest.java:29:10:29:59 | toString(...) | provenance | MaD:559 | | StringTokenizerTest.java:29:41:29:47 | taint(...) : String | StringTokenizerTest.java:29:10:29:48 | getTSVInstance(...) : StringTokenizer | provenance | MaD:551 | @@ -2563,7 +2563,7 @@ edges | StringTokenizerTest.java:39:11:39:38 | new StringTokenizer(...) : StringTokenizer | StringTokenizerTest.java:39:10:39:55 | previousToken(...) | provenance | MaD:557 | | StringTokenizerTest.java:39:31:39:37 | taint(...) : String | StringTokenizerTest.java:39:11:39:38 | new StringTokenizer(...) : StringTokenizer | provenance | MaD:547 | | StringTokenizerTest.java:42:10:42:61 | reset(...) : StringTokenizer | StringTokenizerTest.java:42:10:42:72 | toString(...) | provenance | MaD:559 | -| StringTokenizerTest.java:42:40:42:46 | taint(...) : String | StringTokenizerTest.java:42:40:42:60 | toCharArray(...) : char[] | provenance | MaD:8 | +| StringTokenizerTest.java:42:40:42:46 | taint(...) : String | StringTokenizerTest.java:42:40:42:60 | toCharArray(...) : char[] | provenance | MaD:7 | | StringTokenizerTest.java:42:40:42:60 | toCharArray(...) : char[] | StringTokenizerTest.java:42:10:42:61 | reset(...) : StringTokenizer | provenance | MaD:558 | | StringTokenizerTest.java:43:10:43:47 | reset(...) : StringTokenizer | StringTokenizerTest.java:43:10:43:58 | toString(...) | provenance | MaD:559 | | StringTokenizerTest.java:43:40:43:46 | taint(...) : String | StringTokenizerTest.java:43:10:43:47 | reset(...) : StringTokenizer | provenance | MaD:558 | @@ -2614,9 +2614,9 @@ edges | Test.java:63:36:63:42 | taint(...) : String | Test.java:63:14:63:43 | getDigits(...) | provenance | MaD:104 | | Test.java:64:37:64:43 | taint(...) : String | Test.java:64:14:64:61 | getIfBlank(...) | provenance | MaD:105 | | Test.java:65:37:65:43 | taint(...) : String | Test.java:65:14:65:61 | getIfEmpty(...) | provenance | MaD:106 | -| Test.java:73:31:73:37 | taint(...) : String | Test.java:73:31:73:51 | toCharArray(...) : char[] | provenance | MaD:8 | +| Test.java:73:31:73:37 | taint(...) : String | Test.java:73:31:73:51 | toCharArray(...) : char[] | provenance | MaD:7 | | Test.java:73:31:73:51 | toCharArray(...) : char[] | Test.java:73:14:73:57 | join(...) | provenance | MaD:107 | -| Test.java:74:31:74:37 | taint(...) : String | Test.java:74:31:74:51 | toCharArray(...) : char[] | provenance | MaD:8 | +| Test.java:74:31:74:37 | taint(...) : String | Test.java:74:31:74:51 | toCharArray(...) : char[] | provenance | MaD:7 | | Test.java:74:31:74:51 | toCharArray(...) : char[] | Test.java:74:14:74:63 | join(...) | provenance | MaD:108 | | Test.java:77:9:77:19 | taintedList [post update] : ArrayList [] : String | Test.java:78:31:78:41 | taintedList : ArrayList [] : String | provenance | | | Test.java:77:9:77:19 | taintedList [post update] : ArrayList [] : String | Test.java:79:31:79:41 | taintedList : ArrayList [] : String | provenance | | @@ -2628,9 +2628,9 @@ edges | Test.java:78:31:78:41 | taintedList : ArrayList [] : String | Test.java:78:14:78:47 | join(...) | provenance | MaD:109 | | Test.java:79:31:79:41 | taintedList : ArrayList [] : String | Test.java:79:14:79:49 | join(...) | provenance | MaD:110 | | Test.java:81:46:81:52 | taint(...) : String | Test.java:81:14:81:53 | join(...) | provenance | MaD:111 | -| Test.java:83:31:83:41 | taintedList : ArrayList [] : String | Test.java:83:31:83:52 | iterator(...) : Iterator [] : String | provenance | MaD:7 | +| Test.java:83:31:83:41 | taintedList : ArrayList [] : String | Test.java:83:31:83:52 | iterator(...) : Iterator [] : String | provenance | MaD:6 | | Test.java:83:31:83:52 | iterator(...) : Iterator [] : String | Test.java:83:14:83:58 | join(...) | provenance | MaD:119 | -| Test.java:84:31:84:41 | taintedList : ArrayList [] : String | Test.java:84:31:84:52 | iterator(...) : Iterator [] : String | provenance | MaD:7 | +| Test.java:84:31:84:41 | taintedList : ArrayList [] : String | Test.java:84:31:84:52 | iterator(...) : Iterator [] : String | provenance | MaD:6 | | Test.java:84:31:84:52 | iterator(...) : Iterator [] : String | Test.java:84:14:84:60 | join(...) | provenance | MaD:120 | | Test.java:85:57:85:63 | taint(...) : String | Test.java:85:14:85:64 | join(...) | provenance | MaD:121 | | Test.java:87:31:87:41 | taintedList : ArrayList [] : String | Test.java:87:14:87:53 | join(...) | provenance | MaD:122 | @@ -2774,7 +2774,7 @@ edges | Test.java:263:33:263:39 | taint(...) : String | Test.java:263:14:263:53 | unwrap(...) | provenance | MaD:215 | | Test.java:266:36:266:42 | taint(...) : String | Test.java:266:14:266:43 | upperCase(...) | provenance | MaD:216 | | Test.java:267:36:267:42 | taint(...) : String | Test.java:267:14:267:49 | upperCase(...) | provenance | MaD:217 | -| Test.java:268:34:268:40 | taint(...) : String | Test.java:268:34:268:54 | toCharArray(...) : char[] | provenance | MaD:8 | +| Test.java:268:34:268:40 | taint(...) : String | Test.java:268:34:268:54 | toCharArray(...) : char[] | provenance | MaD:7 | | Test.java:268:34:268:54 | toCharArray(...) : char[] | Test.java:268:14:268:55 | valueOf(...) | provenance | MaD:218 | | Test.java:269:31:269:37 | taint(...) : String | Test.java:269:14:269:43 | wrap(...) | provenance | MaD:219 | | Test.java:270:31:270:37 | taint(...) : String | Test.java:270:14:270:55 | wrap(...) | provenance | MaD:220 | @@ -2784,239 +2784,239 @@ edges | Test.java:274:51:274:57 | taint(...) : String | Test.java:274:14:274:58 | wrapIfMissing(...) | provenance | MaD:222 | | TextStringBuilderTest.java:17:35:17:64 | new TextStringBuilder(...) : TextStringBuilder | TextStringBuilderTest.java:17:72:17:76 | cons1 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:17:57:17:63 | taint(...) : String | TextStringBuilderTest.java:17:35:17:64 | new TextStringBuilder(...) : TextStringBuilder | provenance | MaD:561 | -| TextStringBuilderTest.java:17:72:17:76 | cons1 : TextStringBuilder | TextStringBuilderTest.java:17:72:17:87 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:17:72:17:76 | cons1 : TextStringBuilder | TextStringBuilderTest.java:17:72:17:87 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:17:72:17:76 | cons1 : TextStringBuilder | TextStringBuilderTest.java:17:72:17:87 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:18:35:18:78 | new TextStringBuilder(...) : TextStringBuilder | TextStringBuilderTest.java:18:86:18:90 | cons2 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:18:57:18:77 | (...)... : String | TextStringBuilderTest.java:18:35:18:78 | new TextStringBuilder(...) : TextStringBuilder | provenance | MaD:560 | | TextStringBuilderTest.java:18:71:18:77 | taint(...) : String | TextStringBuilderTest.java:18:57:18:77 | (...)... : String | provenance | | -| TextStringBuilderTest.java:18:86:18:90 | cons2 : TextStringBuilder | TextStringBuilderTest.java:18:86:18:101 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:18:86:18:90 | cons2 : TextStringBuilder | TextStringBuilderTest.java:18:86:18:101 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:18:86:18:90 | cons2 : TextStringBuilder | TextStringBuilderTest.java:18:86:18:101 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:20:58:20:60 | sb1 [post update] : TextStringBuilder | TextStringBuilderTest.java:20:98:20:100 | sb1 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:20:69:20:75 | taint(...) : String | TextStringBuilderTest.java:20:69:20:89 | toCharArray(...) : char[] | provenance | MaD:8 | +| TextStringBuilderTest.java:20:69:20:75 | taint(...) : String | TextStringBuilderTest.java:20:69:20:89 | toCharArray(...) : char[] | provenance | MaD:7 | | TextStringBuilderTest.java:20:69:20:89 | toCharArray(...) : char[] | TextStringBuilderTest.java:20:58:20:60 | sb1 [post update] : TextStringBuilder | provenance | MaD:563 | -| TextStringBuilderTest.java:20:98:20:100 | sb1 : TextStringBuilder | TextStringBuilderTest.java:20:98:20:111 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:20:98:20:100 | sb1 : TextStringBuilder | TextStringBuilderTest.java:20:98:20:111 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:20:98:20:100 | sb1 : TextStringBuilder | TextStringBuilderTest.java:20:98:20:111 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:21:58:21:60 | sb2 [post update] : TextStringBuilder | TextStringBuilderTest.java:21:104:21:106 | sb2 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:21:69:21:75 | taint(...) : String | TextStringBuilderTest.java:21:69:21:89 | toCharArray(...) : char[] | provenance | MaD:8 | +| TextStringBuilderTest.java:21:69:21:75 | taint(...) : String | TextStringBuilderTest.java:21:69:21:89 | toCharArray(...) : char[] | provenance | MaD:7 | | TextStringBuilderTest.java:21:69:21:89 | toCharArray(...) : char[] | TextStringBuilderTest.java:21:58:21:60 | sb2 [post update] : TextStringBuilder | provenance | MaD:564 | -| TextStringBuilderTest.java:21:104:21:106 | sb2 : TextStringBuilder | TextStringBuilderTest.java:21:104:21:117 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:21:104:21:106 | sb2 : TextStringBuilder | TextStringBuilderTest.java:21:104:21:117 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:21:104:21:106 | sb2 : TextStringBuilder | TextStringBuilderTest.java:21:104:21:117 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:22:58:22:60 | sb3 [post update] : TextStringBuilder | TextStringBuilderTest.java:22:115:22:117 | sb3 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:22:69:22:106 | wrap(...) : CharBuffer | TextStringBuilderTest.java:22:58:22:60 | sb3 [post update] : TextStringBuilder | provenance | MaD:576 | -| TextStringBuilderTest.java:22:85:22:91 | taint(...) : String | TextStringBuilderTest.java:22:85:22:105 | toCharArray(...) : char[] | provenance | MaD:8 | -| TextStringBuilderTest.java:22:85:22:105 | toCharArray(...) : char[] | TextStringBuilderTest.java:22:69:22:106 | wrap(...) : CharBuffer | provenance | MaD:1 | -| TextStringBuilderTest.java:22:115:22:117 | sb3 : TextStringBuilder | TextStringBuilderTest.java:22:115:22:128 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:22:85:22:91 | taint(...) : String | TextStringBuilderTest.java:22:85:22:105 | toCharArray(...) : char[] | provenance | MaD:7 | +| TextStringBuilderTest.java:22:85:22:105 | toCharArray(...) : char[] | TextStringBuilderTest.java:22:69:22:106 | wrap(...) : CharBuffer | provenance | MaD:10 | +| TextStringBuilderTest.java:22:115:22:117 | sb3 : TextStringBuilder | TextStringBuilderTest.java:22:115:22:128 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:22:115:22:117 | sb3 : TextStringBuilder | TextStringBuilderTest.java:22:115:22:128 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:23:58:23:60 | sb4 [post update] : TextStringBuilder | TextStringBuilderTest.java:23:121:23:123 | sb4 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:23:69:23:106 | wrap(...) : CharBuffer | TextStringBuilderTest.java:23:58:23:60 | sb4 [post update] : TextStringBuilder | provenance | MaD:577 | -| TextStringBuilderTest.java:23:85:23:91 | taint(...) : String | TextStringBuilderTest.java:23:85:23:105 | toCharArray(...) : char[] | provenance | MaD:8 | -| TextStringBuilderTest.java:23:85:23:105 | toCharArray(...) : char[] | TextStringBuilderTest.java:23:69:23:106 | wrap(...) : CharBuffer | provenance | MaD:1 | -| TextStringBuilderTest.java:23:121:23:123 | sb4 : TextStringBuilder | TextStringBuilderTest.java:23:121:23:134 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:23:85:23:91 | taint(...) : String | TextStringBuilderTest.java:23:85:23:105 | toCharArray(...) : char[] | provenance | MaD:7 | +| TextStringBuilderTest.java:23:85:23:105 | toCharArray(...) : char[] | TextStringBuilderTest.java:23:69:23:106 | wrap(...) : CharBuffer | provenance | MaD:10 | +| TextStringBuilderTest.java:23:121:23:123 | sb4 : TextStringBuilder | TextStringBuilderTest.java:23:121:23:134 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:23:121:23:123 | sb4 : TextStringBuilder | TextStringBuilderTest.java:23:121:23:134 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:24:58:24:60 | sb5 [post update] : TextStringBuilder | TextStringBuilderTest.java:24:98:24:100 | sb5 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:24:69:24:89 | (...)... : String | TextStringBuilderTest.java:24:58:24:60 | sb5 [post update] : TextStringBuilder | provenance | MaD:4 | +| TextStringBuilderTest.java:24:69:24:89 | (...)... : String | TextStringBuilderTest.java:24:58:24:60 | sb5 [post update] : TextStringBuilder | provenance | MaD:3 | | TextStringBuilderTest.java:24:69:24:89 | (...)... : String | TextStringBuilderTest.java:24:58:24:60 | sb5 [post update] : TextStringBuilder | provenance | MaD:565 | | TextStringBuilderTest.java:24:83:24:89 | taint(...) : String | TextStringBuilderTest.java:24:69:24:89 | (...)... : String | provenance | | -| TextStringBuilderTest.java:24:98:24:100 | sb5 : TextStringBuilder | TextStringBuilderTest.java:24:98:24:111 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:24:98:24:100 | sb5 : TextStringBuilder | TextStringBuilderTest.java:24:98:24:111 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:24:98:24:100 | sb5 : TextStringBuilder | TextStringBuilderTest.java:24:98:24:111 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:25:58:25:60 | sb6 [post update] : TextStringBuilder | TextStringBuilderTest.java:25:104:25:106 | sb6 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:25:69:25:89 | (...)... : String | TextStringBuilderTest.java:25:58:25:60 | sb6 [post update] : TextStringBuilder | provenance | MaD:4 | +| TextStringBuilderTest.java:25:69:25:89 | (...)... : String | TextStringBuilderTest.java:25:58:25:60 | sb6 [post update] : TextStringBuilder | provenance | MaD:3 | | TextStringBuilderTest.java:25:69:25:89 | (...)... : String | TextStringBuilderTest.java:25:58:25:60 | sb6 [post update] : TextStringBuilder | provenance | MaD:566 | | TextStringBuilderTest.java:25:83:25:89 | taint(...) : String | TextStringBuilderTest.java:25:69:25:89 | (...)... : String | provenance | | -| TextStringBuilderTest.java:25:104:25:106 | sb6 : TextStringBuilder | TextStringBuilderTest.java:25:104:25:117 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:25:104:25:106 | sb6 : TextStringBuilder | TextStringBuilderTest.java:25:104:25:117 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:25:104:25:106 | sb6 : TextStringBuilder | TextStringBuilderTest.java:25:104:25:117 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:26:58:26:60 | sb7 [post update] : TextStringBuilder | TextStringBuilderTest.java:26:92:26:94 | sb7 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:26:69:26:83 | (...)... : String | TextStringBuilderTest.java:26:58:26:60 | sb7 [post update] : TextStringBuilder | provenance | MaD:567 | | TextStringBuilderTest.java:26:77:26:83 | taint(...) : String | TextStringBuilderTest.java:26:69:26:83 | (...)... : String | provenance | | -| TextStringBuilderTest.java:26:92:26:94 | sb7 : TextStringBuilder | TextStringBuilderTest.java:26:92:26:105 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:26:92:26:94 | sb7 : TextStringBuilder | TextStringBuilderTest.java:26:92:26:105 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:26:92:26:94 | sb7 : TextStringBuilder | TextStringBuilderTest.java:26:92:26:105 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:28:64:28:68 | auxsb [post update] : TextStringBuilder | TextStringBuilderTest.java:29:73:29:77 | auxsb : TextStringBuilder | provenance | | | TextStringBuilderTest.java:28:77:28:83 | taint(...) : String | TextStringBuilderTest.java:28:64:28:68 | auxsb [post update] : TextStringBuilder | provenance | MaD:568 | | TextStringBuilderTest.java:29:62:29:64 | sb8 [post update] : TextStringBuilder | TextStringBuilderTest.java:29:86:29:88 | sb8 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:29:73:29:77 | auxsb : TextStringBuilder | TextStringBuilderTest.java:29:62:29:64 | sb8 [post update] : TextStringBuilder | provenance | MaD:578 | -| TextStringBuilderTest.java:29:86:29:88 | sb8 : TextStringBuilder | TextStringBuilderTest.java:29:86:29:99 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:29:86:29:88 | sb8 : TextStringBuilder | TextStringBuilderTest.java:29:86:29:99 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:29:86:29:88 | sb8 : TextStringBuilder | TextStringBuilderTest.java:29:86:29:99 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:31:58:31:60 | sb9 [post update] : TextStringBuilder | TextStringBuilderTest.java:31:102:31:104 | sb9 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:31:69:31:93 | new StringBuffer(...) : StringBuffer | TextStringBuilderTest.java:31:58:31:60 | sb9 [post update] : TextStringBuilder | provenance | MaD:572 | -| TextStringBuilderTest.java:31:86:31:92 | taint(...) : String | TextStringBuilderTest.java:31:69:31:93 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| TextStringBuilderTest.java:31:102:31:104 | sb9 : TextStringBuilder | TextStringBuilderTest.java:31:102:31:115 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:31:86:31:92 | taint(...) : String | TextStringBuilderTest.java:31:69:31:93 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| TextStringBuilderTest.java:31:102:31:104 | sb9 : TextStringBuilder | TextStringBuilderTest.java:31:102:31:115 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:31:102:31:104 | sb9 : TextStringBuilder | TextStringBuilderTest.java:31:102:31:115 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:32:59:32:62 | sb10 [post update] : TextStringBuilder | TextStringBuilderTest.java:32:110:32:113 | sb10 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:32:71:32:95 | new StringBuffer(...) : StringBuffer | TextStringBuilderTest.java:32:59:32:62 | sb10 [post update] : TextStringBuilder | provenance | MaD:573 | -| TextStringBuilderTest.java:32:88:32:94 | taint(...) : String | TextStringBuilderTest.java:32:71:32:95 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| TextStringBuilderTest.java:32:110:32:113 | sb10 : TextStringBuilder | TextStringBuilderTest.java:32:110:32:124 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:32:88:32:94 | taint(...) : String | TextStringBuilderTest.java:32:71:32:95 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| TextStringBuilderTest.java:32:110:32:113 | sb10 : TextStringBuilder | TextStringBuilderTest.java:32:110:32:124 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:32:110:32:113 | sb10 : TextStringBuilder | TextStringBuilderTest.java:32:110:32:124 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:33:59:33:62 | sb11 [post update] : TextStringBuilder | TextStringBuilderTest.java:33:105:33:108 | sb11 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:33:71:33:96 | new StringBuilder(...) : StringBuilder | TextStringBuilderTest.java:33:59:33:62 | sb11 [post update] : TextStringBuilder | provenance | MaD:574 | -| TextStringBuilderTest.java:33:89:33:95 | taint(...) : String | TextStringBuilderTest.java:33:71:33:96 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| TextStringBuilderTest.java:33:105:33:108 | sb11 : TextStringBuilder | TextStringBuilderTest.java:33:105:33:119 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:33:89:33:95 | taint(...) : String | TextStringBuilderTest.java:33:71:33:96 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| TextStringBuilderTest.java:33:105:33:108 | sb11 : TextStringBuilder | TextStringBuilderTest.java:33:105:33:119 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:33:105:33:108 | sb11 : TextStringBuilder | TextStringBuilderTest.java:33:105:33:119 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:34:59:34:62 | sb12 [post update] : TextStringBuilder | TextStringBuilderTest.java:34:111:34:114 | sb12 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:34:71:34:96 | new StringBuilder(...) : StringBuilder | TextStringBuilderTest.java:34:59:34:62 | sb12 [post update] : TextStringBuilder | provenance | MaD:575 | -| TextStringBuilderTest.java:34:89:34:95 | taint(...) : String | TextStringBuilderTest.java:34:71:34:96 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| TextStringBuilderTest.java:34:111:34:114 | sb12 : TextStringBuilder | TextStringBuilderTest.java:34:111:34:125 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:34:89:34:95 | taint(...) : String | TextStringBuilderTest.java:34:71:34:96 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| TextStringBuilderTest.java:34:111:34:114 | sb12 : TextStringBuilder | TextStringBuilderTest.java:34:111:34:125 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:34:111:34:114 | sb12 : TextStringBuilder | TextStringBuilderTest.java:34:111:34:125 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:35:59:35:62 | sb13 [post update] : TextStringBuilder | TextStringBuilderTest.java:35:86:35:89 | sb13 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:35:71:35:77 | taint(...) : String | TextStringBuilderTest.java:35:59:35:62 | sb13 [post update] : TextStringBuilder | provenance | MaD:568 | -| TextStringBuilderTest.java:35:86:35:89 | sb13 : TextStringBuilder | TextStringBuilderTest.java:35:86:35:100 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:35:86:35:89 | sb13 : TextStringBuilder | TextStringBuilderTest.java:35:86:35:100 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:35:86:35:89 | sb13 : TextStringBuilder | TextStringBuilderTest.java:35:86:35:100 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:36:59:36:62 | sb14 [post update] : TextStringBuilder | TextStringBuilderTest.java:36:92:36:95 | sb14 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:36:71:36:77 | taint(...) : String | TextStringBuilderTest.java:36:59:36:62 | sb14 [post update] : TextStringBuilder | provenance | MaD:569 | -| TextStringBuilderTest.java:36:92:36:95 | sb14 : TextStringBuilder | TextStringBuilderTest.java:36:92:36:106 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:36:92:36:95 | sb14 : TextStringBuilder | TextStringBuilderTest.java:36:92:36:106 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:36:92:36:95 | sb14 : TextStringBuilder | TextStringBuilderTest.java:36:92:36:106 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:37:59:37:62 | sb15 [post update] : TextStringBuilder | TextStringBuilderTest.java:37:104:37:107 | sb15 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:37:71:37:77 | taint(...) : String | TextStringBuilderTest.java:37:59:37:62 | sb15 [post update] : TextStringBuilder | provenance | MaD:570 | -| TextStringBuilderTest.java:37:104:37:107 | sb15 : TextStringBuilder | TextStringBuilderTest.java:37:104:37:118 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:37:104:37:107 | sb15 : TextStringBuilder | TextStringBuilderTest.java:37:104:37:118 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:37:104:37:107 | sb15 : TextStringBuilder | TextStringBuilderTest.java:37:104:37:118 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:38:59:38:62 | sb16 [post update] : TextStringBuilder | TextStringBuilderTest.java:38:111:38:114 | sb16 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:38:59:38:103 | new ..[] { .. } : Object[] [[]] : String | TextStringBuilderTest.java:38:59:38:62 | sb16 [post update] : TextStringBuilder | provenance | MaD:571 | | TextStringBuilderTest.java:38:88:38:94 | taint(...) : String | TextStringBuilderTest.java:38:59:38:103 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| TextStringBuilderTest.java:38:111:38:114 | sb16 : TextStringBuilder | TextStringBuilderTest.java:38:111:38:125 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:38:111:38:114 | sb16 : TextStringBuilder | TextStringBuilderTest.java:38:111:38:125 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:38:111:38:114 | sb16 : TextStringBuilder | TextStringBuilderTest.java:38:111:38:125 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:41:13:41:23 | taintedList [post update] : ArrayList [] : String | TextStringBuilderTest.java:42:78:42:88 | taintedList : ArrayList [] : String | provenance | | | TextStringBuilderTest.java:41:13:41:23 | taintedList [post update] : ArrayList [] : String | TextStringBuilderTest.java:43:78:43:88 | taintedList : ArrayList [] : String | provenance | | | TextStringBuilderTest.java:41:29:41:35 | taint(...) : String | TextStringBuilderTest.java:41:13:41:23 | taintedList [post update] : ArrayList [] : String | provenance | MaD:11 | | TextStringBuilderTest.java:42:63:42:66 | sb17 [post update] : TextStringBuilder | TextStringBuilderTest.java:42:97:42:100 | sb17 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:42:78:42:88 | taintedList : ArrayList [] : String | TextStringBuilderTest.java:42:63:42:66 | sb17 [post update] : TextStringBuilder | provenance | MaD:580 | -| TextStringBuilderTest.java:42:97:42:100 | sb17 : TextStringBuilder | TextStringBuilderTest.java:42:97:42:111 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:42:97:42:100 | sb17 : TextStringBuilder | TextStringBuilderTest.java:42:97:42:111 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:42:97:42:100 | sb17 : TextStringBuilder | TextStringBuilderTest.java:42:97:42:111 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:43:63:43:66 | sb18 [post update] : TextStringBuilder | TextStringBuilderTest.java:43:108:43:111 | sb18 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:43:78:43:88 | taintedList : ArrayList [] : String | TextStringBuilderTest.java:43:78:43:99 | iterator(...) : Iterator [] : String | provenance | MaD:7 | +| TextStringBuilderTest.java:43:78:43:88 | taintedList : ArrayList [] : String | TextStringBuilderTest.java:43:78:43:99 | iterator(...) : Iterator [] : String | provenance | MaD:6 | | TextStringBuilderTest.java:43:78:43:99 | iterator(...) : Iterator [] : String | TextStringBuilderTest.java:43:63:43:66 | sb18 [post update] : TextStringBuilder | provenance | MaD:581 | -| TextStringBuilderTest.java:43:108:43:111 | sb18 : TextStringBuilder | TextStringBuilderTest.java:43:108:43:122 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:43:108:43:111 | sb18 : TextStringBuilder | TextStringBuilderTest.java:43:108:43:122 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:43:108:43:111 | sb18 : TextStringBuilder | TextStringBuilderTest.java:43:108:43:122 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:45:59:45:62 | sb19 [post update] : TextStringBuilder | TextStringBuilderTest.java:45:98:45:101 | sb19 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:45:59:45:90 | new ..[] { .. } : Object[] [[]] : String | TextStringBuilderTest.java:45:59:45:62 | sb19 [post update] : TextStringBuilder | provenance | MaD:582 | | TextStringBuilderTest.java:45:83:45:89 | taint(...) : String | TextStringBuilderTest.java:45:59:45:90 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| TextStringBuilderTest.java:45:98:45:101 | sb19 : TextStringBuilder | TextStringBuilderTest.java:45:98:45:112 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:45:98:45:101 | sb19 : TextStringBuilder | TextStringBuilderTest.java:45:98:45:112 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:45:98:45:101 | sb19 : TextStringBuilder | TextStringBuilderTest.java:45:98:45:112 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:46:59:46:62 | sb20 [post update] : TextStringBuilder | TextStringBuilderTest.java:46:98:46:101 | sb20 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:46:59:46:90 | new ..[] { .. } : Object[] [[]] : String | TextStringBuilderTest.java:46:59:46:62 | sb20 [post update] : TextStringBuilder | provenance | MaD:582 | | TextStringBuilderTest.java:46:74:46:80 | taint(...) : String | TextStringBuilderTest.java:46:59:46:90 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| TextStringBuilderTest.java:46:98:46:101 | sb20 : TextStringBuilder | TextStringBuilderTest.java:46:98:46:112 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:46:98:46:101 | sb20 : TextStringBuilder | TextStringBuilderTest.java:46:98:46:112 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:46:98:46:101 | sb20 : TextStringBuilder | TextStringBuilderTest.java:46:98:46:112 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:47:59:47:62 | sb21 [post update] : TextStringBuilder | TextStringBuilderTest.java:47:111:47:114 | sb21 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:47:88:47:94 | taint(...) : String | TextStringBuilderTest.java:47:59:47:62 | sb21 [post update] : TextStringBuilder | provenance | MaD:584 | -| TextStringBuilderTest.java:47:111:47:114 | sb21 : TextStringBuilder | TextStringBuilderTest.java:47:111:47:125 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:47:111:47:114 | sb21 : TextStringBuilder | TextStringBuilderTest.java:47:111:47:125 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:47:111:47:114 | sb21 : TextStringBuilder | TextStringBuilderTest.java:47:111:47:125 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:48:59:48:62 | sb22 [post update] : TextStringBuilder | TextStringBuilderTest.java:48:112:48:115 | sb22 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:48:89:48:95 | taint(...) : String | TextStringBuilderTest.java:48:59:48:62 | sb22 [post update] : TextStringBuilder | provenance | MaD:586 | -| TextStringBuilderTest.java:48:112:48:115 | sb22 : TextStringBuilder | TextStringBuilderTest.java:48:112:48:126 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:48:112:48:115 | sb22 : TextStringBuilder | TextStringBuilderTest.java:48:112:48:126 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:48:112:48:115 | sb22 : TextStringBuilder | TextStringBuilderTest.java:48:112:48:126 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:49:59:49:62 | sb23 [post update] : TextStringBuilder | TextStringBuilderTest.java:49:102:49:105 | sb23 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:49:73:49:79 | taint(...) : String | TextStringBuilderTest.java:49:73:49:93 | toCharArray(...) : char[] | provenance | MaD:8 | +| TextStringBuilderTest.java:49:73:49:79 | taint(...) : String | TextStringBuilderTest.java:49:73:49:93 | toCharArray(...) : char[] | provenance | MaD:7 | | TextStringBuilderTest.java:49:73:49:93 | toCharArray(...) : char[] | TextStringBuilderTest.java:49:59:49:62 | sb23 [post update] : TextStringBuilder | provenance | MaD:601 | -| TextStringBuilderTest.java:49:102:49:105 | sb23 : TextStringBuilder | TextStringBuilderTest.java:49:102:49:116 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:49:102:49:105 | sb23 : TextStringBuilder | TextStringBuilderTest.java:49:102:49:116 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:49:102:49:105 | sb23 : TextStringBuilder | TextStringBuilderTest.java:49:102:49:116 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:50:59:50:62 | sb24 [post update] : TextStringBuilder | TextStringBuilderTest.java:50:108:50:111 | sb24 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:50:73:50:79 | taint(...) : String | TextStringBuilderTest.java:50:73:50:93 | toCharArray(...) : char[] | provenance | MaD:8 | +| TextStringBuilderTest.java:50:73:50:79 | taint(...) : String | TextStringBuilderTest.java:50:73:50:93 | toCharArray(...) : char[] | provenance | MaD:7 | | TextStringBuilderTest.java:50:73:50:93 | toCharArray(...) : char[] | TextStringBuilderTest.java:50:59:50:62 | sb24 [post update] : TextStringBuilder | provenance | MaD:602 | -| TextStringBuilderTest.java:50:108:50:111 | sb24 : TextStringBuilder | TextStringBuilderTest.java:50:108:50:122 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:50:108:50:111 | sb24 : TextStringBuilder | TextStringBuilderTest.java:50:108:50:122 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:50:108:50:111 | sb24 : TextStringBuilder | TextStringBuilderTest.java:50:108:50:122 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:51:59:51:62 | sb25 [post update] : TextStringBuilder | TextStringBuilderTest.java:51:96:51:99 | sb25 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:51:73:51:87 | (...)... : String | TextStringBuilderTest.java:51:59:51:62 | sb25 [post update] : TextStringBuilder | provenance | MaD:603 | | TextStringBuilderTest.java:51:81:51:87 | taint(...) : String | TextStringBuilderTest.java:51:73:51:87 | (...)... : String | provenance | | -| TextStringBuilderTest.java:51:96:51:99 | sb25 : TextStringBuilder | TextStringBuilderTest.java:51:96:51:110 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:51:96:51:99 | sb25 : TextStringBuilder | TextStringBuilderTest.java:51:96:51:110 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:51:96:51:99 | sb25 : TextStringBuilder | TextStringBuilderTest.java:51:96:51:110 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:53:64:53:68 | auxsb [post update] : TextStringBuilder | TextStringBuilderTest.java:54:77:54:81 | auxsb : TextStringBuilder | provenance | | | TextStringBuilderTest.java:53:79:53:85 | taint(...) : String | TextStringBuilderTest.java:53:64:53:68 | auxsb [post update] : TextStringBuilder | provenance | MaD:604 | | TextStringBuilderTest.java:54:63:54:66 | sb26 [post update] : TextStringBuilder | TextStringBuilderTest.java:54:90:54:93 | sb26 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:54:77:54:81 | auxsb : TextStringBuilder | TextStringBuilderTest.java:54:63:54:66 | sb26 [post update] : TextStringBuilder | provenance | MaD:612 | -| TextStringBuilderTest.java:54:90:54:93 | sb26 : TextStringBuilder | TextStringBuilderTest.java:54:90:54:104 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:54:90:54:93 | sb26 : TextStringBuilder | TextStringBuilderTest.java:54:90:54:104 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:54:90:54:93 | sb26 : TextStringBuilder | TextStringBuilderTest.java:54:90:54:104 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:56:59:56:62 | sb27 [post update] : TextStringBuilder | TextStringBuilderTest.java:56:106:56:109 | sb27 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:56:73:56:97 | new StringBuffer(...) : StringBuffer | TextStringBuilderTest.java:56:59:56:62 | sb27 [post update] : TextStringBuilder | provenance | MaD:608 | -| TextStringBuilderTest.java:56:90:56:96 | taint(...) : String | TextStringBuilderTest.java:56:73:56:97 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| TextStringBuilderTest.java:56:106:56:109 | sb27 : TextStringBuilder | TextStringBuilderTest.java:56:106:56:120 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:56:90:56:96 | taint(...) : String | TextStringBuilderTest.java:56:73:56:97 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| TextStringBuilderTest.java:56:106:56:109 | sb27 : TextStringBuilder | TextStringBuilderTest.java:56:106:56:120 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:56:106:56:109 | sb27 : TextStringBuilder | TextStringBuilderTest.java:56:106:56:120 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:57:59:57:62 | sb28 [post update] : TextStringBuilder | TextStringBuilderTest.java:57:112:57:115 | sb28 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:57:73:57:97 | new StringBuffer(...) : StringBuffer | TextStringBuilderTest.java:57:59:57:62 | sb28 [post update] : TextStringBuilder | provenance | MaD:609 | -| TextStringBuilderTest.java:57:90:57:96 | taint(...) : String | TextStringBuilderTest.java:57:73:57:97 | new StringBuffer(...) : StringBuffer | provenance | MaD:9 | -| TextStringBuilderTest.java:57:112:57:115 | sb28 : TextStringBuilder | TextStringBuilderTest.java:57:112:57:126 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:57:90:57:96 | taint(...) : String | TextStringBuilderTest.java:57:73:57:97 | new StringBuffer(...) : StringBuffer | provenance | MaD:8 | +| TextStringBuilderTest.java:57:112:57:115 | sb28 : TextStringBuilder | TextStringBuilderTest.java:57:112:57:126 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:57:112:57:115 | sb28 : TextStringBuilder | TextStringBuilderTest.java:57:112:57:126 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:58:59:58:62 | sb29 [post update] : TextStringBuilder | TextStringBuilderTest.java:58:107:58:110 | sb29 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:58:73:58:98 | new StringBuilder(...) : StringBuilder | TextStringBuilderTest.java:58:59:58:62 | sb29 [post update] : TextStringBuilder | provenance | MaD:610 | -| TextStringBuilderTest.java:58:91:58:97 | taint(...) : String | TextStringBuilderTest.java:58:73:58:98 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| TextStringBuilderTest.java:58:107:58:110 | sb29 : TextStringBuilder | TextStringBuilderTest.java:58:107:58:121 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:58:91:58:97 | taint(...) : String | TextStringBuilderTest.java:58:73:58:98 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| TextStringBuilderTest.java:58:107:58:110 | sb29 : TextStringBuilder | TextStringBuilderTest.java:58:107:58:121 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:58:107:58:110 | sb29 : TextStringBuilder | TextStringBuilderTest.java:58:107:58:121 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:59:59:59:62 | sb30 [post update] : TextStringBuilder | TextStringBuilderTest.java:59:113:59:116 | sb30 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:59:73:59:98 | new StringBuilder(...) : StringBuilder | TextStringBuilderTest.java:59:59:59:62 | sb30 [post update] : TextStringBuilder | provenance | MaD:611 | -| TextStringBuilderTest.java:59:91:59:97 | taint(...) : String | TextStringBuilderTest.java:59:73:59:98 | new StringBuilder(...) : StringBuilder | provenance | MaD:10 | -| TextStringBuilderTest.java:59:113:59:116 | sb30 : TextStringBuilder | TextStringBuilderTest.java:59:113:59:127 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:59:91:59:97 | taint(...) : String | TextStringBuilderTest.java:59:73:59:98 | new StringBuilder(...) : StringBuilder | provenance | MaD:9 | +| TextStringBuilderTest.java:59:113:59:116 | sb30 : TextStringBuilder | TextStringBuilderTest.java:59:113:59:127 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:59:113:59:116 | sb30 : TextStringBuilder | TextStringBuilderTest.java:59:113:59:127 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:60:59:60:62 | sb31 [post update] : TextStringBuilder | TextStringBuilderTest.java:60:88:60:91 | sb31 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:60:73:60:79 | taint(...) : String | TextStringBuilderTest.java:60:59:60:62 | sb31 [post update] : TextStringBuilder | provenance | MaD:604 | -| TextStringBuilderTest.java:60:88:60:91 | sb31 : TextStringBuilder | TextStringBuilderTest.java:60:88:60:102 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:60:88:60:91 | sb31 : TextStringBuilder | TextStringBuilderTest.java:60:88:60:102 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:60:88:60:91 | sb31 : TextStringBuilder | TextStringBuilderTest.java:60:88:60:102 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:61:59:61:62 | sb32 [post update] : TextStringBuilder | TextStringBuilderTest.java:61:94:61:97 | sb32 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:61:73:61:79 | taint(...) : String | TextStringBuilderTest.java:61:59:61:62 | sb32 [post update] : TextStringBuilder | provenance | MaD:605 | -| TextStringBuilderTest.java:61:94:61:97 | sb32 : TextStringBuilder | TextStringBuilderTest.java:61:94:61:108 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:61:94:61:97 | sb32 : TextStringBuilder | TextStringBuilderTest.java:61:94:61:108 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:61:94:61:97 | sb32 : TextStringBuilder | TextStringBuilderTest.java:61:94:61:108 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:62:59:62:62 | sb33 [post update] : TextStringBuilder | TextStringBuilderTest.java:62:106:62:109 | sb33 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:62:73:62:79 | taint(...) : String | TextStringBuilderTest.java:62:59:62:62 | sb33 [post update] : TextStringBuilder | provenance | MaD:606 | -| TextStringBuilderTest.java:62:106:62:109 | sb33 : TextStringBuilder | TextStringBuilderTest.java:62:106:62:120 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:62:106:62:109 | sb33 : TextStringBuilder | TextStringBuilderTest.java:62:106:62:120 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:62:106:62:109 | sb33 : TextStringBuilder | TextStringBuilderTest.java:62:106:62:120 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:63:59:63:62 | sb34 [post update] : TextStringBuilder | TextStringBuilderTest.java:63:113:63:116 | sb34 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:63:59:63:105 | new ..[] { .. } : Object[] [[]] : String | TextStringBuilderTest.java:63:59:63:62 | sb34 [post update] : TextStringBuilder | provenance | MaD:607 | | TextStringBuilderTest.java:63:90:63:96 | taint(...) : String | TextStringBuilderTest.java:63:59:63:105 | new ..[] { .. } : Object[] [[]] : String | provenance | | -| TextStringBuilderTest.java:63:113:63:116 | sb34 : TextStringBuilder | TextStringBuilderTest.java:63:113:63:127 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:63:113:63:116 | sb34 : TextStringBuilder | TextStringBuilderTest.java:63:113:63:127 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:63:113:63:116 | sb34 : TextStringBuilder | TextStringBuilderTest.java:63:113:63:127 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:64:59:64:62 | sb35 [post update] : TextStringBuilder | TextStringBuilderTest.java:64:95:64:98 | sb35 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:64:80:64:86 | taint(...) : String | TextStringBuilderTest.java:64:59:64:62 | sb35 [post update] : TextStringBuilder | provenance | MaD:591 | -| TextStringBuilderTest.java:64:95:64:98 | sb35 : TextStringBuilder | TextStringBuilderTest.java:64:95:64:109 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:64:95:64:98 | sb35 : TextStringBuilder | TextStringBuilderTest.java:64:95:64:109 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:64:95:64:98 | sb35 : TextStringBuilder | TextStringBuilderTest.java:64:95:64:109 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:65:59:65:62 | sb36 [post update] : TextStringBuilder | TextStringBuilderTest.java:65:98:65:101 | sb36 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:65:80:65:86 | taint(...) : String | TextStringBuilderTest.java:65:59:65:62 | sb36 [post update] : TextStringBuilder | provenance | MaD:592 | -| TextStringBuilderTest.java:65:98:65:101 | sb36 : TextStringBuilder | TextStringBuilderTest.java:65:98:65:112 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:65:98:65:101 | sb36 : TextStringBuilder | TextStringBuilderTest.java:65:98:65:112 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:65:98:65:101 | sb36 : TextStringBuilder | TextStringBuilderTest.java:65:98:65:112 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:66:59:66:62 | sb37 [post update] : TextStringBuilder | TextStringBuilderTest.java:66:106:66:109 | sb37 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:66:80:66:86 | taint(...) : String | TextStringBuilderTest.java:66:59:66:62 | sb37 [post update] : TextStringBuilder | provenance | MaD:593 | -| TextStringBuilderTest.java:66:106:66:109 | sb37 : TextStringBuilder | TextStringBuilderTest.java:66:106:66:120 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:66:106:66:109 | sb37 : TextStringBuilder | TextStringBuilderTest.java:66:106:66:120 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:66:106:66:109 | sb37 : TextStringBuilder | TextStringBuilderTest.java:66:106:66:120 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:67:59:67:62 | sb38 [post update] : TextStringBuilder | TextStringBuilderTest.java:67:99:67:102 | sb38 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:67:84:67:90 | taint(...) : String | TextStringBuilderTest.java:67:59:67:62 | sb38 [post update] : TextStringBuilder | provenance | MaD:593 | -| TextStringBuilderTest.java:67:99:67:102 | sb38 : TextStringBuilder | TextStringBuilderTest.java:67:99:67:113 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:67:99:67:102 | sb38 : TextStringBuilder | TextStringBuilderTest.java:67:99:67:113 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:67:99:67:102 | sb38 : TextStringBuilder | TextStringBuilderTest.java:67:99:67:113 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:69:64:69:68 | auxsb [post update] : TextStringBuilder | TextStringBuilderTest.java:70:63:70:67 | auxsb : TextStringBuilder | provenance | | | TextStringBuilderTest.java:69:79:69:85 | taint(...) : String | TextStringBuilderTest.java:69:64:69:68 | auxsb [post update] : TextStringBuilder | provenance | MaD:604 | | TextStringBuilderTest.java:70:63:70:67 | auxsb : TextStringBuilder | TextStringBuilderTest.java:70:78:70:81 | sb39 [post update] : TextStringBuilder | provenance | MaD:594 | | TextStringBuilderTest.java:70:78:70:81 | sb39 [post update] : TextStringBuilder | TextStringBuilderTest.java:70:90:70:93 | sb39 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:70:90:70:93 | sb39 : TextStringBuilder | TextStringBuilderTest.java:70:90:70:104 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:70:90:70:93 | sb39 : TextStringBuilder | TextStringBuilderTest.java:70:90:70:104 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:70:90:70:93 | sb39 : TextStringBuilder | TextStringBuilderTest.java:70:90:70:104 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:74:13:74:23 | taintedList [post update] : ArrayList [] : String | TextStringBuilderTest.java:75:89:75:99 | taintedList : ArrayList [] : String | provenance | | | TextStringBuilderTest.java:74:13:74:23 | taintedList [post update] : ArrayList [] : String | TextStringBuilderTest.java:76:89:76:99 | taintedList : ArrayList [] : String | provenance | | | TextStringBuilderTest.java:74:29:74:35 | taint(...) : String | TextStringBuilderTest.java:74:13:74:23 | taintedList [post update] : ArrayList [] : String | provenance | MaD:11 | | TextStringBuilderTest.java:75:63:75:66 | sb40 [post update] : TextStringBuilder | TextStringBuilderTest.java:75:114:75:117 | sb40 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:75:89:75:99 | taintedList : ArrayList [] : String | TextStringBuilderTest.java:75:63:75:66 | sb40 [post update] : TextStringBuilder | provenance | MaD:597 | -| TextStringBuilderTest.java:75:114:75:117 | sb40 : TextStringBuilder | TextStringBuilderTest.java:75:114:75:128 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:75:114:75:117 | sb40 : TextStringBuilder | TextStringBuilderTest.java:75:114:75:128 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:75:114:75:117 | sb40 : TextStringBuilder | TextStringBuilderTest.java:75:114:75:128 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:76:63:76:66 | sb41 [post update] : TextStringBuilder | TextStringBuilderTest.java:76:125:76:128 | sb41 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:76:89:76:99 | taintedList : ArrayList [] : String | TextStringBuilderTest.java:76:89:76:110 | iterator(...) : Iterator [] : String | provenance | MaD:7 | +| TextStringBuilderTest.java:76:89:76:99 | taintedList : ArrayList [] : String | TextStringBuilderTest.java:76:89:76:110 | iterator(...) : Iterator [] : String | provenance | MaD:6 | | TextStringBuilderTest.java:76:89:76:110 | iterator(...) : Iterator [] : String | TextStringBuilderTest.java:76:63:76:66 | sb41 [post update] : TextStringBuilder | provenance | MaD:598 | -| TextStringBuilderTest.java:76:125:76:128 | sb41 : TextStringBuilder | TextStringBuilderTest.java:76:125:76:139 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:76:125:76:128 | sb41 : TextStringBuilder | TextStringBuilderTest.java:76:125:76:139 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:76:125:76:128 | sb41 : TextStringBuilder | TextStringBuilderTest.java:76:125:76:139 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:78:63:78:66 | sb42 [post update] : TextStringBuilder | TextStringBuilderTest.java:78:119:78:122 | sb42 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:78:104:78:110 | taint(...) : String | TextStringBuilderTest.java:78:63:78:66 | sb42 [post update] : TextStringBuilder | provenance | MaD:596 | -| TextStringBuilderTest.java:78:119:78:122 | sb42 : TextStringBuilder | TextStringBuilderTest.java:78:119:78:133 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:78:119:78:122 | sb42 : TextStringBuilder | TextStringBuilderTest.java:78:119:78:133 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:78:119:78:122 | sb42 : TextStringBuilder | TextStringBuilderTest.java:78:119:78:133 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:79:63:79:66 | sb43 [post update] : TextStringBuilder | TextStringBuilderTest.java:79:130:79:133 | sb43 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:79:115:79:121 | taint(...) : String | TextStringBuilderTest.java:79:63:79:66 | sb43 [post update] : TextStringBuilder | provenance | MaD:596 | -| TextStringBuilderTest.java:79:130:79:133 | sb43 : TextStringBuilder | TextStringBuilderTest.java:79:130:79:144 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:79:130:79:133 | sb43 : TextStringBuilder | TextStringBuilderTest.java:79:130:79:144 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:79:130:79:133 | sb43 : TextStringBuilder | TextStringBuilderTest.java:79:130:79:144 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:80:37:80:60 | {...} : String[] [[]] : String | TextStringBuilderTest.java:82:89:82:100 | taintedArray : String[] [[]] : String | provenance | | | TextStringBuilderTest.java:80:52:80:58 | taint(...) : String | TextStringBuilderTest.java:80:37:80:60 | {...} : String[] [[]] : String | provenance | | | TextStringBuilderTest.java:82:63:82:66 | sb44 [post update] : TextStringBuilder | TextStringBuilderTest.java:82:115:82:118 | sb44 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:82:89:82:100 | taintedArray : String[] [[]] : String | TextStringBuilderTest.java:82:63:82:66 | sb44 [post update] : TextStringBuilder | provenance | MaD:599 | -| TextStringBuilderTest.java:82:115:82:118 | sb44 : TextStringBuilder | TextStringBuilderTest.java:82:115:82:129 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:82:115:82:118 | sb44 : TextStringBuilder | TextStringBuilderTest.java:82:115:82:129 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:82:115:82:118 | sb44 : TextStringBuilder | TextStringBuilderTest.java:82:115:82:129 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:83:63:83:66 | sb45 [post update] : TextStringBuilder | TextStringBuilderTest.java:83:120:83:123 | sb45 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:83:105:83:111 | taint(...) : String | TextStringBuilderTest.java:83:63:83:66 | sb45 [post update] : TextStringBuilder | provenance | MaD:596 | -| TextStringBuilderTest.java:83:120:83:123 | sb45 : TextStringBuilder | TextStringBuilderTest.java:83:120:83:134 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:83:120:83:123 | sb45 : TextStringBuilder | TextStringBuilderTest.java:83:120:83:134 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:83:120:83:123 | sb45 : TextStringBuilder | TextStringBuilderTest.java:83:120:83:134 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:86:63:86:66 | sb46 [post update] : TextStringBuilder | TextStringBuilderTest.java:88:13:88:16 | sb46 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:86:75:86:81 | taint(...) : String | TextStringBuilderTest.java:86:63:86:66 | sb46 [post update] : TextStringBuilder | provenance | MaD:568 | | TextStringBuilderTest.java:88:13:88:16 | sb46 : TextStringBuilder | TextStringBuilderTest.java:88:13:88:27 | asReader(...) : Reader | provenance | MaD:613 | -| TextStringBuilderTest.java:88:13:88:27 | asReader(...) : Reader | TextStringBuilderTest.java:88:34:88:39 | target [post update] : char[] | provenance | MaD:2 | +| TextStringBuilderTest.java:88:13:88:27 | asReader(...) : Reader | TextStringBuilderTest.java:88:34:88:39 | target [post update] : char[] | provenance | MaD:1 | | TextStringBuilderTest.java:88:34:88:39 | target [post update] : char[] | TextStringBuilderTest.java:89:18:89:23 | target | provenance | | | TextStringBuilderTest.java:91:59:91:62 | sb47 [post update] : TextStringBuilder | TextStringBuilderTest.java:91:86:91:89 | sb47 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:91:71:91:77 | taint(...) : String | TextStringBuilderTest.java:91:59:91:62 | sb47 [post update] : TextStringBuilder | provenance | MaD:568 | @@ -3038,23 +3038,23 @@ edges | TextStringBuilderTest.java:103:13:103:16 | sb51 : TextStringBuilder | TextStringBuilderTest.java:103:33:103:38 | target [post update] : char[] | provenance | MaD:623 | | TextStringBuilderTest.java:103:33:103:38 | target [post update] : char[] | TextStringBuilderTest.java:104:18:104:23 | target | provenance | | | TextStringBuilderTest.java:106:59:106:62 | sb52 [post update] : TextStringBuilder | TextStringBuilderTest.java:106:103:106:106 | sb52 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:106:74:106:80 | taint(...) : String | TextStringBuilderTest.java:106:74:106:94 | toCharArray(...) : char[] | provenance | MaD:8 | +| TextStringBuilderTest.java:106:74:106:80 | taint(...) : String | TextStringBuilderTest.java:106:74:106:94 | toCharArray(...) : char[] | provenance | MaD:7 | | TextStringBuilderTest.java:106:74:106:94 | toCharArray(...) : char[] | TextStringBuilderTest.java:106:59:106:62 | sb52 [post update] : TextStringBuilder | provenance | MaD:625 | -| TextStringBuilderTest.java:106:103:106:106 | sb52 : TextStringBuilder | TextStringBuilderTest.java:106:103:106:117 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:106:103:106:106 | sb52 : TextStringBuilder | TextStringBuilderTest.java:106:103:106:117 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:106:103:106:106 | sb52 : TextStringBuilder | TextStringBuilderTest.java:106:103:106:117 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:107:59:107:62 | sb53 [post update] : TextStringBuilder | TextStringBuilderTest.java:107:109:107:112 | sb53 : TextStringBuilder | provenance | | -| TextStringBuilderTest.java:107:74:107:80 | taint(...) : String | TextStringBuilderTest.java:107:74:107:94 | toCharArray(...) : char[] | provenance | MaD:8 | +| TextStringBuilderTest.java:107:74:107:80 | taint(...) : String | TextStringBuilderTest.java:107:74:107:94 | toCharArray(...) : char[] | provenance | MaD:7 | | TextStringBuilderTest.java:107:74:107:94 | toCharArray(...) : char[] | TextStringBuilderTest.java:107:59:107:62 | sb53 [post update] : TextStringBuilder | provenance | MaD:625 | -| TextStringBuilderTest.java:107:109:107:112 | sb53 : TextStringBuilder | TextStringBuilderTest.java:107:109:107:123 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:107:109:107:112 | sb53 : TextStringBuilder | TextStringBuilderTest.java:107:109:107:123 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:107:109:107:112 | sb53 : TextStringBuilder | TextStringBuilderTest.java:107:109:107:123 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:108:59:108:62 | sb54 [post update] : TextStringBuilder | TextStringBuilderTest.java:108:89:108:92 | sb54 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:108:74:108:80 | taint(...) : String | TextStringBuilderTest.java:108:59:108:62 | sb54 [post update] : TextStringBuilder | provenance | MaD:625 | -| TextStringBuilderTest.java:108:89:108:92 | sb54 : TextStringBuilder | TextStringBuilderTest.java:108:89:108:103 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:108:89:108:92 | sb54 : TextStringBuilder | TextStringBuilderTest.java:108:89:108:103 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:108:89:108:92 | sb54 : TextStringBuilder | TextStringBuilderTest.java:108:89:108:103 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:109:59:109:62 | sb55 [post update] : TextStringBuilder | TextStringBuilderTest.java:109:97:109:100 | sb55 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:109:74:109:88 | (...)... : String | TextStringBuilderTest.java:109:59:109:62 | sb55 [post update] : TextStringBuilder | provenance | MaD:625 | | TextStringBuilderTest.java:109:82:109:88 | taint(...) : String | TextStringBuilderTest.java:109:74:109:88 | (...)... : String | provenance | | -| TextStringBuilderTest.java:109:97:109:100 | sb55 : TextStringBuilder | TextStringBuilderTest.java:109:97:109:111 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:109:97:109:100 | sb55 : TextStringBuilder | TextStringBuilderTest.java:109:97:109:111 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:109:97:109:100 | sb55 : TextStringBuilder | TextStringBuilderTest.java:109:97:109:111 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:110:59:110:62 | sb56 [post update] : TextStringBuilder | TextStringBuilderTest.java:110:86:110:89 | sb56 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:110:71:110:77 | taint(...) : String | TextStringBuilderTest.java:110:59:110:62 | sb56 [post update] : TextStringBuilder | provenance | MaD:568 | @@ -3063,41 +3063,41 @@ edges | TextStringBuilderTest.java:111:71:111:77 | taint(...) : String | TextStringBuilderTest.java:111:59:111:62 | sb57 [post update] : TextStringBuilder | provenance | MaD:568 | | TextStringBuilderTest.java:111:86:111:89 | sb57 : TextStringBuilder | TextStringBuilderTest.java:111:86:111:105 | midString(...) | provenance | MaD:627 | | TextStringBuilderTest.java:113:35:113:59 | new StringReader(...) : StringReader | TextStringBuilderTest.java:114:77:114:82 | reader : StringReader | provenance | | -| TextStringBuilderTest.java:113:52:113:58 | taint(...) : String | TextStringBuilderTest.java:113:35:113:59 | new StringReader(...) : StringReader | provenance | MaD:3 | +| TextStringBuilderTest.java:113:52:113:58 | taint(...) : String | TextStringBuilderTest.java:113:35:113:59 | new StringReader(...) : StringReader | provenance | MaD:2 | | TextStringBuilderTest.java:114:63:114:66 | sb58 [post update] : TextStringBuilder | TextStringBuilderTest.java:114:91:114:94 | sb58 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:114:77:114:82 | reader : StringReader | TextStringBuilderTest.java:114:63:114:66 | sb58 [post update] : TextStringBuilder | provenance | MaD:629 | -| TextStringBuilderTest.java:114:91:114:94 | sb58 : TextStringBuilder | TextStringBuilderTest.java:114:91:114:105 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:114:91:114:94 | sb58 : TextStringBuilder | TextStringBuilderTest.java:114:91:114:105 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:114:91:114:94 | sb58 : TextStringBuilder | TextStringBuilderTest.java:114:91:114:105 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:116:59:116:62 | sb59 [post update] : TextStringBuilder | TextStringBuilderTest.java:116:93:116:96 | sb59 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:116:78:116:84 | taint(...) : String | TextStringBuilderTest.java:116:59:116:62 | sb59 [post update] : TextStringBuilder | provenance | MaD:631 | -| TextStringBuilderTest.java:116:93:116:96 | sb59 : TextStringBuilder | TextStringBuilderTest.java:116:93:116:107 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:116:93:116:96 | sb59 : TextStringBuilder | TextStringBuilderTest.java:116:93:116:107 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:116:93:116:96 | sb59 : TextStringBuilder | TextStringBuilderTest.java:116:93:116:107 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:117:59:117:62 | sb60 [post update] : TextStringBuilder | TextStringBuilderTest.java:117:102:117:105 | sb60 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:117:78:117:84 | taint(...) : String | TextStringBuilderTest.java:117:59:117:62 | sb60 [post update] : TextStringBuilder | provenance | MaD:632 | -| TextStringBuilderTest.java:117:102:117:105 | sb60 : TextStringBuilder | TextStringBuilderTest.java:117:102:117:116 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:117:102:117:105 | sb60 : TextStringBuilder | TextStringBuilderTest.java:117:102:117:116 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:117:102:117:105 | sb60 : TextStringBuilder | TextStringBuilderTest.java:117:102:117:116 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:118:59:118:62 | sb61 [post update] : TextStringBuilder | TextStringBuilderTest.java:118:111:118:114 | sb61 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:118:96:118:102 | taint(...) : String | TextStringBuilderTest.java:118:59:118:62 | sb61 [post update] : TextStringBuilder | provenance | MaD:634 | -| TextStringBuilderTest.java:118:111:118:114 | sb61 : TextStringBuilder | TextStringBuilderTest.java:118:111:118:125 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:118:111:118:114 | sb61 : TextStringBuilder | TextStringBuilderTest.java:118:111:118:125 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:118:111:118:114 | sb61 : TextStringBuilder | TextStringBuilderTest.java:118:111:118:125 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:119:59:119:62 | sb62 [post update] : TextStringBuilder | TextStringBuilderTest.java:119:100:119:103 | sb62 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:119:85:119:91 | taint(...) : String | TextStringBuilderTest.java:119:59:119:62 | sb62 [post update] : TextStringBuilder | provenance | MaD:634 | -| TextStringBuilderTest.java:119:100:119:103 | sb62 : TextStringBuilder | TextStringBuilderTest.java:119:100:119:114 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:119:100:119:103 | sb62 : TextStringBuilder | TextStringBuilderTest.java:119:100:119:114 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:119:100:119:103 | sb62 : TextStringBuilder | TextStringBuilderTest.java:119:100:119:114 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:121:59:121:62 | sb64 [post update] : TextStringBuilder | TextStringBuilderTest.java:121:113:121:116 | sb64 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:121:98:121:104 | taint(...) : String | TextStringBuilderTest.java:121:59:121:62 | sb64 [post update] : TextStringBuilder | provenance | MaD:636 | -| TextStringBuilderTest.java:121:113:121:116 | sb64 : TextStringBuilder | TextStringBuilderTest.java:121:113:121:127 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:121:113:121:116 | sb64 : TextStringBuilder | TextStringBuilderTest.java:121:113:121:127 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:121:113:121:116 | sb64 : TextStringBuilder | TextStringBuilderTest.java:121:113:121:127 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:122:59:122:62 | sb65 [post update] : TextStringBuilder | TextStringBuilderTest.java:122:102:122:105 | sb65 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:122:87:122:93 | taint(...) : String | TextStringBuilderTest.java:122:59:122:62 | sb65 [post update] : TextStringBuilder | provenance | MaD:636 | -| TextStringBuilderTest.java:122:102:122:105 | sb65 : TextStringBuilder | TextStringBuilderTest.java:122:102:122:116 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:122:102:122:105 | sb65 : TextStringBuilder | TextStringBuilderTest.java:122:102:122:116 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:122:102:122:105 | sb65 : TextStringBuilder | TextStringBuilderTest.java:122:102:122:116 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:124:59:124:62 | sb67 [post update] : TextStringBuilder | TextStringBuilderTest.java:124:86:124:89 | sb67 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:124:71:124:77 | taint(...) : String | TextStringBuilderTest.java:124:59:124:62 | sb67 [post update] : TextStringBuilder | provenance | MaD:568 | | TextStringBuilderTest.java:124:86:124:89 | sb67 : TextStringBuilder | TextStringBuilderTest.java:124:86:124:104 | rightString(...) | provenance | MaD:638 | | TextStringBuilderTest.java:125:59:125:62 | sb68 [post update] : TextStringBuilder | TextStringBuilderTest.java:125:86:125:89 | sb68 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:125:71:125:77 | taint(...) : String | TextStringBuilderTest.java:125:59:125:62 | sb68 [post update] : TextStringBuilder | provenance | MaD:568 | -| TextStringBuilderTest.java:125:86:125:89 | sb68 : TextStringBuilder | TextStringBuilderTest.java:125:86:125:107 | subSequence(...) | provenance | MaD:5 | +| TextStringBuilderTest.java:125:86:125:89 | sb68 : TextStringBuilder | TextStringBuilderTest.java:125:86:125:107 | subSequence(...) | provenance | MaD:4 | | TextStringBuilderTest.java:125:86:125:89 | sb68 : TextStringBuilder | TextStringBuilderTest.java:125:86:125:107 | subSequence(...) | provenance | MaD:643 | | TextStringBuilderTest.java:126:59:126:62 | sb69 [post update] : TextStringBuilder | TextStringBuilderTest.java:126:86:126:89 | sb69 : TextStringBuilder | provenance | | | TextStringBuilderTest.java:126:71:126:77 | taint(...) : String | TextStringBuilderTest.java:126:59:126:62 | sb69 [post update] : TextStringBuilder | provenance | MaD:568 | @@ -3118,16 +3118,16 @@ edges | TextStringBuilderTest.java:131:71:131:77 | taint(...) : String | TextStringBuilderTest.java:131:59:131:62 | sb74 [post update] : TextStringBuilder | provenance | MaD:568 | | TextStringBuilderTest.java:131:86:131:89 | sb74 : TextStringBuilder | TextStringBuilderTest.java:131:86:131:107 | toStringBuilder(...) | provenance | MaD:648 | | TextStringBuilderTest.java:136:14:136:58 | append(...) : TextStringBuilder | TextStringBuilderTest.java:136:14:136:82 | append(...) : TextStringBuilder | provenance | MaD:562 | -| TextStringBuilderTest.java:136:14:136:82 | append(...) : TextStringBuilder | TextStringBuilderTest.java:136:14:136:93 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:136:14:136:82 | append(...) : TextStringBuilder | TextStringBuilderTest.java:136:14:136:93 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:136:14:136:82 | append(...) : TextStringBuilder | TextStringBuilderTest.java:136:14:136:93 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:136:51:136:57 | taint(...) : String | TextStringBuilderTest.java:136:14:136:58 | append(...) : TextStringBuilder | provenance | MaD:568+MaD:562 | | TextStringBuilderTest.java:139:9:139:45 | append(...) [post update] : TextStringBuilder | TextStringBuilderTest.java:140:14:140:31 | fluentBackflowTest : TextStringBuilder | provenance | MaD:562 | | TextStringBuilderTest.java:139:54:139:60 | taint(...) : String | TextStringBuilderTest.java:139:9:139:45 | append(...) [post update] : TextStringBuilder | provenance | MaD:568 | -| TextStringBuilderTest.java:140:14:140:31 | fluentBackflowTest : TextStringBuilder | TextStringBuilderTest.java:140:14:140:42 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:140:14:140:31 | fluentBackflowTest : TextStringBuilder | TextStringBuilderTest.java:140:14:140:42 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:140:14:140:31 | fluentBackflowTest : TextStringBuilder | TextStringBuilderTest.java:140:14:140:42 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:144:9:144:46 | append(...) [post update] : TextStringBuilder | TextStringBuilderTest.java:145:14:145:32 | fluentBackflowTest2 : TextStringBuilder | provenance | MaD:562 | | TextStringBuilderTest.java:144:55:144:61 | taint(...) : String | TextStringBuilderTest.java:144:9:144:46 | append(...) [post update] : TextStringBuilder | provenance | MaD:568 | -| TextStringBuilderTest.java:145:14:145:32 | fluentBackflowTest2 : TextStringBuilder | TextStringBuilderTest.java:145:14:145:43 | toString(...) | provenance | MaD:6 | +| TextStringBuilderTest.java:145:14:145:32 | fluentBackflowTest2 : TextStringBuilder | TextStringBuilderTest.java:145:14:145:43 | toString(...) | provenance | MaD:5 | | TextStringBuilderTest.java:145:14:145:32 | fluentBackflowTest2 : TextStringBuilder | TextStringBuilderTest.java:145:14:145:43 | toString(...) | provenance | MaD:646 | | TextStringBuilderTest.java:148:50:148:79 | new TextStringBuilder(...) : TextStringBuilder | TextStringBuilderTest.java:149:14:149:33 | fluentAllMethodsTest : TextStringBuilder | provenance | | | TextStringBuilderTest.java:148:72:148:78 | taint(...) : String | TextStringBuilderTest.java:148:50:148:79 | new TextStringBuilder(...) : TextStringBuilder | provenance | MaD:561 | @@ -3198,7 +3198,7 @@ edges | ToStringBuilderTest.java:21:71:21:85 | (...)... : String | ToStringBuilderTest.java:21:59:21:62 | sb11 [post update] : ToStringBuilder | provenance | MaD:20 | | ToStringBuilderTest.java:21:79:21:85 | taint(...) : String | ToStringBuilderTest.java:21:71:21:85 | (...)... : String | provenance | | | ToStringBuilderTest.java:21:94:21:97 | sb11 : ToStringBuilder | ToStringBuilderTest.java:21:94:21:115 | getStringBuffer(...) : StringBuffer | provenance | MaD:29 | -| ToStringBuilderTest.java:21:94:21:115 | getStringBuffer(...) : StringBuffer | ToStringBuilderTest.java:21:94:21:126 | toString(...) | provenance | MaD:6 | +| ToStringBuilderTest.java:21:94:21:115 | getStringBuffer(...) : StringBuffer | ToStringBuilderTest.java:21:94:21:126 | toString(...) | provenance | MaD:5 | | ToStringBuilderTest.java:25:14:25:58 | append(...) : ToStringBuilder | ToStringBuilderTest.java:25:14:25:82 | append(...) : ToStringBuilder | provenance | MaD:19 | | ToStringBuilderTest.java:25:14:25:82 | append(...) : ToStringBuilder | ToStringBuilderTest.java:25:14:25:93 | toString(...) | provenance | MaD:30 | | ToStringBuilderTest.java:25:51:25:57 | taint(...) : String | ToStringBuilderTest.java:25:14:25:58 | append(...) : ToStringBuilder | provenance | MaD:20+MaD:19 | From 43b52a09213d4c5da5d52188c1f8941844f51a97 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 20 Aug 2024 15:57:24 +0200 Subject: [PATCH 122/404] Java: Add change note. --- java/ql/lib/change-notes/2024-08-20-dataflow-dispatch.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2024-08-20-dataflow-dispatch.md diff --git a/java/ql/lib/change-notes/2024-08-20-dataflow-dispatch.md b/java/ql/lib/change-notes/2024-08-20-dataflow-dispatch.md new file mode 100644 index 00000000000..b67cea4c8ba --- /dev/null +++ b/java/ql/lib/change-notes/2024-08-20-dataflow-dispatch.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* A generated (Models as Data) summary model is no longer used, if there exists a source code alternative. This primarily affects the analysis, when the analysis includes generated models for the source code being analysed. From 021fd1450ea7eb4db578035153b2d179fa523f66 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 27 Aug 2024 11:43:06 +0200 Subject: [PATCH 123/404] Java: Add some dispatch examples to the external flow step test. --- .../dataflow/external-models/C.java | 32 +++++++++++++++++++ .../dataflow/external-models/steps.ext.yml | 2 ++ .../external-models/stubs/Library.java | 4 +++ 3 files changed, 38 insertions(+) diff --git a/java/ql/test/library-tests/dataflow/external-models/C.java b/java/ql/test/library-tests/dataflow/external-models/C.java index c0270dbe9f1..79d43480703 100644 --- a/java/ql/test/library-tests/dataflow/external-models/C.java +++ b/java/ql/test/library-tests/dataflow/external-models/C.java @@ -56,6 +56,24 @@ public class C { lib.apiStepArgQualGeneratedIgnored(arg1); } + void fooPossibleLibraryDispatch(Library lib) { + Object arg1 = new Object(); + + lib.id(arg1); + } + + void fooExplicitDispatch() { + Object arg1 = new Object(); + + MyLibrary lib = new MyLibrary(); + + lib.id(arg1); + } + + void fooGeneric(MyGenericLibrary lib) { + lib.get(); + } + Object stepArgRes(Object x) { return null; } @@ -73,4 +91,18 @@ public class C { Object stepArgResGenerated(Object x) { return null; } + + class MyLibrary extends Library { + @Override + // Bad implementation of the id function. + public Object id(Object x) { + return null; + } + } + + public class MyGenericLibrary { + public T get() { + return null; + } + } } diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml index fbfcf0536ae..a0f01e48d51 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml +++ b/java/ql/test/library-tests/dataflow/external-models/steps.ext.yml @@ -9,11 +9,13 @@ extensions: - ["my.qltest", "C", False, "stepQualRes", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["my.qltest", "C", False, "stepQualArg", "(Object)", "", "Argument[this]", "Argument[0]", "taint", "manual"] - ["my.qltest", "C", False, "stepArgResGenerated", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] + - ["my.qltest", "C$MyGenericLibrary", True, "get", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"] - ["my.qltest.external", "Library", False, "apiStepArgResGenerated", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] - ["my.qltest.external", "Library", False, "apiStepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] - ["my.qltest.external", "Library", False, "apiStepArgResGeneratedIgnored", "(Object,Object)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - ["my.qltest.external", "Library", False, "apiStepArgQualGenerated", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] - ["my.qltest.external", "Library", False, "apiStepArgQualGeneratedIgnored", "(Object)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"] + - ["my.qltest.external", "Library", False, "id", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"] - addsTo: pack: codeql/java-all extensible: neutralModel diff --git a/java/ql/test/library-tests/dataflow/external-models/stubs/Library.java b/java/ql/test/library-tests/dataflow/external-models/stubs/Library.java index 945d8671b39..2515c8aebfa 100644 --- a/java/ql/test/library-tests/dataflow/external-models/stubs/Library.java +++ b/java/ql/test/library-tests/dataflow/external-models/stubs/Library.java @@ -16,4 +16,8 @@ public class Library { public Object apiStepArgQualGeneratedIgnored(Object x) { return null; } + + public Object id(Object x) { + return null; + } } From 8f734ad1b2b2869430ed7436b38e9a6d1c072854 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 27 Aug 2024 11:43:47 +0200 Subject: [PATCH 124/404] Java: Tighten the criteria for when we disregard generated models. --- .../code/java/dataflow/internal/DataFlowDispatch.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll index 775d3c0067b..633a8cd3472 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll @@ -45,7 +45,7 @@ private module DispatchImpl { * The following heuristic is applied for finding the appropriate callable: * 1. If an exact manual model exists, only dispatch to the summarized callable. * 2. If a (non exact) manual model exists and/or if the source code is available, dispatch to both/either. - * 3. Only dispatch to a summarized callable (based on a generated model) if neither of the above apply. + * 3. Only dispatch to a summarized callable in case the static call target in not in source. */ DataFlowCallable viableCallable(DataFlowCall c) { exists(Call call | call = c.asCall() | @@ -53,11 +53,11 @@ private module DispatchImpl { or not ( // Only use summarized callables with generated summaries in case - // we are not able to dispatch to a source declaration. + // the static call target is not in the source code. // Note that if applyGeneratedModel holds it implies that there doesn't - // exist a manual (exact) model. - exists(Callable callable | callable = sourceDispatch(call) | - callable.fromSource() and not callable.isStub() + // exist a manual model. + exists(Callable staticTarget | staticTarget = call.getCallee().getSourceDeclaration() | + staticTarget.fromSource() and not staticTarget.isStub() ) and result.asSummarizedCallable().applyGeneratedModel() ) and From 15b06907ddd8b45491f4de1e7e6401c48009aa97 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 27 Aug 2024 11:51:16 +0200 Subject: [PATCH 125/404] Java: Updated expected test output. --- .../test/library-tests/dataflow/external-models/steps.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/test/library-tests/dataflow/external-models/steps.expected b/java/ql/test/library-tests/dataflow/external-models/steps.expected index e9cbb7ec99e..37d38018502 100644 --- a/java/ql/test/library-tests/dataflow/external-models/steps.expected +++ b/java/ql/test/library-tests/dataflow/external-models/steps.expected @@ -11,3 +11,4 @@ invalidModelRow | C.java:44:32:44:35 | arg1 | C.java:44:5:44:36 | apiStepArgResGenerated(...) | | C.java:50:45:50:48 | arg2 | C.java:50:5:50:49 | apiStepArgResGeneratedIgnored(...) | | C.java:52:33:52:36 | arg1 | C.java:52:5:52:7 | lib [post update] | +| C.java:62:12:62:15 | arg1 | C.java:62:5:62:16 | id(...) | From 1cb23e7e8650c39f41c08097d1315424bad9073f Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 27 Aug 2024 13:16:10 +0100 Subject: [PATCH 126/404] Exclude certificates from being cinsidered sensitive data by cleartext-storage and cleartext-logging queries --- .../security/dataflow/CleartextLoggingCustomizations.qll | 3 ++- .../security/dataflow/CleartextStorageCustomizations.qll | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll index ae61bd04314..d794b024996 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll @@ -41,7 +41,8 @@ module CleartextLogging { */ class SensitiveDataSourceAsSource extends Source, SensitiveDataSource { SensitiveDataSourceAsSource() { - not SensitiveDataSource.super.getClassification() = SensitiveDataClassification::id() + not SensitiveDataSource.super.getClassification() = + [SensitiveDataClassification::id(), SensitiveDataClassification::certificate()] } override SensitiveDataClassification getClassification() { diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll index 001b9395ef4..ebe70bc1b59 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll @@ -40,7 +40,8 @@ module CleartextStorage { */ class SensitiveDataSourceAsSource extends Source, SensitiveDataSource { SensitiveDataSourceAsSource() { - not SensitiveDataSource.super.getClassification() = SensitiveDataClassification::id() + not SensitiveDataSource.super.getClassification() = + [SensitiveDataClassification::id(), SensitiveDataClassification::certificate()] } override SensitiveDataClassification getClassification() { From fc24ca304d141b02797fc88f5370078bdc1257e8 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 27 Aug 2024 14:03:01 +0100 Subject: [PATCH 127/404] Update tests --- .../CleartextLogging.expected | 2 -- .../Security/CWE-312-CleartextLogging/test.py | 6 ++--- .../CleartextStorage.expected | 22 +++++++++---------- .../Security/CWE-312-CleartextStorage/test.py | 11 +++++++++- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected index 1322f5b80e6..dca1a33e73a 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/CleartextLogging.expected @@ -30,7 +30,6 @@ nodes | test.py:23:58:23:65 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | | test.py:27:40:27:47 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | | test.py:30:58:30:65 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | -| test.py:34:30:34:39 | ControlFlowNode for get_cert() | semmle.label | ControlFlowNode for get_cert() | | test.py:37:11:37:24 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:39:22:39:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | | test.py:40:22:40:35 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | @@ -73,7 +72,6 @@ subpaths | test.py:23:58:23:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:23:58:23:65 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:27:40:27:47 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:27:40:27:47 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:30:58:30:65 | ControlFlowNode for password | test.py:19:16:19:29 | ControlFlowNode for get_password() | test.py:30:58:30:65 | ControlFlowNode for password | This expression logs $@ as clear text. | test.py:19:16:19:29 | ControlFlowNode for get_password() | sensitive data (password) | -| test.py:34:30:34:39 | ControlFlowNode for get_cert() | test.py:34:30:34:39 | ControlFlowNode for get_cert() | test.py:34:30:34:39 | ControlFlowNode for get_cert() | This expression logs $@ as clear text. | test.py:34:30:34:39 | ControlFlowNode for get_cert() | sensitive data (certificate) | | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | test.py:37:11:37:24 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:37:11:37:24 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | test.py:39:22:39:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:39:22:39:35 | ControlFlowNode for get_password() | sensitive data (password) | | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | test.py:40:22:40:35 | ControlFlowNode for get_password() | This expression logs $@ as clear text. | test.py:40:22:40:35 | ControlFlowNode for get_password() | sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py index 94a8c9db836..d8d70c56bd5 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextLogging/test.py @@ -31,7 +31,7 @@ def log_password(): def log_cert(): - logging.debug("Cert=%s", get_cert()) # NOT OK + logging.debug("Cert=%s", get_cert()) # OK def print_password(): print(get_password()) # NOT OK @@ -52,8 +52,8 @@ def log_private(): print(passportNo) # NOT OK def log2(post_code, zipCode, home_address): - print(post_code) # NOT OK, but NOT FOUND - "code" is treated as enxrypted and thus not sensitive - print(zipCode) # NOT OK, but NOT FOUND - "code" is treated as enxrypted and thus not sensitive + print(post_code) # NOT OK, but NOT FOUND - "code" is treated as encrypted and thus not sensitive + print(zipCode) # NOT OK, but NOT FOUND - "code" is treated as encrypted and thus not sensitive print(home_address) # NOT OK def log3(user_latitude, user_longitude): diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected index eac0bd37b1b..c3c1206ce92 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/CleartextStorage.expected @@ -3,10 +3,10 @@ edges | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | password_in_cookie.py:7:5:7:12 | ControlFlowNode for password | provenance | | | password_in_cookie.py:14:5:14:12 | ControlFlowNode for password | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | provenance | | | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | password_in_cookie.py:14:5:14:12 | ControlFlowNode for password | provenance | | -| test.py:6:5:6:8 | ControlFlowNode for cert | test.py:8:20:8:23 | ControlFlowNode for cert | provenance | | -| test.py:6:5:6:8 | ControlFlowNode for cert | test.py:9:9:9:13 | ControlFlowNode for lines | provenance | | -| test.py:6:12:6:21 | ControlFlowNode for get_cert() | test.py:6:5:6:8 | ControlFlowNode for cert | provenance | | -| test.py:9:9:9:13 | ControlFlowNode for lines | test.py:10:25:10:29 | ControlFlowNode for lines | provenance | | +| test.py:15:5:15:12 | ControlFlowNode for password | test.py:17:20:17:27 | ControlFlowNode for password | provenance | | +| test.py:15:5:15:12 | ControlFlowNode for password | test.py:18:9:18:13 | ControlFlowNode for lines | provenance | | +| test.py:15:16:15:29 | ControlFlowNode for get_password() | test.py:15:5:15:12 | ControlFlowNode for password | provenance | | +| test.py:18:9:18:13 | ControlFlowNode for lines | test.py:19:25:19:29 | ControlFlowNode for lines | provenance | | nodes | password_in_cookie.py:7:5:7:12 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | @@ -14,14 +14,14 @@ nodes | password_in_cookie.py:14:5:14:12 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | -| test.py:6:5:6:8 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert | -| test.py:6:12:6:21 | ControlFlowNode for get_cert() | semmle.label | ControlFlowNode for get_cert() | -| test.py:8:20:8:23 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert | -| test.py:9:9:9:13 | ControlFlowNode for lines | semmle.label | ControlFlowNode for lines | -| test.py:10:25:10:29 | ControlFlowNode for lines | semmle.label | ControlFlowNode for lines | +| test.py:15:5:15:12 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +| test.py:15:16:15:29 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | +| test.py:17:20:17:27 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +| test.py:18:9:18:13 | ControlFlowNode for lines | semmle.label | ControlFlowNode for lines | +| test.py:19:25:19:29 | ControlFlowNode for lines | semmle.label | ControlFlowNode for lines | subpaths #select | password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | password_in_cookie.py:9:33:9:40 | ControlFlowNode for password | This expression stores $@ as clear text. | password_in_cookie.py:7:16:7:43 | ControlFlowNode for Attribute() | sensitive data (password) | | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | password_in_cookie.py:16:33:16:40 | ControlFlowNode for password | This expression stores $@ as clear text. | password_in_cookie.py:14:16:14:43 | ControlFlowNode for Attribute() | sensitive data (password) | -| test.py:8:20:8:23 | ControlFlowNode for cert | test.py:6:12:6:21 | ControlFlowNode for get_cert() | test.py:8:20:8:23 | ControlFlowNode for cert | This expression stores $@ as clear text. | test.py:6:12:6:21 | ControlFlowNode for get_cert() | sensitive data (certificate) | -| test.py:10:25:10:29 | ControlFlowNode for lines | test.py:6:12:6:21 | ControlFlowNode for get_cert() | test.py:10:25:10:29 | ControlFlowNode for lines | This expression stores $@ as clear text. | test.py:6:12:6:21 | ControlFlowNode for get_cert() | sensitive data (certificate) | +| test.py:17:20:17:27 | ControlFlowNode for password | test.py:15:16:15:29 | ControlFlowNode for get_password() | test.py:17:20:17:27 | ControlFlowNode for password | This expression stores $@ as clear text. | test.py:15:16:15:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:19:25:19:29 | ControlFlowNode for lines | test.py:15:16:15:29 | ControlFlowNode for get_password() | test.py:19:25:19:29 | ControlFlowNode for lines | This expression stores $@ as clear text. | test.py:15:16:15:29 | ControlFlowNode for get_password() | sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/test.py b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/test.py index f232f1a2ad6..6d04aa4b170 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/test.py +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage/test.py @@ -1,12 +1,21 @@ def get_cert(): return "" +def get_password(): + return "password" def write_cert(filename): cert = get_cert() with open(filename, "w") as file: - file.write(cert) # NOT OK + file.write(cert) # OK lines = [cert + "\n"] + file.writelines(lines) # OK + +def write_password(filename): + password = get_password() + with open(filename, "w") as file: + file.write(password) # NOT OK + lines = [password + "\n"] file.writelines(lines) # NOT OK def FPs(): From 80b6135a64d0acbdcd1a6bfe40bb896e710940e6 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 27 Aug 2024 14:48:57 +0200 Subject: [PATCH 128/404] Data flow: Move `toNormalSinkNodeEx` into `PathNodeMid` --- .../codeql/dataflow/internal/DataFlowImpl.qll | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 75ccdbecf9f..3af2de29cc1 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -246,16 +246,6 @@ module MakeImpl Lang> { ReturnKindExt getKind() { result = pos.getKind() } } - /** If `node` corresponds to a sink, gets the normal node for that sink. */ - pragma[nomagic] - private NodeEx toNormalSinkNodeEx(NodeEx node) { - exists(Node n | - node.asNodeOrImplicitRead() = n and - (Config::isSink(n) or Config::isSink(n, _)) and - result.asNode() = n - ) - } - private predicate inBarrier(NodeEx node) { exists(Node n | node.asNode() = n and @@ -2607,7 +2597,7 @@ module MakeImpl Lang> { TPathNodeSink(NodeEx node, FlowState state) { exists(PathNodeMid sink | sink.isAtSink() and - node = toNormalSinkNodeEx(sink.getNodeEx()) and + node = sink.toNormalSinkNodeEx() and state = sink.getState() ) } or @@ -2734,6 +2724,16 @@ module MakeImpl Lang> { ) } + /** If this node corresponds to a sink, gets the normal node for that sink. */ + pragma[nomagic] + NodeEx toNormalSinkNodeEx() { + exists(Node n | + node.asNodeOrImplicitRead() = n and + (Config::isSink(n) or Config::isSink(n, _)) and + result.asNode() = n + ) + } + override PathNodeImpl getASuccessorImpl(string label) { // an intermediate step to another intermediate node exists(string l2 | result = this.getSuccMid(l2) | @@ -2825,7 +2825,7 @@ module MakeImpl Lang> { PathNodeSink projectToSink(string model) { this.isAtSink() and sinkModel(node, model) and - result.getNodeEx() = toNormalSinkNodeEx(node) and + result.getNodeEx() = this.toNormalSinkNodeEx() and result.getState() = state } } From b589fcad1124bb5b0fecd84fdf640a99d1f24da7 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 27 Aug 2024 15:42:24 +0200 Subject: [PATCH 129/404] Data flow: Tweak join-order in `toNormalSinkNodeEx` --- shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 3af2de29cc1..dc0da810f11 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2728,7 +2728,7 @@ module MakeImpl Lang> { pragma[nomagic] NodeEx toNormalSinkNodeEx() { exists(Node n | - node.asNodeOrImplicitRead() = n and + pragma[only_bind_out](node.asNodeOrImplicitRead()) = n and (Config::isSink(n) or Config::isSink(n, _)) and result.asNode() = n ) From 927710017ec7db99b990c8d8a4c89f9f65477059 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 27 Aug 2024 16:57:03 +0200 Subject: [PATCH 130/404] Rust: add some configuration and logging --- rust/Cargo.lock | 1207 +++++++++++++++++++++++++++++++++++++++----- rust/Cargo.toml | 10 + rust/src/config.rs | 45 ++ rust/src/main.rs | 110 ++-- 4 files changed, 1186 insertions(+), 186 deletions(-) create mode 100644 rust/src/config.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 3c02ab3803a..84d942c586f 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -11,6 +11,70 @@ dependencies = [ "tracing", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.86" @@ -23,12 +87,27 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "atomic" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" +dependencies = [ + "bytemuck", +] + [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -41,6 +120,18 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" + [[package]] name = "camino" version = "1.1.7" @@ -73,6 +164,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cc" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -123,22 +223,99 @@ dependencies = [ "chalk-derive", "chalk-ir", "ena", - "indexmap", + "indexmap 2.4.0", "itertools", "petgraph", "rustc-hash", "tracing", ] +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[package]] +name = "clap" +version = "4.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + [[package]] name = "codeql-rust" version = "0.1.0" dependencies = [ + "anyhow", + "clap", + "figment", + "log", + "num-traits", + "ra_ap_base_db 0.0.231", "ra_ap_hir", + "ra_ap_hir_def 0.0.231", "ra_ap_load-cargo", "ra_ap_project_model", + "serde", + "serde_with", + "stderrlog", ] +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "countme" version = "3.0.1" @@ -185,6 +362,41 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -192,12 +404,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "drop_bomb" version = "0.1.5" @@ -225,6 +447,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "figment" +version = "0.10.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" +dependencies = [ + "atomic", + "pear", + "serde", + "uncased", + "version_check", +] + [[package]] name = "filetime" version = "0.2.24" @@ -243,6 +478,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -258,6 +499,12 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.5" @@ -270,6 +517,24 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "home" version = "0.5.9" @@ -279,6 +544,46 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.4.0" @@ -286,9 +591,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", + "serde", ] +[[package]] +name = "inlinable_string" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" + [[package]] name = "inotify" version = "0.9.6" @@ -309,6 +621,23 @@ dependencies = [ "libc", ] +[[package]] +name = "is-terminal" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.12.1" @@ -330,6 +659,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b23360e99b8717f20aaa4598f5a6541efbe30630039fbc7706cf954a87947ae" +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -466,6 +804,21 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -501,6 +854,29 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "pear" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" +dependencies = [ + "inlinable_string", + "pear_codegen", + "yansi", +] + +[[package]] +name = "pear_codegen" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + [[package]] name = "perf-event" version = "0.4.7" @@ -527,7 +903,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 2.4.0", ] [[package]] @@ -536,6 +912,12 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro2" version = "1.0.86" @@ -545,6 +927,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", +] + [[package]] name = "quote" version = "1.0.36" @@ -561,7 +956,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80b1d613eee933486c0613a7bc26e515e46f43adf479d1edd5e537f983e9ce46" dependencies = [ "bitflags 2.6.0", - "ra-ap-rustc_index", + "ra-ap-rustc_index 0.53.0", + "tracing", +] + +[[package]] +name = "ra-ap-rustc_abi" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b011c39d409940a890414e3a7b239762ac16d88029ad71b050a8374831b93790" +dependencies = [ + "bitflags 2.6.0", + "ra-ap-rustc_index 0.63.0", "tracing", ] @@ -572,7 +978,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f072060ac77e9e1a02cc20028095993af7e72cc0804779c68bcbf47b16de49c9" dependencies = [ "arrayvec", - "ra-ap-rustc_index_macros", + "ra-ap-rustc_index_macros 0.53.0", + "smallvec", +] + +[[package]] +name = "ra-ap-rustc_index" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9027acdee649b0b27eb10b7db5be833efee3362d394935c5eed8f0745a9d43ce" +dependencies = [ + "arrayvec", + "ra-ap-rustc_index_macros 0.63.0", "smallvec", ] @@ -588,6 +1005,17 @@ dependencies = [ "synstructure", ] +[[package]] +name = "ra-ap-rustc_index_macros" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "540b86dc0384141ac8e825fc2874cd44bffd4277d99d8ec63ee416f1a98d5997" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "ra-ap-rustc_lexer" version = "0.53.0" @@ -598,14 +1026,34 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "ra-ap-rustc_lexer" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bdf98bb457b47b9ae4aeebf867d0ca440c86925e0b6381658c4a02589748c9d" +dependencies = [ + "unicode-properties", + "unicode-xid", +] + [[package]] name = "ra-ap-rustc_parse_format" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dad7a491c2554590222e0c9212dcb7c2e7aceb668875075012a35ea780d135" dependencies = [ - "ra-ap-rustc_index", - "ra-ap-rustc_lexer", + "ra-ap-rustc_index 0.53.0", + "ra-ap-rustc_lexer 0.53.0", +] + +[[package]] +name = "ra-ap-rustc_parse_format" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8fe3556ab6311bb775220563a300e2bf62ec56404521fe0c511a583937683d5" +dependencies = [ + "ra-ap-rustc_index 0.63.0", + "ra-ap-rustc_lexer 0.63.0", ] [[package]] @@ -614,7 +1062,7 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34768e1faf88c31f2e9ad57b48318a52b507dafac0cddbf01b5d63bfc0b0a365" dependencies = [ - "ra-ap-rustc_index", + "ra-ap-rustc_index 0.53.0", "rustc-hash", "rustc_apfloat", "smallvec", @@ -629,13 +1077,34 @@ checksum = "2aae8f3b0315876c1aa11dc0aac7795b27cb9e21a2a870667842e97e6b7dc3b5" dependencies = [ "la-arena", "lz4_flex", - "ra_ap_cfg", - "ra_ap_intern", - "ra_ap_salsa", - "ra_ap_span", - "ra_ap_stdx", - "ra_ap_syntax", - "ra_ap_vfs", + "ra_ap_cfg 0.0.229", + "ra_ap_intern 0.0.229", + "ra_ap_salsa 0.0.229", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_syntax 0.0.229", + "ra_ap_vfs 0.0.229", + "rustc-hash", + "semver", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_base_db" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f98f5aab31c0667a8c892e91ba22140af28ba1ef364120a2e3a13e6e39a3aa6" +dependencies = [ + "la-arena", + "lz4_flex", + "ra_ap_cfg 0.0.231", + "ra_ap_intern 0.0.231", + "ra_ap_salsa 0.0.231", + "ra_ap_span 0.0.231", + "ra_ap_stdx 0.0.231", + "ra_ap_syntax 0.0.231", + "ra_ap_vfs 0.0.231", "rustc-hash", "semver", "tracing", @@ -648,8 +1117,19 @@ version = "0.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac59191045154789b3b3f9f8c67f35439c3cbd9e36107dd62d04d4a4b2c95322" dependencies = [ - "ra_ap_intern", - "ra_ap_tt", + "ra_ap_intern 0.0.229", + "ra_ap_tt 0.0.229", + "rustc-hash", +] + +[[package]] +name = "ra_ap_cfg" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29e1d1365f6d9b9712678f19781af1d0b348fd08f5117fb0788d0aedf28b1e39" +dependencies = [ + "ra_ap_intern 0.0.231", + "ra_ap_tt 0.0.231", "rustc-hash", ] @@ -663,16 +1143,16 @@ dependencies = [ "either", "itertools", "once_cell", - "ra_ap_base_db", - "ra_ap_cfg", - "ra_ap_hir_def", - "ra_ap_hir_expand", + "ra_ap_base_db 0.0.229", + "ra_ap_cfg 0.0.229", + "ra_ap_hir_def 0.0.229", + "ra_ap_hir_expand 0.0.229", "ra_ap_hir_ty", - "ra_ap_intern", - "ra_ap_span", - "ra_ap_stdx", - "ra_ap_syntax", - "ra_ap_tt", + "ra_ap_intern 0.0.229", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_syntax 0.0.229", + "ra_ap_tt 0.0.229", "rustc-hash", "smallvec", "tracing", @@ -692,23 +1172,59 @@ dependencies = [ "drop_bomb", "either", "fst", - "hashbrown", - "indexmap", + "hashbrown 0.14.5", + "indexmap 2.4.0", "itertools", "la-arena", "once_cell", - "ra-ap-rustc_abi", - "ra-ap-rustc_parse_format", - "ra_ap_base_db", - "ra_ap_cfg", - "ra_ap_hir_expand", - "ra_ap_intern", - "ra_ap_limit", - "ra_ap_mbe", - "ra_ap_span", - "ra_ap_stdx", - "ra_ap_syntax", - "ra_ap_tt", + "ra-ap-rustc_abi 0.53.0", + "ra-ap-rustc_parse_format 0.53.0", + "ra_ap_base_db 0.0.229", + "ra_ap_cfg 0.0.229", + "ra_ap_hir_expand 0.0.229", + "ra_ap_intern 0.0.229", + "ra_ap_limit 0.0.229", + "ra_ap_mbe 0.0.229", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_syntax 0.0.229", + "ra_ap_tt 0.0.229", + "rustc-hash", + "rustc_apfloat", + "smallvec", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_hir_def" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f1f7b81fc94e9753859e6f5525307e1bfe9e9149e1404bdd405fa8f3e7b509" +dependencies = [ + "arrayvec", + "bitflags 2.6.0", + "cov-mark", + "dashmap", + "drop_bomb", + "either", + "fst", + "hashbrown 0.14.5", + "indexmap 2.4.0", + "itertools", + "la-arena", + "ra-ap-rustc_abi 0.63.0", + "ra-ap-rustc_parse_format 0.63.0", + "ra_ap_base_db 0.0.231", + "ra_ap_cfg 0.0.231", + "ra_ap_hir_expand 0.0.231", + "ra_ap_intern 0.0.231", + "ra_ap_limit 0.0.231", + "ra_ap_mbe 0.0.231", + "ra_ap_span 0.0.231", + "ra_ap_stdx 0.0.231", + "ra_ap_syntax 0.0.231", + "ra_ap_tt 0.0.231", "rustc-hash", "rustc_apfloat", "smallvec", @@ -724,20 +1240,48 @@ checksum = "b7e3c27bb239be9c6f835790f32d1a6e82345713c2ea63605d3270f06daf5caf" dependencies = [ "cov-mark", "either", - "hashbrown", + "hashbrown 0.14.5", "itertools", "la-arena", - "ra_ap_base_db", - "ra_ap_cfg", - "ra_ap_intern", - "ra_ap_limit", - "ra_ap_mbe", - "ra_ap_parser", - "ra_ap_span", - "ra_ap_stdx", - "ra_ap_syntax", - "ra_ap_syntax-bridge", - "ra_ap_tt", + "ra_ap_base_db 0.0.229", + "ra_ap_cfg 0.0.229", + "ra_ap_intern 0.0.229", + "ra_ap_limit 0.0.229", + "ra_ap_mbe 0.0.229", + "ra_ap_parser 0.0.229", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_syntax 0.0.229", + "ra_ap_syntax-bridge 0.0.229", + "ra_ap_tt 0.0.229", + "rustc-hash", + "smallvec", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_hir_expand" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e10670696adf8b7c930f02d16326b397288ce0ef02676e41dd142817badc7b" +dependencies = [ + "cov-mark", + "either", + "hashbrown 0.14.5", + "itertools", + "la-arena", + "ra_ap_base_db 0.0.231", + "ra_ap_cfg 0.0.231", + "ra_ap_intern 0.0.231", + "ra_ap_limit 0.0.231", + "ra_ap_mbe 0.0.231", + "ra_ap_parser 0.0.231", + "ra_ap_span 0.0.231", + "ra_ap_stdx 0.0.231", + "ra_ap_syntax 0.0.231", + "ra_ap_syntax-bridge 0.0.231", + "ra_ap_tt 0.0.231", "rustc-hash", "smallvec", "tracing", @@ -759,23 +1303,23 @@ dependencies = [ "cov-mark", "either", "ena", - "indexmap", + "indexmap 2.4.0", "itertools", "la-arena", "nohash-hasher", "once_cell", "oorandom", - "ra-ap-rustc_abi", - "ra-ap-rustc_index", + "ra-ap-rustc_abi 0.53.0", + "ra-ap-rustc_index 0.53.0", "ra-ap-rustc_pattern_analysis", - "ra_ap_base_db", - "ra_ap_hir_def", - "ra_ap_hir_expand", - "ra_ap_intern", - "ra_ap_limit", - "ra_ap_span", - "ra_ap_stdx", - "ra_ap_syntax", + "ra_ap_base_db 0.0.229", + "ra_ap_hir_def 0.0.229", + "ra_ap_hir_expand 0.0.229", + "ra_ap_intern 0.0.229", + "ra_ap_limit 0.0.229", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_syntax 0.0.229", "rustc-hash", "rustc_apfloat", "scoped-tls", @@ -797,21 +1341,21 @@ dependencies = [ "crossbeam-channel", "either", "fst", - "indexmap", + "indexmap 2.4.0", "itertools", "line-index", "memchr", "nohash-hasher", "once_cell", - "ra_ap_base_db", + "ra_ap_base_db 0.0.229", "ra_ap_hir", - "ra_ap_limit", - "ra_ap_parser", + "ra_ap_limit 0.0.229", + "ra_ap_parser 0.0.229", "ra_ap_profile", - "ra_ap_span", - "ra_ap_stdx", - "ra_ap_syntax", - "ra_ap_text_edit", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_syntax 0.0.229", + "ra_ap_text_edit 0.0.229", "rayon", "rustc-hash", "tracing", @@ -825,7 +1369,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeec56dfe875fd865cc9afb7d0a0a6af832bf323b6db461844ba1de2fa7006b" dependencies = [ "dashmap", - "hashbrown", + "hashbrown 0.14.5", + "rustc-hash", + "sptr", + "triomphe", +] + +[[package]] +name = "ra_ap_intern" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3376767f47bb4f16cf14a54dad0fe4058d3baac6f9394662cd026a4b572e0a6a" +dependencies = [ + "dashmap", + "hashbrown 0.14.5", "rustc-hash", "sptr", "triomphe", @@ -837,6 +1394,12 @@ version = "0.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6d33f2d8eda04460315de38992e3681dd799c27e712788a7aeee9909bc1c0f5" +[[package]] +name = "ra_ap_limit" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d20a0946a1510ddad977d54f2deab510e27d4e9a7406942152560312a9d14211" + [[package]] name = "ra_ap_load-cargo" version = "0.0.229" @@ -846,15 +1409,15 @@ dependencies = [ "anyhow", "crossbeam-channel", "itertools", - "ra_ap_hir_expand", + "ra_ap_hir_expand 0.0.229", "ra_ap_ide_db", - "ra_ap_intern", - "ra_ap_paths", + "ra_ap_intern 0.0.229", + "ra_ap_paths 0.0.229", "ra_ap_proc_macro_api", "ra_ap_project_model", - "ra_ap_span", - "ra_ap_tt", - "ra_ap_vfs", + "ra_ap_span 0.0.229", + "ra_ap_tt 0.0.229", + "ra_ap_vfs 0.0.229", "ra_ap_vfs-notify", "tracing", ] @@ -867,13 +1430,33 @@ checksum = "77e45337e002d5c0efcba96769da0bd2d94c4e66e2d315f627fea7c877380141" dependencies = [ "arrayvec", "cov-mark", - "ra_ap_intern", - "ra_ap_parser", - "ra_ap_span", - "ra_ap_stdx", - "ra_ap_syntax", - "ra_ap_syntax-bridge", - "ra_ap_tt", + "ra_ap_intern 0.0.229", + "ra_ap_parser 0.0.229", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_syntax 0.0.229", + "ra_ap_syntax-bridge 0.0.229", + "ra_ap_tt 0.0.229", + "rustc-hash", + "smallvec", + "tracing", +] + +[[package]] +name = "ra_ap_mbe" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1b121f5ccf31043a05a45c713f230adec971a81eb391a003ffdf0122c4982bc" +dependencies = [ + "arrayvec", + "cov-mark", + "ra_ap_intern 0.0.231", + "ra_ap_parser 0.0.231", + "ra_ap_span 0.0.231", + "ra_ap_stdx 0.0.231", + "ra_ap_syntax 0.0.231", + "ra_ap_syntax-bridge 0.0.231", + "ra_ap_tt 0.0.231", "rustc-hash", "smallvec", "tracing", @@ -886,8 +1469,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "094cb41571e0c97501e1171f638bfdf4edb5f376d283b1ab04f3411aa3a44f51" dependencies = [ "drop_bomb", - "ra-ap-rustc_lexer", - "ra_ap_limit", + "ra-ap-rustc_lexer 0.53.0", + "ra_ap_limit 0.0.229", + "tracing", +] + +[[package]] +name = "ra_ap_parser" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bba94511bed529739ab103ecf42248bb2a348f26c6a77365cc0f64e7995ff7" +dependencies = [ + "drop_bomb", + "ra-ap-rustc_lexer 0.63.0", + "ra_ap_limit 0.0.231", "tracing", ] @@ -901,19 +1496,28 @@ dependencies = [ "serde", ] +[[package]] +name = "ra_ap_paths" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cf2e1472a025d3110ce176757ae60b550003ab492ed835abcc95964b2dd3ec8" +dependencies = [ + "camino", +] + [[package]] name = "ra_ap_proc_macro_api" version = "0.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a2480058c6228d6ccdd6cfe1fa01c081f081ec6a6ea1a241b88618576ae6eff" dependencies = [ - "indexmap", - "ra_ap_base_db", - "ra_ap_intern", - "ra_ap_paths", - "ra_ap_span", - "ra_ap_stdx", - "ra_ap_tt", + "indexmap 2.4.0", + "ra_ap_base_db 0.0.229", + "ra_ap_intern 0.0.229", + "ra_ap_paths 0.0.229", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_tt 0.0.229", "rustc-hash", "serde", "serde_json", @@ -942,12 +1546,12 @@ dependencies = [ "cargo_metadata", "itertools", "la-arena", - "ra_ap_base_db", - "ra_ap_cfg", - "ra_ap_intern", - "ra_ap_paths", - "ra_ap_span", - "ra_ap_stdx", + "ra_ap_base_db 0.0.229", + "ra_ap_cfg 0.0.229", + "ra_ap_intern 0.0.229", + "ra_ap_paths 0.0.229", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", "ra_ap_toolchain", "rustc-hash", "semver", @@ -963,12 +1567,30 @@ version = "0.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f6e29648a086801b2bd047a88e9b73782c354fca9117d1208bebbfd6a849a61" dependencies = [ - "indexmap", + "indexmap 2.4.0", "itertools", "lock_api", "oorandom", "parking_lot", - "ra_ap_salsa-macros", + "ra_ap_salsa-macros 0.0.229", + "rustc-hash", + "smallvec", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_salsa" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90a0c97538b300ac985999b68b797e9097f68069b91682029b98df15ffd005b5" +dependencies = [ + "indexmap 2.4.0", + "itertools", + "lock_api", + "oorandom", + "parking_lot", + "ra_ap_salsa-macros 0.0.231", "rustc-hash", "smallvec", "tracing", @@ -981,7 +1603,19 @@ version = "0.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d104209e089a63a1aa8f9a5f06c6350b1508d856fca4c25002f1d8e7c04a685b" dependencies = [ - "heck", + "heck 0.4.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ra_ap_salsa-macros" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79745f516e5963a928aa2bc87d273c39a9bc3661283fe42103987c6d0da66d89" +dependencies = [ + "heck 0.4.1", "proc-macro2", "quote", "syn", @@ -993,12 +1627,28 @@ version = "0.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d30beb9ac55357e4c56f8f8e5c84571ce204f10ba43b55640c51053e806e6b8" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", "la-arena", - "ra_ap_salsa", - "ra_ap_stdx", - "ra_ap_syntax", - "ra_ap_vfs", + "ra_ap_salsa 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_syntax 0.0.229", + "ra_ap_vfs 0.0.229", + "rustc-hash", + "text-size", +] + +[[package]] +name = "ra_ap_span" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be5a26bfa587bd20da97371a406e4b2139c153dd7a4b6f1509e9a7d42dcbf22" +dependencies = [ + "hashbrown 0.14.5", + "la-arena", + "ra_ap_salsa 0.0.231", + "ra_ap_stdx 0.0.231", + "ra_ap_syntax 0.0.231", + "ra_ap_vfs 0.0.231", "rustc-hash", "text-size", ] @@ -1018,6 +1668,21 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ra_ap_stdx" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca9d3c7ff6fdc0ffd392ea4a33d7ec295eeab11943883c4c1089e006f4c760bb" +dependencies = [ + "always-assert", + "crossbeam-channel", + "itertools", + "jod-thread", + "libc", + "miow", + "windows-sys 0.52.0", +] + [[package]] name = "ra_ap_syntax" version = "0.0.229" @@ -1026,13 +1691,34 @@ checksum = "575c1e3deb1cb39e0939a95a4cb4339ee95b1283157cf03bc1bdaf76e6ebca8d" dependencies = [ "cov-mark", "either", - "indexmap", + "indexmap 2.4.0", "itertools", "once_cell", - "ra-ap-rustc_lexer", - "ra_ap_parser", - "ra_ap_stdx", - "ra_ap_text_edit", + "ra-ap-rustc_lexer 0.53.0", + "ra_ap_parser 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_text_edit 0.0.229", + "rowan", + "rustc-hash", + "smol_str", + "tracing", + "triomphe", +] + +[[package]] +name = "ra_ap_syntax" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81403d6261c22d4407f25023c2140c04ae66fb27cb370afd096bc3d1dd9884ba" +dependencies = [ + "cov-mark", + "either", + "indexmap 2.4.0", + "itertools", + "ra-ap-rustc_lexer 0.63.0", + "ra_ap_parser 0.0.231", + "ra_ap_stdx 0.0.231", + "ra_ap_text_edit 0.0.231", "rowan", "rustc-hash", "smol_str", @@ -1046,12 +1732,28 @@ version = "0.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f19c53a1f9f50d76f50b7c0c83cda0fa5de09a182d8f4ae3575ea986a24fa234" dependencies = [ - "ra_ap_intern", - "ra_ap_parser", - "ra_ap_span", - "ra_ap_stdx", - "ra_ap_syntax", - "ra_ap_tt", + "ra_ap_intern 0.0.229", + "ra_ap_parser 0.0.229", + "ra_ap_span 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_syntax 0.0.229", + "ra_ap_tt 0.0.229", + "rustc-hash", + "tracing", +] + +[[package]] +name = "ra_ap_syntax-bridge" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2c55c65a50855847be853e3572381b53b5faf2527f954024d06e0f7c6898c26" +dependencies = [ + "ra_ap_intern 0.0.231", + "ra_ap_parser 0.0.231", + "ra_ap_span 0.0.231", + "ra_ap_stdx 0.0.231", + "ra_ap_syntax 0.0.231", + "ra_ap_tt 0.0.231", "rustc-hash", "tracing", ] @@ -1066,6 +1768,16 @@ dependencies = [ "text-size", ] +[[package]] +name = "ra_ap_text_edit" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4916f05a8a78db53248a5ce0aa49167013d7dd7e7e59df82aaf284f5febd24f6" +dependencies = [ + "itertools", + "text-size", +] + [[package]] name = "ra_ap_toolchain" version = "0.0.229" @@ -1083,9 +1795,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "851bc23c870c67bd729e33056e001a2e07b16a31da13affe73d78e77049b12b8" dependencies = [ "arrayvec", - "ra-ap-rustc_lexer", - "ra_ap_intern", - "ra_ap_stdx", + "ra-ap-rustc_lexer 0.53.0", + "ra_ap_intern 0.0.229", + "ra_ap_stdx 0.0.229", + "text-size", +] + +[[package]] +name = "ra_ap_tt" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7214288c8c784a5ac6db30d9043f9d20602354478228ae5b21dc773434ea75c" +dependencies = [ + "arrayvec", + "ra-ap-rustc_lexer 0.63.0", + "ra_ap_intern 0.0.231", + "ra_ap_stdx 0.0.231", "text-size", ] @@ -1096,10 +1821,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3b152d631514508b7322cda383a454e2a56b0b5ecd8562a8f1e40aabe9fb236" dependencies = [ "fst", - "indexmap", + "indexmap 2.4.0", "nohash-hasher", - "ra_ap_paths", - "ra_ap_stdx", + "ra_ap_paths 0.0.229", + "ra_ap_stdx 0.0.229", + "rustc-hash", + "tracing", +] + +[[package]] +name = "ra_ap_vfs" +version = "0.0.231" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "636c6c02fddbfe8af3cd47056794d9ad10fc2241381851e970f6319c21bc86fb" +dependencies = [ + "crossbeam-channel", + "fst", + "indexmap 2.4.0", + "nohash-hasher", + "ra_ap_paths 0.0.231", + "ra_ap_stdx 0.0.231", "rustc-hash", "tracing", ] @@ -1112,9 +1853,9 @@ checksum = "e516915fb4822a3d480404d35c20f240ae16a297ef52a68dc8cff748093f3abd" dependencies = [ "crossbeam-channel", "notify", - "ra_ap_paths", - "ra_ap_stdx", - "ra_ap_vfs", + "ra_ap_paths 0.0.229", + "ra_ap_stdx 0.0.229", + "ra_ap_vfs 0.0.229", "rayon", "rustc-hash", "tracing", @@ -1157,7 +1898,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49" dependencies = [ "countme", - "hashbrown", + "hashbrown 0.14.5", "memoffset", "rustc-hash", "text-size", @@ -1217,18 +1958,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.207" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.207" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", @@ -1247,6 +1988,42 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.4.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "smallvec" version = "1.13.2" @@ -1274,6 +2051,25 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "stderrlog" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c910772f992ab17d32d6760e167d2353f4130ed50e796752689556af07dc6b" +dependencies = [ + "chrono", + "is-terminal", + "log", + "termcolor", + "thread_local", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.74" @@ -1296,6 +2092,15 @@ dependencies = [ "syn", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "text-size" version = "1.1.1" @@ -1322,6 +2127,47 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tracing" version = "0.1.40" @@ -1369,6 +2215,15 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" +[[package]] +name = "uncased" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-ident" version = "1.0.12" @@ -1387,6 +2242,18 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "walkdir" version = "2.5.0" @@ -1403,13 +2270,77 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + [[package]] name = "winapi-util" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -1559,3 +2490,9 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index e36cdfced04..4f49f7fba09 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -4,6 +4,16 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow = "1.0.86" +clap = { version = "4.5.16", features = ["derive"] } +figment = { version = "0.10.19", features = ["env"]} +log = "0.4.22" +num-traits = "0.2.19" +ra_ap_base_db = "0.0.231" ra_ap_hir = "0.0.229" +ra_ap_hir_def = "0.0.231" ra_ap_load-cargo = "0.0.229" ra_ap_project_model = "0.0.229" +serde = "1.0.209" +serde_with = "3.9.0" +stderrlog = "0.6.0" diff --git a/rust/src/config.rs b/rust/src/config.rs new file mode 100644 index 00000000000..c37ed508620 --- /dev/null +++ b/rust/src/config.rs @@ -0,0 +1,45 @@ +use std::path::PathBuf; +use serde::{Deserialize, Serialize}; +use serde_with; +use figment::{Figment, providers::{Env, Serialized}}; +use clap::{Parser, ArgAction}; + + +#[serde_with::apply(_ => #[serde(default)])] +#[derive(Debug, Deserialize, Default)] +pub struct Config { + pub scratch_dir: PathBuf, + pub trap_dir: PathBuf, + pub source_archive_dir: PathBuf, + pub verbose: u8, + pub inputs: Vec, +} + +#[serde_with::apply(_ => #[serde(skip_serializing_if = "is_default")])] +#[derive(clap::Parser, Serialize)] +#[command(about, long_about = None)] +struct CliArgs { + #[arg(long)] + scratch_dir: Option, + #[arg(long)] + trap_dir: Option, + #[arg(long)] + source_archive_dir: Option, + #[arg(short, long, action = ArgAction::Count)] + pub verbose: u8, + + inputs: Vec, +} + +fn is_default(t: &T) -> bool { + *t == Default::default() +} + +impl Config { + pub fn extract() -> figment::Result { + Figment::new() + .merge(Env::prefixed("CODEQL_EXTRACTOR_RUST_")) + .merge(Serialized::defaults(CliArgs::parse())) + .extract() + } +} diff --git a/rust/src/main.rs b/rust/src/main.rs index f5f966119d7..7dedc239b24 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -1,66 +1,74 @@ -use ra_ap_hir::{Crate, ModuleDef, Name, HirDisplay, DefWithBody}; use ra_ap_project_model::CargoConfig; -use std::env; -use std::path::Path; +use anyhow::Context; +use log; +use ra_ap_hir::db::DefDatabase; +use ra_ap_hir::{ModuleDefId}; +use ra_ap_hir::AdtId::{EnumId, UnionId, StructId}; use ra_ap_load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice}; -fn extract_name(n: Option) -> String { - match n { - Some(v) => v.as_str().to_owned(), - None => String::from(""), - } -} -fn main() { - let args: Vec = env::args().collect(); +mod config; + + +fn main() -> anyhow::Result<()> { + let cfg = config::Config::extract().context("failed to load configuration")?; + stderrlog::new() + .module(module_path!()) + .verbosity(2 + cfg.verbose as usize) + .init()?; + log::info!("{cfg:?}"); + let config = CargoConfig { ..Default::default() }; - let no_progress = &|_| (); + let no_progress = |_| (); let load_config = LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, }; - let (db, vfs, macro_server) = load_workspace_at(&Path::new(&args[1]), &config, &load_config, no_progress).unwrap(); - let mut worklist: Vec<_> = - Crate::all(&db).into_iter().map(|krate| krate.root_module()).collect(); - - while let Some(module) = worklist.pop() { - println!("Module: {}", extract_name(module.name(&db))); - for d in module.declarations(&db) { - match d { - ModuleDef::Module(e) => { - println!(" {}", e.display(&db)); - } - ModuleDef::Function(e) => { - println!(" {}", e.display(&db)); - } - ModuleDef::Adt(e) => { - println!(" {}", e.display(&db)); - } - ModuleDef::Variant(e) => { - println!(" {}", e.display(&db)); - } - ModuleDef::Const(e) => { - println!(" {}", e.display(&db)); - } - ModuleDef::Static(e) => { - println!(" {}", e.display(&db)); - } - ModuleDef::Trait(e) => { - println!(" {}", e.display(&db)); - } - ModuleDef::TraitAlias(e) => { - println!(" {}", e.display(&db)); - } - ModuleDef::TypeAlias(e) => { - println!(" {}", e.display(&db)); - } - ModuleDef::BuiltinType(_e) => {} - ModuleDef::Macro(e) => { - println!(" {}", e.display(&db)); + for manifest in cfg.inputs { + let (db, vfs, _macro_server) = load_workspace_at(&manifest, &config, &load_config, &no_progress)?; + let def_db: &dyn DefDatabase = &db; + let crates = def_db.crate_graph(); + for crate_id in crates.iter().take(1) { + let krate = &crates[crate_id]; + let file = vfs.file_path(krate.root_file_id); + println!("Crate: idx={:x} {}", crate_id.into_raw().into_u32(), file); + let def_map = def_db.crate_def_map(crate_id); + for (module_id, &ref module) in def_map.modules.iter() { + println!(" Module: idx={:x} {:?}", module_id.into_raw().into_u32(), module.origin); + for ref decl_id in module.scope.declarations() { + match decl_id { + ModuleDefId::ModuleId(id) => { + println!(" Module: idx={:x}", id.local_id.into_raw().into_u32()); + } + ModuleDefId::FunctionId(id) => { + let function = def_db.function_data(*id); + println!(" Function: {:?}", function); + } + ModuleDefId::AdtId(StructId(id)) => { + let s = def_db.struct_data(*id); + println!(" Struct: {:?}", s); + } + ModuleDefId::AdtId(EnumId(id)) => { + let e = def_db.enum_data(*id); + println!(" Enum: {:?}", e); + } + ModuleDefId::AdtId(UnionId(id)) => { + let u = def_db.union_data(*id); + println!(" Union: {:?}", u); + } + ModuleDefId::EnumVariantId(_) => {} + ModuleDefId::ConstId(_) => {} + ModuleDefId::StaticId(_) => {} + ModuleDefId::TraitId(_) => {} + ModuleDefId::TraitAliasId(_) => {} + ModuleDefId::TypeAliasId(_) => {} + ModuleDefId::BuiltinType(_) => {} + ModuleDefId::MacroId(_) => {} + } } } } - worklist.extend(module.children(&db)); } + Ok(()) } From 2a2b79e6df838c866ad663e7ee2cab93ed556dcb Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 27 Aug 2024 17:50:53 +0200 Subject: [PATCH 131/404] Rust: skeleton trap file emission code --- rust/src/main.rs | 2 +- rust/src/trap.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 rust/src/trap.rs diff --git a/rust/src/main.rs b/rust/src/main.rs index 7dedc239b24..b6c8b102032 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -8,7 +8,7 @@ use ra_ap_load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice mod config; - +mod trap; fn main() -> anyhow::Result<()> { let cfg = config::Config::extract().context("failed to load configuration")?; diff --git a/rust/src/trap.rs b/rust/src/trap.rs new file mode 100644 index 00000000000..bfdfd728884 --- /dev/null +++ b/rust/src/trap.rs @@ -0,0 +1,53 @@ +use std::fmt::Formatter; +use std::fs::File; +use std::io::Write; +use std::path::{PathBuf}; + +#[derive(Debug)] +struct TrapLabel(u64); + +impl std::fmt::Display for TrapLabel { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "#{:x}", self.0) + } +} + +trait TrapEntry: std::fmt::Display {} + +#[derive(Debug)] +struct TrapFile { + label_index: u64, + file: File, +} + +impl TrapFile { + pub fn new(path: &PathBuf) -> std::io::Result { + let file = File::create(path)?; + Ok(TrapFile { + label_index: 0, + file: file, + }) + } + + pub fn insert_comment(&mut self, comment: &str) -> std::io::Result<()> { + write!(self.file, "/* {comment} */\n") + } + + pub fn allocate_label(&mut self) -> std::io::Result { + let ret = TrapLabel(self.label_index); + write!(self.file, "{ret}=*\n")?; + self.label_index += 1; + Ok(ret) + } + + pub fn allocate_label_for(&mut self, key: &str) -> std::io::Result { + let ret = TrapLabel(self.label_index); + write!(self.file, "{ret}=\"{}\"\n", key.replace("\"", "\"\""))?; + self.label_index += 1; + Ok(ret) + } + + pub fn emit(&mut self, entry: T) -> std::io::Result<()> { + write!(self.file, "{entry}\n") + } +} From f3dea1d647556afc7b76113343d445ba84e212c9 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 27 Aug 2024 14:16:25 +0100 Subject: [PATCH 132/404] Add changenote --- .../ql/src/change-notes/2024-08-27-sensitive-certificate.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/src/change-notes/2024-08-27-sensitive-certificate.md diff --git a/python/ql/src/change-notes/2024-08-27-sensitive-certificate.md b/python/ql/src/change-notes/2024-08-27-sensitive-certificate.md new file mode 100644 index 00000000000..9db609ebbe6 --- /dev/null +++ b/python/ql/src/change-notes/2024-08-27-sensitive-certificate.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `py/clear-text-logging-sensitive-data` and `py/clear-text-storage-sensitive-data` queries have been updated to exclude the `certificate` classification of of sensitive sources, which often do not actually contain sensitive data. \ No newline at end of file From a8591c79c5dff1c8209d7fa7fd3a63d3f70632e3 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 28 Aug 2024 09:11:34 +0100 Subject: [PATCH 133/404] Update test --- .../CleartextStorage.expected | 24 +++++++++---------- .../CWE-312-CleartextStorage-py3/test.py | 12 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected index 6b252ea7833..588cfae32ef 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/CleartextStorage.expected @@ -1,16 +1,16 @@ edges -| test.py:9:5:9:8 | ControlFlowNode for cert | test.py:12:21:12:24 | ControlFlowNode for cert | provenance | | -| test.py:9:5:9:8 | ControlFlowNode for cert | test.py:13:22:13:41 | ControlFlowNode for Attribute() | provenance | | -| test.py:9:5:9:8 | ControlFlowNode for cert | test.py:15:26:15:29 | ControlFlowNode for cert | provenance | | -| test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:9:5:9:8 | ControlFlowNode for cert | provenance | | +| test.py:9:5:9:12 | ControlFlowNode for password | test.py:12:21:12:28 | ControlFlowNode for password | provenance | | +| test.py:9:5:9:12 | ControlFlowNode for password | test.py:13:22:13:45 | ControlFlowNode for Attribute() | provenance | | +| test.py:9:5:9:12 | ControlFlowNode for password | test.py:15:26:15:33 | ControlFlowNode for password | provenance | | +| test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:9:5:9:12 | ControlFlowNode for password | provenance | | nodes -| test.py:9:5:9:8 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert | -| test.py:9:12:9:21 | ControlFlowNode for get_cert() | semmle.label | ControlFlowNode for get_cert() | -| test.py:12:21:12:24 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert | -| test.py:13:22:13:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| test.py:15:26:15:29 | ControlFlowNode for cert | semmle.label | ControlFlowNode for cert | +| test.py:9:5:9:12 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +| test.py:9:16:9:29 | ControlFlowNode for get_password() | semmle.label | ControlFlowNode for get_password() | +| test.py:12:21:12:28 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +| test.py:13:22:13:45 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:15:26:15:33 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | subpaths #select -| test.py:12:21:12:24 | ControlFlowNode for cert | test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:12:21:12:24 | ControlFlowNode for cert | This expression stores $@ as clear text. | test.py:9:12:9:21 | ControlFlowNode for get_cert() | sensitive data (certificate) | -| test.py:13:22:13:41 | ControlFlowNode for Attribute() | test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:13:22:13:41 | ControlFlowNode for Attribute() | This expression stores $@ as clear text. | test.py:9:12:9:21 | ControlFlowNode for get_cert() | sensitive data (certificate) | -| test.py:15:26:15:29 | ControlFlowNode for cert | test.py:9:12:9:21 | ControlFlowNode for get_cert() | test.py:15:26:15:29 | ControlFlowNode for cert | This expression stores $@ as clear text. | test.py:9:12:9:21 | ControlFlowNode for get_cert() | sensitive data (certificate) | +| test.py:12:21:12:28 | ControlFlowNode for password | test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:12:21:12:28 | ControlFlowNode for password | This expression stores $@ as clear text. | test.py:9:16:9:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:13:22:13:45 | ControlFlowNode for Attribute() | test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:13:22:13:45 | ControlFlowNode for Attribute() | This expression stores $@ as clear text. | test.py:9:16:9:29 | ControlFlowNode for get_password() | sensitive data (password) | +| test.py:15:26:15:33 | ControlFlowNode for password | test.py:9:16:9:29 | ControlFlowNode for get_password() | test.py:15:26:15:33 | ControlFlowNode for password | This expression stores $@ as clear text. | test.py:9:16:9:29 | ControlFlowNode for get_password() | sensitive data (password) | diff --git a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/test.py b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/test.py index 980a24e274d..91b7fb7e6c2 100644 --- a/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/test.py +++ b/python/ql/test/query-tests/Security/CWE-312-CleartextStorage-py3/test.py @@ -1,15 +1,15 @@ import pathlib -def get_cert(): - return "" +def get_password(): + return "password" def write_password(filename): - cert = get_cert() + password = get_password() path = pathlib.Path(filename) - path.write_text(cert) # NOT OK - path.write_bytes(cert.encode("utf-8")) # NOT OK + path.write_text(password) # NOT OK + path.write_bytes(password.encode("utf-8")) # NOT OK - path.open("w").write(cert) # NOT OK + path.open("w").write(password) # NOT OK From bfc6fee828ed9c6ae8ea33996a9ba143c16d942e Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Wed, 28 Aug 2024 10:37:59 +0200 Subject: [PATCH 134/404] Go: Move all integration tests. We no longer need the platform-specific directories, so simplify the test organization. If you want to retain the `linux` directory for two tests, or not do this at all, just skip merging this PR. It's purely optional. --- .../go => }/bazel-sample-1/build_environment.expected | 0 .../{all-platforms/go => }/bazel-sample-1/diagnostics.expected | 0 .../{all-platforms/go => }/bazel-sample-1/src/BUILD.bazel | 0 .../{all-platforms/go => }/bazel-sample-1/src/go.mod | 0 .../{all-platforms/go => }/bazel-sample-1/src/go.sum | 0 .../{all-platforms/go => }/bazel-sample-1/src/test.go | 0 .../{all-platforms/go => }/bazel-sample-1/src/todel.go | 0 .../{all-platforms/go => }/bazel-sample-1/test.expected | 0 .../{all-platforms/go => }/bazel-sample-1/test.py | 0 .../{all-platforms/go => }/bazel-sample-1/test.ql | 0 .../go => }/bazel-sample-2/build_environment.expected | 0 .../{all-platforms/go => }/bazel-sample-2/diagnostics.expected | 0 .../{all-platforms/go => }/bazel-sample-2/src/BUILD | 0 .../{all-platforms/go => }/bazel-sample-2/src/go.mod | 0 .../{all-platforms/go => }/bazel-sample-2/src/go.sum | 0 .../{all-platforms/go => }/bazel-sample-2/src/test.go | 0 .../{all-platforms/go => }/bazel-sample-2/src/todel.go | 0 .../{all-platforms/go => }/bazel-sample-2/test.expected | 0 .../{all-platforms/go => }/bazel-sample-2/test.py | 0 .../{all-platforms/go => }/bazel-sample-2/test.ql | 0 .../go => }/configure-baseline/src/a/vendor/avendor.go | 0 .../go => }/configure-baseline/src/a/vendor/modules.txt | 0 .../go => }/configure-baseline/src/b/vendor/bvendor.go | 0 .../go => }/configure-baseline/src/b/vendor/modules.txt | 0 .../go => }/configure-baseline/src/c/vendor/cvendor.go | 0 .../{all-platforms/go => }/configure-baseline/src/root.go | 0 .../{all-platforms/go => }/configure-baseline/test.py | 0 .../build_environment.expected | 0 .../{linux-only/go => }/dep-sample/diagnostics.expected | 0 .../{linux-only/go => }/dep-sample/test.expected | 0 go/ql/integration-tests/{linux-only/go => }/dep-sample/test.py | 0 .../go/go-get-without-modules-sample => dep-sample}/test.ql | 0 .../{linux-only/go => }/dep-sample/work/Gopkg.lock | 0 .../{linux-only/go => }/dep-sample/work/Gopkg.toml | 0 .../integration-tests/{linux-only/go => }/dep-sample/work/test.go | 0 .../go => }/dep-sample/work/vendor/golang.org/x/time/AUTHORS | 0 .../go => }/dep-sample/work/vendor/golang.org/x/time/CONTRIBUTORS | 0 .../go => }/dep-sample/work/vendor/golang.org/x/time/LICENSE | 0 .../go => }/dep-sample/work/vendor/golang.org/x/time/PATENTS | 0 .../go => }/dep-sample/work/vendor/golang.org/x/time/rate/rate.go | 0 .../build_environment.expected | 0 .../build-constraints-exclude-all-go-files/diagnostics.expected | 0 .../diagnostics/build-constraints-exclude-all-go-files/test.py | 0 .../build-constraints-exclude-all-go-files/work/go.mod | 0 .../build-constraints-exclude-all-go-files/work/go.sum | 0 .../build-constraints-exclude-all-go-files/work/test.go | 0 .../go-files-found-not-processed}/build_environment.expected | 0 .../diagnostics/go-files-found-not-processed/diagnostics.expected | 0 .../diagnostics/go-files-found-not-processed/test.expected | 0 .../go => }/diagnostics/go-files-found-not-processed/test.py | 0 .../go => }/diagnostics/go-files-found-not-processed/test.ql | 0 .../go => }/diagnostics/go-files-found-not-processed/work/go.mod | 0 .../go => }/diagnostics/go-files-found-not-processed/work/go.sum | 0 .../diagnostics/go-files-found-not-processed/work/subdir/go.mod | 0 .../diagnostics/go-files-found-not-processed/work/subdir/go.sum | 0 .../diagnostics/go-files-found-not-processed/work/subdir/test.go | 0 .../invalid-toolchain-version}/build_environment.expected | 0 .../diagnostics/invalid-toolchain-version/diagnostics.expected | 0 .../go => }/diagnostics/invalid-toolchain-version/src/go.mod | 0 .../go => }/diagnostics/invalid-toolchain-version/src/main.go | 0 .../go => }/diagnostics/invalid-toolchain-version/test.py | 0 .../newer-go-version-needed}/build_environment.expected | 0 .../diagnostics/newer-go-version-needed/diagnostics.expected | 0 .../go => }/diagnostics/newer-go-version-needed/test.py | 0 .../go => }/diagnostics/newer-go-version-needed/work/go.mod | 0 .../go => }/diagnostics/newer-go-version-needed/work/go.sum | 0 .../go => }/diagnostics/newer-go-version-needed/work/test.go | 0 .../no-go-files-found}/build_environment.expected | 0 .../go => }/diagnostics/no-go-files-found/diagnostics.expected | 0 .../{all-platforms/go => }/diagnostics/no-go-files-found/test.py | 0 .../go => }/diagnostics/no-go-files-found/work/test.txt | 0 .../package-not-found-with-go-mod}/build_environment.expected | 0 .../package-not-found-with-go-mod/diagnostics.expected | 0 .../go => }/diagnostics/package-not-found-with-go-mod/test.py | 0 .../go => }/diagnostics/package-not-found-with-go-mod/work/go.mod | 0 .../go => }/diagnostics/package-not-found-with-go-mod/work/go.sum | 0 .../diagnostics/package-not-found-with-go-mod/work/test.go | 0 .../package-not-found-without-go-mod}/build_environment.expected | 0 .../package-not-found-without-go-mod/diagnostics.expected | 0 .../go => }/diagnostics/package-not-found-without-go-mod/test.py | 0 .../diagnostics/package-not-found-without-go-mod/work/test.go | 0 .../unsupported-relative-path}/build_environment.expected | 0 .../diagnostics/unsupported-relative-path/diagnostics.expected | 0 .../go => }/diagnostics/unsupported-relative-path/test.py | 0 .../diagnostics/unsupported-relative-path/work/main/main.go | 0 .../unsupported-relative-path/work/main/subpkg/subpkg.go | 0 .../build_environment.expected | 0 .../{all-platforms/go => }/extract-vendor/diagnostics.expected | 0 .../{all-platforms/go => }/extract-vendor/src/go.mod | 0 .../{all-platforms/go => }/extract-vendor/src/go.sum | 0 .../{all-platforms/go => }/extract-vendor/src/test.go | 0 .../go => }/extract-vendor/src/vendor/example.com/test/add.go | 0 .../{all-platforms/go => }/extract-vendor/src/vendor/modules.txt | 0 .../{all-platforms/go => }/extract-vendor/test.expected | 0 .../{all-platforms/go => }/extract-vendor/test.py | 0 .../{all-platforms/go => }/extract-vendor/test.ql | 0 .../go/go-mod-sample => glide-sample}/build_environment.expected | 0 .../{linux-only/go => }/glide-sample/diagnostics.expected | 0 .../go => }/glide-sample/force_sequential_test_execution | 0 .../{linux-only/go => }/glide-sample/test.expected | 0 go/ql/integration-tests/{linux-only/go => }/glide-sample/test.py | 0 .../{all-platforms/go/go-mod-sample => glide-sample}/test.ql | 0 .../{linux-only/go => }/glide-sample/work/glide.lock | 0 .../{linux-only/go => }/glide-sample/work/glide.yaml | 0 .../{linux-only/go => }/glide-sample/work/test.go | 0 .../go => }/glide-sample/work/vendor/golang.org/x/time/AUTHORS | 0 .../glide-sample/work/vendor/golang.org/x/time/CONTRIBUTING.md | 0 .../glide-sample/work/vendor/golang.org/x/time/CONTRIBUTORS | 0 .../go => }/glide-sample/work/vendor/golang.org/x/time/LICENSE | 0 .../go => }/glide-sample/work/vendor/golang.org/x/time/PATENTS | 0 .../go => }/glide-sample/work/vendor/golang.org/x/time/README.md | 0 .../go => }/glide-sample/work/vendor/golang.org/x/time/go.mod | 0 .../glide-sample/work/vendor/golang.org/x/time/rate/rate.go | 0 .../glide-sample/work/vendor/golang.org/x/time/rate/rate_test.go | 0 .../build_environment.expected | 0 .../go => }/go-get-without-modules-sample/src/test.go | 0 .../go => }/go-get-without-modules-sample/test.expected | 0 .../{all-platforms/go => }/go-get-without-modules-sample/test.py | 0 .../go/make-sample => go-get-without-modules-sample}/test.ql | 0 .../go-version-bump => go-mod-sample}/build_environment.expected | 0 .../{all-platforms/go => }/go-mod-sample/diagnostics.expected | 0 .../{all-platforms/go => }/go-mod-sample/src/Makefile | 0 .../{all-platforms/go => }/go-mod-sample/src/go.mod | 0 .../{all-platforms/go => }/go-mod-sample/src/go.sum | 0 .../{all-platforms/go => }/go-mod-sample/src/test.go | 0 .../{all-platforms/go => }/go-mod-sample/test.expected | 0 .../{all-platforms/go => }/go-mod-sample/test.py | 0 .../{all-platforms/go/ninja-sample => go-mod-sample}/test.ql | 0 .../build_environment.expected | 0 .../go => }/go-mod-without-version/diagnostics.expected | 0 .../{all-platforms/go => }/go-mod-without-version/src/go.mod | 0 .../{all-platforms/go => }/go-mod-without-version/src/go.sum | 0 .../go => }/go-mod-without-version/src/subdir/add.go | 0 .../{all-platforms/go => }/go-mod-without-version/src/test.go | 0 .../{all-platforms/go => }/go-mod-without-version/test.expected | 0 .../{all-platforms/go => }/go-mod-without-version/test.py | 0 .../{all-platforms/go => }/go-mod-without-version/test.ql | 0 .../mixed-layout => go-version-bump}/build_environment.expected | 0 .../{all-platforms/go => }/go-version-bump/diagnostics.expected | 0 .../{all-platforms/go => }/go-version-bump/src/go.mod | 0 .../{all-platforms/go => }/go-version-bump/src/main.go | 0 .../{all-platforms/go => }/go-version-bump/test.py | 0 .../go/ninja-sample => make-sample}/build_environment.expected | 0 .../{all-platforms/go => }/make-sample/diagnostics.expected | 0 .../{all-platforms/go => }/make-sample/src/Makefile | 0 .../{all-platforms/go => }/make-sample/src/go.mod | 0 .../{all-platforms/go => }/make-sample/src/go.sum | 0 .../{all-platforms/go => }/make-sample/src/test.go | 0 .../{all-platforms/go => }/make-sample/src/todel.go | 0 .../{all-platforms/go => }/make-sample/test.expected | 0 .../integration-tests/{all-platforms/go => }/make-sample/test.py | 0 .../{linux-only/go/dep-sample => make-sample}/test.ql | 0 .../build_environment.expected | 0 .../{all-platforms/go => }/mixed-layout/diagnostics.expected | 0 .../{all-platforms/go => }/mixed-layout/src/module/go.mod | 0 .../{all-platforms/go => }/mixed-layout/src/module/go.sum | 0 .../{all-platforms/go => }/mixed-layout/src/module/test.go | 0 .../{all-platforms/go => }/mixed-layout/src/stray-files/test.go | 0 .../{all-platforms/go => }/mixed-layout/src/workspace/go.work | 0 .../go => }/mixed-layout/src/workspace/subdir/go.mod | 0 .../go => }/mixed-layout/src/workspace/subdir/go.sum | 0 .../go => }/mixed-layout/src/workspace/subdir/test.go | 0 .../{all-platforms/go => }/mixed-layout/test.expected | 0 .../integration-tests/{all-platforms/go => }/mixed-layout/test.py | 0 .../integration-tests/{all-platforms/go => }/mixed-layout/test.ql | 0 .../build_environment.expected | 0 .../{all-platforms/go => }/ninja-sample/diagnostics.expected | 0 .../{all-platforms/go => }/ninja-sample/src/.ninja_log | 0 .../{all-platforms/go => }/ninja-sample/src/build.ninja | 0 .../{all-platforms/go => }/ninja-sample/src/go.mod | 0 .../{all-platforms/go => }/ninja-sample/src/go.sum | 0 .../{all-platforms/go => }/ninja-sample/src/test.go | 0 .../{all-platforms/go => }/ninja-sample/src/todel.go | 0 .../{all-platforms/go => }/ninja-sample/test.expected | 0 .../integration-tests/{all-platforms/go => }/ninja-sample/test.py | 0 .../{linux-only/go/glide-sample => ninja-sample}/test.ql | 0 .../newer-go-needed/build_environment.expected | 0 .../newer-go-needed/diagnostics.expected | 0 .../go => }/resolve-build-environment/newer-go-needed/src/go.mod | 0 .../go => }/resolve-build-environment/newer-go-needed/src/main.go | 0 .../go => }/resolve-build-environment/newer-go-needed/test.py | 0 .../build_environment.expected | 0 .../single-go-mod-and-go-files-not-under-it/diagnostics.expected | 0 .../go => }/single-go-mod-and-go-files-not-under-it/src/main.go | 0 .../single-go-mod-and-go-files-not-under-it/src/subdir/go.mod | 0 .../single-go-mod-and-go-files-not-under-it/src/subdir/go.sum | 0 .../src/subdir/subsubdir/add.go | 0 .../single-go-mod-and-go-files-not-under-it/src/subdir/test.go | 0 .../go => }/single-go-mod-and-go-files-not-under-it/test.expected | 0 .../go => }/single-go-mod-and-go-files-not-under-it/test.py | 0 .../go => }/single-go-mod-and-go-files-not-under-it/test.ql | 0 .../build_environment.expected | 0 .../go => }/single-go-mod-in-root/diagnostics.expected | 0 .../{all-platforms/go => }/single-go-mod-in-root/src/go.mod | 0 .../{all-platforms/go => }/single-go-mod-in-root/src/go.sum | 0 .../go => }/single-go-mod-in-root/src/subdir/add.go | 0 .../{all-platforms/go => }/single-go-mod-in-root/src/test.go | 0 .../{all-platforms/go => }/single-go-mod-in-root/test.expected | 0 .../{all-platforms/go => }/single-go-mod-in-root/test.py | 0 .../{all-platforms/go => }/single-go-mod-in-root/test.ql | 0 .../build_environment.expected | 0 .../go => }/single-go-mod-not-in-root/diagnostics.expected | 0 .../go => }/single-go-mod-not-in-root/src/subdir/go.mod | 0 .../go => }/single-go-mod-not-in-root/src/subdir/go.sum | 0 .../go => }/single-go-mod-not-in-root/src/subdir/subsubdir/add.go | 0 .../go => }/single-go-mod-not-in-root/src/subdir/test.go | 0 .../go => }/single-go-mod-not-in-root/test.expected | 0 .../{all-platforms/go => }/single-go-mod-not-in-root/test.py | 0 .../{all-platforms/go => }/single-go-mod-not-in-root/test.ql | 0 .../build_environment.expected | 0 .../go => }/single-go-work-not-in-root/diagnostics.expected | 0 .../go => }/single-go-work-not-in-root/src/modules/go.work | 0 .../go => }/single-go-work-not-in-root/src/modules/subdir1/go.mod | 0 .../go => }/single-go-work-not-in-root/src/modules/subdir1/go.sum | 0 .../src/modules/subdir1/subsubdir1/add.go | 0 .../single-go-work-not-in-root/src/modules/subdir1/test.go | 0 .../go => }/single-go-work-not-in-root/src/modules/subdir2/go.mod | 0 .../go => }/single-go-work-not-in-root/src/modules/subdir2/go.sum | 0 .../src/modules/subdir2/subsubdir2/add.go | 0 .../single-go-work-not-in-root/src/modules/subdir2/test.go | 0 .../go => }/single-go-work-not-in-root/test.expected | 0 .../{all-platforms/go => }/single-go-work-not-in-root/test.py | 0 .../{all-platforms/go => }/single-go-work-not-in-root/test.ql | 0 .../build_environment.expected | 0 .../go => }/two-go-mods-nested-none-in-root/diagnostics.expected | 0 .../go => }/two-go-mods-nested-none-in-root/src/subdir0/go.mod | 0 .../go => }/two-go-mods-nested-none-in-root/src/subdir0/go.sum | 0 .../two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.mod | 0 .../two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.sum | 0 .../src/subdir0/subdir1/subsubdir1/add.go | 0 .../two-go-mods-nested-none-in-root/src/subdir0/subdir1/test.go | 0 .../two-go-mods-nested-none-in-root/src/subdir0/subdir2/add.go | 0 .../go => }/two-go-mods-nested-none-in-root/src/subdir0/test.go | 0 .../go => }/two-go-mods-nested-none-in-root/test.expected | 0 .../go => }/two-go-mods-nested-none-in-root/test.py | 0 .../go => }/two-go-mods-nested-none-in-root/test.ql | 0 .../build_environment.expected | 0 .../go => }/two-go-mods-nested-one-in-root/diagnostics.expected | 0 .../go => }/two-go-mods-nested-one-in-root/src/go.mod | 0 .../go => }/two-go-mods-nested-one-in-root/src/go.sum | 0 .../go => }/two-go-mods-nested-one-in-root/src/subdir1/go.mod | 0 .../go => }/two-go-mods-nested-one-in-root/src/subdir1/go.sum | 0 .../two-go-mods-nested-one-in-root/src/subdir1/subsubdir1/add.go | 0 .../go => }/two-go-mods-nested-one-in-root/src/subdir1/test.go | 0 .../go => }/two-go-mods-nested-one-in-root/src/subdir2/add.go | 0 .../go => }/two-go-mods-nested-one-in-root/src/test.go | 0 .../go => }/two-go-mods-nested-one-in-root/test.expected | 0 .../{all-platforms/go => }/two-go-mods-nested-one-in-root/test.py | 0 .../{all-platforms/go => }/two-go-mods-nested-one-in-root/test.ql | 0 .../build_environment.expected | 0 .../go => }/two-go-mods-not-nested/diagnostics.expected | 0 .../go => }/two-go-mods-not-nested/src/subdir1/go.mod | 0 .../go => }/two-go-mods-not-nested/src/subdir1/go.sum | 0 .../go => }/two-go-mods-not-nested/src/subdir1/subsubdir1/add.go | 0 .../go => }/two-go-mods-not-nested/src/subdir1/test.go | 0 .../go => }/two-go-mods-not-nested/src/subdir2/go.mod | 0 .../go => }/two-go-mods-not-nested/src/subdir2/go.sum | 0 .../go => }/two-go-mods-not-nested/src/subdir2/subsubdir2/add.go | 0 .../go => }/two-go-mods-not-nested/src/subdir2/test.go | 0 .../{all-platforms/go => }/two-go-mods-not-nested/test.expected | 0 .../{all-platforms/go => }/two-go-mods-not-nested/test.py | 0 .../{all-platforms/go => }/two-go-mods-not-nested/test.ql | 0 .../build_environment.expected | 0 .../go => }/two-go-mods-one-failure/diagnostics.expected | 0 .../go => }/two-go-mods-one-failure/src/subdir1/go.mod | 0 .../go => }/two-go-mods-one-failure/src/subdir1/go.sum | 0 .../go => }/two-go-mods-one-failure/src/subdir1/subsubdir1/add.go | 0 .../go => }/two-go-mods-one-failure/src/subdir1/test.go | 0 .../go => }/two-go-mods-one-failure/src/subdir2/go.mod | 0 .../go => }/two-go-mods-one-failure/src/subdir2/go.sum | 0 .../go => }/two-go-mods-one-failure/src/subdir2/subsubdir2/add.go | 0 .../go => }/two-go-mods-one-failure/src/subdir2/test.go | 0 .../{all-platforms/go => }/two-go-mods-one-failure/test.expected | 0 .../{all-platforms/go => }/two-go-mods-one-failure/test.py | 0 .../{all-platforms/go => }/two-go-mods-one-failure/test.ql | 0 275 files changed, 0 insertions(+), 0 deletions(-) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/src/BUILD.bazel (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/src/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/src/todel.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-1/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/src/BUILD (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/src/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/src/todel.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/bazel-sample-2/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go => }/configure-baseline/src/a/vendor/avendor.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/configure-baseline/src/a/vendor/modules.txt (100%) rename go/ql/integration-tests/{all-platforms/go => }/configure-baseline/src/b/vendor/bvendor.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/configure-baseline/src/b/vendor/modules.txt (100%) rename go/ql/integration-tests/{all-platforms/go => }/configure-baseline/src/c/vendor/cvendor.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/configure-baseline/src/root.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/configure-baseline/test.py (100%) rename go/ql/integration-tests/{all-platforms/go/diagnostics/build-constraints-exclude-all-go-files => dep-sample}/build_environment.expected (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/diagnostics.expected (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/test.expected (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/test.py (100%) rename go/ql/integration-tests/{all-platforms/go/go-get-without-modules-sample => dep-sample}/test.ql (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/work/Gopkg.lock (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/work/Gopkg.toml (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/work/test.go (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/work/vendor/golang.org/x/time/AUTHORS (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/work/vendor/golang.org/x/time/CONTRIBUTORS (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/work/vendor/golang.org/x/time/LICENSE (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/work/vendor/golang.org/x/time/PATENTS (100%) rename go/ql/integration-tests/{linux-only/go => }/dep-sample/work/vendor/golang.org/x/time/rate/rate.go (100%) rename go/ql/integration-tests/{all-platforms/go/diagnostics/go-files-found-not-processed => diagnostics/build-constraints-exclude-all-go-files}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/build-constraints-exclude-all-go-files/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/build-constraints-exclude-all-go-files/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/build-constraints-exclude-all-go-files/work/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/build-constraints-exclude-all-go-files/work/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/build-constraints-exclude-all-go-files/work/test.go (100%) rename go/ql/integration-tests/{all-platforms/go/diagnostics/invalid-toolchain-version => diagnostics/go-files-found-not-processed}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/go-files-found-not-processed/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/go-files-found-not-processed/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/go-files-found-not-processed/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/go-files-found-not-processed/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/go-files-found-not-processed/work/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/go-files-found-not-processed/work/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/go-files-found-not-processed/work/subdir/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/go-files-found-not-processed/work/subdir/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/go-files-found-not-processed/work/subdir/test.go (100%) rename go/ql/integration-tests/{all-platforms/go/diagnostics/newer-go-version-needed => diagnostics/invalid-toolchain-version}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/invalid-toolchain-version/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/invalid-toolchain-version/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/invalid-toolchain-version/src/main.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/invalid-toolchain-version/test.py (100%) rename go/ql/integration-tests/{all-platforms/go/diagnostics/no-go-files-found => diagnostics/newer-go-version-needed}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/newer-go-version-needed/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/newer-go-version-needed/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/newer-go-version-needed/work/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/newer-go-version-needed/work/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/newer-go-version-needed/work/test.go (100%) rename go/ql/integration-tests/{all-platforms/go/diagnostics/package-not-found-with-go-mod => diagnostics/no-go-files-found}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/no-go-files-found/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/no-go-files-found/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/no-go-files-found/work/test.txt (100%) rename go/ql/integration-tests/{all-platforms/go/diagnostics/package-not-found-without-go-mod => diagnostics/package-not-found-with-go-mod}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/package-not-found-with-go-mod/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/package-not-found-with-go-mod/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/package-not-found-with-go-mod/work/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/package-not-found-with-go-mod/work/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/package-not-found-with-go-mod/work/test.go (100%) rename go/ql/integration-tests/{all-platforms/go/diagnostics/unsupported-relative-path => diagnostics/package-not-found-without-go-mod}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/package-not-found-without-go-mod/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/package-not-found-without-go-mod/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/package-not-found-without-go-mod/work/test.go (100%) rename go/ql/integration-tests/{all-platforms/go/extract-vendor => diagnostics/unsupported-relative-path}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/unsupported-relative-path/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/unsupported-relative-path/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/unsupported-relative-path/work/main/main.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/diagnostics/unsupported-relative-path/work/main/subpkg/subpkg.go (100%) rename go/ql/integration-tests/{all-platforms/go/go-get-without-modules-sample => extract-vendor}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/extract-vendor/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/extract-vendor/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/extract-vendor/src/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/extract-vendor/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/extract-vendor/src/vendor/example.com/test/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/extract-vendor/src/vendor/modules.txt (100%) rename go/ql/integration-tests/{all-platforms/go => }/extract-vendor/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/extract-vendor/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/extract-vendor/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/go-mod-sample => glide-sample}/build_environment.expected (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/diagnostics.expected (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/force_sequential_test_execution (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/test.expected (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/test.py (100%) rename go/ql/integration-tests/{all-platforms/go/go-mod-sample => glide-sample}/test.ql (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/glide.lock (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/glide.yaml (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/test.go (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/vendor/golang.org/x/time/AUTHORS (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTING.md (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTORS (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/vendor/golang.org/x/time/LICENSE (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/vendor/golang.org/x/time/PATENTS (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/vendor/golang.org/x/time/README.md (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/vendor/golang.org/x/time/go.mod (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/vendor/golang.org/x/time/rate/rate.go (100%) rename go/ql/integration-tests/{linux-only/go => }/glide-sample/work/vendor/golang.org/x/time/rate/rate_test.go (100%) rename go/ql/integration-tests/{all-platforms/go/go-mod-without-version => go-get-without-modules-sample}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-get-without-modules-sample/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-get-without-modules-sample/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-get-without-modules-sample/test.py (100%) rename go/ql/integration-tests/{all-platforms/go/make-sample => go-get-without-modules-sample}/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/go-version-bump => go-mod-sample}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-sample/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-sample/src/Makefile (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-sample/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-sample/src/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-sample/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-sample/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-sample/test.py (100%) rename go/ql/integration-tests/{all-platforms/go/ninja-sample => go-mod-sample}/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/make-sample => go-mod-without-version}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-without-version/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-without-version/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-without-version/src/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-without-version/src/subdir/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-without-version/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-without-version/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-without-version/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-mod-without-version/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/mixed-layout => go-version-bump}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-version-bump/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-version-bump/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-version-bump/src/main.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/go-version-bump/test.py (100%) rename go/ql/integration-tests/{all-platforms/go/ninja-sample => make-sample}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/make-sample/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/make-sample/src/Makefile (100%) rename go/ql/integration-tests/{all-platforms/go => }/make-sample/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/make-sample/src/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/make-sample/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/make-sample/src/todel.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/make-sample/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/make-sample/test.py (100%) rename go/ql/integration-tests/{linux-only/go/dep-sample => make-sample}/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/single-go-mod-and-go-files-not-under-it => mixed-layout}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/src/module/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/src/module/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/src/module/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/src/stray-files/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/src/workspace/go.work (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/src/workspace/subdir/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/src/workspace/subdir/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/src/workspace/subdir/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/mixed-layout/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/single-go-mod-in-root => ninja-sample}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/ninja-sample/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/ninja-sample/src/.ninja_log (100%) rename go/ql/integration-tests/{all-platforms/go => }/ninja-sample/src/build.ninja (100%) rename go/ql/integration-tests/{all-platforms/go => }/ninja-sample/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/ninja-sample/src/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/ninja-sample/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/ninja-sample/src/todel.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/ninja-sample/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/ninja-sample/test.py (100%) rename go/ql/integration-tests/{linux-only/go/glide-sample => ninja-sample}/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go => }/resolve-build-environment/newer-go-needed/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/resolve-build-environment/newer-go-needed/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/resolve-build-environment/newer-go-needed/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/resolve-build-environment/newer-go-needed/src/main.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/resolve-build-environment/newer-go-needed/test.py (100%) rename go/ql/integration-tests/{all-platforms/go/single-go-mod-not-in-root => single-go-mod-and-go-files-not-under-it}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-and-go-files-not-under-it/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-and-go-files-not-under-it/src/main.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-and-go-files-not-under-it/src/subdir/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-and-go-files-not-under-it/src/subdir/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-and-go-files-not-under-it/src/subdir/subsubdir/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-and-go-files-not-under-it/src/subdir/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-and-go-files-not-under-it/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-and-go-files-not-under-it/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-and-go-files-not-under-it/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/single-go-work-not-in-root => single-go-mod-in-root}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-in-root/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-in-root/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-in-root/src/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-in-root/src/subdir/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-in-root/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-in-root/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-in-root/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-in-root/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/two-go-mods-nested-none-in-root => single-go-mod-not-in-root}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-not-in-root/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-not-in-root/src/subdir/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-not-in-root/src/subdir/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-not-in-root/src/subdir/subsubdir/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-not-in-root/src/subdir/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-not-in-root/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-not-in-root/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-mod-not-in-root/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/two-go-mods-nested-one-in-root => single-go-work-not-in-root}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/src/modules/go.work (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/src/modules/subdir1/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/src/modules/subdir1/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/src/modules/subdir1/subsubdir1/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/src/modules/subdir1/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/src/modules/subdir2/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/src/modules/subdir2/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/src/modules/subdir2/subsubdir2/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/src/modules/subdir2/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/single-go-work-not-in-root/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/two-go-mods-not-nested => two-go-mods-nested-none-in-root}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/src/subdir0/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/src/subdir0/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/src/subdir0/subdir1/subsubdir1/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/src/subdir0/subdir1/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/src/subdir0/subdir2/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/src/subdir0/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-none-in-root/test.ql (100%) rename go/ql/integration-tests/{all-platforms/go/two-go-mods-one-failure => two-go-mods-nested-one-in-root}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/src/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/src/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/src/subdir1/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/src/subdir1/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/src/subdir1/subsubdir1/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/src/subdir1/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/src/subdir2/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/src/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-nested-one-in-root/test.ql (100%) rename go/ql/integration-tests/{linux-only/go/dep-sample => two-go-mods-not-nested}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/src/subdir1/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/src/subdir1/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/src/subdir1/subsubdir1/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/src/subdir1/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/src/subdir2/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/src/subdir2/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/src/subdir2/subsubdir2/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/src/subdir2/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-not-nested/test.ql (100%) rename go/ql/integration-tests/{linux-only/go/glide-sample => two-go-mods-one-failure}/build_environment.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/diagnostics.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/src/subdir1/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/src/subdir1/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/src/subdir1/subsubdir1/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/src/subdir1/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/src/subdir2/go.mod (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/src/subdir2/go.sum (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/src/subdir2/subsubdir2/add.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/src/subdir2/test.go (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/test.expected (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/test.py (100%) rename go/ql/integration-tests/{all-platforms/go => }/two-go-mods-one-failure/test.ql (100%) diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/build_environment.expected b/go/ql/integration-tests/bazel-sample-1/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/build_environment.expected rename to go/ql/integration-tests/bazel-sample-1/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/diagnostics.expected b/go/ql/integration-tests/bazel-sample-1/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/diagnostics.expected rename to go/ql/integration-tests/bazel-sample-1/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/BUILD.bazel b/go/ql/integration-tests/bazel-sample-1/src/BUILD.bazel similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/BUILD.bazel rename to go/ql/integration-tests/bazel-sample-1/src/BUILD.bazel diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/go.mod b/go/ql/integration-tests/bazel-sample-1/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/go.mod rename to go/ql/integration-tests/bazel-sample-1/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/go.sum b/go/ql/integration-tests/bazel-sample-1/src/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/go.sum rename to go/ql/integration-tests/bazel-sample-1/src/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/test.go b/go/ql/integration-tests/bazel-sample-1/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/test.go rename to go/ql/integration-tests/bazel-sample-1/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/todel.go b/go/ql/integration-tests/bazel-sample-1/src/todel.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/src/todel.go rename to go/ql/integration-tests/bazel-sample-1/src/todel.go diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/test.expected b/go/ql/integration-tests/bazel-sample-1/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/test.expected rename to go/ql/integration-tests/bazel-sample-1/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/test.py b/go/ql/integration-tests/bazel-sample-1/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/test.py rename to go/ql/integration-tests/bazel-sample-1/test.py diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-1/test.ql b/go/ql/integration-tests/bazel-sample-1/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-1/test.ql rename to go/ql/integration-tests/bazel-sample-1/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/build_environment.expected b/go/ql/integration-tests/bazel-sample-2/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/build_environment.expected rename to go/ql/integration-tests/bazel-sample-2/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/diagnostics.expected b/go/ql/integration-tests/bazel-sample-2/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/diagnostics.expected rename to go/ql/integration-tests/bazel-sample-2/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/BUILD b/go/ql/integration-tests/bazel-sample-2/src/BUILD similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/BUILD rename to go/ql/integration-tests/bazel-sample-2/src/BUILD diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/go.mod b/go/ql/integration-tests/bazel-sample-2/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/go.mod rename to go/ql/integration-tests/bazel-sample-2/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/go.sum b/go/ql/integration-tests/bazel-sample-2/src/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/go.sum rename to go/ql/integration-tests/bazel-sample-2/src/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/test.go b/go/ql/integration-tests/bazel-sample-2/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/test.go rename to go/ql/integration-tests/bazel-sample-2/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/todel.go b/go/ql/integration-tests/bazel-sample-2/src/todel.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/src/todel.go rename to go/ql/integration-tests/bazel-sample-2/src/todel.go diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/test.expected b/go/ql/integration-tests/bazel-sample-2/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/test.expected rename to go/ql/integration-tests/bazel-sample-2/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/test.py b/go/ql/integration-tests/bazel-sample-2/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/test.py rename to go/ql/integration-tests/bazel-sample-2/test.py diff --git a/go/ql/integration-tests/all-platforms/go/bazel-sample-2/test.ql b/go/ql/integration-tests/bazel-sample-2/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/bazel-sample-2/test.ql rename to go/ql/integration-tests/bazel-sample-2/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/avendor.go b/go/ql/integration-tests/configure-baseline/src/a/vendor/avendor.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/avendor.go rename to go/ql/integration-tests/configure-baseline/src/a/vendor/avendor.go diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/modules.txt b/go/ql/integration-tests/configure-baseline/src/a/vendor/modules.txt similarity index 100% rename from go/ql/integration-tests/all-platforms/go/configure-baseline/src/a/vendor/modules.txt rename to go/ql/integration-tests/configure-baseline/src/a/vendor/modules.txt diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/bvendor.go b/go/ql/integration-tests/configure-baseline/src/b/vendor/bvendor.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/bvendor.go rename to go/ql/integration-tests/configure-baseline/src/b/vendor/bvendor.go diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/modules.txt b/go/ql/integration-tests/configure-baseline/src/b/vendor/modules.txt similarity index 100% rename from go/ql/integration-tests/all-platforms/go/configure-baseline/src/b/vendor/modules.txt rename to go/ql/integration-tests/configure-baseline/src/b/vendor/modules.txt diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/c/vendor/cvendor.go b/go/ql/integration-tests/configure-baseline/src/c/vendor/cvendor.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/configure-baseline/src/c/vendor/cvendor.go rename to go/ql/integration-tests/configure-baseline/src/c/vendor/cvendor.go diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/src/root.go b/go/ql/integration-tests/configure-baseline/src/root.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/configure-baseline/src/root.go rename to go/ql/integration-tests/configure-baseline/src/root.go diff --git a/go/ql/integration-tests/all-platforms/go/configure-baseline/test.py b/go/ql/integration-tests/configure-baseline/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/configure-baseline/test.py rename to go/ql/integration-tests/configure-baseline/test.py diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/build_environment.expected b/go/ql/integration-tests/dep-sample/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/build_environment.expected rename to go/ql/integration-tests/dep-sample/build_environment.expected diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/diagnostics.expected b/go/ql/integration-tests/dep-sample/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/diagnostics.expected rename to go/ql/integration-tests/dep-sample/diagnostics.expected diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/test.expected b/go/ql/integration-tests/dep-sample/test.expected similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/test.expected rename to go/ql/integration-tests/dep-sample/test.expected diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/test.py b/go/ql/integration-tests/dep-sample/test.py similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/test.py rename to go/ql/integration-tests/dep-sample/test.py diff --git a/go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/test.ql b/go/ql/integration-tests/dep-sample/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/test.ql rename to go/ql/integration-tests/dep-sample/test.ql diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/work/Gopkg.lock b/go/ql/integration-tests/dep-sample/work/Gopkg.lock similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/work/Gopkg.lock rename to go/ql/integration-tests/dep-sample/work/Gopkg.lock diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/work/Gopkg.toml b/go/ql/integration-tests/dep-sample/work/Gopkg.toml similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/work/Gopkg.toml rename to go/ql/integration-tests/dep-sample/work/Gopkg.toml diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/work/test.go b/go/ql/integration-tests/dep-sample/work/test.go similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/work/test.go rename to go/ql/integration-tests/dep-sample/work/test.go diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/AUTHORS b/go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/AUTHORS similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/AUTHORS rename to go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/AUTHORS diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/CONTRIBUTORS b/go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/CONTRIBUTORS similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/CONTRIBUTORS rename to go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/CONTRIBUTORS diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/LICENSE b/go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/LICENSE similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/LICENSE rename to go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/LICENSE diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/PATENTS b/go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/PATENTS similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/PATENTS rename to go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/PATENTS diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/rate/rate.go b/go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/rate/rate.go similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/work/vendor/golang.org/x/time/rate/rate.go rename to go/ql/integration-tests/dep-sample/work/vendor/golang.org/x/time/rate/rate.go diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/build_environment.expected b/go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/build_environment.expected rename to go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/diagnostics.expected b/go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/diagnostics.expected rename to go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/test.py b/go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/test.py rename to go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/test.py diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/work/go.mod b/go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/work/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/work/go.mod rename to go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/work/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/work/go.sum b/go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/work/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/work/go.sum rename to go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/work/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/work/test.go b/go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/work/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/build-constraints-exclude-all-go-files/work/test.go rename to go/ql/integration-tests/diagnostics/build-constraints-exclude-all-go-files/work/test.go diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/build_environment.expected b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/build_environment.expected rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/diagnostics.expected b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/diagnostics.expected rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/test.expected b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/test.expected rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/test.py b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/test.py rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/test.py diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/test.ql b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/test.ql rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/go.mod b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/go.mod rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/go.sum b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/go.sum rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/subdir/go.mod b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/subdir/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/subdir/go.mod rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/subdir/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/subdir/go.sum b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/subdir/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/subdir/go.sum rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/subdir/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/subdir/test.go b/go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/subdir/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/go-files-found-not-processed/work/subdir/test.go rename to go/ql/integration-tests/diagnostics/go-files-found-not-processed/work/subdir/test.go diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/build_environment.expected b/go/ql/integration-tests/diagnostics/invalid-toolchain-version/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/build_environment.expected rename to go/ql/integration-tests/diagnostics/invalid-toolchain-version/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/diagnostics.expected b/go/ql/integration-tests/diagnostics/invalid-toolchain-version/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/diagnostics.expected rename to go/ql/integration-tests/diagnostics/invalid-toolchain-version/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/src/go.mod b/go/ql/integration-tests/diagnostics/invalid-toolchain-version/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/src/go.mod rename to go/ql/integration-tests/diagnostics/invalid-toolchain-version/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/src/main.go b/go/ql/integration-tests/diagnostics/invalid-toolchain-version/src/main.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/src/main.go rename to go/ql/integration-tests/diagnostics/invalid-toolchain-version/src/main.go diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/test.py b/go/ql/integration-tests/diagnostics/invalid-toolchain-version/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/invalid-toolchain-version/test.py rename to go/ql/integration-tests/diagnostics/invalid-toolchain-version/test.py diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/no-go-files-found/build_environment.expected b/go/ql/integration-tests/diagnostics/newer-go-version-needed/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/no-go-files-found/build_environment.expected rename to go/ql/integration-tests/diagnostics/newer-go-version-needed/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/diagnostics.expected b/go/ql/integration-tests/diagnostics/newer-go-version-needed/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/diagnostics.expected rename to go/ql/integration-tests/diagnostics/newer-go-version-needed/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/test.py b/go/ql/integration-tests/diagnostics/newer-go-version-needed/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/test.py rename to go/ql/integration-tests/diagnostics/newer-go-version-needed/test.py diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/work/go.mod b/go/ql/integration-tests/diagnostics/newer-go-version-needed/work/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/work/go.mod rename to go/ql/integration-tests/diagnostics/newer-go-version-needed/work/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/work/go.sum b/go/ql/integration-tests/diagnostics/newer-go-version-needed/work/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/work/go.sum rename to go/ql/integration-tests/diagnostics/newer-go-version-needed/work/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/work/test.go b/go/ql/integration-tests/diagnostics/newer-go-version-needed/work/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/newer-go-version-needed/work/test.go rename to go/ql/integration-tests/diagnostics/newer-go-version-needed/work/test.go diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/build_environment.expected b/go/ql/integration-tests/diagnostics/no-go-files-found/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/build_environment.expected rename to go/ql/integration-tests/diagnostics/no-go-files-found/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/no-go-files-found/diagnostics.expected b/go/ql/integration-tests/diagnostics/no-go-files-found/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/no-go-files-found/diagnostics.expected rename to go/ql/integration-tests/diagnostics/no-go-files-found/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/no-go-files-found/test.py b/go/ql/integration-tests/diagnostics/no-go-files-found/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/no-go-files-found/test.py rename to go/ql/integration-tests/diagnostics/no-go-files-found/test.py diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/no-go-files-found/work/test.txt b/go/ql/integration-tests/diagnostics/no-go-files-found/work/test.txt similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/no-go-files-found/work/test.txt rename to go/ql/integration-tests/diagnostics/no-go-files-found/work/test.txt diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-without-go-mod/build_environment.expected b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-without-go-mod/build_environment.expected rename to go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/diagnostics.expected b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/diagnostics.expected rename to go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/test.py b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/test.py rename to go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/test.py diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/work/go.mod b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/work/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/work/go.mod rename to go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/work/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/work/go.sum b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/work/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/work/go.sum rename to go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/work/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/work/test.go b/go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/work/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-with-go-mod/work/test.go rename to go/ql/integration-tests/diagnostics/package-not-found-with-go-mod/work/test.go diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/build_environment.expected b/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/build_environment.expected rename to go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-without-go-mod/diagnostics.expected b/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-without-go-mod/diagnostics.expected rename to go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-without-go-mod/test.py b/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-without-go-mod/test.py rename to go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/test.py diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-without-go-mod/work/test.go b/go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/work/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/package-not-found-without-go-mod/work/test.go rename to go/ql/integration-tests/diagnostics/package-not-found-without-go-mod/work/test.go diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/build_environment.expected b/go/ql/integration-tests/diagnostics/unsupported-relative-path/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/build_environment.expected rename to go/ql/integration-tests/diagnostics/unsupported-relative-path/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/diagnostics.expected b/go/ql/integration-tests/diagnostics/unsupported-relative-path/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/diagnostics.expected rename to go/ql/integration-tests/diagnostics/unsupported-relative-path/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/test.py b/go/ql/integration-tests/diagnostics/unsupported-relative-path/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/test.py rename to go/ql/integration-tests/diagnostics/unsupported-relative-path/test.py diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/work/main/main.go b/go/ql/integration-tests/diagnostics/unsupported-relative-path/work/main/main.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/work/main/main.go rename to go/ql/integration-tests/diagnostics/unsupported-relative-path/work/main/main.go diff --git a/go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/work/main/subpkg/subpkg.go b/go/ql/integration-tests/diagnostics/unsupported-relative-path/work/main/subpkg/subpkg.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/diagnostics/unsupported-relative-path/work/main/subpkg/subpkg.go rename to go/ql/integration-tests/diagnostics/unsupported-relative-path/work/main/subpkg/subpkg.go diff --git a/go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/build_environment.expected b/go/ql/integration-tests/extract-vendor/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/build_environment.expected rename to go/ql/integration-tests/extract-vendor/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/diagnostics.expected b/go/ql/integration-tests/extract-vendor/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/diagnostics.expected rename to go/ql/integration-tests/extract-vendor/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/src/go.mod b/go/ql/integration-tests/extract-vendor/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/src/go.mod rename to go/ql/integration-tests/extract-vendor/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/src/go.sum b/go/ql/integration-tests/extract-vendor/src/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/src/go.sum rename to go/ql/integration-tests/extract-vendor/src/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/src/test.go b/go/ql/integration-tests/extract-vendor/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/src/test.go rename to go/ql/integration-tests/extract-vendor/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/src/vendor/example.com/test/add.go b/go/ql/integration-tests/extract-vendor/src/vendor/example.com/test/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/src/vendor/example.com/test/add.go rename to go/ql/integration-tests/extract-vendor/src/vendor/example.com/test/add.go diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/src/vendor/modules.txt b/go/ql/integration-tests/extract-vendor/src/vendor/modules.txt similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/src/vendor/modules.txt rename to go/ql/integration-tests/extract-vendor/src/vendor/modules.txt diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/test.expected b/go/ql/integration-tests/extract-vendor/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/test.expected rename to go/ql/integration-tests/extract-vendor/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/test.py b/go/ql/integration-tests/extract-vendor/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/test.py rename to go/ql/integration-tests/extract-vendor/test.py diff --git a/go/ql/integration-tests/all-platforms/go/extract-vendor/test.ql b/go/ql/integration-tests/extract-vendor/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/extract-vendor/test.ql rename to go/ql/integration-tests/extract-vendor/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-sample/build_environment.expected b/go/ql/integration-tests/glide-sample/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-sample/build_environment.expected rename to go/ql/integration-tests/glide-sample/build_environment.expected diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/diagnostics.expected b/go/ql/integration-tests/glide-sample/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/diagnostics.expected rename to go/ql/integration-tests/glide-sample/diagnostics.expected diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/force_sequential_test_execution b/go/ql/integration-tests/glide-sample/force_sequential_test_execution similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/force_sequential_test_execution rename to go/ql/integration-tests/glide-sample/force_sequential_test_execution diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/test.expected b/go/ql/integration-tests/glide-sample/test.expected similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/test.expected rename to go/ql/integration-tests/glide-sample/test.expected diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/test.py b/go/ql/integration-tests/glide-sample/test.py similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/test.py rename to go/ql/integration-tests/glide-sample/test.py diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-sample/test.ql b/go/ql/integration-tests/glide-sample/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-sample/test.ql rename to go/ql/integration-tests/glide-sample/test.ql diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/glide.lock b/go/ql/integration-tests/glide-sample/work/glide.lock similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/glide.lock rename to go/ql/integration-tests/glide-sample/work/glide.lock diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/glide.yaml b/go/ql/integration-tests/glide-sample/work/glide.yaml similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/glide.yaml rename to go/ql/integration-tests/glide-sample/work/glide.yaml diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/test.go b/go/ql/integration-tests/glide-sample/work/test.go similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/test.go rename to go/ql/integration-tests/glide-sample/work/test.go diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/AUTHORS b/go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/AUTHORS similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/AUTHORS rename to go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/AUTHORS diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTING.md b/go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTING.md similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTING.md rename to go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTING.md diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTORS b/go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTORS similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTORS rename to go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/CONTRIBUTORS diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/LICENSE b/go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/LICENSE similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/LICENSE rename to go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/LICENSE diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/PATENTS b/go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/PATENTS similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/PATENTS rename to go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/PATENTS diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/README.md b/go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/README.md similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/README.md rename to go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/README.md diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/go.mod b/go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/go.mod similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/go.mod rename to go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/go.mod diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/rate/rate.go b/go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/rate/rate.go similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/rate/rate.go rename to go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/rate/rate.go diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/rate/rate_test.go b/go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/rate/rate_test.go similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/work/vendor/golang.org/x/time/rate/rate_test.go rename to go/ql/integration-tests/glide-sample/work/vendor/golang.org/x/time/rate/rate_test.go diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-without-version/build_environment.expected b/go/ql/integration-tests/go-get-without-modules-sample/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-without-version/build_environment.expected rename to go/ql/integration-tests/go-get-without-modules-sample/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/src/test.go b/go/ql/integration-tests/go-get-without-modules-sample/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/src/test.go rename to go/ql/integration-tests/go-get-without-modules-sample/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/test.expected b/go/ql/integration-tests/go-get-without-modules-sample/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/test.expected rename to go/ql/integration-tests/go-get-without-modules-sample/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/test.py b/go/ql/integration-tests/go-get-without-modules-sample/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-get-without-modules-sample/test.py rename to go/ql/integration-tests/go-get-without-modules-sample/test.py diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/test.ql b/go/ql/integration-tests/go-get-without-modules-sample/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/test.ql rename to go/ql/integration-tests/go-get-without-modules-sample/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/go-version-bump/build_environment.expected b/go/ql/integration-tests/go-mod-sample/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-version-bump/build_environment.expected rename to go/ql/integration-tests/go-mod-sample/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-sample/diagnostics.expected b/go/ql/integration-tests/go-mod-sample/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-sample/diagnostics.expected rename to go/ql/integration-tests/go-mod-sample/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-sample/src/Makefile b/go/ql/integration-tests/go-mod-sample/src/Makefile similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-sample/src/Makefile rename to go/ql/integration-tests/go-mod-sample/src/Makefile diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-sample/src/go.mod b/go/ql/integration-tests/go-mod-sample/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-sample/src/go.mod rename to go/ql/integration-tests/go-mod-sample/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-sample/src/go.sum b/go/ql/integration-tests/go-mod-sample/src/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-sample/src/go.sum rename to go/ql/integration-tests/go-mod-sample/src/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-sample/src/test.go b/go/ql/integration-tests/go-mod-sample/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-sample/src/test.go rename to go/ql/integration-tests/go-mod-sample/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-sample/test.expected b/go/ql/integration-tests/go-mod-sample/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-sample/test.expected rename to go/ql/integration-tests/go-mod-sample/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-sample/test.py b/go/ql/integration-tests/go-mod-sample/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-sample/test.py rename to go/ql/integration-tests/go-mod-sample/test.py diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/test.ql b/go/ql/integration-tests/go-mod-sample/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/test.ql rename to go/ql/integration-tests/go-mod-sample/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/build_environment.expected b/go/ql/integration-tests/go-mod-without-version/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/build_environment.expected rename to go/ql/integration-tests/go-mod-without-version/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-without-version/diagnostics.expected b/go/ql/integration-tests/go-mod-without-version/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-without-version/diagnostics.expected rename to go/ql/integration-tests/go-mod-without-version/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-without-version/src/go.mod b/go/ql/integration-tests/go-mod-without-version/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-without-version/src/go.mod rename to go/ql/integration-tests/go-mod-without-version/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-without-version/src/go.sum b/go/ql/integration-tests/go-mod-without-version/src/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-without-version/src/go.sum rename to go/ql/integration-tests/go-mod-without-version/src/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-without-version/src/subdir/add.go b/go/ql/integration-tests/go-mod-without-version/src/subdir/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-without-version/src/subdir/add.go rename to go/ql/integration-tests/go-mod-without-version/src/subdir/add.go diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-without-version/src/test.go b/go/ql/integration-tests/go-mod-without-version/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-without-version/src/test.go rename to go/ql/integration-tests/go-mod-without-version/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-without-version/test.expected b/go/ql/integration-tests/go-mod-without-version/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-without-version/test.expected rename to go/ql/integration-tests/go-mod-without-version/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-without-version/test.py b/go/ql/integration-tests/go-mod-without-version/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-without-version/test.py rename to go/ql/integration-tests/go-mod-without-version/test.py diff --git a/go/ql/integration-tests/all-platforms/go/go-mod-without-version/test.ql b/go/ql/integration-tests/go-mod-without-version/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-mod-without-version/test.ql rename to go/ql/integration-tests/go-mod-without-version/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/build_environment.expected b/go/ql/integration-tests/go-version-bump/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/build_environment.expected rename to go/ql/integration-tests/go-version-bump/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-version-bump/diagnostics.expected b/go/ql/integration-tests/go-version-bump/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-version-bump/diagnostics.expected rename to go/ql/integration-tests/go-version-bump/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/go-version-bump/src/go.mod b/go/ql/integration-tests/go-version-bump/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-version-bump/src/go.mod rename to go/ql/integration-tests/go-version-bump/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/go-version-bump/src/main.go b/go/ql/integration-tests/go-version-bump/src/main.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-version-bump/src/main.go rename to go/ql/integration-tests/go-version-bump/src/main.go diff --git a/go/ql/integration-tests/all-platforms/go/go-version-bump/test.py b/go/ql/integration-tests/go-version-bump/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/go-version-bump/test.py rename to go/ql/integration-tests/go-version-bump/test.py diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/build_environment.expected b/go/ql/integration-tests/make-sample/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/build_environment.expected rename to go/ql/integration-tests/make-sample/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/diagnostics.expected b/go/ql/integration-tests/make-sample/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/diagnostics.expected rename to go/ql/integration-tests/make-sample/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/src/Makefile b/go/ql/integration-tests/make-sample/src/Makefile similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/src/Makefile rename to go/ql/integration-tests/make-sample/src/Makefile diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/src/go.mod b/go/ql/integration-tests/make-sample/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/src/go.mod rename to go/ql/integration-tests/make-sample/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/src/go.sum b/go/ql/integration-tests/make-sample/src/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/src/go.sum rename to go/ql/integration-tests/make-sample/src/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/src/test.go b/go/ql/integration-tests/make-sample/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/src/test.go rename to go/ql/integration-tests/make-sample/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/src/todel.go b/go/ql/integration-tests/make-sample/src/todel.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/src/todel.go rename to go/ql/integration-tests/make-sample/src/todel.go diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/test.expected b/go/ql/integration-tests/make-sample/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/test.expected rename to go/ql/integration-tests/make-sample/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/make-sample/test.py b/go/ql/integration-tests/make-sample/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/make-sample/test.py rename to go/ql/integration-tests/make-sample/test.py diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/test.ql b/go/ql/integration-tests/make-sample/test.ql similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/test.ql rename to go/ql/integration-tests/make-sample/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/build_environment.expected b/go/ql/integration-tests/mixed-layout/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/build_environment.expected rename to go/ql/integration-tests/mixed-layout/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/diagnostics.expected b/go/ql/integration-tests/mixed-layout/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/diagnostics.expected rename to go/ql/integration-tests/mixed-layout/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/src/module/go.mod b/go/ql/integration-tests/mixed-layout/src/module/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/src/module/go.mod rename to go/ql/integration-tests/mixed-layout/src/module/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/src/module/go.sum b/go/ql/integration-tests/mixed-layout/src/module/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/src/module/go.sum rename to go/ql/integration-tests/mixed-layout/src/module/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/src/module/test.go b/go/ql/integration-tests/mixed-layout/src/module/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/src/module/test.go rename to go/ql/integration-tests/mixed-layout/src/module/test.go diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/src/stray-files/test.go b/go/ql/integration-tests/mixed-layout/src/stray-files/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/src/stray-files/test.go rename to go/ql/integration-tests/mixed-layout/src/stray-files/test.go diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/src/workspace/go.work b/go/ql/integration-tests/mixed-layout/src/workspace/go.work similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/src/workspace/go.work rename to go/ql/integration-tests/mixed-layout/src/workspace/go.work diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/src/workspace/subdir/go.mod b/go/ql/integration-tests/mixed-layout/src/workspace/subdir/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/src/workspace/subdir/go.mod rename to go/ql/integration-tests/mixed-layout/src/workspace/subdir/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/src/workspace/subdir/go.sum b/go/ql/integration-tests/mixed-layout/src/workspace/subdir/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/src/workspace/subdir/go.sum rename to go/ql/integration-tests/mixed-layout/src/workspace/subdir/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/src/workspace/subdir/test.go b/go/ql/integration-tests/mixed-layout/src/workspace/subdir/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/src/workspace/subdir/test.go rename to go/ql/integration-tests/mixed-layout/src/workspace/subdir/test.go diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/test.expected b/go/ql/integration-tests/mixed-layout/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/test.expected rename to go/ql/integration-tests/mixed-layout/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/test.py b/go/ql/integration-tests/mixed-layout/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/test.py rename to go/ql/integration-tests/mixed-layout/test.py diff --git a/go/ql/integration-tests/all-platforms/go/mixed-layout/test.ql b/go/ql/integration-tests/mixed-layout/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/mixed-layout/test.ql rename to go/ql/integration-tests/mixed-layout/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/build_environment.expected b/go/ql/integration-tests/ninja-sample/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/build_environment.expected rename to go/ql/integration-tests/ninja-sample/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/diagnostics.expected b/go/ql/integration-tests/ninja-sample/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/diagnostics.expected rename to go/ql/integration-tests/ninja-sample/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/src/.ninja_log b/go/ql/integration-tests/ninja-sample/src/.ninja_log similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/src/.ninja_log rename to go/ql/integration-tests/ninja-sample/src/.ninja_log diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/src/build.ninja b/go/ql/integration-tests/ninja-sample/src/build.ninja similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/src/build.ninja rename to go/ql/integration-tests/ninja-sample/src/build.ninja diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/src/go.mod b/go/ql/integration-tests/ninja-sample/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/src/go.mod rename to go/ql/integration-tests/ninja-sample/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/src/go.sum b/go/ql/integration-tests/ninja-sample/src/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/src/go.sum rename to go/ql/integration-tests/ninja-sample/src/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/src/test.go b/go/ql/integration-tests/ninja-sample/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/src/test.go rename to go/ql/integration-tests/ninja-sample/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/src/todel.go b/go/ql/integration-tests/ninja-sample/src/todel.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/src/todel.go rename to go/ql/integration-tests/ninja-sample/src/todel.go diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/test.expected b/go/ql/integration-tests/ninja-sample/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/test.expected rename to go/ql/integration-tests/ninja-sample/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/ninja-sample/test.py b/go/ql/integration-tests/ninja-sample/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/ninja-sample/test.py rename to go/ql/integration-tests/ninja-sample/test.py diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/test.ql b/go/ql/integration-tests/ninja-sample/test.ql similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/test.ql rename to go/ql/integration-tests/ninja-sample/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/build_environment.expected b/go/ql/integration-tests/resolve-build-environment/newer-go-needed/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/build_environment.expected rename to go/ql/integration-tests/resolve-build-environment/newer-go-needed/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/diagnostics.expected b/go/ql/integration-tests/resolve-build-environment/newer-go-needed/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/diagnostics.expected rename to go/ql/integration-tests/resolve-build-environment/newer-go-needed/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/src/go.mod b/go/ql/integration-tests/resolve-build-environment/newer-go-needed/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/src/go.mod rename to go/ql/integration-tests/resolve-build-environment/newer-go-needed/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/src/main.go b/go/ql/integration-tests/resolve-build-environment/newer-go-needed/src/main.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/src/main.go rename to go/ql/integration-tests/resolve-build-environment/newer-go-needed/src/main.go diff --git a/go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/test.py b/go/ql/integration-tests/resolve-build-environment/newer-go-needed/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/resolve-build-environment/newer-go-needed/test.py rename to go/ql/integration-tests/resolve-build-environment/newer-go-needed/test.py diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/build_environment.expected b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/build_environment.expected rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/diagnostics.expected b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/diagnostics.expected rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/main.go b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/main.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/main.go rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/main.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/subdir/go.mod b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/subdir/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/subdir/go.mod rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/subdir/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/subdir/go.sum b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/subdir/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/subdir/go.sum rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/subdir/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/subdir/subsubdir/add.go b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/subdir/subsubdir/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/subdir/subsubdir/add.go rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/subdir/subsubdir/add.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/subdir/test.go b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/subdir/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/src/subdir/test.go rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/src/subdir/test.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/test.expected b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/test.expected rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/test.py b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/test.py rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/test.py diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/test.ql b/go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-and-go-files-not-under-it/test.ql rename to go/ql/integration-tests/single-go-mod-and-go-files-not-under-it/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/build_environment.expected b/go/ql/integration-tests/single-go-mod-in-root/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/build_environment.expected rename to go/ql/integration-tests/single-go-mod-in-root/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/diagnostics.expected b/go/ql/integration-tests/single-go-mod-in-root/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/diagnostics.expected rename to go/ql/integration-tests/single-go-mod-in-root/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/src/go.mod b/go/ql/integration-tests/single-go-mod-in-root/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/src/go.mod rename to go/ql/integration-tests/single-go-mod-in-root/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/src/go.sum b/go/ql/integration-tests/single-go-mod-in-root/src/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/src/go.sum rename to go/ql/integration-tests/single-go-mod-in-root/src/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/src/subdir/add.go b/go/ql/integration-tests/single-go-mod-in-root/src/subdir/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/src/subdir/add.go rename to go/ql/integration-tests/single-go-mod-in-root/src/subdir/add.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/src/test.go b/go/ql/integration-tests/single-go-mod-in-root/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/src/test.go rename to go/ql/integration-tests/single-go-mod-in-root/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/test.expected b/go/ql/integration-tests/single-go-mod-in-root/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/test.expected rename to go/ql/integration-tests/single-go-mod-in-root/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/test.py b/go/ql/integration-tests/single-go-mod-in-root/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/test.py rename to go/ql/integration-tests/single-go-mod-in-root/test.py diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/test.ql b/go/ql/integration-tests/single-go-mod-in-root/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-in-root/test.ql rename to go/ql/integration-tests/single-go-mod-in-root/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/build_environment.expected b/go/ql/integration-tests/single-go-mod-not-in-root/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/build_environment.expected rename to go/ql/integration-tests/single-go-mod-not-in-root/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/diagnostics.expected b/go/ql/integration-tests/single-go-mod-not-in-root/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/diagnostics.expected rename to go/ql/integration-tests/single-go-mod-not-in-root/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/src/subdir/go.mod b/go/ql/integration-tests/single-go-mod-not-in-root/src/subdir/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/src/subdir/go.mod rename to go/ql/integration-tests/single-go-mod-not-in-root/src/subdir/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/src/subdir/go.sum b/go/ql/integration-tests/single-go-mod-not-in-root/src/subdir/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/src/subdir/go.sum rename to go/ql/integration-tests/single-go-mod-not-in-root/src/subdir/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/src/subdir/subsubdir/add.go b/go/ql/integration-tests/single-go-mod-not-in-root/src/subdir/subsubdir/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/src/subdir/subsubdir/add.go rename to go/ql/integration-tests/single-go-mod-not-in-root/src/subdir/subsubdir/add.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/src/subdir/test.go b/go/ql/integration-tests/single-go-mod-not-in-root/src/subdir/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/src/subdir/test.go rename to go/ql/integration-tests/single-go-mod-not-in-root/src/subdir/test.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/test.expected b/go/ql/integration-tests/single-go-mod-not-in-root/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/test.expected rename to go/ql/integration-tests/single-go-mod-not-in-root/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/test.py b/go/ql/integration-tests/single-go-mod-not-in-root/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/test.py rename to go/ql/integration-tests/single-go-mod-not-in-root/test.py diff --git a/go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/test.ql b/go/ql/integration-tests/single-go-mod-not-in-root/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-mod-not-in-root/test.ql rename to go/ql/integration-tests/single-go-mod-not-in-root/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/build_environment.expected b/go/ql/integration-tests/single-go-work-not-in-root/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/build_environment.expected rename to go/ql/integration-tests/single-go-work-not-in-root/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/diagnostics.expected b/go/ql/integration-tests/single-go-work-not-in-root/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/diagnostics.expected rename to go/ql/integration-tests/single-go-work-not-in-root/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/go.work b/go/ql/integration-tests/single-go-work-not-in-root/src/modules/go.work similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/go.work rename to go/ql/integration-tests/single-go-work-not-in-root/src/modules/go.work diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir1/go.mod b/go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir1/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir1/go.mod rename to go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir1/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir1/go.sum b/go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir1/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir1/go.sum rename to go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir1/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir1/subsubdir1/add.go b/go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir1/subsubdir1/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir1/subsubdir1/add.go rename to go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir1/subsubdir1/add.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir1/test.go b/go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir1/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir1/test.go rename to go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir1/test.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir2/go.mod b/go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir2/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir2/go.mod rename to go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir2/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir2/go.sum b/go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir2/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir2/go.sum rename to go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir2/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir2/subsubdir2/add.go b/go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir2/subsubdir2/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir2/subsubdir2/add.go rename to go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir2/subsubdir2/add.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir2/test.go b/go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir2/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/src/modules/subdir2/test.go rename to go/ql/integration-tests/single-go-work-not-in-root/src/modules/subdir2/test.go diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/test.expected b/go/ql/integration-tests/single-go-work-not-in-root/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/test.expected rename to go/ql/integration-tests/single-go-work-not-in-root/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/test.py b/go/ql/integration-tests/single-go-work-not-in-root/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/test.py rename to go/ql/integration-tests/single-go-work-not-in-root/test.py diff --git a/go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/test.ql b/go/ql/integration-tests/single-go-work-not-in-root/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/single-go-work-not-in-root/test.ql rename to go/ql/integration-tests/single-go-work-not-in-root/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/build_environment.expected b/go/ql/integration-tests/two-go-mods-nested-none-in-root/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/build_environment.expected rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/diagnostics.expected b/go/ql/integration-tests/two-go-mods-nested-none-in-root/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/diagnostics.expected rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/go.mod b/go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/go.mod rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/go.sum b/go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/go.sum rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.mod b/go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.mod rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.sum b/go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.sum rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir1/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir1/subsubdir1/add.go b/go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir1/subsubdir1/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir1/subsubdir1/add.go rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir1/subsubdir1/add.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir1/test.go b/go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir1/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir1/test.go rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir1/test.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir2/add.go b/go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir2/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/subdir2/add.go rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/subdir2/add.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/test.go b/go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/src/subdir0/test.go rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/src/subdir0/test.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/test.expected b/go/ql/integration-tests/two-go-mods-nested-none-in-root/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/test.expected rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/test.py b/go/ql/integration-tests/two-go-mods-nested-none-in-root/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/test.py rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/test.py diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/test.ql b/go/ql/integration-tests/two-go-mods-nested-none-in-root/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-none-in-root/test.ql rename to go/ql/integration-tests/two-go-mods-nested-none-in-root/test.ql diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/build_environment.expected b/go/ql/integration-tests/two-go-mods-nested-one-in-root/build_environment.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/build_environment.expected rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/diagnostics.expected b/go/ql/integration-tests/two-go-mods-nested-one-in-root/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/diagnostics.expected rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/go.mod b/go/ql/integration-tests/two-go-mods-nested-one-in-root/src/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/go.mod rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/src/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/go.sum b/go/ql/integration-tests/two-go-mods-nested-one-in-root/src/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/go.sum rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/src/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir1/go.mod b/go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir1/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir1/go.mod rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir1/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir1/go.sum b/go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir1/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir1/go.sum rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir1/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir1/subsubdir1/add.go b/go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir1/subsubdir1/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir1/subsubdir1/add.go rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir1/subsubdir1/add.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir1/test.go b/go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir1/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir1/test.go rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir1/test.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir2/add.go b/go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir2/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/subdir2/add.go rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/src/subdir2/add.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/test.go b/go/ql/integration-tests/two-go-mods-nested-one-in-root/src/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/src/test.go rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/src/test.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/test.expected b/go/ql/integration-tests/two-go-mods-nested-one-in-root/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/test.expected rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/test.py b/go/ql/integration-tests/two-go-mods-nested-one-in-root/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/test.py rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/test.py diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/test.ql b/go/ql/integration-tests/two-go-mods-nested-one-in-root/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-nested-one-in-root/test.ql rename to go/ql/integration-tests/two-go-mods-nested-one-in-root/test.ql diff --git a/go/ql/integration-tests/linux-only/go/dep-sample/build_environment.expected b/go/ql/integration-tests/two-go-mods-not-nested/build_environment.expected similarity index 100% rename from go/ql/integration-tests/linux-only/go/dep-sample/build_environment.expected rename to go/ql/integration-tests/two-go-mods-not-nested/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/diagnostics.expected b/go/ql/integration-tests/two-go-mods-not-nested/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/diagnostics.expected rename to go/ql/integration-tests/two-go-mods-not-nested/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir1/go.mod b/go/ql/integration-tests/two-go-mods-not-nested/src/subdir1/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir1/go.mod rename to go/ql/integration-tests/two-go-mods-not-nested/src/subdir1/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir1/go.sum b/go/ql/integration-tests/two-go-mods-not-nested/src/subdir1/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir1/go.sum rename to go/ql/integration-tests/two-go-mods-not-nested/src/subdir1/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir1/subsubdir1/add.go b/go/ql/integration-tests/two-go-mods-not-nested/src/subdir1/subsubdir1/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir1/subsubdir1/add.go rename to go/ql/integration-tests/two-go-mods-not-nested/src/subdir1/subsubdir1/add.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir1/test.go b/go/ql/integration-tests/two-go-mods-not-nested/src/subdir1/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir1/test.go rename to go/ql/integration-tests/two-go-mods-not-nested/src/subdir1/test.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir2/go.mod b/go/ql/integration-tests/two-go-mods-not-nested/src/subdir2/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir2/go.mod rename to go/ql/integration-tests/two-go-mods-not-nested/src/subdir2/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir2/go.sum b/go/ql/integration-tests/two-go-mods-not-nested/src/subdir2/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir2/go.sum rename to go/ql/integration-tests/two-go-mods-not-nested/src/subdir2/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir2/subsubdir2/add.go b/go/ql/integration-tests/two-go-mods-not-nested/src/subdir2/subsubdir2/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir2/subsubdir2/add.go rename to go/ql/integration-tests/two-go-mods-not-nested/src/subdir2/subsubdir2/add.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir2/test.go b/go/ql/integration-tests/two-go-mods-not-nested/src/subdir2/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/src/subdir2/test.go rename to go/ql/integration-tests/two-go-mods-not-nested/src/subdir2/test.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/test.expected b/go/ql/integration-tests/two-go-mods-not-nested/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/test.expected rename to go/ql/integration-tests/two-go-mods-not-nested/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/test.py b/go/ql/integration-tests/two-go-mods-not-nested/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/test.py rename to go/ql/integration-tests/two-go-mods-not-nested/test.py diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/test.ql b/go/ql/integration-tests/two-go-mods-not-nested/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-not-nested/test.ql rename to go/ql/integration-tests/two-go-mods-not-nested/test.ql diff --git a/go/ql/integration-tests/linux-only/go/glide-sample/build_environment.expected b/go/ql/integration-tests/two-go-mods-one-failure/build_environment.expected similarity index 100% rename from go/ql/integration-tests/linux-only/go/glide-sample/build_environment.expected rename to go/ql/integration-tests/two-go-mods-one-failure/build_environment.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/diagnostics.expected b/go/ql/integration-tests/two-go-mods-one-failure/diagnostics.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/diagnostics.expected rename to go/ql/integration-tests/two-go-mods-one-failure/diagnostics.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir1/go.mod b/go/ql/integration-tests/two-go-mods-one-failure/src/subdir1/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir1/go.mod rename to go/ql/integration-tests/two-go-mods-one-failure/src/subdir1/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir1/go.sum b/go/ql/integration-tests/two-go-mods-one-failure/src/subdir1/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir1/go.sum rename to go/ql/integration-tests/two-go-mods-one-failure/src/subdir1/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir1/subsubdir1/add.go b/go/ql/integration-tests/two-go-mods-one-failure/src/subdir1/subsubdir1/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir1/subsubdir1/add.go rename to go/ql/integration-tests/two-go-mods-one-failure/src/subdir1/subsubdir1/add.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir1/test.go b/go/ql/integration-tests/two-go-mods-one-failure/src/subdir1/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir1/test.go rename to go/ql/integration-tests/two-go-mods-one-failure/src/subdir1/test.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir2/go.mod b/go/ql/integration-tests/two-go-mods-one-failure/src/subdir2/go.mod similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir2/go.mod rename to go/ql/integration-tests/two-go-mods-one-failure/src/subdir2/go.mod diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir2/go.sum b/go/ql/integration-tests/two-go-mods-one-failure/src/subdir2/go.sum similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir2/go.sum rename to go/ql/integration-tests/two-go-mods-one-failure/src/subdir2/go.sum diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir2/subsubdir2/add.go b/go/ql/integration-tests/two-go-mods-one-failure/src/subdir2/subsubdir2/add.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir2/subsubdir2/add.go rename to go/ql/integration-tests/two-go-mods-one-failure/src/subdir2/subsubdir2/add.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir2/test.go b/go/ql/integration-tests/two-go-mods-one-failure/src/subdir2/test.go similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/src/subdir2/test.go rename to go/ql/integration-tests/two-go-mods-one-failure/src/subdir2/test.go diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/test.expected b/go/ql/integration-tests/two-go-mods-one-failure/test.expected similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/test.expected rename to go/ql/integration-tests/two-go-mods-one-failure/test.expected diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/test.py b/go/ql/integration-tests/two-go-mods-one-failure/test.py similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/test.py rename to go/ql/integration-tests/two-go-mods-one-failure/test.py diff --git a/go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/test.ql b/go/ql/integration-tests/two-go-mods-one-failure/test.ql similarity index 100% rename from go/ql/integration-tests/all-platforms/go/two-go-mods-one-failure/test.ql rename to go/ql/integration-tests/two-go-mods-one-failure/test.ql From b7b475d13b960e6c46b42b008e774daf7d831343 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Wed, 28 Aug 2024 10:41:53 +0200 Subject: [PATCH 135/404] JS: Move all integration tests. We no longer need the platform-specific directories, so simplify the test organization. If you don't want this change, just skip merging this PR. It's purely optional. The PR also deletes a spurious qlpack.yml that I missed when converting the tests to pytest. --- .../ql/integration-tests/all-platforms/no-types/qlpack.yml | 3 --- .../diagnostics/internal-error/diagnostics.expected | 0 .../diagnostics/internal-error/src/my_failure.ts | 0 .../{all-platforms => }/diagnostics/internal-error/test.py | 0 .../diagnostics/internal-error/tsconfig.json | 0 .../{all-platforms => }/diagnostics/syntax-error/bad.js | 0 .../diagnostics/syntax-error/diagnostics.expected | 0 .../{all-platforms => }/diagnostics/syntax-error/test.py | 0 .../ql/integration-tests/{all-platforms => }/no-types/foo.ts | 0 .../{all-platforms => }/no-types/javascript.expected | 0 .../{all-platforms => }/no-types/javascript.ql | 0 .../ql/integration-tests/{all-platforms => }/no-types/test.py | 0 .../{all-platforms => }/no-types/tsconfig.json | 0 13 files changed, 3 deletions(-) delete mode 100644 javascript/ql/integration-tests/all-platforms/no-types/qlpack.yml rename javascript/ql/integration-tests/{all-platforms => }/diagnostics/internal-error/diagnostics.expected (100%) rename javascript/ql/integration-tests/{all-platforms => }/diagnostics/internal-error/src/my_failure.ts (100%) rename javascript/ql/integration-tests/{all-platforms => }/diagnostics/internal-error/test.py (100%) rename javascript/ql/integration-tests/{all-platforms => }/diagnostics/internal-error/tsconfig.json (100%) rename javascript/ql/integration-tests/{all-platforms => }/diagnostics/syntax-error/bad.js (100%) rename javascript/ql/integration-tests/{all-platforms => }/diagnostics/syntax-error/diagnostics.expected (100%) rename javascript/ql/integration-tests/{all-platforms => }/diagnostics/syntax-error/test.py (100%) rename javascript/ql/integration-tests/{all-platforms => }/no-types/foo.ts (100%) rename javascript/ql/integration-tests/{all-platforms => }/no-types/javascript.expected (100%) rename javascript/ql/integration-tests/{all-platforms => }/no-types/javascript.ql (100%) rename javascript/ql/integration-tests/{all-platforms => }/no-types/test.py (100%) rename javascript/ql/integration-tests/{all-platforms => }/no-types/tsconfig.json (100%) diff --git a/javascript/ql/integration-tests/all-platforms/no-types/qlpack.yml b/javascript/ql/integration-tests/all-platforms/no-types/qlpack.yml deleted file mode 100644 index 8d1460010cb..00000000000 --- a/javascript/ql/integration-tests/all-platforms/no-types/qlpack.yml +++ /dev/null @@ -1,3 +0,0 @@ -dependencies: - codeql/javascript-all: '*' -warnOnImplicitThis: true diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/diagnostics.expected b/javascript/ql/integration-tests/diagnostics/internal-error/diagnostics.expected similarity index 100% rename from javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/diagnostics.expected rename to javascript/ql/integration-tests/diagnostics/internal-error/diagnostics.expected diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/src/my_failure.ts b/javascript/ql/integration-tests/diagnostics/internal-error/src/my_failure.ts similarity index 100% rename from javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/src/my_failure.ts rename to javascript/ql/integration-tests/diagnostics/internal-error/src/my_failure.ts diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/test.py b/javascript/ql/integration-tests/diagnostics/internal-error/test.py similarity index 100% rename from javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/test.py rename to javascript/ql/integration-tests/diagnostics/internal-error/test.py diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/tsconfig.json b/javascript/ql/integration-tests/diagnostics/internal-error/tsconfig.json similarity index 100% rename from javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/tsconfig.json rename to javascript/ql/integration-tests/diagnostics/internal-error/tsconfig.json diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/bad.js b/javascript/ql/integration-tests/diagnostics/syntax-error/bad.js similarity index 100% rename from javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/bad.js rename to javascript/ql/integration-tests/diagnostics/syntax-error/bad.js diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/diagnostics.expected b/javascript/ql/integration-tests/diagnostics/syntax-error/diagnostics.expected similarity index 100% rename from javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/diagnostics.expected rename to javascript/ql/integration-tests/diagnostics/syntax-error/diagnostics.expected diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/test.py b/javascript/ql/integration-tests/diagnostics/syntax-error/test.py similarity index 100% rename from javascript/ql/integration-tests/all-platforms/diagnostics/syntax-error/test.py rename to javascript/ql/integration-tests/diagnostics/syntax-error/test.py diff --git a/javascript/ql/integration-tests/all-platforms/no-types/foo.ts b/javascript/ql/integration-tests/no-types/foo.ts similarity index 100% rename from javascript/ql/integration-tests/all-platforms/no-types/foo.ts rename to javascript/ql/integration-tests/no-types/foo.ts diff --git a/javascript/ql/integration-tests/all-platforms/no-types/javascript.expected b/javascript/ql/integration-tests/no-types/javascript.expected similarity index 100% rename from javascript/ql/integration-tests/all-platforms/no-types/javascript.expected rename to javascript/ql/integration-tests/no-types/javascript.expected diff --git a/javascript/ql/integration-tests/all-platforms/no-types/javascript.ql b/javascript/ql/integration-tests/no-types/javascript.ql similarity index 100% rename from javascript/ql/integration-tests/all-platforms/no-types/javascript.ql rename to javascript/ql/integration-tests/no-types/javascript.ql diff --git a/javascript/ql/integration-tests/all-platforms/no-types/test.py b/javascript/ql/integration-tests/no-types/test.py similarity index 100% rename from javascript/ql/integration-tests/all-platforms/no-types/test.py rename to javascript/ql/integration-tests/no-types/test.py diff --git a/javascript/ql/integration-tests/all-platforms/no-types/tsconfig.json b/javascript/ql/integration-tests/no-types/tsconfig.json similarity index 100% rename from javascript/ql/integration-tests/all-platforms/no-types/tsconfig.json rename to javascript/ql/integration-tests/no-types/tsconfig.json From 3326bc417c79f6c0aa386d7be47bbabef1de755c Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Wed, 28 Aug 2024 10:45:05 +0200 Subject: [PATCH 136/404] Ruby: Move all integration tests. We no longer need the platform-specific directories, so simplify the test organization. If you don't want this change, just skip merging this PR. It's purely optional. --- .../{all-platforms => }/diagnostics/syntax-error/bad.rb | 0 .../diagnostics/syntax-error/diagnostics.expected | 0 .../{all-platforms => }/diagnostics/syntax-error/test.py | 0 .../diagnostics/unknown-encoding/diagnostics.expected | 0 .../{all-platforms => }/diagnostics/unknown-encoding/encoding.rb | 0 .../{all-platforms => }/diagnostics/unknown-encoding/test.py | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename ruby/ql/integration-tests/{all-platforms => }/diagnostics/syntax-error/bad.rb (100%) rename ruby/ql/integration-tests/{all-platforms => }/diagnostics/syntax-error/diagnostics.expected (100%) rename ruby/ql/integration-tests/{all-platforms => }/diagnostics/syntax-error/test.py (100%) rename ruby/ql/integration-tests/{all-platforms => }/diagnostics/unknown-encoding/diagnostics.expected (100%) rename ruby/ql/integration-tests/{all-platforms => }/diagnostics/unknown-encoding/encoding.rb (100%) rename ruby/ql/integration-tests/{all-platforms => }/diagnostics/unknown-encoding/test.py (100%) diff --git a/ruby/ql/integration-tests/all-platforms/diagnostics/syntax-error/bad.rb b/ruby/ql/integration-tests/diagnostics/syntax-error/bad.rb similarity index 100% rename from ruby/ql/integration-tests/all-platforms/diagnostics/syntax-error/bad.rb rename to ruby/ql/integration-tests/diagnostics/syntax-error/bad.rb diff --git a/ruby/ql/integration-tests/all-platforms/diagnostics/syntax-error/diagnostics.expected b/ruby/ql/integration-tests/diagnostics/syntax-error/diagnostics.expected similarity index 100% rename from ruby/ql/integration-tests/all-platforms/diagnostics/syntax-error/diagnostics.expected rename to ruby/ql/integration-tests/diagnostics/syntax-error/diagnostics.expected diff --git a/ruby/ql/integration-tests/all-platforms/diagnostics/syntax-error/test.py b/ruby/ql/integration-tests/diagnostics/syntax-error/test.py similarity index 100% rename from ruby/ql/integration-tests/all-platforms/diagnostics/syntax-error/test.py rename to ruby/ql/integration-tests/diagnostics/syntax-error/test.py diff --git a/ruby/ql/integration-tests/all-platforms/diagnostics/unknown-encoding/diagnostics.expected b/ruby/ql/integration-tests/diagnostics/unknown-encoding/diagnostics.expected similarity index 100% rename from ruby/ql/integration-tests/all-platforms/diagnostics/unknown-encoding/diagnostics.expected rename to ruby/ql/integration-tests/diagnostics/unknown-encoding/diagnostics.expected diff --git a/ruby/ql/integration-tests/all-platforms/diagnostics/unknown-encoding/encoding.rb b/ruby/ql/integration-tests/diagnostics/unknown-encoding/encoding.rb similarity index 100% rename from ruby/ql/integration-tests/all-platforms/diagnostics/unknown-encoding/encoding.rb rename to ruby/ql/integration-tests/diagnostics/unknown-encoding/encoding.rb diff --git a/ruby/ql/integration-tests/all-platforms/diagnostics/unknown-encoding/test.py b/ruby/ql/integration-tests/diagnostics/unknown-encoding/test.py similarity index 100% rename from ruby/ql/integration-tests/all-platforms/diagnostics/unknown-encoding/test.py rename to ruby/ql/integration-tests/diagnostics/unknown-encoding/test.py From a92a84571999dc5c19cc823e8df50b1bb4679ea6 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Wed, 28 Aug 2024 10:47:17 +0200 Subject: [PATCH 137/404] Swift: Move all integration tests. We are no longer bound to the platform-specific directories, so simplify the test organization. If you don't want this change, just skip merging this PR. It's purely optional. --- .../{osx-only => }/autobuilder/failure/.gitignore | 0 .../{osx-only => }/autobuilder/failure/diagnostics.expected | 0 .../autobuilder/failure/hello-failure.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist | 0 .../integration-tests/{osx-only => }/autobuilder/failure/test.py | 0 .../autobuilder/no-build-system/diagnostics.expected | 0 .../{osx-only => }/autobuilder/no-build-system/test.py | 0 .../{osx-only => }/autobuilder/no-build-system/x.swift | 0 .../autobuilder/no-swift-with-spm/diagnostics.expected | 0 .../no-swift-with-spm/hello-objective.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist | 0 .../autobuilder/no-swift-with-spm/hello-objective/Package.swift | 0 .../autobuilder/no-swift-with-spm/hello-objective/main.m | 0 .../{osx-only => }/autobuilder/no-swift-with-spm/test.py | 0 .../{osx-only => }/autobuilder/no-swift/diagnostics.expected | 0 .../no-swift/hello-objective.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist | 0 .../{osx-only => }/autobuilder/no-swift/hello-objective/main.m | 0 .../integration-tests/{osx-only => }/autobuilder/no-swift/test.py | 0 .../{osx-only => }/autobuilder/no-xcode-with-spm/Package.swift | 0 .../autobuilder/no-xcode-with-spm/diagnostics.expected | 0 .../{osx-only => }/autobuilder/no-xcode-with-spm/test.py | 0 .../{osx-only => }/autobuilder/no-xcode-with-spm/x.swift | 0 .../{osx-only => }/autobuilder/only-tests-with-spm/Package.swift | 0 .../autobuilder/only-tests-with-spm/diagnostics.expected | 0 .../only-tests-with-spm/hello-tests.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../{osx-only => }/autobuilder/only-tests-with-spm/test.py | 0 .../{osx-only => }/autobuilder/only-tests/diagnostics.expected | 0 .../autobuilder/only-tests/hello-tests.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../{osx-only => }/autobuilder/only-tests/test.py | 0 .../autobuilder/xcode-fails-spm-works/Files.expected | 0 .../{osx-only => }/autobuilder/xcode-fails-spm-works/Files.ql | 0 .../autobuilder/xcode-fails-spm-works/Package.swift | 0 .../xcode-fails-spm-works/Sources/hello-world/hello_world.swift | 0 .../codeql-swift-autobuild-test.xcodeproj/project.pbxproj | 0 .../codeql-swift-autobuild-test/AppDelegate.swift | 0 .../{osx-only => }/autobuilder/xcode-fails-spm-works/test.py | 0 .../RegexLiteralExpr/RegexLiteralExpr.expected | 0 .../{linux-only => linux}/RegexLiteralExpr/RegexLiteralExpr.ql | 0 .../{linux-only => linux}/RegexLiteralExpr/regex.swift | 0 .../{linux-only => linux}/RegexLiteralExpr/test.py | 0 .../{osx-only => osx}/canonical-case/Files.expected | 0 .../integration-tests/{osx-only => osx}/canonical-case/Files.ql | 0 .../{osx-only => osx}/canonical-case/MiXeDcAsE.swifT | 0 .../integration-tests/{osx-only => osx}/canonical-case/build.sh | 0 .../ql/integration-tests/{osx-only => osx}/canonical-case/test.py | 0 .../{osx-only => osx}/hello-xcode/Files.expected | 0 swift/ql/integration-tests/{osx-only => osx}/hello-xcode/Files.ql | 0 .../codeql-swift-autobuild-test.xcodeproj/project.pbxproj | 0 .../hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift | 0 swift/ql/integration-tests/{osx-only => osx}/hello-xcode/test.py | 0 .../{posix-only => posix}/cross-references/Classes.expected | 0 .../{posix-only => posix}/cross-references/Classes.ql | 0 .../cross-references/Deinitializers.expected | 0 .../{posix-only => posix}/cross-references/Deinitializers.ql | 0 .../{posix-only => posix}/cross-references/Enums.expected | 0 .../{posix-only => posix}/cross-references/Enums.ql | 0 .../{posix-only => posix}/cross-references/Functions.expected | 0 .../{posix-only => posix}/cross-references/Functions.ql | 0 .../{posix-only => posix}/cross-references/Initializers.expected | 0 .../{posix-only => posix}/cross-references/Initializers.ql | 0 .../{posix-only => posix}/cross-references/Module.expected | 0 .../{posix-only => posix}/cross-references/Module.ql | 0 .../{posix-only => posix}/cross-references/Operators.expected | 0 .../{posix-only => posix}/cross-references/Operators.ql | 0 .../{posix-only => posix}/cross-references/Package.swift | 0 .../{posix-only => posix}/cross-references/Protocols.expected | 0 .../{posix-only => posix}/cross-references/Protocols.ql | 0 .../cross-references/Sources/cross-references/lib.swift | 0 .../cross-references/Sources/cross-references/main.swift | 0 .../{posix-only => posix}/cross-references/Structs.expected | 0 .../{posix-only => posix}/cross-references/Structs.ql | 0 .../{posix-only => posix}/cross-references/VarDecls.expected | 0 .../{posix-only => posix}/cross-references/VarDecls.ql | 0 .../{posix-only => posix}/cross-references/test.py | 0 .../{posix-only => posix}/deduplication/BuiltinTypes.expected | 0 .../{posix-only => posix}/deduplication/BuiltinTypes.ql | 0 .../{posix-only => posix}/deduplication/Decls.expected | 0 .../{posix-only => posix}/deduplication/Decls.ql | 0 .../{posix-only => posix}/deduplication/Package.swift | 0 .../{posix-only => posix}/deduplication/Relevant.qll | 0 .../deduplication/Sources/deduplication/def.swift | 0 .../deduplication/Sources/deduplication/use.swift | 0 .../{posix-only => posix}/deduplication/Types.expected | 0 .../{posix-only => posix}/deduplication/Types.ql | 0 .../integration-tests/{posix-only => posix}/deduplication/test.py | 0 .../{posix-only => posix}/frontend-invocations/.gitignore | 0 .../{posix-only => posix}/frontend-invocations/A.swift | 0 .../{posix-only => posix}/frontend-invocations/B.swift | 0 .../{posix-only => posix}/frontend-invocations/C.swift | 0 .../{posix-only => posix}/frontend-invocations/D.swift | 0 .../{posix-only => posix}/frontend-invocations/E.swift | 0 .../{posix-only => posix}/frontend-invocations/Esup.swift | 0 .../{posix-only => posix}/frontend-invocations/F1.swift | 0 .../{posix-only => posix}/frontend-invocations/F2.swift | 0 .../{posix-only => posix}/frontend-invocations/F3.swift | 0 .../{posix-only => posix}/frontend-invocations/F4.swift | 0 .../{posix-only => posix}/frontend-invocations/F5.swift | 0 .../{posix-only => posix}/frontend-invocations/Files.expected | 0 .../{posix-only => posix}/frontend-invocations/Files.ql | 0 .../{posix-only => posix}/frontend-invocations/G.swift | 0 .../{posix-only => posix}/frontend-invocations/H1.swift | 0 .../{posix-only => posix}/frontend-invocations/H2.swift | 0 .../{posix-only => posix}/frontend-invocations/H3.swift | 0 .../{posix-only => posix}/frontend-invocations/I1.swift | 0 .../{posix-only => posix}/frontend-invocations/I2.swift | 0 .../{posix-only => posix}/frontend-invocations/Modules.expected | 0 .../{posix-only => posix}/frontend-invocations/Modules.ql | 0 .../{posix-only => posix}/frontend-invocations/build.sh | 0 .../{posix-only => posix}/frontend-invocations/dir/.empty | 0 .../{posix-only => posix}/frontend-invocations/test.py | 0 .../{posix-only => posix}/hello-world/Bodies.expected | 0 .../integration-tests/{posix-only => posix}/hello-world/Bodies.ql | 0 .../{posix-only => posix}/hello-world/Package.swift | 0 .../hello-world/Sources/hello-world/hello_world.swift | 0 .../{posix-only => posix}/hello-world/test.expected | 0 .../integration-tests/{posix-only => posix}/hello-world/test.py | 0 .../integration-tests/{posix-only => posix}/hello-world/test.ql | 0 .../{posix-only => posix}/linkage-awareness/Bodies.expected | 0 .../{posix-only => posix}/linkage-awareness/Bodies.ql | 0 .../{posix-only => posix}/linkage-awareness/Foo1/Package.swift | 0 .../linkage-awareness/Foo1/Sources/foo/main.swift | 0 .../{posix-only => posix}/linkage-awareness/Foo2/Package.swift | 0 .../linkage-awareness/Foo2/Sources/foo/main.swift | 0 .../{posix-only => posix}/linkage-awareness/build.sh | 0 .../{posix-only => posix}/linkage-awareness/test.py | 0 .../{posix-only => posix}/partial-modules/A/Package.swift | 0 .../{posix-only => posix}/partial-modules/A/Sources/A/A.swift | 0 .../{posix-only => posix}/partial-modules/A/Sources/A/Asup.swift | 0 .../{posix-only => posix}/partial-modules/B/Package.swift | 0 .../{posix-only => posix}/partial-modules/B/Sources/B/B.swift | 0 .../{posix-only => posix}/partial-modules/B/Sources/B/Bsup.swift | 0 .../{posix-only => posix}/partial-modules/Modules.expected | 0 .../{posix-only => posix}/partial-modules/Modules.ql | 0 .../{posix-only => posix}/partial-modules/Package.swift | 0 .../partial-modules/Sources/partial-modules/partial_modules.swift | 0 .../{posix-only => posix}/partial-modules/Unknown.expected | 0 .../{posix-only => posix}/partial-modules/Unknown.ql | 0 .../{posix-only => posix}/partial-modules/test.py | 0 .../integration-tests/{posix-only => posix}/symlinks/.gitignore | 0 .../{posix-only => posix}/symlinks/Files.expected | 0 .../ql/integration-tests/{posix-only => posix}/symlinks/Files.ql | 0 .../integration-tests/{posix-only => posix}/symlinks/main.swift | 0 .../{posix-only => posix}/symlinks/preserve/Package.swift | 0 .../{posix-only => posix}/symlinks/preserve/Sources/.gitkeep | 0 .../{posix-only => posix}/symlinks/resolve/Package.swift | 0 .../{posix-only => posix}/symlinks/resolve/Sources/.gitkeep | 0 swift/ql/integration-tests/{posix-only => posix}/symlinks/test.py | 0 153 files changed, 0 insertions(+), 0 deletions(-) rename swift/ql/integration-tests/{osx-only => }/autobuilder/failure/.gitignore (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/failure/diagnostics.expected (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/failure/hello-failure.xcodeproj/project.pbxproj (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/failure/test.py (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-build-system/diagnostics.expected (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-build-system/test.py (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-build-system/x.swift (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift-with-spm/diagnostics.expected (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.pbxproj (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift-with-spm/hello-objective/Package.swift (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift-with-spm/hello-objective/main.m (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift-with-spm/test.py (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift/diagnostics.expected (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift/hello-objective.xcodeproj/project.pbxproj (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift/hello-objective/main.m (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-swift/test.py (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-xcode-with-spm/Package.swift (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-xcode-with-spm/diagnostics.expected (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-xcode-with-spm/test.py (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/no-xcode-with-spm/x.swift (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/only-tests-with-spm/Package.swift (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/only-tests-with-spm/diagnostics.expected (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.pbxproj (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/only-tests-with-spm/test.py (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/only-tests/diagnostics.expected (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/only-tests/hello-tests.xcodeproj/project.pbxproj (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/only-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/only-tests/test.py (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/xcode-fails-spm-works/Files.expected (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/xcode-fails-spm-works/Files.ql (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/xcode-fails-spm-works/Package.swift (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/xcode-fails-spm-works/Sources/hello-world/hello_world.swift (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test.xcodeproj/project.pbxproj (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test/AppDelegate.swift (100%) rename swift/ql/integration-tests/{osx-only => }/autobuilder/xcode-fails-spm-works/test.py (100%) rename swift/ql/integration-tests/{linux-only => linux}/RegexLiteralExpr/RegexLiteralExpr.expected (100%) rename swift/ql/integration-tests/{linux-only => linux}/RegexLiteralExpr/RegexLiteralExpr.ql (100%) rename swift/ql/integration-tests/{linux-only => linux}/RegexLiteralExpr/regex.swift (100%) rename swift/ql/integration-tests/{linux-only => linux}/RegexLiteralExpr/test.py (100%) rename swift/ql/integration-tests/{osx-only => osx}/canonical-case/Files.expected (100%) rename swift/ql/integration-tests/{osx-only => osx}/canonical-case/Files.ql (100%) rename swift/ql/integration-tests/{osx-only => osx}/canonical-case/MiXeDcAsE.swifT (100%) rename swift/ql/integration-tests/{osx-only => osx}/canonical-case/build.sh (100%) rename swift/ql/integration-tests/{osx-only => osx}/canonical-case/test.py (100%) rename swift/ql/integration-tests/{osx-only => osx}/hello-xcode/Files.expected (100%) rename swift/ql/integration-tests/{osx-only => osx}/hello-xcode/Files.ql (100%) rename swift/ql/integration-tests/{osx-only => osx}/hello-xcode/codeql-swift-autobuild-test.xcodeproj/project.pbxproj (100%) rename swift/ql/integration-tests/{osx-only => osx}/hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift (100%) rename swift/ql/integration-tests/{osx-only => osx}/hello-xcode/test.py (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Classes.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Classes.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Deinitializers.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Deinitializers.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Enums.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Enums.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Functions.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Functions.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Initializers.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Initializers.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Module.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Module.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Operators.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Operators.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Protocols.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Protocols.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Sources/cross-references/lib.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Sources/cross-references/main.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Structs.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/Structs.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/VarDecls.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/VarDecls.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/cross-references/test.py (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/BuiltinTypes.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/BuiltinTypes.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/Decls.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/Decls.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/Relevant.qll (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/Sources/deduplication/def.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/Sources/deduplication/use.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/Types.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/Types.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/deduplication/test.py (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/.gitignore (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/A.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/B.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/C.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/D.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/E.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/Esup.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/F1.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/F2.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/F3.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/F4.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/F5.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/Files.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/Files.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/G.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/H1.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/H2.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/H3.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/I1.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/I2.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/Modules.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/Modules.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/build.sh (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/dir/.empty (100%) rename swift/ql/integration-tests/{posix-only => posix}/frontend-invocations/test.py (100%) rename swift/ql/integration-tests/{posix-only => posix}/hello-world/Bodies.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/hello-world/Bodies.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/hello-world/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/hello-world/Sources/hello-world/hello_world.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/hello-world/test.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/hello-world/test.py (100%) rename swift/ql/integration-tests/{posix-only => posix}/hello-world/test.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/linkage-awareness/Bodies.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/linkage-awareness/Bodies.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/linkage-awareness/Foo1/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/linkage-awareness/Foo1/Sources/foo/main.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/linkage-awareness/Foo2/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/linkage-awareness/Foo2/Sources/foo/main.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/linkage-awareness/build.sh (100%) rename swift/ql/integration-tests/{posix-only => posix}/linkage-awareness/test.py (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/A/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/A/Sources/A/A.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/A/Sources/A/Asup.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/B/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/B/Sources/B/B.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/B/Sources/B/Bsup.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/Modules.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/Modules.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/Sources/partial-modules/partial_modules.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/Unknown.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/Unknown.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/partial-modules/test.py (100%) rename swift/ql/integration-tests/{posix-only => posix}/symlinks/.gitignore (100%) rename swift/ql/integration-tests/{posix-only => posix}/symlinks/Files.expected (100%) rename swift/ql/integration-tests/{posix-only => posix}/symlinks/Files.ql (100%) rename swift/ql/integration-tests/{posix-only => posix}/symlinks/main.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/symlinks/preserve/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/symlinks/preserve/Sources/.gitkeep (100%) rename swift/ql/integration-tests/{posix-only => posix}/symlinks/resolve/Package.swift (100%) rename swift/ql/integration-tests/{posix-only => posix}/symlinks/resolve/Sources/.gitkeep (100%) rename swift/ql/integration-tests/{posix-only => posix}/symlinks/test.py (100%) diff --git a/swift/ql/integration-tests/osx-only/autobuilder/failure/.gitignore b/swift/ql/integration-tests/autobuilder/failure/.gitignore similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/failure/.gitignore rename to swift/ql/integration-tests/autobuilder/failure/.gitignore diff --git a/swift/ql/integration-tests/osx-only/autobuilder/failure/diagnostics.expected b/swift/ql/integration-tests/autobuilder/failure/diagnostics.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/failure/diagnostics.expected rename to swift/ql/integration-tests/autobuilder/failure/diagnostics.expected diff --git a/swift/ql/integration-tests/osx-only/autobuilder/failure/hello-failure.xcodeproj/project.pbxproj b/swift/ql/integration-tests/autobuilder/failure/hello-failure.xcodeproj/project.pbxproj similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/failure/hello-failure.xcodeproj/project.pbxproj rename to swift/ql/integration-tests/autobuilder/failure/hello-failure.xcodeproj/project.pbxproj diff --git a/swift/ql/integration-tests/osx-only/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/ql/integration-tests/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to swift/ql/integration-tests/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/swift/ql/integration-tests/osx-only/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/swift/ql/integration-tests/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to swift/ql/integration-tests/autobuilder/failure/hello-failure.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/swift/ql/integration-tests/osx-only/autobuilder/failure/test.py b/swift/ql/integration-tests/autobuilder/failure/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/failure/test.py rename to swift/ql/integration-tests/autobuilder/failure/test.py diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-build-system/diagnostics.expected b/swift/ql/integration-tests/autobuilder/no-build-system/diagnostics.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-build-system/diagnostics.expected rename to swift/ql/integration-tests/autobuilder/no-build-system/diagnostics.expected diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-build-system/test.py b/swift/ql/integration-tests/autobuilder/no-build-system/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-build-system/test.py rename to swift/ql/integration-tests/autobuilder/no-build-system/test.py diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-build-system/x.swift b/swift/ql/integration-tests/autobuilder/no-build-system/x.swift similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-build-system/x.swift rename to swift/ql/integration-tests/autobuilder/no-build-system/x.swift diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/diagnostics.expected b/swift/ql/integration-tests/autobuilder/no-swift-with-spm/diagnostics.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/diagnostics.expected rename to swift/ql/integration-tests/autobuilder/no-swift-with-spm/diagnostics.expected diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.pbxproj b/swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.pbxproj similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.pbxproj rename to swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.pbxproj diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective/Package.swift b/swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective/Package.swift similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective/Package.swift rename to swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective/Package.swift diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective/main.m b/swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective/main.m similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/hello-objective/main.m rename to swift/ql/integration-tests/autobuilder/no-swift-with-spm/hello-objective/main.m diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/test.py b/swift/ql/integration-tests/autobuilder/no-swift-with-spm/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift-with-spm/test.py rename to swift/ql/integration-tests/autobuilder/no-swift-with-spm/test.py diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift/diagnostics.expected b/swift/ql/integration-tests/autobuilder/no-swift/diagnostics.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift/diagnostics.expected rename to swift/ql/integration-tests/autobuilder/no-swift/diagnostics.expected diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift/hello-objective.xcodeproj/project.pbxproj b/swift/ql/integration-tests/autobuilder/no-swift/hello-objective.xcodeproj/project.pbxproj similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift/hello-objective.xcodeproj/project.pbxproj rename to swift/ql/integration-tests/autobuilder/no-swift/hello-objective.xcodeproj/project.pbxproj diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/ql/integration-tests/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to swift/ql/integration-tests/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/swift/ql/integration-tests/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to swift/ql/integration-tests/autobuilder/no-swift/hello-objective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift/hello-objective/main.m b/swift/ql/integration-tests/autobuilder/no-swift/hello-objective/main.m similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift/hello-objective/main.m rename to swift/ql/integration-tests/autobuilder/no-swift/hello-objective/main.m diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-swift/test.py b/swift/ql/integration-tests/autobuilder/no-swift/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-swift/test.py rename to swift/ql/integration-tests/autobuilder/no-swift/test.py diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-xcode-with-spm/Package.swift b/swift/ql/integration-tests/autobuilder/no-xcode-with-spm/Package.swift similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-xcode-with-spm/Package.swift rename to swift/ql/integration-tests/autobuilder/no-xcode-with-spm/Package.swift diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-xcode-with-spm/diagnostics.expected b/swift/ql/integration-tests/autobuilder/no-xcode-with-spm/diagnostics.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-xcode-with-spm/diagnostics.expected rename to swift/ql/integration-tests/autobuilder/no-xcode-with-spm/diagnostics.expected diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-xcode-with-spm/test.py b/swift/ql/integration-tests/autobuilder/no-xcode-with-spm/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-xcode-with-spm/test.py rename to swift/ql/integration-tests/autobuilder/no-xcode-with-spm/test.py diff --git a/swift/ql/integration-tests/osx-only/autobuilder/no-xcode-with-spm/x.swift b/swift/ql/integration-tests/autobuilder/no-xcode-with-spm/x.swift similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/no-xcode-with-spm/x.swift rename to swift/ql/integration-tests/autobuilder/no-xcode-with-spm/x.swift diff --git a/swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/Package.swift b/swift/ql/integration-tests/autobuilder/only-tests-with-spm/Package.swift similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/Package.swift rename to swift/ql/integration-tests/autobuilder/only-tests-with-spm/Package.swift diff --git a/swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/diagnostics.expected b/swift/ql/integration-tests/autobuilder/only-tests-with-spm/diagnostics.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/diagnostics.expected rename to swift/ql/integration-tests/autobuilder/only-tests-with-spm/diagnostics.expected diff --git a/swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.pbxproj b/swift/ql/integration-tests/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.pbxproj similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.pbxproj rename to swift/ql/integration-tests/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.pbxproj diff --git a/swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/ql/integration-tests/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to swift/ql/integration-tests/autobuilder/only-tests-with-spm/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/test.py b/swift/ql/integration-tests/autobuilder/only-tests-with-spm/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/only-tests-with-spm/test.py rename to swift/ql/integration-tests/autobuilder/only-tests-with-spm/test.py diff --git a/swift/ql/integration-tests/osx-only/autobuilder/only-tests/diagnostics.expected b/swift/ql/integration-tests/autobuilder/only-tests/diagnostics.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/only-tests/diagnostics.expected rename to swift/ql/integration-tests/autobuilder/only-tests/diagnostics.expected diff --git a/swift/ql/integration-tests/osx-only/autobuilder/only-tests/hello-tests.xcodeproj/project.pbxproj b/swift/ql/integration-tests/autobuilder/only-tests/hello-tests.xcodeproj/project.pbxproj similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/only-tests/hello-tests.xcodeproj/project.pbxproj rename to swift/ql/integration-tests/autobuilder/only-tests/hello-tests.xcodeproj/project.pbxproj diff --git a/swift/ql/integration-tests/osx-only/autobuilder/only-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/ql/integration-tests/autobuilder/only-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/only-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to swift/ql/integration-tests/autobuilder/only-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/swift/ql/integration-tests/osx-only/autobuilder/only-tests/test.py b/swift/ql/integration-tests/autobuilder/only-tests/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/only-tests/test.py rename to swift/ql/integration-tests/autobuilder/only-tests/test.py diff --git a/swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/Files.expected b/swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/Files.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/Files.expected rename to swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/Files.expected diff --git a/swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/Files.ql b/swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/Files.ql similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/Files.ql rename to swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/Files.ql diff --git a/swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/Package.swift b/swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/Package.swift similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/Package.swift rename to swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/Package.swift diff --git a/swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/Sources/hello-world/hello_world.swift b/swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/Sources/hello-world/hello_world.swift similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/Sources/hello-world/hello_world.swift rename to swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/Sources/hello-world/hello_world.swift diff --git a/swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test.xcodeproj/project.pbxproj b/swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test.xcodeproj/project.pbxproj similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test.xcodeproj/project.pbxproj rename to swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test.xcodeproj/project.pbxproj diff --git a/swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test/AppDelegate.swift b/swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test/AppDelegate.swift similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test/AppDelegate.swift rename to swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/codeql-swift-autobuild-test/AppDelegate.swift diff --git a/swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/test.py b/swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/autobuilder/xcode-fails-spm-works/test.py rename to swift/ql/integration-tests/autobuilder/xcode-fails-spm-works/test.py diff --git a/swift/ql/integration-tests/linux-only/RegexLiteralExpr/RegexLiteralExpr.expected b/swift/ql/integration-tests/linux/RegexLiteralExpr/RegexLiteralExpr.expected similarity index 100% rename from swift/ql/integration-tests/linux-only/RegexLiteralExpr/RegexLiteralExpr.expected rename to swift/ql/integration-tests/linux/RegexLiteralExpr/RegexLiteralExpr.expected diff --git a/swift/ql/integration-tests/linux-only/RegexLiteralExpr/RegexLiteralExpr.ql b/swift/ql/integration-tests/linux/RegexLiteralExpr/RegexLiteralExpr.ql similarity index 100% rename from swift/ql/integration-tests/linux-only/RegexLiteralExpr/RegexLiteralExpr.ql rename to swift/ql/integration-tests/linux/RegexLiteralExpr/RegexLiteralExpr.ql diff --git a/swift/ql/integration-tests/linux-only/RegexLiteralExpr/regex.swift b/swift/ql/integration-tests/linux/RegexLiteralExpr/regex.swift similarity index 100% rename from swift/ql/integration-tests/linux-only/RegexLiteralExpr/regex.swift rename to swift/ql/integration-tests/linux/RegexLiteralExpr/regex.swift diff --git a/swift/ql/integration-tests/linux-only/RegexLiteralExpr/test.py b/swift/ql/integration-tests/linux/RegexLiteralExpr/test.py similarity index 100% rename from swift/ql/integration-tests/linux-only/RegexLiteralExpr/test.py rename to swift/ql/integration-tests/linux/RegexLiteralExpr/test.py diff --git a/swift/ql/integration-tests/osx-only/canonical-case/Files.expected b/swift/ql/integration-tests/osx/canonical-case/Files.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/canonical-case/Files.expected rename to swift/ql/integration-tests/osx/canonical-case/Files.expected diff --git a/swift/ql/integration-tests/osx-only/canonical-case/Files.ql b/swift/ql/integration-tests/osx/canonical-case/Files.ql similarity index 100% rename from swift/ql/integration-tests/osx-only/canonical-case/Files.ql rename to swift/ql/integration-tests/osx/canonical-case/Files.ql diff --git a/swift/ql/integration-tests/osx-only/canonical-case/MiXeDcAsE.swifT b/swift/ql/integration-tests/osx/canonical-case/MiXeDcAsE.swifT similarity index 100% rename from swift/ql/integration-tests/osx-only/canonical-case/MiXeDcAsE.swifT rename to swift/ql/integration-tests/osx/canonical-case/MiXeDcAsE.swifT diff --git a/swift/ql/integration-tests/osx-only/canonical-case/build.sh b/swift/ql/integration-tests/osx/canonical-case/build.sh similarity index 100% rename from swift/ql/integration-tests/osx-only/canonical-case/build.sh rename to swift/ql/integration-tests/osx/canonical-case/build.sh diff --git a/swift/ql/integration-tests/osx-only/canonical-case/test.py b/swift/ql/integration-tests/osx/canonical-case/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/canonical-case/test.py rename to swift/ql/integration-tests/osx/canonical-case/test.py diff --git a/swift/ql/integration-tests/osx-only/hello-xcode/Files.expected b/swift/ql/integration-tests/osx/hello-xcode/Files.expected similarity index 100% rename from swift/ql/integration-tests/osx-only/hello-xcode/Files.expected rename to swift/ql/integration-tests/osx/hello-xcode/Files.expected diff --git a/swift/ql/integration-tests/osx-only/hello-xcode/Files.ql b/swift/ql/integration-tests/osx/hello-xcode/Files.ql similarity index 100% rename from swift/ql/integration-tests/osx-only/hello-xcode/Files.ql rename to swift/ql/integration-tests/osx/hello-xcode/Files.ql diff --git a/swift/ql/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test.xcodeproj/project.pbxproj b/swift/ql/integration-tests/osx/hello-xcode/codeql-swift-autobuild-test.xcodeproj/project.pbxproj similarity index 100% rename from swift/ql/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test.xcodeproj/project.pbxproj rename to swift/ql/integration-tests/osx/hello-xcode/codeql-swift-autobuild-test.xcodeproj/project.pbxproj diff --git a/swift/ql/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift b/swift/ql/integration-tests/osx/hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift similarity index 100% rename from swift/ql/integration-tests/osx-only/hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift rename to swift/ql/integration-tests/osx/hello-xcode/codeql-swift-autobuild-test/AppDelegate.swift diff --git a/swift/ql/integration-tests/osx-only/hello-xcode/test.py b/swift/ql/integration-tests/osx/hello-xcode/test.py similarity index 100% rename from swift/ql/integration-tests/osx-only/hello-xcode/test.py rename to swift/ql/integration-tests/osx/hello-xcode/test.py diff --git a/swift/ql/integration-tests/posix-only/cross-references/Classes.expected b/swift/ql/integration-tests/posix/cross-references/Classes.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Classes.expected rename to swift/ql/integration-tests/posix/cross-references/Classes.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/Classes.ql b/swift/ql/integration-tests/posix/cross-references/Classes.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Classes.ql rename to swift/ql/integration-tests/posix/cross-references/Classes.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/Deinitializers.expected b/swift/ql/integration-tests/posix/cross-references/Deinitializers.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Deinitializers.expected rename to swift/ql/integration-tests/posix/cross-references/Deinitializers.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/Deinitializers.ql b/swift/ql/integration-tests/posix/cross-references/Deinitializers.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Deinitializers.ql rename to swift/ql/integration-tests/posix/cross-references/Deinitializers.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/Enums.expected b/swift/ql/integration-tests/posix/cross-references/Enums.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Enums.expected rename to swift/ql/integration-tests/posix/cross-references/Enums.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/Enums.ql b/swift/ql/integration-tests/posix/cross-references/Enums.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Enums.ql rename to swift/ql/integration-tests/posix/cross-references/Enums.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/Functions.expected b/swift/ql/integration-tests/posix/cross-references/Functions.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Functions.expected rename to swift/ql/integration-tests/posix/cross-references/Functions.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/Functions.ql b/swift/ql/integration-tests/posix/cross-references/Functions.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Functions.ql rename to swift/ql/integration-tests/posix/cross-references/Functions.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/Initializers.expected b/swift/ql/integration-tests/posix/cross-references/Initializers.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Initializers.expected rename to swift/ql/integration-tests/posix/cross-references/Initializers.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/Initializers.ql b/swift/ql/integration-tests/posix/cross-references/Initializers.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Initializers.ql rename to swift/ql/integration-tests/posix/cross-references/Initializers.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/Module.expected b/swift/ql/integration-tests/posix/cross-references/Module.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Module.expected rename to swift/ql/integration-tests/posix/cross-references/Module.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/Module.ql b/swift/ql/integration-tests/posix/cross-references/Module.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Module.ql rename to swift/ql/integration-tests/posix/cross-references/Module.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/Operators.expected b/swift/ql/integration-tests/posix/cross-references/Operators.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Operators.expected rename to swift/ql/integration-tests/posix/cross-references/Operators.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/Operators.ql b/swift/ql/integration-tests/posix/cross-references/Operators.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Operators.ql rename to swift/ql/integration-tests/posix/cross-references/Operators.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/Package.swift b/swift/ql/integration-tests/posix/cross-references/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Package.swift rename to swift/ql/integration-tests/posix/cross-references/Package.swift diff --git a/swift/ql/integration-tests/posix-only/cross-references/Protocols.expected b/swift/ql/integration-tests/posix/cross-references/Protocols.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Protocols.expected rename to swift/ql/integration-tests/posix/cross-references/Protocols.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/Protocols.ql b/swift/ql/integration-tests/posix/cross-references/Protocols.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Protocols.ql rename to swift/ql/integration-tests/posix/cross-references/Protocols.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/Sources/cross-references/lib.swift b/swift/ql/integration-tests/posix/cross-references/Sources/cross-references/lib.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Sources/cross-references/lib.swift rename to swift/ql/integration-tests/posix/cross-references/Sources/cross-references/lib.swift diff --git a/swift/ql/integration-tests/posix-only/cross-references/Sources/cross-references/main.swift b/swift/ql/integration-tests/posix/cross-references/Sources/cross-references/main.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Sources/cross-references/main.swift rename to swift/ql/integration-tests/posix/cross-references/Sources/cross-references/main.swift diff --git a/swift/ql/integration-tests/posix-only/cross-references/Structs.expected b/swift/ql/integration-tests/posix/cross-references/Structs.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Structs.expected rename to swift/ql/integration-tests/posix/cross-references/Structs.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/Structs.ql b/swift/ql/integration-tests/posix/cross-references/Structs.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/Structs.ql rename to swift/ql/integration-tests/posix/cross-references/Structs.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/VarDecls.expected b/swift/ql/integration-tests/posix/cross-references/VarDecls.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/VarDecls.expected rename to swift/ql/integration-tests/posix/cross-references/VarDecls.expected diff --git a/swift/ql/integration-tests/posix-only/cross-references/VarDecls.ql b/swift/ql/integration-tests/posix/cross-references/VarDecls.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/VarDecls.ql rename to swift/ql/integration-tests/posix/cross-references/VarDecls.ql diff --git a/swift/ql/integration-tests/posix-only/cross-references/test.py b/swift/ql/integration-tests/posix/cross-references/test.py similarity index 100% rename from swift/ql/integration-tests/posix-only/cross-references/test.py rename to swift/ql/integration-tests/posix/cross-references/test.py diff --git a/swift/ql/integration-tests/posix-only/deduplication/BuiltinTypes.expected b/swift/ql/integration-tests/posix/deduplication/BuiltinTypes.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/BuiltinTypes.expected rename to swift/ql/integration-tests/posix/deduplication/BuiltinTypes.expected diff --git a/swift/ql/integration-tests/posix-only/deduplication/BuiltinTypes.ql b/swift/ql/integration-tests/posix/deduplication/BuiltinTypes.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/BuiltinTypes.ql rename to swift/ql/integration-tests/posix/deduplication/BuiltinTypes.ql diff --git a/swift/ql/integration-tests/posix-only/deduplication/Decls.expected b/swift/ql/integration-tests/posix/deduplication/Decls.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/Decls.expected rename to swift/ql/integration-tests/posix/deduplication/Decls.expected diff --git a/swift/ql/integration-tests/posix-only/deduplication/Decls.ql b/swift/ql/integration-tests/posix/deduplication/Decls.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/Decls.ql rename to swift/ql/integration-tests/posix/deduplication/Decls.ql diff --git a/swift/ql/integration-tests/posix-only/deduplication/Package.swift b/swift/ql/integration-tests/posix/deduplication/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/Package.swift rename to swift/ql/integration-tests/posix/deduplication/Package.swift diff --git a/swift/ql/integration-tests/posix-only/deduplication/Relevant.qll b/swift/ql/integration-tests/posix/deduplication/Relevant.qll similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/Relevant.qll rename to swift/ql/integration-tests/posix/deduplication/Relevant.qll diff --git a/swift/ql/integration-tests/posix-only/deduplication/Sources/deduplication/def.swift b/swift/ql/integration-tests/posix/deduplication/Sources/deduplication/def.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/Sources/deduplication/def.swift rename to swift/ql/integration-tests/posix/deduplication/Sources/deduplication/def.swift diff --git a/swift/ql/integration-tests/posix-only/deduplication/Sources/deduplication/use.swift b/swift/ql/integration-tests/posix/deduplication/Sources/deduplication/use.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/Sources/deduplication/use.swift rename to swift/ql/integration-tests/posix/deduplication/Sources/deduplication/use.swift diff --git a/swift/ql/integration-tests/posix-only/deduplication/Types.expected b/swift/ql/integration-tests/posix/deduplication/Types.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/Types.expected rename to swift/ql/integration-tests/posix/deduplication/Types.expected diff --git a/swift/ql/integration-tests/posix-only/deduplication/Types.ql b/swift/ql/integration-tests/posix/deduplication/Types.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/Types.ql rename to swift/ql/integration-tests/posix/deduplication/Types.ql diff --git a/swift/ql/integration-tests/posix-only/deduplication/test.py b/swift/ql/integration-tests/posix/deduplication/test.py similarity index 100% rename from swift/ql/integration-tests/posix-only/deduplication/test.py rename to swift/ql/integration-tests/posix/deduplication/test.py diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/.gitignore b/swift/ql/integration-tests/posix/frontend-invocations/.gitignore similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/.gitignore rename to swift/ql/integration-tests/posix/frontend-invocations/.gitignore diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/A.swift b/swift/ql/integration-tests/posix/frontend-invocations/A.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/A.swift rename to swift/ql/integration-tests/posix/frontend-invocations/A.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/B.swift b/swift/ql/integration-tests/posix/frontend-invocations/B.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/B.swift rename to swift/ql/integration-tests/posix/frontend-invocations/B.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/C.swift b/swift/ql/integration-tests/posix/frontend-invocations/C.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/C.swift rename to swift/ql/integration-tests/posix/frontend-invocations/C.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/D.swift b/swift/ql/integration-tests/posix/frontend-invocations/D.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/D.swift rename to swift/ql/integration-tests/posix/frontend-invocations/D.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/E.swift b/swift/ql/integration-tests/posix/frontend-invocations/E.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/E.swift rename to swift/ql/integration-tests/posix/frontend-invocations/E.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/Esup.swift b/swift/ql/integration-tests/posix/frontend-invocations/Esup.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/Esup.swift rename to swift/ql/integration-tests/posix/frontend-invocations/Esup.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/F1.swift b/swift/ql/integration-tests/posix/frontend-invocations/F1.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/F1.swift rename to swift/ql/integration-tests/posix/frontend-invocations/F1.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/F2.swift b/swift/ql/integration-tests/posix/frontend-invocations/F2.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/F2.swift rename to swift/ql/integration-tests/posix/frontend-invocations/F2.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/F3.swift b/swift/ql/integration-tests/posix/frontend-invocations/F3.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/F3.swift rename to swift/ql/integration-tests/posix/frontend-invocations/F3.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/F4.swift b/swift/ql/integration-tests/posix/frontend-invocations/F4.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/F4.swift rename to swift/ql/integration-tests/posix/frontend-invocations/F4.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/F5.swift b/swift/ql/integration-tests/posix/frontend-invocations/F5.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/F5.swift rename to swift/ql/integration-tests/posix/frontend-invocations/F5.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/Files.expected b/swift/ql/integration-tests/posix/frontend-invocations/Files.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/Files.expected rename to swift/ql/integration-tests/posix/frontend-invocations/Files.expected diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/Files.ql b/swift/ql/integration-tests/posix/frontend-invocations/Files.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/Files.ql rename to swift/ql/integration-tests/posix/frontend-invocations/Files.ql diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/G.swift b/swift/ql/integration-tests/posix/frontend-invocations/G.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/G.swift rename to swift/ql/integration-tests/posix/frontend-invocations/G.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/H1.swift b/swift/ql/integration-tests/posix/frontend-invocations/H1.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/H1.swift rename to swift/ql/integration-tests/posix/frontend-invocations/H1.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/H2.swift b/swift/ql/integration-tests/posix/frontend-invocations/H2.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/H2.swift rename to swift/ql/integration-tests/posix/frontend-invocations/H2.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/H3.swift b/swift/ql/integration-tests/posix/frontend-invocations/H3.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/H3.swift rename to swift/ql/integration-tests/posix/frontend-invocations/H3.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/I1.swift b/swift/ql/integration-tests/posix/frontend-invocations/I1.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/I1.swift rename to swift/ql/integration-tests/posix/frontend-invocations/I1.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/I2.swift b/swift/ql/integration-tests/posix/frontend-invocations/I2.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/I2.swift rename to swift/ql/integration-tests/posix/frontend-invocations/I2.swift diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/Modules.expected b/swift/ql/integration-tests/posix/frontend-invocations/Modules.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/Modules.expected rename to swift/ql/integration-tests/posix/frontend-invocations/Modules.expected diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/Modules.ql b/swift/ql/integration-tests/posix/frontend-invocations/Modules.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/Modules.ql rename to swift/ql/integration-tests/posix/frontend-invocations/Modules.ql diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/build.sh b/swift/ql/integration-tests/posix/frontend-invocations/build.sh similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/build.sh rename to swift/ql/integration-tests/posix/frontend-invocations/build.sh diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/dir/.empty b/swift/ql/integration-tests/posix/frontend-invocations/dir/.empty similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/dir/.empty rename to swift/ql/integration-tests/posix/frontend-invocations/dir/.empty diff --git a/swift/ql/integration-tests/posix-only/frontend-invocations/test.py b/swift/ql/integration-tests/posix/frontend-invocations/test.py similarity index 100% rename from swift/ql/integration-tests/posix-only/frontend-invocations/test.py rename to swift/ql/integration-tests/posix/frontend-invocations/test.py diff --git a/swift/ql/integration-tests/posix-only/hello-world/Bodies.expected b/swift/ql/integration-tests/posix/hello-world/Bodies.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/hello-world/Bodies.expected rename to swift/ql/integration-tests/posix/hello-world/Bodies.expected diff --git a/swift/ql/integration-tests/posix-only/hello-world/Bodies.ql b/swift/ql/integration-tests/posix/hello-world/Bodies.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/hello-world/Bodies.ql rename to swift/ql/integration-tests/posix/hello-world/Bodies.ql diff --git a/swift/ql/integration-tests/posix-only/hello-world/Package.swift b/swift/ql/integration-tests/posix/hello-world/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/hello-world/Package.swift rename to swift/ql/integration-tests/posix/hello-world/Package.swift diff --git a/swift/ql/integration-tests/posix-only/hello-world/Sources/hello-world/hello_world.swift b/swift/ql/integration-tests/posix/hello-world/Sources/hello-world/hello_world.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/hello-world/Sources/hello-world/hello_world.swift rename to swift/ql/integration-tests/posix/hello-world/Sources/hello-world/hello_world.swift diff --git a/swift/ql/integration-tests/posix-only/hello-world/test.expected b/swift/ql/integration-tests/posix/hello-world/test.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/hello-world/test.expected rename to swift/ql/integration-tests/posix/hello-world/test.expected diff --git a/swift/ql/integration-tests/posix-only/hello-world/test.py b/swift/ql/integration-tests/posix/hello-world/test.py similarity index 100% rename from swift/ql/integration-tests/posix-only/hello-world/test.py rename to swift/ql/integration-tests/posix/hello-world/test.py diff --git a/swift/ql/integration-tests/posix-only/hello-world/test.ql b/swift/ql/integration-tests/posix/hello-world/test.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/hello-world/test.ql rename to swift/ql/integration-tests/posix/hello-world/test.ql diff --git a/swift/ql/integration-tests/posix-only/linkage-awareness/Bodies.expected b/swift/ql/integration-tests/posix/linkage-awareness/Bodies.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/linkage-awareness/Bodies.expected rename to swift/ql/integration-tests/posix/linkage-awareness/Bodies.expected diff --git a/swift/ql/integration-tests/posix-only/linkage-awareness/Bodies.ql b/swift/ql/integration-tests/posix/linkage-awareness/Bodies.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/linkage-awareness/Bodies.ql rename to swift/ql/integration-tests/posix/linkage-awareness/Bodies.ql diff --git a/swift/ql/integration-tests/posix-only/linkage-awareness/Foo1/Package.swift b/swift/ql/integration-tests/posix/linkage-awareness/Foo1/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/linkage-awareness/Foo1/Package.swift rename to swift/ql/integration-tests/posix/linkage-awareness/Foo1/Package.swift diff --git a/swift/ql/integration-tests/posix-only/linkage-awareness/Foo1/Sources/foo/main.swift b/swift/ql/integration-tests/posix/linkage-awareness/Foo1/Sources/foo/main.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/linkage-awareness/Foo1/Sources/foo/main.swift rename to swift/ql/integration-tests/posix/linkage-awareness/Foo1/Sources/foo/main.swift diff --git a/swift/ql/integration-tests/posix-only/linkage-awareness/Foo2/Package.swift b/swift/ql/integration-tests/posix/linkage-awareness/Foo2/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/linkage-awareness/Foo2/Package.swift rename to swift/ql/integration-tests/posix/linkage-awareness/Foo2/Package.swift diff --git a/swift/ql/integration-tests/posix-only/linkage-awareness/Foo2/Sources/foo/main.swift b/swift/ql/integration-tests/posix/linkage-awareness/Foo2/Sources/foo/main.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/linkage-awareness/Foo2/Sources/foo/main.swift rename to swift/ql/integration-tests/posix/linkage-awareness/Foo2/Sources/foo/main.swift diff --git a/swift/ql/integration-tests/posix-only/linkage-awareness/build.sh b/swift/ql/integration-tests/posix/linkage-awareness/build.sh similarity index 100% rename from swift/ql/integration-tests/posix-only/linkage-awareness/build.sh rename to swift/ql/integration-tests/posix/linkage-awareness/build.sh diff --git a/swift/ql/integration-tests/posix-only/linkage-awareness/test.py b/swift/ql/integration-tests/posix/linkage-awareness/test.py similarity index 100% rename from swift/ql/integration-tests/posix-only/linkage-awareness/test.py rename to swift/ql/integration-tests/posix/linkage-awareness/test.py diff --git a/swift/ql/integration-tests/posix-only/partial-modules/A/Package.swift b/swift/ql/integration-tests/posix/partial-modules/A/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/A/Package.swift rename to swift/ql/integration-tests/posix/partial-modules/A/Package.swift diff --git a/swift/ql/integration-tests/posix-only/partial-modules/A/Sources/A/A.swift b/swift/ql/integration-tests/posix/partial-modules/A/Sources/A/A.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/A/Sources/A/A.swift rename to swift/ql/integration-tests/posix/partial-modules/A/Sources/A/A.swift diff --git a/swift/ql/integration-tests/posix-only/partial-modules/A/Sources/A/Asup.swift b/swift/ql/integration-tests/posix/partial-modules/A/Sources/A/Asup.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/A/Sources/A/Asup.swift rename to swift/ql/integration-tests/posix/partial-modules/A/Sources/A/Asup.swift diff --git a/swift/ql/integration-tests/posix-only/partial-modules/B/Package.swift b/swift/ql/integration-tests/posix/partial-modules/B/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/B/Package.swift rename to swift/ql/integration-tests/posix/partial-modules/B/Package.swift diff --git a/swift/ql/integration-tests/posix-only/partial-modules/B/Sources/B/B.swift b/swift/ql/integration-tests/posix/partial-modules/B/Sources/B/B.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/B/Sources/B/B.swift rename to swift/ql/integration-tests/posix/partial-modules/B/Sources/B/B.swift diff --git a/swift/ql/integration-tests/posix-only/partial-modules/B/Sources/B/Bsup.swift b/swift/ql/integration-tests/posix/partial-modules/B/Sources/B/Bsup.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/B/Sources/B/Bsup.swift rename to swift/ql/integration-tests/posix/partial-modules/B/Sources/B/Bsup.swift diff --git a/swift/ql/integration-tests/posix-only/partial-modules/Modules.expected b/swift/ql/integration-tests/posix/partial-modules/Modules.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/Modules.expected rename to swift/ql/integration-tests/posix/partial-modules/Modules.expected diff --git a/swift/ql/integration-tests/posix-only/partial-modules/Modules.ql b/swift/ql/integration-tests/posix/partial-modules/Modules.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/Modules.ql rename to swift/ql/integration-tests/posix/partial-modules/Modules.ql diff --git a/swift/ql/integration-tests/posix-only/partial-modules/Package.swift b/swift/ql/integration-tests/posix/partial-modules/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/Package.swift rename to swift/ql/integration-tests/posix/partial-modules/Package.swift diff --git a/swift/ql/integration-tests/posix-only/partial-modules/Sources/partial-modules/partial_modules.swift b/swift/ql/integration-tests/posix/partial-modules/Sources/partial-modules/partial_modules.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/Sources/partial-modules/partial_modules.swift rename to swift/ql/integration-tests/posix/partial-modules/Sources/partial-modules/partial_modules.swift diff --git a/swift/ql/integration-tests/posix-only/partial-modules/Unknown.expected b/swift/ql/integration-tests/posix/partial-modules/Unknown.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/Unknown.expected rename to swift/ql/integration-tests/posix/partial-modules/Unknown.expected diff --git a/swift/ql/integration-tests/posix-only/partial-modules/Unknown.ql b/swift/ql/integration-tests/posix/partial-modules/Unknown.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/Unknown.ql rename to swift/ql/integration-tests/posix/partial-modules/Unknown.ql diff --git a/swift/ql/integration-tests/posix-only/partial-modules/test.py b/swift/ql/integration-tests/posix/partial-modules/test.py similarity index 100% rename from swift/ql/integration-tests/posix-only/partial-modules/test.py rename to swift/ql/integration-tests/posix/partial-modules/test.py diff --git a/swift/ql/integration-tests/posix-only/symlinks/.gitignore b/swift/ql/integration-tests/posix/symlinks/.gitignore similarity index 100% rename from swift/ql/integration-tests/posix-only/symlinks/.gitignore rename to swift/ql/integration-tests/posix/symlinks/.gitignore diff --git a/swift/ql/integration-tests/posix-only/symlinks/Files.expected b/swift/ql/integration-tests/posix/symlinks/Files.expected similarity index 100% rename from swift/ql/integration-tests/posix-only/symlinks/Files.expected rename to swift/ql/integration-tests/posix/symlinks/Files.expected diff --git a/swift/ql/integration-tests/posix-only/symlinks/Files.ql b/swift/ql/integration-tests/posix/symlinks/Files.ql similarity index 100% rename from swift/ql/integration-tests/posix-only/symlinks/Files.ql rename to swift/ql/integration-tests/posix/symlinks/Files.ql diff --git a/swift/ql/integration-tests/posix-only/symlinks/main.swift b/swift/ql/integration-tests/posix/symlinks/main.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/symlinks/main.swift rename to swift/ql/integration-tests/posix/symlinks/main.swift diff --git a/swift/ql/integration-tests/posix-only/symlinks/preserve/Package.swift b/swift/ql/integration-tests/posix/symlinks/preserve/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/symlinks/preserve/Package.swift rename to swift/ql/integration-tests/posix/symlinks/preserve/Package.swift diff --git a/swift/ql/integration-tests/posix-only/symlinks/preserve/Sources/.gitkeep b/swift/ql/integration-tests/posix/symlinks/preserve/Sources/.gitkeep similarity index 100% rename from swift/ql/integration-tests/posix-only/symlinks/preserve/Sources/.gitkeep rename to swift/ql/integration-tests/posix/symlinks/preserve/Sources/.gitkeep diff --git a/swift/ql/integration-tests/posix-only/symlinks/resolve/Package.swift b/swift/ql/integration-tests/posix/symlinks/resolve/Package.swift similarity index 100% rename from swift/ql/integration-tests/posix-only/symlinks/resolve/Package.swift rename to swift/ql/integration-tests/posix/symlinks/resolve/Package.swift diff --git a/swift/ql/integration-tests/posix-only/symlinks/resolve/Sources/.gitkeep b/swift/ql/integration-tests/posix/symlinks/resolve/Sources/.gitkeep similarity index 100% rename from swift/ql/integration-tests/posix-only/symlinks/resolve/Sources/.gitkeep rename to swift/ql/integration-tests/posix/symlinks/resolve/Sources/.gitkeep diff --git a/swift/ql/integration-tests/posix-only/symlinks/test.py b/swift/ql/integration-tests/posix/symlinks/test.py similarity index 100% rename from swift/ql/integration-tests/posix-only/symlinks/test.py rename to swift/ql/integration-tests/posix/symlinks/test.py From d6049cd98b38e0844669c7fea6ec25e273e83a35 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 28 Aug 2024 10:54:16 +0200 Subject: [PATCH 138/404] C++: Add additional implementations of NonThrowingFunction and make minor fixes to docs --- .../code/cpp/models/implementations/Printf.qll | 13 +++++++------ .../code/cpp/models/implementations/Strcat.qll | 5 ++++- .../code/cpp/models/implementations/Strcpy.qll | 5 ++++- .../code/cpp/models/interfaces/NonThrowing.qll | 4 +--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index 677b9245b6b..a62e528c8a4 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -8,11 +8,12 @@ import semmle.code.cpp.models.interfaces.FormattingFunction import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard functions `printf`, `wprintf` and their glib variants. */ -private class Printf extends FormattingFunction, AliasFunction { +private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunction { Printf() { this instanceof TopLevelFunction and ( @@ -36,7 +37,7 @@ private class Printf extends FormattingFunction, AliasFunction { /** * The standard functions `fprintf`, `fwprintf` and their glib variants. */ -private class Fprintf extends FormattingFunction { +private class Fprintf extends FormattingFunction, NonThrowingFunction { Fprintf() { this instanceof TopLevelFunction and ( @@ -54,7 +55,7 @@ private class Fprintf extends FormattingFunction { /** * The standard function `sprintf` and its Microsoft and glib variants. */ -private class Sprintf extends FormattingFunction { +private class Sprintf extends FormattingFunction, NonThrowingFunction { Sprintf() { this instanceof TopLevelFunction and ( @@ -97,7 +98,7 @@ private class Sprintf extends FormattingFunction { /** * Implements `Snprintf`. */ -private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction { +private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonThrowingFunction { SnprintfImpl() { this instanceof TopLevelFunction and ( @@ -172,7 +173,7 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction { * and * https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms860435(v=msdn.10) */ -private class StringCchPrintf extends FormattingFunction { +private class StringCchPrintf extends FormattingFunction, NonThrowingFunction { StringCchPrintf() { this instanceof TopLevelFunction and exists(string baseName | @@ -204,7 +205,7 @@ private class StringCchPrintf extends FormattingFunction { /** * The standard function `syslog`. */ -private class Syslog extends FormattingFunction { +private class Syslog extends FormattingFunction, NonThrowingFunction { Syslog() { this instanceof TopLevelFunction and this.hasGlobalName("syslog") and diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll index f081a36fac6..9b11ed0af15 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll @@ -7,13 +7,16 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard function `strcat` and its wide, sized, and Microsoft variants. * * Does not include `strlcat`, which is covered by `StrlcatFunction` */ -class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction { +class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction, + NonThrowingFunction +{ StrcatFunction() { this.hasGlobalOrStdOrBslName([ "strcat", // strcat(dst, src) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll index 1858da65234..b7f06f0cebf 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll @@ -7,11 +7,14 @@ import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.SideEffect +import semmle.code.cpp.models.interfaces.NonThrowing /** * The standard function `strcpy` and its wide, sized, and Microsoft variants. */ -class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction { +class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction, + NonThrowingFunction +{ StrcpyFunction() { this.hasGlobalOrStdOrBslName([ "strcpy", // strcpy(dst, src) diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll index f3ec13b5bd5..64901d39ad3 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll @@ -1,7 +1,5 @@ /** - * Provides an abstract class for modeling functions that never throws. - * - * See also `ThrowingFunction` for modeling functions that do throw. + * Provides an abstract class for modeling functions that never throw. */ import semmle.code.cpp.Function From 27bc8ed6afefa3d75a1ca00286b15ea1b1ed39c0 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 28 Aug 2024 11:38:29 +0200 Subject: [PATCH 139/404] Address review comment --- .../codeql/dataflow/internal/DataFlowImpl.qll | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 9c50d245aa5..c47ed472fda 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2693,26 +2693,26 @@ module MakeImpl Lang> { ) { not inBarrier(node2, state) and not outBarrier(node1, state) and - exists(NodeEx node0, boolean preservesValue0, DataFlowType t0, string label0, Ap ap | - Input::localStep(node0, state, node2, state, preservesValue0, t0, cc, label0) and + exists(NodeEx mid, boolean preservesValue2, DataFlowType t2, string label2, Ap ap | + Input::localStep(mid, state, node2, state, preservesValue2, t2, cc, label2) and revFlow(node2, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and - not outBarrier(node0, state) and + not outBarrier(mid, state) and (preservesValue = true or ap instanceof ApNil) | - node1 = node0 and + node1 = mid and localFlowEntry(node1, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and - preservesValue = preservesValue0 and - label = label0 and - t = t0 and + preservesValue = preservesValue2 and + label = label2 and + t = t2 and node1 != node2 or exists(boolean preservesValue1, DataFlowType t1, string label1 | - localFlowStepPlus(node1, pragma[only_bind_into](state), node0, preservesValue1, t1, + localFlowStepPlus(node1, pragma[only_bind_into](state), mid, preservesValue1, t1, cc, label1) and - not node0 instanceof FlowCheckNode and - preservesValue = preservesValue0.booleanAnd(preservesValue1) and - label = mergeLabels(label1, label0) and - if preservesValue0 = true then t = t1 else t = t0 + not mid instanceof FlowCheckNode and + preservesValue = preservesValue2.booleanAnd(preservesValue1) and + label = mergeLabels(label1, label2) and + if preservesValue2 = true then t = t1 else t = t2 ) ) } From 9e861ce7174da8963cff7e892fcfbf5c3fa42266 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 27 Aug 2024 13:53:06 +0200 Subject: [PATCH 140/404] C++: Add support for more clang builtins --- .../exprs.ql | 17 + .../old.dbscheme | 2317 +++++++++++++++++ .../semmlecode.cpp.dbscheme | 2310 ++++++++++++++++ .../sizeof_bind.ql | 14 + .../upgrade.properties | 4 + .../code/cpp/exprs/BuiltInOperations.qll | 56 + cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll | 47 + cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll | 2 + cpp/ql/lib/semmlecode.cpp.dbscheme | 9 +- cpp/ql/lib/semmlecode.cpp.dbscheme.stats | 886 ++++--- .../old.dbscheme | 2310 ++++++++++++++++ .../semmlecode.cpp.dbscheme | 2317 +++++++++++++++++ .../upgrade.properties | 2 + .../builtins/type_traits/clang.cpp | 15 +- .../builtins/type_traits/expr.expected | 14 + .../types/datasizeof/datasizeof.cpp | 30 + .../types/datasizeof/datasizeof.expected | 10 + .../types/datasizeof/datasizeof.ql | 10 + 18 files changed, 9938 insertions(+), 432 deletions(-) create mode 100644 cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/exprs.ql create mode 100644 cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme create mode 100644 cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/semmlecode.cpp.dbscheme create mode 100644 cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/sizeof_bind.ql create mode 100644 cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/upgrade.properties create mode 100644 cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/old.dbscheme create mode 100644 cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/semmlecode.cpp.dbscheme create mode 100644 cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/upgrade.properties create mode 100644 cpp/ql/test/library-tests/types/datasizeof/datasizeof.cpp create mode 100644 cpp/ql/test/library-tests/types/datasizeof/datasizeof.expected create mode 100644 cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql diff --git a/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/exprs.ql b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/exprs.ql new file mode 100644 index 00000000000..e575df01b5c --- /dev/null +++ b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/exprs.ql @@ -0,0 +1,17 @@ +class Expr extends @expr { + string toString() { none() } +} + +class Location extends @location_expr { + string toString() { none() } +} + +predicate isExprWithNewBuiltin(Expr expr) { + exists(int kind | exprs(expr, kind, _) | 385 <= kind and kind <= 388) +} + +from Expr expr, int kind, int kind_new, Location location +where + exprs(expr, kind, location) and + if isExprWithNewBuiltin(expr) then kind_new = 1 else kind_new = kind +select expr, kind_new, location diff --git a/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme new file mode 100644 index 00000000000..02a123a1a68 --- /dev/null +++ b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme @@ -0,0 +1,2317 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/semmlecode.cpp.dbscheme b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..68930f3b81b --- /dev/null +++ b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/semmlecode.cpp.dbscheme @@ -0,0 +1,2310 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/sizeof_bind.ql b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/sizeof_bind.ql new file mode 100644 index 00000000000..47077d7fc82 --- /dev/null +++ b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/sizeof_bind.ql @@ -0,0 +1,14 @@ +class Expr extends @expr { + string toString() { none() } +} + +class Type extends @type { + string toString() { none() } +} + +from Expr expr, Type type, int kind +where + sizeof_bind(expr, type) and + exprs(expr, kind, _) and + (kind = 93 or kind = 94) +select expr, type diff --git a/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/upgrade.properties b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/upgrade.properties new file mode 100644 index 00000000000..8b6ce267a06 --- /dev/null +++ b/cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/upgrade.properties @@ -0,0 +1,4 @@ +description: Add new builtin operations +compatibility: partial +exprs.rel: run exprs.qlo +sizeof_bind.rel: run sizeof_bind.qlo diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index dcf72604ca9..dc55bcda9e6 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -1885,3 +1885,59 @@ class BuiltInOperationIsWinInterface extends BuiltInOperation, @iswininterface { override string getAPrimaryQlClass() { result = "BuiltInOperationIsWinInterface" } } + +/** + * A C++ `__is_trivially_equality_comparable` built-in operation. + * + * Returns `true` if comparing two objects of type `_Tp` is equivalent to + * comparing their object representations. + * + * ``` + * template + * struct is_trivially_equality_comparable + * : public integral_constant + * {}; + * ``` + */ +class BuiltInOperationIsTriviallyEqualityComparable extends BuiltInOperation, + @istriviallyequalitycomparable +{ + override string toString() { result = "__is_trivially_equality_comparable" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyEqualityComparable" } +} + +/** + * A C++ `__is_scoped_enum` built-in operation (used by some implementations + * of the `` header). + * + * Returns `true` if a type is a scoped enum. + * ``` + * template + * constexpr bool is_scoped_enum = __is_scoped_enum(_Tp); + * ``` + */ +class BuiltInOperationIsScopedEnum extends BuiltInOperation, @isscopedenum { + override string toString() { result = "__is_scoped_enum" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationIsScopedEnum" } +} + +/** + * A C++ `__is_trivially_relocatable` built-in operation. + * + * Returns `true` if moving an object of type `_Tp` is equivalent to + * copying the underlying bytes. + * + * ``` + * template + * struct is_trivially_relocatable + * : public integral_constant + * {}; + * ``` + */ +class BuiltInOperationIsTriviallyRelocatable extends BuiltInOperation, @istriviallyrelocatable { + override string toString() { result = "__is_trivially_relocatable" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyRelocatable" } +} diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll index e3ce623d217..b36624d127c 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll @@ -791,6 +791,53 @@ class AlignofTypeOperator extends AlignofOperator { override string toString() { result = "alignof(" + this.getTypeOperand().getName() + ")" } } +/** + * A C++ `__datasizeof` expression (used by some implementations + * of the `` header). + * + * The `__datasizeof` expression behaves identical to `sizeof` except + * that the result ignores tail padding. + */ +class DatasizeofOperator extends Expr, @datasizeof { + override int getPrecedence() { result = 16 } +} + +/** + * A C++ `__datasizeof` expression whose operand is an expression. + */ +class DatasizeofExprOperator extends DatasizeofOperator { + DatasizeofExprOperator() { exists(this.getChild(0)) } + + override string getAPrimaryQlClass() { result = "DatasizeofExprOperator" } + + /** Gets the contained expression. */ + Expr getExprOperand() { result = this.getChild(0) } + + override string toString() { result = "sizeof()" } + + override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() } + + override predicate mayBeGloballyImpure() { this.getExprOperand().mayBeGloballyImpure() } +} + +/** + * A C++ `__datasizeof` expression whose operand is a type name. + */ +class DatasizeofTypeOperator extends DatasizeofOperator { + DatasizeofTypeOperator() { sizeof_bind(underlyingElement(this), _) } + + override string getAPrimaryQlClass() { result = "DatasizeofTypeOperator" } + + /** Gets the contained type. */ + Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) } + + override string toString() { result = "sizeof(" + this.getTypeOperand().getName() + ")" } + + override predicate mayBeImpure() { none() } + + override predicate mayBeGloballyImpure() { none() } +} + /** * A C/C++ array to pointer conversion. * diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll index 0689bf46070..d85962b9fe7 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll @@ -304,6 +304,8 @@ class Expr extends StmtParent, @expr { e instanceof NoExceptExpr or e instanceof AlignofOperator + or + e instanceof DatasizeofOperator ) or exists(Decltype d | d.getExpr() = this.getParentWithConversions*()) diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index 68930f3b81b..02a123a1a68 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1788,6 +1788,10 @@ case @expr.kind of | 382 = @isvalidwinrttype | 383 = @iswinclass | 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof ; @var_args_expr = @vastartexpr @@ -1901,6 +1905,9 @@ case @expr.kind of | @isvalidwinrttype | @iswinclass | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable ; new_allocated_type( @@ -1961,7 +1968,7 @@ uuidof_bind( int type_id: @type ref ); -@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; sizeof_bind( unique int expr: @runtime_sizeof_or_alignof ref, diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index ce799a53e70..d2d1f3a4e63 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -2,7 +2,7 @@ @compilation - 9741 + 9742 @externalDataElement @@ -16,14 +16,14 @@ @svnentry 575525 - - @location_stmt - 3819884 - @location_default 29768335 + + @location_stmt + 3819884 + @diagnostic 4996 @@ -42,7 +42,7 @@ @macro_expansion - 33257696 + 33257908 @other_macro_reference @@ -98,7 +98,7 @@ @localvariable - 576947 + 576952 @enumconstant @@ -392,26 +392,6 @@ @specifier 24747 - - @gnuattribute - 553773 - - - @stdattribute - 253558 - - - @declspec - 239153 - - - @msattribute - 3 - - - @alignas - 4669 - @attribute_arg_token 25213 @@ -436,6 +416,26 @@ @attribute_arg_expr 3 + + @gnuattribute + 553773 + + + @stdattribute + 253563 + + + @declspec + 239153 + + + @msattribute + 3 + + + @alignas + 4669 + @derivation 391568 @@ -446,7 +446,7 @@ @comment - 8265960 + 8266137 @namespace @@ -554,7 +554,7 @@ @pdiffexpr - 33689 + 33690 @lshiftexpr @@ -638,7 +638,7 @@ @assignorexpr - 23627 + 23628 @assignxorexpr @@ -662,11 +662,11 @@ @commaexpr - 122838 + 122841 @subscriptexpr - 364479 + 364482 @callexpr @@ -966,11 +966,11 @@ @static_cast - 215643 + 215649 @reinterpret_cast - 31620 + 31621 @const_cast @@ -1340,6 +1340,22 @@ @iswininterface 1 + + @istriviallyequalitycomparable + 2 + + + @isscopedenum + 2 + + + @istriviallyrelocatable + 2 + + + @datasizeof + 10 + @stmt_expr 1486025 @@ -1350,7 +1366,7 @@ @stmt_while - 29316 + 29317 @stmt_goto @@ -1390,11 +1406,11 @@ @stmt_decl - 593107 + 593124 @stmt_empty - 192683 + 192685 @stmt_continue @@ -1434,7 +1450,7 @@ @stmt_constexpr_if - 52997 + 52998 @stmt_co_return @@ -1470,7 +1486,7 @@ @ppd_define - 2291875 + 2291924 @ppd_undef @@ -1482,7 +1498,7 @@ @ppd_line - 27520 + 27521 @ppd_error @@ -1490,7 +1506,7 @@ @ppd_pragma - 296704 + 296710 @ppd_objc_import @@ -1532,11 +1548,11 @@ compilations - 9741 + 9742 id - 9741 + 9742 cwd @@ -1554,7 +1570,7 @@ 1 2 - 9741 + 9742 @@ -2128,7 +2144,7 @@ seconds - 9588 + 9628 @@ -2209,47 +2225,52 @@ 3 4 - 799 + 679 4 5 - 199 + 319 5 - 7 - 119 + 8 + 159 8 - 10 - 159 + 9 + 79 10 11 - 119 + 199 11 - 14 + 17 159 - 14 + 17 18 + 39 + + + 18 + 19 159 - 19 - 24 + 21 + 53 159 - 42 - 85 - 119 + 95 + 96 + 39 @@ -2317,43 +2338,43 @@ 3 4 - 1358 + 1398 4 5 - 399 + 359 5 6 - 239 + 279 6 7 - 439 + 399 7 8 - 119 + 79 8 - 10 + 9 + 239 + + + 9 + 20 279 - 10 - 27 + 24 + 92 279 - - 28 - 89 - 199 - @@ -2403,13 +2424,13 @@ 79 - 123 - 124 + 135 + 136 39 - 137 - 138 + 138 + 139 39 @@ -2426,26 +2447,26 @@ 1 2 - 5073 + 4794 2 3 - 1957 + 2037 3 4 - 1438 + 1478 4 5 - 679 + 878 5 - 45 + 47 439 @@ -2462,32 +2483,32 @@ 1 2 - 4754 + 4394 2 3 - 1438 + 1717 3 4 - 1398 + 1757 4 5 - 799 + 719 5 - 7 - 799 + 9 + 838 - 7 - 74 - 399 + 9 + 77 + 199 @@ -2503,12 +2524,12 @@ 1 2 - 8549 + 8110 2 3 - 1038 + 1518 @@ -2844,15 +2865,15 @@ compilation_finished - 9741 + 9742 id - 9741 + 9742 cpu_seconds - 7314 + 7100 elapsed_seconds @@ -2870,7 +2891,7 @@ 1 2 - 9741 + 9742 @@ -2886,7 +2907,7 @@ 1 2 - 9741 + 9742 @@ -2902,17 +2923,17 @@ 1 2 - 5870 + 5633 2 3 - 993 + 925 3 - 13 - 451 + 17 + 541 @@ -2928,12 +2949,12 @@ 1 2 - 6581 + 6344 2 3 - 733 + 756 @@ -2952,48 +2973,48 @@ 33 - 6 - 7 + 4 + 5 11 - 8 - 9 + 9 + 10 11 - 11 - 12 + 12 + 13 11 - 16 - 17 + 17 + 18 11 - 49 - 50 + 47 + 48 11 - 166 - 167 + 165 + 166 11 - 173 - 174 + 174 + 175 11 - 190 - 191 + 187 + 188 11 - 238 - 239 + 242 + 243 11 @@ -3013,48 +3034,48 @@ 33 - 6 - 7 + 4 + 5 11 - 8 - 9 + 9 + 10 11 - 11 - 12 + 12 + 13 11 - 16 - 17 + 17 + 18 11 - 47 - 48 + 46 + 47 11 - 132 - 133 + 115 + 116 11 - 133 - 134 + 126 + 127 11 - 141 - 142 + 142 + 143 11 - 213 - 214 + 219 + 220 11 @@ -11755,7 +11776,7 @@ fileannotations - 5129296 + 5129447 id @@ -11767,11 +11788,11 @@ name - 54771 + 54773 value - 46045 + 46046 @@ -11790,7 +11811,7 @@ 2 3 - 4729 + 4730 @@ -12011,7 +12032,7 @@ 2 3 - 6219 + 6220 3 @@ -12041,7 +12062,7 @@ 20 34 - 4221 + 4222 34 @@ -12077,7 +12098,7 @@ 1 2 - 54771 + 54773 @@ -12098,7 +12119,7 @@ 2 3 - 8059 + 8060 3 @@ -12164,7 +12185,7 @@ 1 2 - 7156 + 7157 2 @@ -12219,7 +12240,7 @@ 322 399 - 3950 + 3951 399 @@ -12240,7 +12261,7 @@ 1 2 - 46034 + 46035 2 @@ -12331,15 +12352,15 @@ inmacroexpansion - 109779175 + 109779198 id - 18027366 + 18027369 inv - 2700172 + 2700171 @@ -12353,32 +12374,32 @@ 1 3 - 1581957 + 1581956 3 5 - 1077798 + 1077799 5 6 - 1184883 + 1184884 6 7 - 4819925 + 4819927 7 8 - 6385962 + 6385963 8 9 - 2605254 + 2605255 9 @@ -12399,12 +12420,12 @@ 1 2 - 378425 + 378424 2 3 - 544108 + 544106 3 @@ -12434,12 +12455,12 @@ 10 11 - 325486 + 325487 11 337 - 224846 + 224848 339 @@ -12459,7 +12480,7 @@ affectedbymacroexpansion - 35689090 + 35689096 id @@ -12467,7 +12488,7 @@ inv - 2784775 + 2784774 @@ -12481,7 +12502,7 @@ 1 2 - 2815935 + 2815934 2 @@ -12527,7 +12548,7 @@ 1 4 - 229117 + 229116 4 @@ -12597,19 +12618,19 @@ macroinvocations - 33490949 + 33491157 id - 33490949 + 33491157 macro_id - 79482 + 79484 location - 760368 + 760390 kind @@ -12627,7 +12648,7 @@ 1 2 - 33490949 + 33491157 @@ -12643,7 +12664,7 @@ 1 2 - 33490949 + 33491157 @@ -12659,7 +12680,7 @@ 1 2 - 33490949 + 33491157 @@ -12710,7 +12731,7 @@ 26 61 - 6061 + 6062 61 @@ -12741,7 +12762,7 @@ 1 2 - 42467 + 42468 2 @@ -12756,7 +12777,7 @@ 4 6 - 6840 + 6841 6 @@ -12787,7 +12808,7 @@ 1 2 - 73747 + 73749 2 @@ -12808,37 +12829,42 @@ 1 2 - 281218 + 281226 2 3 - 169654 + 169659 3 4 - 70733 + 70735 4 5 - 60325 + 60327 5 - 9 - 70360 + 8 + 53858 - 9 - 21 - 59106 + 8 + 17 + 62889 - 21 - 244764 - 48969 + 17 + 525 + 57030 + + + 534 + 244748 + 4662 @@ -12854,12 +12880,12 @@ 1 2 - 714198 + 714219 2 350 - 46169 + 46171 @@ -12875,7 +12901,7 @@ 1 2 - 760368 + 760390 @@ -12889,13 +12915,13 @@ 12 - 20663 - 20664 + 20662 + 20663 11 - 2946167 - 2946168 + 2946099 + 2946100 11 @@ -12948,15 +12974,15 @@ macroparent - 29950278 + 29950856 id - 29950278 + 29950856 parent_id - 23286721 + 23287102 @@ -12970,7 +12996,7 @@ 1 2 - 29950278 + 29950856 @@ -12986,17 +13012,17 @@ 1 2 - 17992646 + 17992872 2 3 - 4459439 + 4459570 3 88 - 834635 + 834659 @@ -13084,11 +13110,11 @@ macro_argument_unexpanded - 84547741 + 84549814 invocation - 26214485 + 26214874 argument_index @@ -13096,7 +13122,7 @@ text - 318300 + 318310 @@ -13110,22 +13136,22 @@ 1 2 - 7432628 + 7432497 2 3 - 10673794 + 10674075 3 4 - 6139174 + 6139354 4 67 - 1968888 + 1968946 @@ -13141,22 +13167,22 @@ 1 2 - 7502786 + 7502657 2 3 - 10820341 + 10820626 3 4 - 5972849 + 5973025 4 67 - 1918508 + 1918564 @@ -13181,7 +13207,7 @@ 718261 - 2322238 + 2322204 33 @@ -13224,12 +13250,12 @@ 1 2 - 35073 + 35074 2 3 - 61262 + 61264 3 @@ -13239,32 +13265,32 @@ 4 5 - 45086 + 45087 5 7 - 23931 + 23932 7 12 - 18490 + 18592 12 16 - 21617 + 21516 16 23 - 24981 + 24982 23 42 - 24326 + 24327 42 @@ -13274,7 +13300,7 @@ 128 522393 - 21910 + 21911 @@ -13290,17 +13316,17 @@ 1 2 - 230194 + 230201 2 3 - 77822 + 77824 3 9 - 10283 + 10284 @@ -13310,11 +13336,11 @@ macro_argument_expanded - 84547741 + 84549814 invocation - 26214485 + 26214874 argument_index @@ -13322,7 +13348,7 @@ text - 192897 + 192902 @@ -13336,22 +13362,22 @@ 1 2 - 7432628 + 7432497 2 3 - 10673794 + 10674075 3 4 - 6139174 + 6139354 4 67 - 1968888 + 1968946 @@ -13367,22 +13393,22 @@ 1 2 - 10688876 + 10688841 2 3 - 9201666 + 9201903 3 4 - 5208146 + 5208300 4 9 - 1115796 + 1115829 @@ -13407,7 +13433,7 @@ 718261 - 2322238 + 2322204 33 @@ -13455,7 +13481,7 @@ 2 3 - 37308 + 37309 3 @@ -13480,12 +13506,12 @@ 7 9 - 14776 + 14788 9 14 - 12044 + 12033 14 @@ -13500,11 +13526,11 @@ 48 151 - 14471 + 14472 152 - 1060426 + 1060410 13738 @@ -13521,12 +13547,12 @@ 1 2 - 97622 + 97625 2 3 - 80870 + 80872 3 @@ -15161,15 +15187,15 @@ fun_decl_noexcept - 61665 + 61667 fun_decl - 61665 + 61667 constant - 61567 + 61568 @@ -15183,7 +15209,7 @@ 1 2 - 61665 + 61667 @@ -15199,7 +15225,7 @@ 1 2 - 61468 + 61469 2 @@ -17082,7 +17108,7 @@ using_container - 466789 + 466802 parent @@ -17090,7 +17116,7 @@ child - 295983 + 295992 @@ -17160,17 +17186,17 @@ 1 2 - 218307 + 218314 2 3 - 51723 + 51725 3 11 - 23818 + 23819 13 @@ -18289,11 +18315,11 @@ overrides - 125725 + 125735 new - 122753 + 122762 old @@ -18311,7 +18337,7 @@ 1 2 - 119788 + 119798 2 @@ -18719,11 +18745,11 @@ localvariables - 576947 + 576952 id - 576947 + 576952 type_id @@ -18731,7 +18757,7 @@ name - 90548 + 90549 @@ -18745,7 +18771,7 @@ 1 2 - 576947 + 576952 @@ -18761,7 +18787,7 @@ 1 2 - 576947 + 576952 @@ -18854,7 +18880,7 @@ 1 2 - 57031 + 57032 2 @@ -18900,7 +18926,7 @@ 3 1486 - 6644 + 6645 @@ -18910,11 +18936,11 @@ autoderivation - 147958 + 147961 var - 147958 + 147961 derivation_type @@ -18932,7 +18958,7 @@ 1 2 - 147958 + 147961 @@ -21448,15 +21474,15 @@ typedefbase - 1686067 + 1686117 id - 1686067 + 1686117 type_id - 793466 + 793489 @@ -21470,7 +21496,7 @@ 1 2 - 1686067 + 1686117 @@ -21486,22 +21512,22 @@ 1 2 - 617388 + 617406 2 3 - 83252 + 83254 3 6 - 62030 + 62031 6 5437 - 30794 + 30795 @@ -22434,11 +22460,11 @@ is_pod_class - 534689 + 534705 id - 534689 + 534705 @@ -22566,11 +22592,11 @@ class_template_argument - 2883028 + 2882763 type_id - 1315580 + 1315517 index @@ -22578,7 +22604,7 @@ arg_type - 840471 + 840394 @@ -22592,7 +22618,7 @@ 1 2 - 540943 + 540959 2 @@ -22602,12 +22628,12 @@ 3 4 - 231424 + 231397 4 7 - 120368 + 120315 7 @@ -22628,22 +22654,22 @@ 1 2 - 567595 + 567611 2 3 - 410482 + 410483 3 4 - 244869 + 244842 4 113 - 92633 + 92579 @@ -22687,8 +22713,8 @@ 101 - 12810 - 116427 + 12805 + 116418 45 @@ -22751,27 +22777,27 @@ 1 2 - 523378 + 523348 2 3 - 174384 + 174344 3 4 - 51317 + 51341 4 10 - 64016 + 63984 10 10265 - 27374 + 27375 @@ -22787,12 +22813,12 @@ 1 2 - 746573 + 746494 2 3 - 77833 + 77836 3 @@ -23888,22 +23914,22 @@ is_variable_template - 40289 + 40290 id - 40289 + 40290 variable_instantiation - 204304 + 204308 to - 204304 + 204308 from @@ -23921,7 +23947,7 @@ 1 2 - 204304 + 204308 @@ -23937,7 +23963,7 @@ 1 2 - 12214 + 12215 2 @@ -23982,11 +24008,11 @@ variable_template_argument - 383982 + 383990 variable_id - 195635 + 195640 index @@ -23994,7 +24020,7 @@ arg_type - 187558 + 187562 @@ -24008,22 +24034,22 @@ 1 2 - 86095 + 86097 2 3 - 70235 + 70237 3 4 - 28862 + 28863 4 17 - 10441 + 10442 @@ -24039,17 +24065,17 @@ 1 2 - 90429 + 90431 2 3 - 71713 + 71714 3 4 - 24035 + 24036 4 @@ -24187,7 +24213,7 @@ 1 2 - 145594 + 145597 2 @@ -24218,7 +24244,7 @@ 1 2 - 170220 + 170224 2 @@ -25276,15 +25302,15 @@ explicit_specifier_exprs - 32605 + 32606 func_id - 32605 + 32606 constant - 32605 + 32606 @@ -25298,7 +25324,7 @@ 1 2 - 32605 + 32606 @@ -25314,7 +25340,7 @@ 1 2 - 32605 + 32606 @@ -27216,15 +27242,15 @@ enclosingfunction - 118325 + 118329 child - 118325 + 118329 parent - 67663 + 67665 @@ -27238,7 +27264,7 @@ 1 2 - 118325 + 118329 @@ -27254,12 +27280,12 @@ 1 2 - 35761 + 35762 2 3 - 21052 + 21053 3 @@ -27269,7 +27295,7 @@ 4 45 - 4887 + 4888 @@ -28600,19 +28626,19 @@ comments - 8265960 + 8266137 id - 8265960 + 8266137 contents - 3147511 + 3147578 location - 8265960 + 8266137 @@ -28626,7 +28652,7 @@ 1 2 - 8265960 + 8266137 @@ -28642,7 +28668,7 @@ 1 2 - 8265960 + 8266137 @@ -28658,17 +28684,17 @@ 1 2 - 2879275 + 2879337 2 7 - 236614 + 236620 7 32784 - 31620 + 31621 @@ -28684,17 +28710,17 @@ 1 2 - 2879275 + 2879337 2 7 - 236614 + 236620 7 32784 - 31620 + 31621 @@ -28710,7 +28736,7 @@ 1 2 - 8265960 + 8266137 @@ -28726,7 +28752,7 @@ 1 2 - 8265960 + 8266137 @@ -28794,15 +28820,15 @@ exprconv - 7033024 + 7033025 converted - 7033024 + 7033025 conversion - 7033024 + 7033025 @@ -28816,7 +28842,7 @@ 1 2 - 7033024 + 7033025 @@ -28832,7 +28858,7 @@ 1 2 - 7033024 + 7033025 @@ -29557,11 +29583,11 @@ expr_isload - 5096974 + 5096886 expr_id - 5096974 + 5096886 @@ -29837,7 +29863,7 @@ qualifyingelement - 97519 + 97538 location @@ -29951,7 +29977,7 @@ 1 2 - 58401 + 58420 2 @@ -29987,7 +30013,7 @@ 1 2 - 58401 + 58420 2 @@ -30023,7 +30049,7 @@ 1 2 - 63815 + 63834 2 @@ -30136,12 +30162,12 @@ 1 2 - 137074 + 137055 2 3 - 55684 + 55703 3 @@ -30262,7 +30288,7 @@ fun - 511325 + 511344 @@ -30297,12 +30323,12 @@ 1 2 - 315052 + 315090 2 3 - 77912 + 77893 3 @@ -32082,15 +32108,15 @@ expr_types - 18451522 + 18451524 id - 18319865 + 18319863 typeid - 1214570 + 1214606 value_category @@ -32108,12 +32134,12 @@ 1 2 - 18188208 + 18188202 2 3 - 131657 + 131661 @@ -32129,7 +32155,7 @@ 1 2 - 18319865 + 18319863 @@ -32145,42 +32171,42 @@ 1 2 - 438545 + 438558 2 3 - 249328 + 249335 3 4 - 102804 + 102807 4 5 - 81886 + 81888 5 8 - 109283 + 109275 8 14 - 96471 + 96485 14 41 - 91662 + 91665 41 - 125330 - 44589 + 125325 + 44590 @@ -32196,12 +32222,12 @@ 1 2 - 1050188 + 1050219 2 3 - 154189 + 154193 3 @@ -32225,13 +32251,13 @@ 11 - 368484 - 368485 + 368483 + 368484 11 - 1239526 - 1239527 + 1239479 + 1239480 11 @@ -34691,11 +34717,11 @@ stmts - 4630245 + 4630345 id - 4630245 + 4630345 kind @@ -34703,7 +34729,7 @@ location - 2171696 + 2171742 @@ -34717,7 +34743,7 @@ 1 2 - 4630245 + 4630345 @@ -34733,7 +34759,7 @@ 1 2 - 4630245 + 4630345 @@ -34961,22 +34987,22 @@ 1 2 - 1725752 + 1725789 2 3 - 178298 + 178302 3 8 - 167364 + 167367 8 653 - 100280 + 100282 @@ -34992,12 +35018,12 @@ 1 2 - 2117812 + 2117857 2 8 - 53883 + 53884 @@ -35295,15 +35321,15 @@ constexpr_if_then - 52997 + 52998 constexpr_if_stmt - 52997 + 52998 then_id - 52997 + 52998 @@ -35317,7 +35343,7 @@ 1 2 - 52997 + 52998 @@ -35333,7 +35359,7 @@ 1 2 - 52997 + 52998 @@ -35391,15 +35417,15 @@ while_body - 29316 + 29317 while_stmt - 29316 + 29317 body_id - 29316 + 29317 @@ -35413,7 +35439,7 @@ 1 2 - 29316 + 29317 @@ -35429,7 +35455,7 @@ 1 2 - 29316 + 29317 @@ -36308,11 +36334,11 @@ stmt_decl_bind - 580844 + 580849 stmt - 541062 + 541067 num @@ -36320,7 +36346,7 @@ decl - 580740 + 580745 @@ -36334,7 +36360,7 @@ 1 2 - 520373 + 520378 2 @@ -36355,7 +36381,7 @@ 1 2 - 520373 + 520378 2 @@ -36558,7 +36584,7 @@ 1 2 - 580703 + 580708 2 @@ -36579,7 +36605,7 @@ 1 2 - 580740 + 580745 @@ -36589,11 +36615,11 @@ stmt_decl_entry_bind - 580844 + 580849 stmt - 541062 + 541067 num @@ -36601,7 +36627,7 @@ decl_entry - 580786 + 580791 @@ -36615,7 +36641,7 @@ 1 2 - 520373 + 520378 2 @@ -36636,7 +36662,7 @@ 1 2 - 520373 + 520378 2 @@ -36839,7 +36865,7 @@ 1 2 - 580765 + 580770 3 @@ -36860,7 +36886,7 @@ 1 2 - 580786 + 580791 @@ -37410,19 +37436,19 @@ preproctext - 3367675 + 3367747 id - 3367675 + 3367747 head - 2440621 + 2440673 body - 1426388 + 1426418 @@ -37436,7 +37462,7 @@ 1 2 - 3367675 + 3367747 @@ -37452,7 +37478,7 @@ 1 2 - 3367675 + 3367747 @@ -37468,12 +37494,12 @@ 1 2 - 2301824 + 2301873 2 740 - 138797 + 138800 @@ -37489,12 +37515,12 @@ 1 2 - 2381911 + 2381962 2 5 - 58710 + 58711 @@ -37510,12 +37536,12 @@ 1 2 - 1291236 + 1291263 2 6 - 106979 + 106981 6 @@ -37536,17 +37562,17 @@ 1 2 - 1294092 + 1294120 2 7 - 107274 + 107276 7 2980 - 25020 + 25021 diff --git a/cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/old.dbscheme b/cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/old.dbscheme new file mode 100644 index 00000000000..68930f3b81b --- /dev/null +++ b/cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/old.dbscheme @@ -0,0 +1,2310 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..02a123a1a68 --- /dev/null +++ b/cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/semmlecode.cpp.dbscheme @@ -0,0 +1,2317 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/upgrade.properties b/cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/upgrade.properties new file mode 100644 index 00000000000..db0e7e92d0e --- /dev/null +++ b/cpp/ql/lib/upgrades/68930f3b81bbe3fdbb91c850deca1fec8072d62a/upgrade.properties @@ -0,0 +1,2 @@ +description: Add new builtin operations +compatibility: backwards diff --git a/cpp/ql/test/library-tests/builtins/type_traits/clang.cpp b/cpp/ql/test/library-tests/builtins/type_traits/clang.cpp index 167023c1a33..73244454372 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/clang.cpp +++ b/cpp/ql/test/library-tests/builtins/type_traits/clang.cpp @@ -1,4 +1,4 @@ -// semmle-extractor-options: --clang --clang_version 180000 +// semmle-extractor-options: --clang --edg --clang_version --edg 190000 struct S { void f() {} @@ -108,3 +108,16 @@ bool b_is_unbounded_array2 = __is_unbounded_array(int[42]); bool b_is_referenceable1 = __is_referenceable(int); bool b_is_referenceable2 = __is_referenceable(void); + +bool b_is_trivially_equality_comparable1 = __is_trivially_equality_comparable(int); +bool b_is_trivially_equality_comparable2 = __is_trivially_equality_comparable(void); + +enum class E { + a, b +}; + +bool b_is_scoped_enum1 = __is_scoped_enum(E); +bool b_is_scoped_enum2 = __is_scoped_enum(int); + +bool b_is_trivially_relocatable1 = __is_trivially_relocatable(int); +bool b_is_trivially_relocatable2 = __is_trivially_relocatable(void); diff --git a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected index edf63baef9e..55bf0757a49 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected +++ b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected @@ -153,7 +153,21 @@ | clang.cpp:109:28:109:50 | int | | | | clang.cpp:110:28:110:51 | __is_referenceable | void | 0 | | clang.cpp:110:28:110:51 | void | | | +| clang.cpp:112:44:112:82 | __is_trivially_equality_comparable | int | 1 | +| clang.cpp:112:44:112:82 | int | | | +| clang.cpp:113:44:113:83 | __is_trivially_equality_comparable | void | 0 | +| clang.cpp:113:44:113:83 | void | | | +| clang.cpp:119:26:119:44 | E | | | +| clang.cpp:119:26:119:44 | __is_scoped_enum | E | 1 | +| clang.cpp:120:26:120:46 | __is_scoped_enum | int | 0 | +| clang.cpp:120:26:120:46 | int | | | +| clang.cpp:122:36:122:66 | __is_trivially_relocatable | int | 1 | +| clang.cpp:122:36:122:66 | int | | | +| clang.cpp:123:36:123:67 | __is_trivially_relocatable | void | 0 | +| clang.cpp:123:36:123:67 | void | | | | file://:0:0:0:0 | 0 | | 0 | +| file://:0:0:0:0 | 0 | | 0 | +| file://:0:0:0:0 | 1 | | 1 | | file://:0:0:0:0 | 1 | | 1 | | file://:0:0:0:0 | 2 | | 2 | | gcc.cpp:3:25:3:25 | 8 | | 8 | diff --git a/cpp/ql/test/library-tests/types/datasizeof/datasizeof.cpp b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.cpp new file mode 100644 index 00000000000..b6e65889a68 --- /dev/null +++ b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.cpp @@ -0,0 +1,30 @@ +// semmle-extractor-options: --clang --edg --clang_version --edg 190000 + +typedef unsigned int size_t; + +class MyClass +{ +public: + int x; + int *ptr; + char c; +}; + +void func() { + int i; + char c; + int * ptr; + MyClass mc; + int arr[10]; + + size_t sz1 = __datasizeof(int); + size_t sz2 = __datasizeof(char); + size_t sz3 = __datasizeof(int *); + size_t sz4 = __datasizeof(MyClass); + size_t sz5 = __datasizeof(i); + size_t sz6 = __datasizeof(c); + size_t sz7 = __datasizeof(ptr); + size_t sz8 = __datasizeof(mc); + size_t sz9 = __datasizeof(arr); + size_t sz10 = __datasizeof(arr[4]); +} diff --git a/cpp/ql/test/library-tests/types/datasizeof/datasizeof.expected b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.expected new file mode 100644 index 00000000000..e0deac1c2ba --- /dev/null +++ b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.expected @@ -0,0 +1,10 @@ +| datasizeof.cpp:20:15:20:31 | sizeof(int) | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int | +| datasizeof.cpp:21:15:21:32 | sizeof(char) | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char | +| datasizeof.cpp:22:15:22:33 | sizeof(int *) | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * | +| datasizeof.cpp:23:15:23:35 | sizeof(MyClass) | DatasizeofTypeOperator.getTypeOperand() | datasizeof.cpp:5:7:5:13 | MyClass | +| datasizeof.cpp:24:15:24:29 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:24:28:24:28 | i | +| datasizeof.cpp:25:15:25:29 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:25:28:25:28 | c | +| datasizeof.cpp:26:15:26:31 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:26:28:26:30 | ptr | +| datasizeof.cpp:27:15:27:30 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:27:28:27:29 | mc | +| datasizeof.cpp:28:15:28:31 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:28:28:28:30 | arr | +| datasizeof.cpp:29:16:29:35 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:29:29:29:34 | access to array | diff --git a/cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql new file mode 100644 index 00000000000..c2edf1844ff --- /dev/null +++ b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql @@ -0,0 +1,10 @@ +import cpp + +from DatasizeofOperator sto, string elemDesc, Element e +where + elemDesc = "DatasizeofTypeOperator.getTypeOperand()" and + e = sto.(DatasizeofTypeOperator).getTypeOperand() + or + elemDesc = "DatasizeofExprOperator.getExprOperand()" and + e = sto.(DatasizeofExprOperator).getExprOperand() +select sto, elemDesc, e From 026969b6e92466652ae3d80db974f40d4aff62ab Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 28 Aug 2024 12:21:59 +0200 Subject: [PATCH 141/404] C++: Add change note --- .../lib/change-notes/2024-08-28-more-builtin-operations.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2024-08-28-more-builtin-operations.md diff --git a/cpp/ql/lib/change-notes/2024-08-28-more-builtin-operations.md b/cpp/ql/lib/change-notes/2024-08-28-more-builtin-operations.md new file mode 100644 index 00000000000..25314598759 --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-08-28-more-builtin-operations.md @@ -0,0 +1,5 @@ +--- +category: feature +--- +* Added subclasses of `BuiltInOperations` for the `__is_scoped_enum`, `__is_trivially_equality_comparable`, and `__is_trivially_relocatable` builtin operations. +* Added a subclass of `Expr` for `__datasizeof` expressions. From 6a9bd0de1d1a4f12bd599c5754aecaa7fb085608 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 28 Aug 2024 14:13:28 +0200 Subject: [PATCH 142/404] Dataflow: Include FlowState in SummaryCtx. --- .../codeql/dataflow/internal/DataFlowImpl.qll | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index f42da2f2fc0..48d6ba61e2f 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1565,7 +1565,7 @@ module MakeImpl Lang> { fwdFlowIn(node, apa, state, cc, t, ap, allowsFlowThrough) and if allowsFlowThrough = true then ( - summaryCtx = TSummaryCtxSome(node, t, ap) + summaryCtx = TSummaryCtxSome(node, state, t, ap) ) else ( summaryCtx = TSummaryCtxNone() and // When the call contexts of source and sink needs to match then there's @@ -1592,7 +1592,9 @@ module MakeImpl Lang> { private newtype TSummaryCtx = TSummaryCtxNone() or - TSummaryCtxSome(ParamNodeEx p, Typ t, Ap ap) { fwdFlowIn(p, _, _, _, t, ap, true) } + TSummaryCtxSome(ParamNodeEx p, FlowState state, Typ t, Ap ap) { + fwdFlowIn(p, _, state, _, t, ap, true) + } /** * A context for generating flow summaries. This represents flow entry through @@ -1616,10 +1618,11 @@ module MakeImpl Lang> { /** A summary context from which a flow summary can be generated. */ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome { private ParamNodeEx p; + private FlowState state; private Typ t; private Ap ap; - SummaryCtxSome() { this = TSummaryCtxSome(p, t, ap) } + SummaryCtxSome() { this = TSummaryCtxSome(p, state, t, ap) } ParamNodeEx getParamNode() { result = p } @@ -2074,7 +2077,7 @@ module MakeImpl Lang> { fwdFlow(pragma[only_bind_into](ret), state, ccc, summaryCtx, t, ap, pragma[only_bind_into](apa)) and summaryCtx = - TSummaryCtxSome(pragma[only_bind_into](p), _, pragma[only_bind_into](argAp)) and + TSummaryCtxSome(pragma[only_bind_into](p), _, _, pragma[only_bind_into](argAp)) and not outBarrier(ret, state) and kind = ret.getKind() and parameterFlowThroughAllowed(p, kind) and @@ -2110,9 +2113,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowIsEntered0( DataFlowCall call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, - ParamNodeEx p, Typ t, Ap ap + ParamNodeEx p, FlowState state, Typ t, Ap ap ) { - FwdFlowIn::fwdFlowIn(call, arg, _, p, _, cc, innerCc, + FwdFlowIn::fwdFlowIn(call, arg, _, p, state, cc, innerCc, summaryCtx, t, ap, _, _, true) } @@ -2125,9 +2128,9 @@ module MakeImpl Lang> { DataFlowCall call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, SummaryCtxSome innerSummaryCtx ) { - exists(ParamNodeEx p, Typ t, Ap ap | - fwdFlowIsEntered0(call, arg, cc, innerCc, summaryCtx, p, t, ap) and - innerSummaryCtx = TSummaryCtxSome(p, t, ap) + exists(ParamNodeEx p, FlowState state, Typ t, Ap ap | + fwdFlowIsEntered0(call, arg, cc, innerCc, summaryCtx, p, state, t, ap) and + innerSummaryCtx = TSummaryCtxSome(p, state, t, ap) ) } @@ -2160,7 +2163,7 @@ module MakeImpl Lang> { Ap argAp, ApApprox argApa, Ap ap ) { exists(DataFlowCall call, ApApprox apa, boolean allowsFieldFlow | - returnFlowsThrough0(call, state, ccc, ap, apa, ret, TSummaryCtxSome(p, argT, argAp), + returnFlowsThrough0(call, state, ccc, ap, apa, ret, TSummaryCtxSome(p, _, argT, argAp), argApa) and flowThroughOutOfCall(call, ccc, ret, _, allowsFieldFlow, argApa, apa) and pos = ret.getReturnPosition() and @@ -2522,7 +2525,7 @@ module MakeImpl Lang> { exists(Ap ap0 | parameterMayFlowThrough(p, _) and revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, ap0) and - fwdFlow(n, state, any(CcCall ccc), TSummaryCtxSome(p, _, ap), _, ap0, _) + fwdFlow(n, state, any(CcCall ccc), TSummaryCtxSome(p, _, _, ap), _, ap0, _) ) } @@ -3114,8 +3117,7 @@ module MakeImpl Lang> { | fwdFlowThroughStep0(call, arg, cc, state, ccc, summaryCtx, t, ap, apa, ret, innerSummaryCtx, innerArgApa) and - innerSummaryCtx = TSummaryCtxSome(p, innerArgT, innerArgAp) and - revFlow(arg, state0, _, _, _) and + innerSummaryCtx = TSummaryCtxSome(p, state0, innerArgT, innerArgAp) and pn1 = mkPathNode(arg, state0, cc, summaryCtx, innerArgT, innerArgAp) and pn2 = typeStrengthenToPathNode(p, state0, ccc, innerSummaryCtx, innerArgT, innerArgAp) and pn3 = mkPathNode(ret, state, ccc, innerSummaryCtx, t, ap) @@ -3244,7 +3246,7 @@ module MakeImpl Lang> { fwdFlowInStep(arg, node, state, outercc, cc, outerSummaryCtx, t, ap, allowsFlowThrough) and label = "" and if allowsFlowThrough = true - then summaryCtx = TSummaryCtxSome(node, t, ap) + then summaryCtx = TSummaryCtxSome(node, state, t, ap) else summaryCtx = TSummaryCtxNone() ) or From 6d346dbedd27522beb0ca44829008d7717a3a114 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 28 Aug 2024 14:40:04 +0200 Subject: [PATCH 143/404] DataFlow: Bugfix in flow state for value preservation. --- .../dataflow/internal/ContentDataFlowImpl.qll | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll index c63f36bdeda..f4b4b9655e4 100644 --- a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll @@ -51,6 +51,11 @@ module MakeImplContentDataFlow Lang> { */ default predicate isAdditionalFlowStep(Node node1, Node node2) { none() } + /** + * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow steps. + */ + default predicate isAdditionalTaintStep(Node node1, Node node2) { none() } + /** Holds if data flow into `node` is prohibited. */ default predicate isBarrier(Node node) { none() } @@ -101,7 +106,7 @@ module MakeImplContentDataFlow Lang> { predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { storeStep(node1, state1, _, node2, state2) or readStep(node1, state1, _, node2, state2) or - additionalStep(node1, state1, node2, state2) + additionalTaintStep(node1, state1, node2, state2) } predicate isAdditionalFlowStep = ContentConfig::isAdditionalFlowStep/2; @@ -229,8 +234,8 @@ module MakeImplContentDataFlow Lang> { ) } - private predicate additionalStep(Node node1, State state1, Node node2, State state2) { - ContentConfig::isAdditionalFlowStep(node1, node2) and + private predicate additionalTaintStep(Node node1, State state1, Node node2, State state2) { + ContentConfig::isAdditionalTaintStep(node1, node2) and ( state1 instanceof InitState and state2.(InitState).decode(false) @@ -302,12 +307,16 @@ module MakeImplContentDataFlow Lang> { // relation, when flow can reach a sink without going back out Flow::PathGraph::subpaths(pred, succ, _, _) and not reachesSink(succ) - or + ) + or + exists(Node predNode, State predState, Node succNode, State succState | + succNodeAndState(pred, predNode, predState, succ, succNode, succState) + | // needed to record store steps - storeStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) + storeStep(predNode, predState, _, succNode, succState) or // needed to record read steps - readStep(pred.getNode(), pred.getState(), _, succ.getNode(), succ.getState()) + readStep(predNode, predState, _, succNode, succState) ) } From e8595e28e92368eceeba5bd40d91163e6c75849e Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 28 Aug 2024 15:04:38 +0200 Subject: [PATCH 144/404] Update java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll Co-authored-by: Anders Schack-Mulligen --- .../code/java/dataflow/internal/DataFlowDispatch.qll | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll index 633a8cd3472..f63df6ad09e 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll @@ -43,9 +43,12 @@ private module DispatchImpl { /** * Gets a viable implementation of the target of the given `Call`. * The following heuristic is applied for finding the appropriate callable: - * 1. If an exact manual model exists, only dispatch to the summarized callable. - * 2. If a (non exact) manual model exists and/or if the source code is available, dispatch to both/either. - * 3. Only dispatch to a summarized callable in case the static call target in not in source. + * In general, dispatch to both any existing model and any viable source dispatch. + * However, if the model is generated and the static call target is in the source then + * we trust the source more than the model and skip dispatch to the model. + * Vice versa, if the model is manual and the source dispatch has a comparatively low + * confidence then we only dispatch to the model. Additionally, manual models that + * match a source dispatch exactly take precedence over the source. */ DataFlowCallable viableCallable(DataFlowCall c) { exists(Call call | call = c.asCall() | From 2b571cf450dfbb8f2dfc3773a944db68b9e0ad39 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 28 Aug 2024 15:11:42 +0200 Subject: [PATCH 145/404] C++: Address review comments --- cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll | 6 +++--- .../types/datasizeof/datasizeof.expected | 20 +++++++++---------- .../types/datasizeof/datasizeof.ql | 2 +- .../types/sizeof/sizeof.expected | 20 +++++++++---------- .../test/library-tests/types/sizeof/sizeof.ql | 2 +- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll index b36624d127c..85293cc7313 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll @@ -795,7 +795,7 @@ class AlignofTypeOperator extends AlignofOperator { * A C++ `__datasizeof` expression (used by some implementations * of the `` header). * - * The `__datasizeof` expression behaves identical to `sizeof` except + * The `__datasizeof` expression behaves identically to `sizeof` except * that the result ignores tail padding. */ class DatasizeofOperator extends Expr, @datasizeof { @@ -813,7 +813,7 @@ class DatasizeofExprOperator extends DatasizeofOperator { /** Gets the contained expression. */ Expr getExprOperand() { result = this.getChild(0) } - override string toString() { result = "sizeof()" } + override string toString() { result = "__datasizeof()" } override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() } @@ -831,7 +831,7 @@ class DatasizeofTypeOperator extends DatasizeofOperator { /** Gets the contained type. */ Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) } - override string toString() { result = "sizeof(" + this.getTypeOperand().getName() + ")" } + override string toString() { result = "__datasizeof(" + this.getTypeOperand().getName() + ")" } override predicate mayBeImpure() { none() } diff --git a/cpp/ql/test/library-tests/types/datasizeof/datasizeof.expected b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.expected index e0deac1c2ba..0ba70c61898 100644 --- a/cpp/ql/test/library-tests/types/datasizeof/datasizeof.expected +++ b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.expected @@ -1,10 +1,10 @@ -| datasizeof.cpp:20:15:20:31 | sizeof(int) | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int | -| datasizeof.cpp:21:15:21:32 | sizeof(char) | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char | -| datasizeof.cpp:22:15:22:33 | sizeof(int *) | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * | -| datasizeof.cpp:23:15:23:35 | sizeof(MyClass) | DatasizeofTypeOperator.getTypeOperand() | datasizeof.cpp:5:7:5:13 | MyClass | -| datasizeof.cpp:24:15:24:29 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:24:28:24:28 | i | -| datasizeof.cpp:25:15:25:29 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:25:28:25:28 | c | -| datasizeof.cpp:26:15:26:31 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:26:28:26:30 | ptr | -| datasizeof.cpp:27:15:27:30 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:27:28:27:29 | mc | -| datasizeof.cpp:28:15:28:31 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:28:28:28:30 | arr | -| datasizeof.cpp:29:16:29:35 | sizeof() | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:29:29:29:34 | access to array | +| datasizeof.cpp:20:15:20:31 | __datasizeof(int) | 4 | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int | +| datasizeof.cpp:21:15:21:32 | __datasizeof(char) | 1 | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char | +| datasizeof.cpp:22:15:22:33 | __datasizeof(int *) | 8 | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * | +| datasizeof.cpp:23:15:23:35 | __datasizeof(MyClass) | 24 | DatasizeofTypeOperator.getTypeOperand() | datasizeof.cpp:5:7:5:13 | MyClass | +| datasizeof.cpp:24:15:24:29 | __datasizeof() | 4 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:24:28:24:28 | i | +| datasizeof.cpp:25:15:25:29 | __datasizeof() | 1 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:25:28:25:28 | c | +| datasizeof.cpp:26:15:26:31 | __datasizeof() | 8 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:26:28:26:30 | ptr | +| datasizeof.cpp:27:15:27:30 | __datasizeof() | 24 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:27:28:27:29 | mc | +| datasizeof.cpp:28:15:28:31 | __datasizeof() | 40 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:28:28:28:30 | arr | +| datasizeof.cpp:29:16:29:35 | __datasizeof() | 4 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:29:29:29:34 | access to array | diff --git a/cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql index c2edf1844ff..3b839b4a8b9 100644 --- a/cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql +++ b/cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql @@ -7,4 +7,4 @@ where or elemDesc = "DatasizeofExprOperator.getExprOperand()" and e = sto.(DatasizeofExprOperator).getExprOperand() -select sto, elemDesc, e +select sto, sto.getValue(), elemDesc, e diff --git a/cpp/ql/test/library-tests/types/sizeof/sizeof.expected b/cpp/ql/test/library-tests/types/sizeof/sizeof.expected index e75583fb9e5..c0d075126df 100644 --- a/cpp/ql/test/library-tests/types/sizeof/sizeof.expected +++ b/cpp/ql/test/library-tests/types/sizeof/sizeof.expected @@ -1,10 +1,10 @@ -| sizeof.cpp:19:15:19:25 | sizeof(int) | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int | -| sizeof.cpp:20:15:20:26 | sizeof(char) | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char | -| sizeof.cpp:21:15:21:27 | sizeof(int *) | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * | -| sizeof.cpp:22:15:22:29 | sizeof(MyClass) | SizeofTypeOperator.getTypeOperand() | sizeof.cpp:4:7:4:13 | MyClass | -| sizeof.cpp:23:15:23:23 | sizeof() | SizeofExprOperator.getExprOperand() | sizeof.cpp:23:22:23:22 | i | -| sizeof.cpp:24:15:24:23 | sizeof() | SizeofExprOperator.getExprOperand() | sizeof.cpp:24:22:24:22 | c | -| sizeof.cpp:25:15:25:25 | sizeof() | SizeofExprOperator.getExprOperand() | sizeof.cpp:25:22:25:24 | ptr | -| sizeof.cpp:26:15:26:24 | sizeof() | SizeofExprOperator.getExprOperand() | sizeof.cpp:26:22:26:23 | mc | -| sizeof.cpp:27:15:27:25 | sizeof() | SizeofExprOperator.getExprOperand() | sizeof.cpp:27:22:27:24 | arr | -| sizeof.cpp:28:16:28:29 | sizeof() | SizeofExprOperator.getExprOperand() | sizeof.cpp:28:23:28:28 | access to array | +| sizeof.cpp:19:15:19:25 | sizeof(int) | 4 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int | +| sizeof.cpp:20:15:20:26 | sizeof(char) | 1 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char | +| sizeof.cpp:21:15:21:27 | sizeof(int *) | 8 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * | +| sizeof.cpp:22:15:22:29 | sizeof(MyClass) | 16 | SizeofTypeOperator.getTypeOperand() | sizeof.cpp:4:7:4:13 | MyClass | +| sizeof.cpp:23:15:23:23 | sizeof() | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:23:22:23:22 | i | +| sizeof.cpp:24:15:24:23 | sizeof() | 1 | SizeofExprOperator.getExprOperand() | sizeof.cpp:24:22:24:22 | c | +| sizeof.cpp:25:15:25:25 | sizeof() | 8 | SizeofExprOperator.getExprOperand() | sizeof.cpp:25:22:25:24 | ptr | +| sizeof.cpp:26:15:26:24 | sizeof() | 16 | SizeofExprOperator.getExprOperand() | sizeof.cpp:26:22:26:23 | mc | +| sizeof.cpp:27:15:27:25 | sizeof() | 40 | SizeofExprOperator.getExprOperand() | sizeof.cpp:27:22:27:24 | arr | +| sizeof.cpp:28:16:28:29 | sizeof() | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:28:23:28:28 | access to array | diff --git a/cpp/ql/test/library-tests/types/sizeof/sizeof.ql b/cpp/ql/test/library-tests/types/sizeof/sizeof.ql index db8beba69a0..531f55ee45c 100644 --- a/cpp/ql/test/library-tests/types/sizeof/sizeof.ql +++ b/cpp/ql/test/library-tests/types/sizeof/sizeof.ql @@ -7,4 +7,4 @@ where or elemDesc = "SizeofExprOperator.getExprOperand()" and e = sto.(SizeofExprOperator).getExprOperand() -select sto, elemDesc, e +select sto, sto.getValue(), elemDesc, e From d1fecd869be3f519f6780a8fca6ca804f4b96c4e Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 28 Aug 2024 15:40:14 +0200 Subject: [PATCH 146/404] C++: Make StringCchPrintf not extend NonThrowingFunction --- cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll index a62e528c8a4..7286552e3ee 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Printf.qll @@ -173,7 +173,7 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, * and * https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms860435(v=msdn.10) */ -private class StringCchPrintf extends FormattingFunction, NonThrowingFunction { +private class StringCchPrintf extends FormattingFunction { StringCchPrintf() { this instanceof TopLevelFunction and exists(string baseName | From 395656a1cfa0b701ce328d311aea5b8fc987c4d1 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 28 Aug 2024 16:13:32 +0200 Subject: [PATCH 147/404] Java: Extend the logging test with a test case for parameters. --- java/ql/test/library-tests/logging/Test.java | 317 ++++++++-------- .../test/library-tests/logging/test.expected | 343 +++++++++--------- 2 files changed, 335 insertions(+), 325 deletions(-) diff --git a/java/ql/test/library-tests/logging/Test.java b/java/ql/test/library-tests/logging/Test.java index 4dacd6ccf5c..3e609f41735 100644 --- a/java/ql/test/library-tests/logging/Test.java +++ b/java/ql/test/library-tests/logging/Test.java @@ -6,163 +6,172 @@ import org.apache.logging.log4j.message.EntryMessage; import org.apache.logging.log4j.message.Message; import org.slf4j.spi.LoggingEventBuilder; -// Test case generated by GenerateFlowTestCase.ql +// Test case originally generated by GenerateFlowTestCase.ql +// Subsequently modified manually. public class Test { - Object source() { - return null; - } + Object source() { + return null; + } - void sink(Object o) {} + void sink(Object o) {} - public void test() throws Exception { - - { - // "java.util.logging;LogRecord;false;LogRecord;;;Argument[1];Argument[this];taint;manual" - LogRecord out = null; - String in = (String) source(); - out = new LogRecord(null, in); - sink(out); // $ hasTaintFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];ReturnValue;taint;manual" - EntryMessage out = null; - Message in = (Message) source(); - Logger instance = null; - out = instance.traceEntry(in); - sink(out); // $ hasTaintFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];ReturnValue;taint;manual" - EntryMessage out = null; - Object[] in = (Object[]) source(); - Logger instance = null; - out = instance.traceEntry((String) null, in); - sink(out); // $ hasTaintFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];ReturnValue;taint;manual" - EntryMessage out = null; - String in = (String) source(); - Logger instance = null; - out = instance.traceEntry(in, (Object[]) null); - sink(out); // $ hasTaintFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];ReturnValue;taint;manual" - EntryMessage out = null; - String in = (String) source(); - Logger instance = null; - out = instance.traceEntry(in, (org.apache.logging.log4j.util.Supplier[]) null); - sink(out); // $ hasTaintFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];ReturnValue;taint;manual" - EntryMessage out = null; - org.apache.logging.log4j.util.Supplier[] in = - (org.apache.logging.log4j.util.Supplier[]) source(); - Logger instance = null; - out = instance.traceEntry((String) null, in); - sink(out); // $ hasTaintFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceEntry;(Supplier[]);;Argument[0];ReturnValue;taint;manual" - EntryMessage out = null; - org.apache.logging.log4j.util.Supplier[] in = - (org.apache.logging.log4j.util.Supplier[]) source(); - Logger instance = null; - out = instance.traceEntry(in); - sink(out); // $ hasTaintFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[1];ReturnValue;value;manual" - Object out = null; - Object in = (Object) source(); - Logger instance = null; - out = instance.traceExit((EntryMessage) null, in); - sink(out); // $ hasValueFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[1];ReturnValue;value;manual" - Object out = null; - Object in = (Object) source(); - Logger instance = null; - out = instance.traceExit((Message) null, in); - sink(out); // $ hasValueFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];ReturnValue;value;manual" - Object out = null; - Object in = (Object) source(); - Logger instance = null; - out = instance.traceExit(in); - sink(out); // $ hasValueFlow - } - { - // "org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[1];ReturnValue;value;manual" - Object out = null; - Object in = (Object) source(); - Logger instance = null; - out = instance.traceExit((String) null, in); - sink(out); // $ hasValueFlow - } - { - // "org.slf4j.spi;LoggingEventBuilder;true;addArgument;;;Argument[this];ReturnValue;value;manual" - LoggingEventBuilder out = null; - LoggingEventBuilder in = (LoggingEventBuilder) source(); - out = in.addArgument((Object) null); - sink(out); // $ hasValueFlow - } - { - // "org.slf4j.spi;LoggingEventBuilder;true;addArgument;;;Argument[this];ReturnValue;value;manual" - LoggingEventBuilder out = null; - LoggingEventBuilder in = (LoggingEventBuilder) source(); - out = in.addArgument((java.util.function.Supplier) null); - sink(out); // $ hasValueFlow - } - { - // "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[this];ReturnValue;value;manual" - LoggingEventBuilder out = null; - LoggingEventBuilder in = (LoggingEventBuilder) source(); - out = in.addKeyValue((String) null, (Object) null); - sink(out); // $ hasValueFlow - } - { - // "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[this];ReturnValue;value;manual" - LoggingEventBuilder out = null; - LoggingEventBuilder in = (LoggingEventBuilder) source(); - out = in.addKeyValue((String) null, (java.util.function.Supplier) null); - sink(out); // $ hasValueFlow - } - { - // "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[1];Argument[this];taint;manual" - LoggingEventBuilder out = null; - Object in = (Object) source(); - out.addKeyValue((String) null, in); - sink(out); // $ hasTaintFlow - } - { - // "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[1];Argument[this];taint;manual" - LoggingEventBuilder out = null; - java.util.function.Supplier in = (java.util.function.Supplier) source(); - out.addKeyValue((String) null, in); - sink(out); // $ hasTaintFlow - } - { - // "org.slf4j.spi;LoggingEventBuilder;true;addMarker;;;Argument[this];ReturnValue;value;manual" - LoggingEventBuilder out = null; - LoggingEventBuilder in = (LoggingEventBuilder) source(); - out = in.addMarker(null); - sink(out); // $ hasValueFlow - } - { - // "org.slf4j.spi;LoggingEventBuilder;true;setCause;;;Argument[this];ReturnValue;value;manual" - LoggingEventBuilder out = null; - LoggingEventBuilder in = (LoggingEventBuilder) source(); - out = in.setCause(null); - sink(out); // $ hasValueFlow - } - - } + public void test() throws Exception { + { + // "java.util.logging;LogRecord;false;LogRecord;;;Argument[1];Argument[this];taint;manual" + LogRecord out = null; + String in = (String) source(); + out = new LogRecord(null, in); + sink(out); // $ hasTaintFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceEntry;(Message);;Argument[0];ReturnValue;taint;manual" + EntryMessage out = null; + Message in = (Message) source(); + Logger instance = null; + out = instance.traceEntry(in); + sink(out); // $ hasTaintFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];ReturnValue;taint;manual" + EntryMessage out = null; + Object[] in = (Object[]) source(); + Logger instance = null; + out = instance.traceEntry((String) null, in); + sink(out); // $ hasTaintFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceEntry;(String,Object[]);;Argument[0..1];ReturnValue;taint;manual" + EntryMessage out = null; + String in = (String) source(); + Logger instance = null; + out = instance.traceEntry(in, (Object[]) null); + sink(out); // $ hasTaintFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];ReturnValue;taint;manual" + EntryMessage out = null; + String in = (String) source(); + Logger instance = null; + out = instance.traceEntry(in, (org.apache.logging.log4j.util.Supplier[]) null); + sink(out); // $ hasTaintFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceEntry;(String,Supplier[]);;Argument[0..1];ReturnValue;taint;manual" + EntryMessage out = null; + org.apache.logging.log4j.util.Supplier[] in = + (org.apache.logging.log4j.util.Supplier[]) source(); + Logger instance = null; + out = instance.traceEntry((String) null, in); + sink(out); // $ hasTaintFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceEntry;(Supplier[]);;Argument[0];ReturnValue;taint;manual" + EntryMessage out = null; + org.apache.logging.log4j.util.Supplier[] in = + (org.apache.logging.log4j.util.Supplier[]) source(); + Logger instance = null; + out = instance.traceEntry(in); + sink(out); // $ hasTaintFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceExit;(EntryMessage,Object);;Argument[1];ReturnValue;value;manual" + Object out = null; + Object in = (Object) source(); + Logger instance = null; + out = instance.traceExit((EntryMessage) null, in); + sink(out); // $ hasValueFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceExit;(Message,Object);;Argument[1];ReturnValue;value;manual" + Object out = null; + Object in = (Object) source(); + Logger instance = null; + out = instance.traceExit((Message) null, in); + sink(out); // $ hasValueFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceExit;(Object);;Argument[0];ReturnValue;value;manual" + Object out = null; + Object in = (Object) source(); + Logger instance = null; + out = instance.traceExit(in); + sink(out); // $ hasValueFlow + } + { + // "org.apache.logging.log4j;Logger;true;traceExit;(String,Object);;Argument[1];ReturnValue;value;manual" + Object out = null; + Object in = (Object) source(); + Logger instance = null; + out = instance.traceExit((String) null, in); + sink(out); // $ hasValueFlow + } + { + // "org.slf4j.spi;LoggingEventBuilder;true;addArgument;;;Argument[this];ReturnValue;value;manual" + LoggingEventBuilder out = null; + LoggingEventBuilder in = (LoggingEventBuilder) source(); + out = in.addArgument((Object) null); + sink(out); // $ hasValueFlow + } + { + // "org.slf4j.spi;LoggingEventBuilder;true;addArgument;;;Argument[this];ReturnValue;value;manual" + LoggingEventBuilder out = null; + LoggingEventBuilder in = (LoggingEventBuilder) source(); + out = in.addArgument((java.util.function.Supplier) null); + sink(out); // $ hasValueFlow + } + { + // "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[this];ReturnValue;value;manual" + LoggingEventBuilder out = null; + LoggingEventBuilder in = (LoggingEventBuilder) source(); + out = in.addKeyValue((String) null, (Object) null); + sink(out); // $ hasValueFlow + } + { + // "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[this];ReturnValue;value;manual" + LoggingEventBuilder out = null; + LoggingEventBuilder in = (LoggingEventBuilder) source(); + out = in.addKeyValue((String) null, (java.util.function.Supplier) null); + sink(out); // $ hasValueFlow + } + { + // "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[1];Argument[this];taint;manual" + LoggingEventBuilder out = null; + Object in = (Object) source(); + out.addKeyValue((String) null, in); + sink(out); // $ hasTaintFlow + } + { + // "org.slf4j.spi;LoggingEventBuilder;true;addKeyValue;;;Argument[1];Argument[this];taint;manual" + LoggingEventBuilder out = null; + java.util.function.Supplier in = (java.util.function.Supplier) source(); + out.addKeyValue((String) null, in); + sink(out); // $ hasTaintFlow + } + { + // "org.slf4j.spi;LoggingEventBuilder;true;addMarker;;;Argument[this];ReturnValue;value;manual" + LoggingEventBuilder out = null; + LoggingEventBuilder in = (LoggingEventBuilder) source(); + out = in.addMarker(null); + sink(out); // $ hasValueFlow + } + { + // "org.slf4j.spi;LoggingEventBuilder;true;setCause;;;Argument[this];ReturnValue;value;manual" + LoggingEventBuilder out = null; + LoggingEventBuilder in = (LoggingEventBuilder) source(); + out = in.setCause(null); + sink(out); // $ hasValueFlow + } + { + // "java.util.logging;LogRecord;true;getParameters;();;Argument[this].SyntheticField[java.util.logging.LogRecord.parameters].ArrayElement;ReturnValue.ArrayElement;value;manual + // "java.util.logging;LogRecord;true;setParameters;(Object[]);Argument[0].ArrayElement;Argument[this].SyntheticField[java.util.logging.LogRecord.parameters].ArrayElement;value;manual + LogRecord record = new LogRecord(null, null); + Object[] parameters = new Object[1]; + parameters[0] = source(); + record.setParameters(parameters); + Object[] out = record.getParameters(); + sink(out[0]); // $ hasValueFlow + } + } } diff --git a/java/ql/test/library-tests/logging/test.expected b/java/ql/test/library-tests/logging/test.expected index 4b8be156480..e66dd40c96c 100644 --- a/java/ql/test/library-tests/logging/test.expected +++ b/java/ql/test/library-tests/logging/test.expected @@ -14,177 +14,178 @@ models | 13 | Summary: org.slf4j.spi; LoggingEventBuilder; true; addMarker; ; ; Argument[this]; ReturnValue; value; manual | | 14 | Summary: org.slf4j.spi; LoggingEventBuilder; true; setCause; ; ; Argument[this]; ReturnValue; value; manual | edges -| Test.java:23:16:23:32 | (...)... : String | Test.java:24:30:24:31 | in : String | provenance | | -| Test.java:23:25:23:32 | source(...) : Object | Test.java:23:16:23:32 | (...)... : String | provenance | | -| Test.java:24:10:24:32 | new LogRecord(...) : LogRecord | Test.java:25:9:25:11 | out | provenance | | -| Test.java:24:30:24:31 | in : String | Test.java:24:10:24:32 | new LogRecord(...) : LogRecord | provenance | MaD:1 | -| Test.java:30:17:30:34 | (...)... : Message | Test.java:32:30:32:31 | in : Message | provenance | | -| Test.java:30:27:30:34 | source(...) : Object | Test.java:30:17:30:34 | (...)... : Message | provenance | | -| Test.java:32:10:32:32 | traceEntry(...) : EntryMessage | Test.java:33:9:33:11 | out | provenance | | -| Test.java:32:30:32:31 | in : Message | Test.java:32:10:32:32 | traceEntry(...) : EntryMessage | provenance | MaD:2 | -| Test.java:38:18:38:36 | (...)... : Object[] | Test.java:40:45:40:46 | in : Object[] | provenance | | -| Test.java:38:29:38:36 | source(...) : Object | Test.java:38:18:38:36 | (...)... : Object[] | provenance | | -| Test.java:40:10:40:47 | traceEntry(...) : EntryMessage | Test.java:41:9:41:11 | out | provenance | | -| Test.java:40:45:40:46 | in : Object[] | Test.java:40:10:40:47 | traceEntry(...) : EntryMessage | provenance | MaD:3 | -| Test.java:46:16:46:32 | (...)... : String | Test.java:48:30:48:31 | in : String | provenance | | -| Test.java:46:25:46:32 | source(...) : Object | Test.java:46:16:46:32 | (...)... : String | provenance | | -| Test.java:48:10:48:49 | traceEntry(...) : EntryMessage | Test.java:49:9:49:11 | out | provenance | | -| Test.java:48:30:48:31 | in : String | Test.java:48:10:48:49 | traceEntry(...) : EntryMessage | provenance | MaD:3 | -| Test.java:54:16:54:32 | (...)... : String | Test.java:56:30:56:31 | in : String | provenance | | -| Test.java:54:25:54:32 | source(...) : Object | Test.java:54:16:54:32 | (...)... : String | provenance | | -| Test.java:56:10:56:81 | traceEntry(...) : EntryMessage | Test.java:57:9:57:11 | out | provenance | | -| Test.java:56:30:56:31 | in : String | Test.java:56:10:56:81 | traceEntry(...) : EntryMessage | provenance | MaD:4 | -| Test.java:63:6:63:56 | (...)... : Supplier[] | Test.java:65:45:65:46 | in : Supplier[] | provenance | | -| Test.java:63:49:63:56 | source(...) : Object | Test.java:63:6:63:56 | (...)... : Supplier[] | provenance | | -| Test.java:65:10:65:47 | traceEntry(...) : EntryMessage | Test.java:66:9:66:11 | out | provenance | | -| Test.java:65:45:65:46 | in : Supplier[] | Test.java:65:10:65:47 | traceEntry(...) : EntryMessage | provenance | MaD:4 | -| Test.java:72:6:72:56 | (...)... : Supplier[] | Test.java:74:30:74:31 | in : Supplier[] | provenance | | -| Test.java:72:49:72:56 | source(...) : Object | Test.java:72:6:72:56 | (...)... : Supplier[] | provenance | | -| Test.java:74:10:74:32 | traceEntry(...) : EntryMessage | Test.java:75:9:75:11 | out | provenance | | -| Test.java:74:30:74:31 | in : Supplier[] | Test.java:74:10:74:32 | traceEntry(...) : EntryMessage | provenance | MaD:5 | -| Test.java:80:16:80:32 | (...)... : Object | Test.java:82:50:82:51 | in : Object | provenance | | -| Test.java:80:25:80:32 | source(...) : Object | Test.java:80:16:80:32 | (...)... : Object | provenance | | -| Test.java:82:10:82:52 | traceExit(...) : Object | Test.java:83:9:83:11 | out | provenance | | -| Test.java:82:50:82:51 | in : Object | Test.java:82:10:82:52 | traceExit(...) : Object | provenance | MaD:6 | -| Test.java:88:16:88:32 | (...)... : Object | Test.java:90:45:90:46 | in : Object | provenance | | -| Test.java:88:25:88:32 | source(...) : Object | Test.java:88:16:88:32 | (...)... : Object | provenance | | -| Test.java:90:10:90:47 | traceExit(...) : Object | Test.java:91:9:91:11 | out | provenance | | -| Test.java:90:45:90:46 | in : Object | Test.java:90:10:90:47 | traceExit(...) : Object | provenance | MaD:7 | -| Test.java:96:16:96:32 | (...)... : Object | Test.java:98:29:98:30 | in : Object | provenance | | -| Test.java:96:25:96:32 | source(...) : Object | Test.java:96:16:96:32 | (...)... : Object | provenance | | -| Test.java:98:10:98:31 | traceExit(...) : Object | Test.java:99:9:99:11 | out | provenance | | -| Test.java:98:29:98:30 | in : Object | Test.java:98:10:98:31 | traceExit(...) : Object | provenance | MaD:8 | -| Test.java:104:16:104:32 | (...)... : Object | Test.java:106:44:106:45 | in : Object | provenance | | -| Test.java:104:25:104:32 | source(...) : Object | Test.java:104:16:104:32 | (...)... : Object | provenance | | -| Test.java:106:10:106:46 | traceExit(...) : Object | Test.java:107:9:107:11 | out | provenance | | -| Test.java:106:44:106:45 | in : Object | Test.java:106:10:106:46 | traceExit(...) : Object | provenance | MaD:9 | -| Test.java:112:29:112:58 | (...)... : LoggingEventBuilder | Test.java:113:10:113:11 | in : LoggingEventBuilder | provenance | | -| Test.java:112:51:112:58 | source(...) : Object | Test.java:112:29:112:58 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:113:10:113:11 | in : LoggingEventBuilder | Test.java:113:10:113:38 | addArgument(...) : LoggingEventBuilder | provenance | MaD:10 | -| Test.java:113:10:113:38 | addArgument(...) : LoggingEventBuilder | Test.java:114:9:114:11 | out | provenance | | -| Test.java:119:29:119:58 | (...)... : LoggingEventBuilder | Test.java:120:10:120:11 | in : LoggingEventBuilder | provenance | | -| Test.java:119:51:119:58 | source(...) : Object | Test.java:119:29:119:58 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:120:10:120:11 | in : LoggingEventBuilder | Test.java:120:10:120:59 | addArgument(...) : LoggingEventBuilder | provenance | MaD:10 | -| Test.java:120:10:120:59 | addArgument(...) : LoggingEventBuilder | Test.java:121:9:121:11 | out | provenance | | -| Test.java:126:29:126:58 | (...)... : LoggingEventBuilder | Test.java:127:10:127:11 | in : LoggingEventBuilder | provenance | | -| Test.java:126:51:126:58 | source(...) : Object | Test.java:126:29:126:58 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:127:10:127:11 | in : LoggingEventBuilder | Test.java:127:10:127:53 | addKeyValue(...) : LoggingEventBuilder | provenance | MaD:11 | -| Test.java:127:10:127:53 | addKeyValue(...) : LoggingEventBuilder | Test.java:128:9:128:11 | out | provenance | | -| Test.java:133:29:133:58 | (...)... : LoggingEventBuilder | Test.java:134:10:134:11 | in : LoggingEventBuilder | provenance | | -| Test.java:133:51:133:58 | source(...) : Object | Test.java:133:29:133:58 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:134:10:134:11 | in : LoggingEventBuilder | Test.java:134:10:134:74 | addKeyValue(...) : LoggingEventBuilder | provenance | MaD:11 | -| Test.java:134:10:134:74 | addKeyValue(...) : LoggingEventBuilder | Test.java:135:9:135:11 | out | provenance | | -| Test.java:140:16:140:32 | (...)... : Object | Test.java:141:35:141:36 | in : Object | provenance | | -| Test.java:140:25:140:32 | source(...) : Object | Test.java:140:16:140:32 | (...)... : Object | provenance | | -| Test.java:141:4:141:6 | out [post update] : LoggingEventBuilder | Test.java:142:9:142:11 | out | provenance | | -| Test.java:141:35:141:36 | in : Object | Test.java:141:4:141:6 | out [post update] : LoggingEventBuilder | provenance | MaD:12 | -| Test.java:147:37:147:74 | (...)... : Supplier | Test.java:148:35:148:36 | in : Supplier | provenance | | -| Test.java:147:67:147:74 | source(...) : Object | Test.java:147:37:147:74 | (...)... : Supplier | provenance | | -| Test.java:148:4:148:6 | out [post update] : LoggingEventBuilder | Test.java:149:9:149:11 | out | provenance | | -| Test.java:148:35:148:36 | in : Supplier | Test.java:148:4:148:6 | out [post update] : LoggingEventBuilder | provenance | MaD:12 | -| Test.java:154:29:154:58 | (...)... : LoggingEventBuilder | Test.java:155:10:155:11 | in : LoggingEventBuilder | provenance | | -| Test.java:154:51:154:58 | source(...) : Object | Test.java:154:29:154:58 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:155:10:155:11 | in : LoggingEventBuilder | Test.java:155:10:155:27 | addMarker(...) : LoggingEventBuilder | provenance | MaD:13 | -| Test.java:155:10:155:27 | addMarker(...) : LoggingEventBuilder | Test.java:156:9:156:11 | out | provenance | | -| Test.java:161:29:161:58 | (...)... : LoggingEventBuilder | Test.java:162:10:162:11 | in : LoggingEventBuilder | provenance | | -| Test.java:161:51:161:58 | source(...) : Object | Test.java:161:29:161:58 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:162:10:162:11 | in : LoggingEventBuilder | Test.java:162:10:162:26 | setCause(...) : LoggingEventBuilder | provenance | MaD:14 | -| Test.java:162:10:162:26 | setCause(...) : LoggingEventBuilder | Test.java:163:9:163:11 | out | provenance | | +| Test.java:24:19:24:35 | (...)... : String | Test.java:25:33:25:34 | in : String | provenance | | +| Test.java:24:28:24:35 | source(...) : Object | Test.java:24:19:24:35 | (...)... : String | provenance | | +| Test.java:25:13:25:35 | new LogRecord(...) : LogRecord | Test.java:26:12:26:14 | out | provenance | | +| Test.java:25:33:25:34 | in : String | Test.java:25:13:25:35 | new LogRecord(...) : LogRecord | provenance | MaD:1 | +| Test.java:31:20:31:37 | (...)... : Message | Test.java:33:33:33:34 | in : Message | provenance | | +| Test.java:31:30:31:37 | source(...) : Object | Test.java:31:20:31:37 | (...)... : Message | provenance | | +| Test.java:33:13:33:35 | traceEntry(...) : EntryMessage | Test.java:34:12:34:14 | out | provenance | | +| Test.java:33:33:33:34 | in : Message | Test.java:33:13:33:35 | traceEntry(...) : EntryMessage | provenance | MaD:2 | +| Test.java:39:21:39:39 | (...)... : Object[] | Test.java:41:48:41:49 | in : Object[] | provenance | | +| Test.java:39:32:39:39 | source(...) : Object | Test.java:39:21:39:39 | (...)... : Object[] | provenance | | +| Test.java:41:13:41:50 | traceEntry(...) : EntryMessage | Test.java:42:12:42:14 | out | provenance | | +| Test.java:41:48:41:49 | in : Object[] | Test.java:41:13:41:50 | traceEntry(...) : EntryMessage | provenance | MaD:3 | +| Test.java:47:19:47:35 | (...)... : String | Test.java:49:33:49:34 | in : String | provenance | | +| Test.java:47:28:47:35 | source(...) : Object | Test.java:47:19:47:35 | (...)... : String | provenance | | +| Test.java:49:13:49:52 | traceEntry(...) : EntryMessage | Test.java:50:12:50:14 | out | provenance | | +| Test.java:49:33:49:34 | in : String | Test.java:49:13:49:52 | traceEntry(...) : EntryMessage | provenance | MaD:3 | +| Test.java:55:19:55:35 | (...)... : String | Test.java:57:33:57:34 | in : String | provenance | | +| Test.java:55:28:55:35 | source(...) : Object | Test.java:55:19:55:35 | (...)... : String | provenance | | +| Test.java:57:13:57:84 | traceEntry(...) : EntryMessage | Test.java:58:12:58:14 | out | provenance | | +| Test.java:57:33:57:34 | in : String | Test.java:57:13:57:84 | traceEntry(...) : EntryMessage | provenance | MaD:4 | +| Test.java:64:11:64:61 | (...)... : Supplier[] | Test.java:66:48:66:49 | in : Supplier[] | provenance | | +| Test.java:64:54:64:61 | source(...) : Object | Test.java:64:11:64:61 | (...)... : Supplier[] | provenance | | +| Test.java:66:13:66:50 | traceEntry(...) : EntryMessage | Test.java:67:12:67:14 | out | provenance | | +| Test.java:66:48:66:49 | in : Supplier[] | Test.java:66:13:66:50 | traceEntry(...) : EntryMessage | provenance | MaD:4 | +| Test.java:73:11:73:61 | (...)... : Supplier[] | Test.java:75:33:75:34 | in : Supplier[] | provenance | | +| Test.java:73:54:73:61 | source(...) : Object | Test.java:73:11:73:61 | (...)... : Supplier[] | provenance | | +| Test.java:75:13:75:35 | traceEntry(...) : EntryMessage | Test.java:76:12:76:14 | out | provenance | | +| Test.java:75:33:75:34 | in : Supplier[] | Test.java:75:13:75:35 | traceEntry(...) : EntryMessage | provenance | MaD:5 | +| Test.java:81:19:81:35 | (...)... : Object | Test.java:83:53:83:54 | in : Object | provenance | | +| Test.java:81:28:81:35 | source(...) : Object | Test.java:81:19:81:35 | (...)... : Object | provenance | | +| Test.java:83:13:83:55 | traceExit(...) : Object | Test.java:84:12:84:14 | out | provenance | | +| Test.java:83:53:83:54 | in : Object | Test.java:83:13:83:55 | traceExit(...) : Object | provenance | MaD:6 | +| Test.java:89:19:89:35 | (...)... : Object | Test.java:91:48:91:49 | in : Object | provenance | | +| Test.java:89:28:89:35 | source(...) : Object | Test.java:89:19:89:35 | (...)... : Object | provenance | | +| Test.java:91:13:91:50 | traceExit(...) : Object | Test.java:92:12:92:14 | out | provenance | | +| Test.java:91:48:91:49 | in : Object | Test.java:91:13:91:50 | traceExit(...) : Object | provenance | MaD:7 | +| Test.java:97:19:97:35 | (...)... : Object | Test.java:99:32:99:33 | in : Object | provenance | | +| Test.java:97:28:97:35 | source(...) : Object | Test.java:97:19:97:35 | (...)... : Object | provenance | | +| Test.java:99:13:99:34 | traceExit(...) : Object | Test.java:100:12:100:14 | out | provenance | | +| Test.java:99:32:99:33 | in : Object | Test.java:99:13:99:34 | traceExit(...) : Object | provenance | MaD:8 | +| Test.java:105:19:105:35 | (...)... : Object | Test.java:107:47:107:48 | in : Object | provenance | | +| Test.java:105:28:105:35 | source(...) : Object | Test.java:105:19:105:35 | (...)... : Object | provenance | | +| Test.java:107:13:107:49 | traceExit(...) : Object | Test.java:108:12:108:14 | out | provenance | | +| Test.java:107:47:107:48 | in : Object | Test.java:107:13:107:49 | traceExit(...) : Object | provenance | MaD:9 | +| Test.java:113:32:113:61 | (...)... : LoggingEventBuilder | Test.java:114:13:114:14 | in : LoggingEventBuilder | provenance | | +| Test.java:113:54:113:61 | source(...) : Object | Test.java:113:32:113:61 | (...)... : LoggingEventBuilder | provenance | | +| Test.java:114:13:114:14 | in : LoggingEventBuilder | Test.java:114:13:114:41 | addArgument(...) : LoggingEventBuilder | provenance | MaD:10 | +| Test.java:114:13:114:41 | addArgument(...) : LoggingEventBuilder | Test.java:115:12:115:14 | out | provenance | | +| Test.java:120:32:120:61 | (...)... : LoggingEventBuilder | Test.java:121:13:121:14 | in : LoggingEventBuilder | provenance | | +| Test.java:120:54:120:61 | source(...) : Object | Test.java:120:32:120:61 | (...)... : LoggingEventBuilder | provenance | | +| Test.java:121:13:121:14 | in : LoggingEventBuilder | Test.java:121:13:121:62 | addArgument(...) : LoggingEventBuilder | provenance | MaD:10 | +| Test.java:121:13:121:62 | addArgument(...) : LoggingEventBuilder | Test.java:122:12:122:14 | out | provenance | | +| Test.java:127:32:127:61 | (...)... : LoggingEventBuilder | Test.java:128:13:128:14 | in : LoggingEventBuilder | provenance | | +| Test.java:127:54:127:61 | source(...) : Object | Test.java:127:32:127:61 | (...)... : LoggingEventBuilder | provenance | | +| Test.java:128:13:128:14 | in : LoggingEventBuilder | Test.java:128:13:128:56 | addKeyValue(...) : LoggingEventBuilder | provenance | MaD:11 | +| Test.java:128:13:128:56 | addKeyValue(...) : LoggingEventBuilder | Test.java:129:12:129:14 | out | provenance | | +| Test.java:134:32:134:61 | (...)... : LoggingEventBuilder | Test.java:135:13:135:14 | in : LoggingEventBuilder | provenance | | +| Test.java:134:54:134:61 | source(...) : Object | Test.java:134:32:134:61 | (...)... : LoggingEventBuilder | provenance | | +| Test.java:135:13:135:14 | in : LoggingEventBuilder | Test.java:135:13:135:77 | addKeyValue(...) : LoggingEventBuilder | provenance | MaD:11 | +| Test.java:135:13:135:77 | addKeyValue(...) : LoggingEventBuilder | Test.java:136:12:136:14 | out | provenance | | +| Test.java:141:19:141:35 | (...)... : Object | Test.java:142:38:142:39 | in : Object | provenance | | +| Test.java:141:28:141:35 | source(...) : Object | Test.java:141:19:141:35 | (...)... : Object | provenance | | +| Test.java:142:7:142:9 | out [post update] : LoggingEventBuilder | Test.java:143:12:143:14 | out | provenance | | +| Test.java:142:38:142:39 | in : Object | Test.java:142:7:142:9 | out [post update] : LoggingEventBuilder | provenance | MaD:12 | +| Test.java:148:40:148:77 | (...)... : Supplier | Test.java:149:38:149:39 | in : Supplier | provenance | | +| Test.java:148:70:148:77 | source(...) : Object | Test.java:148:40:148:77 | (...)... : Supplier | provenance | | +| Test.java:149:7:149:9 | out [post update] : LoggingEventBuilder | Test.java:150:12:150:14 | out | provenance | | +| Test.java:149:38:149:39 | in : Supplier | Test.java:149:7:149:9 | out [post update] : LoggingEventBuilder | provenance | MaD:12 | +| Test.java:155:32:155:61 | (...)... : LoggingEventBuilder | Test.java:156:13:156:14 | in : LoggingEventBuilder | provenance | | +| Test.java:155:54:155:61 | source(...) : Object | Test.java:155:32:155:61 | (...)... : LoggingEventBuilder | provenance | | +| Test.java:156:13:156:14 | in : LoggingEventBuilder | Test.java:156:13:156:30 | addMarker(...) : LoggingEventBuilder | provenance | MaD:13 | +| Test.java:156:13:156:30 | addMarker(...) : LoggingEventBuilder | Test.java:157:12:157:14 | out | provenance | | +| Test.java:162:32:162:61 | (...)... : LoggingEventBuilder | Test.java:163:13:163:14 | in : LoggingEventBuilder | provenance | | +| Test.java:162:54:162:61 | source(...) : Object | Test.java:162:32:162:61 | (...)... : LoggingEventBuilder | provenance | | +| Test.java:163:13:163:14 | in : LoggingEventBuilder | Test.java:163:13:163:29 | setCause(...) : LoggingEventBuilder | provenance | MaD:14 | +| Test.java:163:13:163:29 | setCause(...) : LoggingEventBuilder | Test.java:164:12:164:14 | out | provenance | | nodes -| Test.java:23:16:23:32 | (...)... : String | semmle.label | (...)... : String | -| Test.java:23:25:23:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:24:10:24:32 | new LogRecord(...) : LogRecord | semmle.label | new LogRecord(...) : LogRecord | -| Test.java:24:30:24:31 | in : String | semmle.label | in : String | -| Test.java:25:9:25:11 | out | semmle.label | out | -| Test.java:30:17:30:34 | (...)... : Message | semmle.label | (...)... : Message | -| Test.java:30:27:30:34 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:32:10:32:32 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | -| Test.java:32:30:32:31 | in : Message | semmle.label | in : Message | -| Test.java:33:9:33:11 | out | semmle.label | out | -| Test.java:38:18:38:36 | (...)... : Object[] | semmle.label | (...)... : Object[] | -| Test.java:38:29:38:36 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:40:10:40:47 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | -| Test.java:40:45:40:46 | in : Object[] | semmle.label | in : Object[] | -| Test.java:41:9:41:11 | out | semmle.label | out | -| Test.java:46:16:46:32 | (...)... : String | semmle.label | (...)... : String | -| Test.java:46:25:46:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:48:10:48:49 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | -| Test.java:48:30:48:31 | in : String | semmle.label | in : String | -| Test.java:49:9:49:11 | out | semmle.label | out | -| Test.java:54:16:54:32 | (...)... : String | semmle.label | (...)... : String | -| Test.java:54:25:54:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:56:10:56:81 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | -| Test.java:56:30:56:31 | in : String | semmle.label | in : String | -| Test.java:57:9:57:11 | out | semmle.label | out | -| Test.java:63:6:63:56 | (...)... : Supplier[] | semmle.label | (...)... : Supplier[] | -| Test.java:63:49:63:56 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:65:10:65:47 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | -| Test.java:65:45:65:46 | in : Supplier[] | semmle.label | in : Supplier[] | -| Test.java:66:9:66:11 | out | semmle.label | out | -| Test.java:72:6:72:56 | (...)... : Supplier[] | semmle.label | (...)... : Supplier[] | -| Test.java:72:49:72:56 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:74:10:74:32 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | -| Test.java:74:30:74:31 | in : Supplier[] | semmle.label | in : Supplier[] | -| Test.java:75:9:75:11 | out | semmle.label | out | -| Test.java:80:16:80:32 | (...)... : Object | semmle.label | (...)... : Object | -| Test.java:80:25:80:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:82:10:82:52 | traceExit(...) : Object | semmle.label | traceExit(...) : Object | -| Test.java:82:50:82:51 | in : Object | semmle.label | in : Object | -| Test.java:83:9:83:11 | out | semmle.label | out | -| Test.java:88:16:88:32 | (...)... : Object | semmle.label | (...)... : Object | -| Test.java:88:25:88:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:90:10:90:47 | traceExit(...) : Object | semmle.label | traceExit(...) : Object | -| Test.java:90:45:90:46 | in : Object | semmle.label | in : Object | -| Test.java:91:9:91:11 | out | semmle.label | out | -| Test.java:96:16:96:32 | (...)... : Object | semmle.label | (...)... : Object | -| Test.java:96:25:96:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:98:10:98:31 | traceExit(...) : Object | semmle.label | traceExit(...) : Object | -| Test.java:98:29:98:30 | in : Object | semmle.label | in : Object | -| Test.java:99:9:99:11 | out | semmle.label | out | -| Test.java:104:16:104:32 | (...)... : Object | semmle.label | (...)... : Object | -| Test.java:104:25:104:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:106:10:106:46 | traceExit(...) : Object | semmle.label | traceExit(...) : Object | -| Test.java:106:44:106:45 | in : Object | semmle.label | in : Object | -| Test.java:107:9:107:11 | out | semmle.label | out | -| Test.java:112:29:112:58 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | -| Test.java:112:51:112:58 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:113:10:113:11 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | -| Test.java:113:10:113:38 | addArgument(...) : LoggingEventBuilder | semmle.label | addArgument(...) : LoggingEventBuilder | -| Test.java:114:9:114:11 | out | semmle.label | out | -| Test.java:119:29:119:58 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | -| Test.java:119:51:119:58 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:120:10:120:11 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | -| Test.java:120:10:120:59 | addArgument(...) : LoggingEventBuilder | semmle.label | addArgument(...) : LoggingEventBuilder | -| Test.java:121:9:121:11 | out | semmle.label | out | -| Test.java:126:29:126:58 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | -| Test.java:126:51:126:58 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:127:10:127:11 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | -| Test.java:127:10:127:53 | addKeyValue(...) : LoggingEventBuilder | semmle.label | addKeyValue(...) : LoggingEventBuilder | -| Test.java:128:9:128:11 | out | semmle.label | out | -| Test.java:133:29:133:58 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | -| Test.java:133:51:133:58 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:134:10:134:11 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | -| Test.java:134:10:134:74 | addKeyValue(...) : LoggingEventBuilder | semmle.label | addKeyValue(...) : LoggingEventBuilder | -| Test.java:135:9:135:11 | out | semmle.label | out | -| Test.java:140:16:140:32 | (...)... : Object | semmle.label | (...)... : Object | -| Test.java:140:25:140:32 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:141:4:141:6 | out [post update] : LoggingEventBuilder | semmle.label | out [post update] : LoggingEventBuilder | -| Test.java:141:35:141:36 | in : Object | semmle.label | in : Object | -| Test.java:142:9:142:11 | out | semmle.label | out | -| Test.java:147:37:147:74 | (...)... : Supplier | semmle.label | (...)... : Supplier | -| Test.java:147:67:147:74 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:148:4:148:6 | out [post update] : LoggingEventBuilder | semmle.label | out [post update] : LoggingEventBuilder | -| Test.java:148:35:148:36 | in : Supplier | semmle.label | in : Supplier | -| Test.java:149:9:149:11 | out | semmle.label | out | -| Test.java:154:29:154:58 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | -| Test.java:154:51:154:58 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:155:10:155:11 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | -| Test.java:155:10:155:27 | addMarker(...) : LoggingEventBuilder | semmle.label | addMarker(...) : LoggingEventBuilder | -| Test.java:156:9:156:11 | out | semmle.label | out | -| Test.java:161:29:161:58 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | -| Test.java:161:51:161:58 | source(...) : Object | semmle.label | source(...) : Object | -| Test.java:162:10:162:11 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | -| Test.java:162:10:162:26 | setCause(...) : LoggingEventBuilder | semmle.label | setCause(...) : LoggingEventBuilder | -| Test.java:163:9:163:11 | out | semmle.label | out | +| Test.java:24:19:24:35 | (...)... : String | semmle.label | (...)... : String | +| Test.java:24:28:24:35 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:25:13:25:35 | new LogRecord(...) : LogRecord | semmle.label | new LogRecord(...) : LogRecord | +| Test.java:25:33:25:34 | in : String | semmle.label | in : String | +| Test.java:26:12:26:14 | out | semmle.label | out | +| Test.java:31:20:31:37 | (...)... : Message | semmle.label | (...)... : Message | +| Test.java:31:30:31:37 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:33:13:33:35 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | +| Test.java:33:33:33:34 | in : Message | semmle.label | in : Message | +| Test.java:34:12:34:14 | out | semmle.label | out | +| Test.java:39:21:39:39 | (...)... : Object[] | semmle.label | (...)... : Object[] | +| Test.java:39:32:39:39 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:41:13:41:50 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | +| Test.java:41:48:41:49 | in : Object[] | semmle.label | in : Object[] | +| Test.java:42:12:42:14 | out | semmle.label | out | +| Test.java:47:19:47:35 | (...)... : String | semmle.label | (...)... : String | +| Test.java:47:28:47:35 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:49:13:49:52 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | +| Test.java:49:33:49:34 | in : String | semmle.label | in : String | +| Test.java:50:12:50:14 | out | semmle.label | out | +| Test.java:55:19:55:35 | (...)... : String | semmle.label | (...)... : String | +| Test.java:55:28:55:35 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:57:13:57:84 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | +| Test.java:57:33:57:34 | in : String | semmle.label | in : String | +| Test.java:58:12:58:14 | out | semmle.label | out | +| Test.java:64:11:64:61 | (...)... : Supplier[] | semmle.label | (...)... : Supplier[] | +| Test.java:64:54:64:61 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:66:13:66:50 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | +| Test.java:66:48:66:49 | in : Supplier[] | semmle.label | in : Supplier[] | +| Test.java:67:12:67:14 | out | semmle.label | out | +| Test.java:73:11:73:61 | (...)... : Supplier[] | semmle.label | (...)... : Supplier[] | +| Test.java:73:54:73:61 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:75:13:75:35 | traceEntry(...) : EntryMessage | semmle.label | traceEntry(...) : EntryMessage | +| Test.java:75:33:75:34 | in : Supplier[] | semmle.label | in : Supplier[] | +| Test.java:76:12:76:14 | out | semmle.label | out | +| Test.java:81:19:81:35 | (...)... : Object | semmle.label | (...)... : Object | +| Test.java:81:28:81:35 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:83:13:83:55 | traceExit(...) : Object | semmle.label | traceExit(...) : Object | +| Test.java:83:53:83:54 | in : Object | semmle.label | in : Object | +| Test.java:84:12:84:14 | out | semmle.label | out | +| Test.java:89:19:89:35 | (...)... : Object | semmle.label | (...)... : Object | +| Test.java:89:28:89:35 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:91:13:91:50 | traceExit(...) : Object | semmle.label | traceExit(...) : Object | +| Test.java:91:48:91:49 | in : Object | semmle.label | in : Object | +| Test.java:92:12:92:14 | out | semmle.label | out | +| Test.java:97:19:97:35 | (...)... : Object | semmle.label | (...)... : Object | +| Test.java:97:28:97:35 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:99:13:99:34 | traceExit(...) : Object | semmle.label | traceExit(...) : Object | +| Test.java:99:32:99:33 | in : Object | semmle.label | in : Object | +| Test.java:100:12:100:14 | out | semmle.label | out | +| Test.java:105:19:105:35 | (...)... : Object | semmle.label | (...)... : Object | +| Test.java:105:28:105:35 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:107:13:107:49 | traceExit(...) : Object | semmle.label | traceExit(...) : Object | +| Test.java:107:47:107:48 | in : Object | semmle.label | in : Object | +| Test.java:108:12:108:14 | out | semmle.label | out | +| Test.java:113:32:113:61 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | +| Test.java:113:54:113:61 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:114:13:114:14 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | +| Test.java:114:13:114:41 | addArgument(...) : LoggingEventBuilder | semmle.label | addArgument(...) : LoggingEventBuilder | +| Test.java:115:12:115:14 | out | semmle.label | out | +| Test.java:120:32:120:61 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | +| Test.java:120:54:120:61 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:121:13:121:14 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | +| Test.java:121:13:121:62 | addArgument(...) : LoggingEventBuilder | semmle.label | addArgument(...) : LoggingEventBuilder | +| Test.java:122:12:122:14 | out | semmle.label | out | +| Test.java:127:32:127:61 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | +| Test.java:127:54:127:61 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:128:13:128:14 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | +| Test.java:128:13:128:56 | addKeyValue(...) : LoggingEventBuilder | semmle.label | addKeyValue(...) : LoggingEventBuilder | +| Test.java:129:12:129:14 | out | semmle.label | out | +| Test.java:134:32:134:61 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | +| Test.java:134:54:134:61 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:135:13:135:14 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | +| Test.java:135:13:135:77 | addKeyValue(...) : LoggingEventBuilder | semmle.label | addKeyValue(...) : LoggingEventBuilder | +| Test.java:136:12:136:14 | out | semmle.label | out | +| Test.java:141:19:141:35 | (...)... : Object | semmle.label | (...)... : Object | +| Test.java:141:28:141:35 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:142:7:142:9 | out [post update] : LoggingEventBuilder | semmle.label | out [post update] : LoggingEventBuilder | +| Test.java:142:38:142:39 | in : Object | semmle.label | in : Object | +| Test.java:143:12:143:14 | out | semmle.label | out | +| Test.java:148:40:148:77 | (...)... : Supplier | semmle.label | (...)... : Supplier | +| Test.java:148:70:148:77 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:149:7:149:9 | out [post update] : LoggingEventBuilder | semmle.label | out [post update] : LoggingEventBuilder | +| Test.java:149:38:149:39 | in : Supplier | semmle.label | in : Supplier | +| Test.java:150:12:150:14 | out | semmle.label | out | +| Test.java:155:32:155:61 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | +| Test.java:155:54:155:61 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:156:13:156:14 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | +| Test.java:156:13:156:30 | addMarker(...) : LoggingEventBuilder | semmle.label | addMarker(...) : LoggingEventBuilder | +| Test.java:157:12:157:14 | out | semmle.label | out | +| Test.java:162:32:162:61 | (...)... : LoggingEventBuilder | semmle.label | (...)... : LoggingEventBuilder | +| Test.java:162:54:162:61 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:163:13:163:14 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | +| Test.java:163:13:163:29 | setCause(...) : LoggingEventBuilder | semmle.label | setCause(...) : LoggingEventBuilder | +| Test.java:164:12:164:14 | out | semmle.label | out | subpaths testFailures +| Test.java:174:21:174:37 | // $ hasValueFlow | Missing result:hasValueFlow= | From bd5529cefae9711d00ed9d3d8105f80cdd2a633c Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 28 Aug 2024 16:14:33 +0200 Subject: [PATCH 148/404] Java: Update the Byte- and CharBuffer models and add models for set- and getParameters on LogRecord. --- java/ql/lib/ext/java.nio.model.yml | 24 ++++++++++----------- java/ql/lib/ext/java.util.logging.model.yml | 6 ++---- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/java/ql/lib/ext/java.nio.model.yml b/java/ql/lib/ext/java.nio.model.yml index 1848916b43b..40c12b6c633 100644 --- a/java/ql/lib/ext/java.nio.model.yml +++ b/java/ql/lib/ext/java.nio.model.yml @@ -5,19 +5,19 @@ extensions: data: - ["java.nio", "ByteBuffer", False, "array", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio", "ByteBuffer", False, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.nio", "ByteBuffer", True, "put", "(ByteBuffer)", "", "Argument[this]", "ReturnValue", "value", "df-manual"] - - ["java.nio", "ByteBuffer", True, "put", "(byte)", "", "Argument[this]", "ReturnValue", "value", "df-manual"] - - ["java.nio", "ByteBuffer", True, "put", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "df-manual"] - - ["java.nio", "ByteBuffer", True, "put", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] - - ["java.nio", "ByteBuffer", True, "put", "(byte[])", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] - - ["java.nio", "ByteBuffer", True, "put", "(byte[],int,int)", "", "Argument[0]", "Argument[this]", "taint", "df-manual"] - - ["java.nio", "ByteBuffer", True, "put", "(byte[],int,int)", "", "Argument[this]", "ReturnValue", "value", "df-manual"] + - ["java.nio", "ByteBuffer", True, "put", "(ByteBuffer)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["java.nio", "ByteBuffer", True, "put", "(ByteBuffer)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte[])", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte[],int,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["java.nio", "ByteBuffer", True, "put", "(byte[],int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.nio", "ByteBuffer", True, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["java.nio", "ByteBuffer", True, "wrap", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] - - ["java.nio", "CharBuffer", True, "wrap", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] - - ["java.nio", "CharBuffer", True, "wrap", "(CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] - - ["java.nio", "CharBuffer", True, "wrap", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] - - ["java.nio", "CharBuffer", True, "wrap", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "df-manual"] + - ["java.nio", "ByteBuffer", True, "wrap", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio", "CharBuffer", True, "wrap", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio", "CharBuffer", True, "wrap", "(CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio", "CharBuffer", True, "wrap", "(char[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio", "CharBuffer", True, "wrap", "(char[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - addsTo: diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml index d13803d73bb..f297bc8cda1 100644 --- a/java/ql/lib/ext/java.util.logging.model.yml +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -47,6 +47,8 @@ extensions: - ["java.util.logging", "Logger", False, "getName", "()", "", "Argument[this].SyntheticField[java.util.logging.Logger.name]", "ReturnValue", "value", "manual"] - ["java.util.logging", "LogRecord", False, "LogRecord", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - ["java.util.logging", "LogRecord", True, "getMessage", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"] + - ["java.util.logging", "LogRecord", True, "getParameters", "()", "", "Argument[this].SyntheticField[java.util.logging.LogRecord.parameters].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"] + - ["java.util.logging", "LogRecord", True, "setParameters", "(Object[])", "", "Argument[0].ArrayElement", "Argument[this].SyntheticField[java.util.logging.LogRecord.parameters].ArrayElement", "value", "manual"] - addsTo: pack: codeql/java-all extensible: neutralModel @@ -54,7 +56,3 @@ extensions: - ["java.util.logging", "Handler", "getEncoding", "()", "summary", "manual"] - ["java.util.logging", "Logger", "isLoggable", "(Level)", "summary", "manual"] - ["java.util.logging", "LogRecord", "getResourceBundle", "()", "summary", "df-manual"] - # If needed, a pair of manual summary models using synthetics can be made for the two - # neutrals below. - - ["java.util.logging", "LogRecord", "getParameters", "()", "summary", "manual"] - - ["java.util.logging", "LogRecord", "setParameters", "", "summary", "df-manual"] From fa5d6f12be07f0de8eaf3518c84978f20fa9bee3 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 28 Aug 2024 16:16:16 +0200 Subject: [PATCH 149/404] Java: Update logging test expected output. --- .../test/library-tests/logging/test.expected | 80 +++++++++++-------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/java/ql/test/library-tests/logging/test.expected b/java/ql/test/library-tests/logging/test.expected index e66dd40c96c..6aec73afeaf 100644 --- a/java/ql/test/library-tests/logging/test.expected +++ b/java/ql/test/library-tests/logging/test.expected @@ -1,18 +1,20 @@ models | 1 | Summary: java.util.logging; LogRecord; false; LogRecord; ; ; Argument[1]; Argument[this]; taint; manual | -| 2 | Summary: org.apache.logging.log4j; Logger; true; traceEntry; (Message); ; Argument[0]; ReturnValue; taint; manual | -| 3 | Summary: org.apache.logging.log4j; Logger; true; traceEntry; (String,Object[]); ; Argument[0..1]; ReturnValue; taint; manual | -| 4 | Summary: org.apache.logging.log4j; Logger; true; traceEntry; (String,Supplier[]); ; Argument[0..1]; ReturnValue; taint; manual | -| 5 | Summary: org.apache.logging.log4j; Logger; true; traceEntry; (Supplier[]); ; Argument[0]; ReturnValue; taint; manual | -| 6 | Summary: org.apache.logging.log4j; Logger; true; traceExit; (EntryMessage,Object); ; Argument[1]; ReturnValue; value; manual | -| 7 | Summary: org.apache.logging.log4j; Logger; true; traceExit; (Message,Object); ; Argument[1]; ReturnValue; value; manual | -| 8 | Summary: org.apache.logging.log4j; Logger; true; traceExit; (Object); ; Argument[0]; ReturnValue; value; manual | -| 9 | Summary: org.apache.logging.log4j; Logger; true; traceExit; (String,Object); ; Argument[1]; ReturnValue; value; manual | -| 10 | Summary: org.slf4j.spi; LoggingEventBuilder; true; addArgument; ; ; Argument[this]; ReturnValue; value; manual | -| 11 | Summary: org.slf4j.spi; LoggingEventBuilder; true; addKeyValue; ; ; Argument[this]; ReturnValue; value; manual | -| 12 | Summary: org.slf4j.spi; LoggingEventBuilder; true; addKeyValue; ; ; Argument[1]; Argument[this]; taint; manual | -| 13 | Summary: org.slf4j.spi; LoggingEventBuilder; true; addMarker; ; ; Argument[this]; ReturnValue; value; manual | -| 14 | Summary: org.slf4j.spi; LoggingEventBuilder; true; setCause; ; ; Argument[this]; ReturnValue; value; manual | +| 2 | Summary: java.util.logging; LogRecord; true; getParameters; (); ; Argument[this].SyntheticField[java.util.logging.LogRecord.parameters].ArrayElement; ReturnValue.ArrayElement; value; manual | +| 3 | Summary: java.util.logging; LogRecord; true; setParameters; (Object[]); ; Argument[0].ArrayElement; Argument[this].SyntheticField[java.util.logging.LogRecord.parameters].ArrayElement; value; manual | +| 4 | Summary: org.apache.logging.log4j; Logger; true; traceEntry; (Message); ; Argument[0]; ReturnValue; taint; manual | +| 5 | Summary: org.apache.logging.log4j; Logger; true; traceEntry; (String,Object[]); ; Argument[0..1]; ReturnValue; taint; manual | +| 6 | Summary: org.apache.logging.log4j; Logger; true; traceEntry; (String,Supplier[]); ; Argument[0..1]; ReturnValue; taint; manual | +| 7 | Summary: org.apache.logging.log4j; Logger; true; traceEntry; (Supplier[]); ; Argument[0]; ReturnValue; taint; manual | +| 8 | Summary: org.apache.logging.log4j; Logger; true; traceExit; (EntryMessage,Object); ; Argument[1]; ReturnValue; value; manual | +| 9 | Summary: org.apache.logging.log4j; Logger; true; traceExit; (Message,Object); ; Argument[1]; ReturnValue; value; manual | +| 10 | Summary: org.apache.logging.log4j; Logger; true; traceExit; (Object); ; Argument[0]; ReturnValue; value; manual | +| 11 | Summary: org.apache.logging.log4j; Logger; true; traceExit; (String,Object); ; Argument[1]; ReturnValue; value; manual | +| 12 | Summary: org.slf4j.spi; LoggingEventBuilder; true; addArgument; ; ; Argument[this]; ReturnValue; value; manual | +| 13 | Summary: org.slf4j.spi; LoggingEventBuilder; true; addKeyValue; ; ; Argument[this]; ReturnValue; value; manual | +| 14 | Summary: org.slf4j.spi; LoggingEventBuilder; true; addKeyValue; ; ; Argument[1]; Argument[this]; taint; manual | +| 15 | Summary: org.slf4j.spi; LoggingEventBuilder; true; addMarker; ; ; Argument[this]; ReturnValue; value; manual | +| 16 | Summary: org.slf4j.spi; LoggingEventBuilder; true; setCause; ; ; Argument[this]; ReturnValue; value; manual | edges | Test.java:24:19:24:35 | (...)... : String | Test.java:25:33:25:34 | in : String | provenance | | | Test.java:24:28:24:35 | source(...) : Object | Test.java:24:19:24:35 | (...)... : String | provenance | | @@ -21,75 +23,82 @@ edges | Test.java:31:20:31:37 | (...)... : Message | Test.java:33:33:33:34 | in : Message | provenance | | | Test.java:31:30:31:37 | source(...) : Object | Test.java:31:20:31:37 | (...)... : Message | provenance | | | Test.java:33:13:33:35 | traceEntry(...) : EntryMessage | Test.java:34:12:34:14 | out | provenance | | -| Test.java:33:33:33:34 | in : Message | Test.java:33:13:33:35 | traceEntry(...) : EntryMessage | provenance | MaD:2 | +| Test.java:33:33:33:34 | in : Message | Test.java:33:13:33:35 | traceEntry(...) : EntryMessage | provenance | MaD:4 | | Test.java:39:21:39:39 | (...)... : Object[] | Test.java:41:48:41:49 | in : Object[] | provenance | | | Test.java:39:32:39:39 | source(...) : Object | Test.java:39:21:39:39 | (...)... : Object[] | provenance | | | Test.java:41:13:41:50 | traceEntry(...) : EntryMessage | Test.java:42:12:42:14 | out | provenance | | -| Test.java:41:48:41:49 | in : Object[] | Test.java:41:13:41:50 | traceEntry(...) : EntryMessage | provenance | MaD:3 | +| Test.java:41:48:41:49 | in : Object[] | Test.java:41:13:41:50 | traceEntry(...) : EntryMessage | provenance | MaD:5 | | Test.java:47:19:47:35 | (...)... : String | Test.java:49:33:49:34 | in : String | provenance | | | Test.java:47:28:47:35 | source(...) : Object | Test.java:47:19:47:35 | (...)... : String | provenance | | | Test.java:49:13:49:52 | traceEntry(...) : EntryMessage | Test.java:50:12:50:14 | out | provenance | | -| Test.java:49:33:49:34 | in : String | Test.java:49:13:49:52 | traceEntry(...) : EntryMessage | provenance | MaD:3 | +| Test.java:49:33:49:34 | in : String | Test.java:49:13:49:52 | traceEntry(...) : EntryMessage | provenance | MaD:5 | | Test.java:55:19:55:35 | (...)... : String | Test.java:57:33:57:34 | in : String | provenance | | | Test.java:55:28:55:35 | source(...) : Object | Test.java:55:19:55:35 | (...)... : String | provenance | | | Test.java:57:13:57:84 | traceEntry(...) : EntryMessage | Test.java:58:12:58:14 | out | provenance | | -| Test.java:57:33:57:34 | in : String | Test.java:57:13:57:84 | traceEntry(...) : EntryMessage | provenance | MaD:4 | +| Test.java:57:33:57:34 | in : String | Test.java:57:13:57:84 | traceEntry(...) : EntryMessage | provenance | MaD:6 | | Test.java:64:11:64:61 | (...)... : Supplier[] | Test.java:66:48:66:49 | in : Supplier[] | provenance | | | Test.java:64:54:64:61 | source(...) : Object | Test.java:64:11:64:61 | (...)... : Supplier[] | provenance | | | Test.java:66:13:66:50 | traceEntry(...) : EntryMessage | Test.java:67:12:67:14 | out | provenance | | -| Test.java:66:48:66:49 | in : Supplier[] | Test.java:66:13:66:50 | traceEntry(...) : EntryMessage | provenance | MaD:4 | +| Test.java:66:48:66:49 | in : Supplier[] | Test.java:66:13:66:50 | traceEntry(...) : EntryMessage | provenance | MaD:6 | | Test.java:73:11:73:61 | (...)... : Supplier[] | Test.java:75:33:75:34 | in : Supplier[] | provenance | | | Test.java:73:54:73:61 | source(...) : Object | Test.java:73:11:73:61 | (...)... : Supplier[] | provenance | | | Test.java:75:13:75:35 | traceEntry(...) : EntryMessage | Test.java:76:12:76:14 | out | provenance | | -| Test.java:75:33:75:34 | in : Supplier[] | Test.java:75:13:75:35 | traceEntry(...) : EntryMessage | provenance | MaD:5 | +| Test.java:75:33:75:34 | in : Supplier[] | Test.java:75:13:75:35 | traceEntry(...) : EntryMessage | provenance | MaD:7 | | Test.java:81:19:81:35 | (...)... : Object | Test.java:83:53:83:54 | in : Object | provenance | | | Test.java:81:28:81:35 | source(...) : Object | Test.java:81:19:81:35 | (...)... : Object | provenance | | | Test.java:83:13:83:55 | traceExit(...) : Object | Test.java:84:12:84:14 | out | provenance | | -| Test.java:83:53:83:54 | in : Object | Test.java:83:13:83:55 | traceExit(...) : Object | provenance | MaD:6 | +| Test.java:83:53:83:54 | in : Object | Test.java:83:13:83:55 | traceExit(...) : Object | provenance | MaD:8 | | Test.java:89:19:89:35 | (...)... : Object | Test.java:91:48:91:49 | in : Object | provenance | | | Test.java:89:28:89:35 | source(...) : Object | Test.java:89:19:89:35 | (...)... : Object | provenance | | | Test.java:91:13:91:50 | traceExit(...) : Object | Test.java:92:12:92:14 | out | provenance | | -| Test.java:91:48:91:49 | in : Object | Test.java:91:13:91:50 | traceExit(...) : Object | provenance | MaD:7 | +| Test.java:91:48:91:49 | in : Object | Test.java:91:13:91:50 | traceExit(...) : Object | provenance | MaD:9 | | Test.java:97:19:97:35 | (...)... : Object | Test.java:99:32:99:33 | in : Object | provenance | | | Test.java:97:28:97:35 | source(...) : Object | Test.java:97:19:97:35 | (...)... : Object | provenance | | | Test.java:99:13:99:34 | traceExit(...) : Object | Test.java:100:12:100:14 | out | provenance | | -| Test.java:99:32:99:33 | in : Object | Test.java:99:13:99:34 | traceExit(...) : Object | provenance | MaD:8 | +| Test.java:99:32:99:33 | in : Object | Test.java:99:13:99:34 | traceExit(...) : Object | provenance | MaD:10 | | Test.java:105:19:105:35 | (...)... : Object | Test.java:107:47:107:48 | in : Object | provenance | | | Test.java:105:28:105:35 | source(...) : Object | Test.java:105:19:105:35 | (...)... : Object | provenance | | | Test.java:107:13:107:49 | traceExit(...) : Object | Test.java:108:12:108:14 | out | provenance | | -| Test.java:107:47:107:48 | in : Object | Test.java:107:13:107:49 | traceExit(...) : Object | provenance | MaD:9 | +| Test.java:107:47:107:48 | in : Object | Test.java:107:13:107:49 | traceExit(...) : Object | provenance | MaD:11 | | Test.java:113:32:113:61 | (...)... : LoggingEventBuilder | Test.java:114:13:114:14 | in : LoggingEventBuilder | provenance | | | Test.java:113:54:113:61 | source(...) : Object | Test.java:113:32:113:61 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:114:13:114:14 | in : LoggingEventBuilder | Test.java:114:13:114:41 | addArgument(...) : LoggingEventBuilder | provenance | MaD:10 | +| Test.java:114:13:114:14 | in : LoggingEventBuilder | Test.java:114:13:114:41 | addArgument(...) : LoggingEventBuilder | provenance | MaD:12 | | Test.java:114:13:114:41 | addArgument(...) : LoggingEventBuilder | Test.java:115:12:115:14 | out | provenance | | | Test.java:120:32:120:61 | (...)... : LoggingEventBuilder | Test.java:121:13:121:14 | in : LoggingEventBuilder | provenance | | | Test.java:120:54:120:61 | source(...) : Object | Test.java:120:32:120:61 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:121:13:121:14 | in : LoggingEventBuilder | Test.java:121:13:121:62 | addArgument(...) : LoggingEventBuilder | provenance | MaD:10 | +| Test.java:121:13:121:14 | in : LoggingEventBuilder | Test.java:121:13:121:62 | addArgument(...) : LoggingEventBuilder | provenance | MaD:12 | | Test.java:121:13:121:62 | addArgument(...) : LoggingEventBuilder | Test.java:122:12:122:14 | out | provenance | | | Test.java:127:32:127:61 | (...)... : LoggingEventBuilder | Test.java:128:13:128:14 | in : LoggingEventBuilder | provenance | | | Test.java:127:54:127:61 | source(...) : Object | Test.java:127:32:127:61 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:128:13:128:14 | in : LoggingEventBuilder | Test.java:128:13:128:56 | addKeyValue(...) : LoggingEventBuilder | provenance | MaD:11 | +| Test.java:128:13:128:14 | in : LoggingEventBuilder | Test.java:128:13:128:56 | addKeyValue(...) : LoggingEventBuilder | provenance | MaD:13 | | Test.java:128:13:128:56 | addKeyValue(...) : LoggingEventBuilder | Test.java:129:12:129:14 | out | provenance | | | Test.java:134:32:134:61 | (...)... : LoggingEventBuilder | Test.java:135:13:135:14 | in : LoggingEventBuilder | provenance | | | Test.java:134:54:134:61 | source(...) : Object | Test.java:134:32:134:61 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:135:13:135:14 | in : LoggingEventBuilder | Test.java:135:13:135:77 | addKeyValue(...) : LoggingEventBuilder | provenance | MaD:11 | +| Test.java:135:13:135:14 | in : LoggingEventBuilder | Test.java:135:13:135:77 | addKeyValue(...) : LoggingEventBuilder | provenance | MaD:13 | | Test.java:135:13:135:77 | addKeyValue(...) : LoggingEventBuilder | Test.java:136:12:136:14 | out | provenance | | | Test.java:141:19:141:35 | (...)... : Object | Test.java:142:38:142:39 | in : Object | provenance | | | Test.java:141:28:141:35 | source(...) : Object | Test.java:141:19:141:35 | (...)... : Object | provenance | | | Test.java:142:7:142:9 | out [post update] : LoggingEventBuilder | Test.java:143:12:143:14 | out | provenance | | -| Test.java:142:38:142:39 | in : Object | Test.java:142:7:142:9 | out [post update] : LoggingEventBuilder | provenance | MaD:12 | +| Test.java:142:38:142:39 | in : Object | Test.java:142:7:142:9 | out [post update] : LoggingEventBuilder | provenance | MaD:14 | | Test.java:148:40:148:77 | (...)... : Supplier | Test.java:149:38:149:39 | in : Supplier | provenance | | | Test.java:148:70:148:77 | source(...) : Object | Test.java:148:40:148:77 | (...)... : Supplier | provenance | | | Test.java:149:7:149:9 | out [post update] : LoggingEventBuilder | Test.java:150:12:150:14 | out | provenance | | -| Test.java:149:38:149:39 | in : Supplier | Test.java:149:7:149:9 | out [post update] : LoggingEventBuilder | provenance | MaD:12 | +| Test.java:149:38:149:39 | in : Supplier | Test.java:149:7:149:9 | out [post update] : LoggingEventBuilder | provenance | MaD:14 | | Test.java:155:32:155:61 | (...)... : LoggingEventBuilder | Test.java:156:13:156:14 | in : LoggingEventBuilder | provenance | | | Test.java:155:54:155:61 | source(...) : Object | Test.java:155:32:155:61 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:156:13:156:14 | in : LoggingEventBuilder | Test.java:156:13:156:30 | addMarker(...) : LoggingEventBuilder | provenance | MaD:13 | +| Test.java:156:13:156:14 | in : LoggingEventBuilder | Test.java:156:13:156:30 | addMarker(...) : LoggingEventBuilder | provenance | MaD:15 | | Test.java:156:13:156:30 | addMarker(...) : LoggingEventBuilder | Test.java:157:12:157:14 | out | provenance | | | Test.java:162:32:162:61 | (...)... : LoggingEventBuilder | Test.java:163:13:163:14 | in : LoggingEventBuilder | provenance | | | Test.java:162:54:162:61 | source(...) : Object | Test.java:162:32:162:61 | (...)... : LoggingEventBuilder | provenance | | -| Test.java:163:13:163:14 | in : LoggingEventBuilder | Test.java:163:13:163:29 | setCause(...) : LoggingEventBuilder | provenance | MaD:14 | +| Test.java:163:13:163:14 | in : LoggingEventBuilder | Test.java:163:13:163:29 | setCause(...) : LoggingEventBuilder | provenance | MaD:16 | | Test.java:163:13:163:29 | setCause(...) : LoggingEventBuilder | Test.java:164:12:164:14 | out | provenance | | +| Test.java:171:7:171:16 | parameters [post update] : Object[] [[]] : Object | Test.java:172:28:172:37 | parameters : Object[] [[]] : Object | provenance | | +| Test.java:171:23:171:30 | source(...) : Object | Test.java:171:7:171:16 | parameters [post update] : Object[] [[]] : Object | provenance | | +| Test.java:172:7:172:12 | record [post update] : LogRecord [java.util.logging.LogRecord.parameters, []] : Object | Test.java:173:22:173:27 | record : LogRecord [java.util.logging.LogRecord.parameters, []] : Object | provenance | | +| Test.java:172:28:172:37 | parameters : Object[] [[]] : Object | Test.java:172:7:172:12 | record [post update] : LogRecord [java.util.logging.LogRecord.parameters, []] : Object | provenance | MaD:3 | +| Test.java:173:22:173:27 | record : LogRecord [java.util.logging.LogRecord.parameters, []] : Object | Test.java:173:22:173:43 | getParameters(...) : Object[] [[]] : Object | provenance | MaD:2 | +| Test.java:173:22:173:43 | getParameters(...) : Object[] [[]] : Object | Test.java:174:12:174:14 | out : Object[] [[]] : Object | provenance | | +| Test.java:174:12:174:14 | out : Object[] [[]] : Object | Test.java:174:12:174:17 | ...[...] | provenance | | nodes | Test.java:24:19:24:35 | (...)... : String | semmle.label | (...)... : String | | Test.java:24:28:24:35 | source(...) : Object | semmle.label | source(...) : Object | @@ -186,6 +195,13 @@ nodes | Test.java:163:13:163:14 | in : LoggingEventBuilder | semmle.label | in : LoggingEventBuilder | | Test.java:163:13:163:29 | setCause(...) : LoggingEventBuilder | semmle.label | setCause(...) : LoggingEventBuilder | | Test.java:164:12:164:14 | out | semmle.label | out | +| Test.java:171:7:171:16 | parameters [post update] : Object[] [[]] : Object | semmle.label | parameters [post update] : Object[] [[]] : Object | +| Test.java:171:23:171:30 | source(...) : Object | semmle.label | source(...) : Object | +| Test.java:172:7:172:12 | record [post update] : LogRecord [java.util.logging.LogRecord.parameters, []] : Object | semmle.label | record [post update] : LogRecord [java.util.logging.LogRecord.parameters, []] : Object | +| Test.java:172:28:172:37 | parameters : Object[] [[]] : Object | semmle.label | parameters : Object[] [[]] : Object | +| Test.java:173:22:173:27 | record : LogRecord [java.util.logging.LogRecord.parameters, []] : Object | semmle.label | record : LogRecord [java.util.logging.LogRecord.parameters, []] : Object | +| Test.java:173:22:173:43 | getParameters(...) : Object[] [[]] : Object | semmle.label | getParameters(...) : Object[] [[]] : Object | +| Test.java:174:12:174:14 | out : Object[] [[]] : Object | semmle.label | out : Object[] [[]] : Object | +| Test.java:174:12:174:17 | ...[...] | semmle.label | ...[...] | subpaths testFailures -| Test.java:174:21:174:37 | // $ hasValueFlow | Missing result:hasValueFlow= | From f40901f391dc5d559ff2110da85cd1f9f2f7f214 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 28 Aug 2024 17:15:49 +0200 Subject: [PATCH 150/404] Rust: archiving + skeleton def translator --- misc/codegen/codegen.py | 7 +- misc/codegen/generators/__init__.py | 2 +- misc/codegen/generators/rustgen.py | 102 +++++ misc/codegen/lib/rust.py | 141 ++++++ .../codegen}/schema_documentation.md | 0 misc/codegen/templates/rust_classes.mustache | 54 +++ misc/codegen/templates/rust_module.mustache | 7 + rust/BUILD.bazel | 4 + rust/Cargo.lock | 428 +++++++++++++++++- rust/Cargo.toml | 1 + rust/src/archive.rs | 28 ++ rust/src/generated/mod.rs | 4 + rust/src/main.rs | 64 +-- rust/src/path.rs | 8 + rust/src/translate.rs | 36 ++ rust/src/trap.rs | 103 ++++- 16 files changed, 914 insertions(+), 75 deletions(-) create mode 100644 misc/codegen/generators/rustgen.py create mode 100644 misc/codegen/lib/rust.py rename {swift => misc/codegen}/schema_documentation.md (100%) create mode 100644 misc/codegen/templates/rust_classes.mustache create mode 100644 misc/codegen/templates/rust_module.mustache create mode 100644 rust/BUILD.bazel create mode 100644 rust/src/archive.rs create mode 100644 rust/src/generated/mod.rs create mode 100644 rust/src/path.rs create mode 100644 rust/src/translate.rs diff --git a/misc/codegen/codegen.py b/misc/codegen/codegen.py index 9dd8a348e1c..a199d19dd12 100755 --- a/misc/codegen/codegen.py +++ b/misc/codegen/codegen.py @@ -30,8 +30,8 @@ def _parse_args() -> argparse.Namespace: p = argparse.ArgumentParser(description="Code generation suite") p.add_argument("--generate", type=lambda x: x.split(","), - help="specify what targets to generate as a comma separated list, choosing among dbscheme, ql, trap " - "and cpp") + help="specify what targets to generate as a comma separated list, choosing among dbscheme, ql, " + "trap, cpp and rust") p.add_argument("--verbose", "-v", action="store_true", help="print more information") p.add_argument("--quiet", "-q", action="store_true", help="only print errors") p.add_argument("--configuration-file", "-c", type=_abspath, default=conf, @@ -57,6 +57,9 @@ def _parse_args() -> argparse.Namespace: p.add_argument("--cpp-output", help="output directory for generated C++ files, required if trap or cpp is provided to " "--generate"), + p.add_argument("--rust-output", + help="output directory for generated Rust files, required if rust is provided to " + "--generate"), p.add_argument("--generated-registry", help="registry file containing information about checked-in generated code. A .gitattributes" "file is generated besides it to mark those files with linguist-generated=true. Must" diff --git a/misc/codegen/generators/__init__.py b/misc/codegen/generators/__init__.py index 985c4b25c12..6cda685b8f9 100644 --- a/misc/codegen/generators/__init__.py +++ b/misc/codegen/generators/__init__.py @@ -1,4 +1,4 @@ -from . import dbschemegen, qlgen, trapgen, cppgen +from . import dbschemegen, qlgen, trapgen, cppgen, rustgen def generate(target, opts, renderer): diff --git a/misc/codegen/generators/rustgen.py b/misc/codegen/generators/rustgen.py new file mode 100644 index 00000000000..dc5494aa731 --- /dev/null +++ b/misc/codegen/generators/rustgen.py @@ -0,0 +1,102 @@ +""" +Rust trap class generation +""" + +import functools +import typing + +import inflection + +from misc.codegen.lib import rust, schema +from misc.codegen.loaders import schemaloader + + +def _get_type(t: str) -> str: + match t: + case None | "boolean": # None means a predicate + return "bool" + case "string": + return "String" + case "int": + return "i32" + case _ if t[0].isupper(): + return "TrapLabel" + case _: + return t + + +def _get_field(cls: schema.Class, p: schema.Property) -> rust.Field: + table_name = None + if not p.is_single: + table_name = f"{cls.name}_{p.name}" + if p.is_predicate: + table_name = inflection.underscore(table_name) + else: + table_name = inflection.tableize(table_name) + args = dict( + field_name=p.name + ("_" if p.name in rust.keywords else ""), + base_type=_get_type(p.type), + is_optional=p.is_optional, + is_repeated=p.is_repeated, + is_predicate=p.is_predicate, + is_unordered=p.is_unordered, + table_name=table_name, + ) + args.update(rust.get_field_override(p.name)) + return rust.Field(**args) + + +def _get_properties( + cls: schema.Class, lookup: dict[str, schema.Class] +) -> typing.Iterable[schema.Property]: + for b in cls.bases: + yield from _get_properties(lookup[b], lookup) + yield from cls.properties + + +class Processor: + def __init__(self, data: schema.Schema): + self._classmap = data.classes + + def _get_class(self, name: str) -> rust.Class: + cls = self._classmap[name] + return rust.Class( + name=name, + fields=[ + _get_field(cls, p) + for p in _get_properties(cls, self._classmap) + if "rust_skip" not in p.pragmas and not p.synth + ], + table_name=inflection.tableize(cls.name), + ) + + def get_classes(self): + ret = {"": []} + for k, cls in self._classmap.items(): + if not cls.synth and not cls.derived: + ret.setdefault(cls.group, []).append(self._get_class(cls.name)) + return ret + + +def generate(opts, renderer): + assert opts.rust_output + processor = Processor(schemaloader.load_file(opts.schema)) + out = opts.rust_output + groups = set() + for group, classes in processor.get_classes().items(): + group = group or "top" + groups.add(group) + renderer.render( + rust.ClassList( + classes, + opts.schema, + ), + out / f"{group}.rs", + ) + renderer.render( + rust.ModuleList( + groups, + opts.schema, + ), + out / f"mod.rs", + ) diff --git a/misc/codegen/lib/rust.py b/misc/codegen/lib/rust.py new file mode 100644 index 00000000000..ee1a3712660 --- /dev/null +++ b/misc/codegen/lib/rust.py @@ -0,0 +1,141 @@ +import dataclasses +import re +import typing + +# taken from https://doc.rust-lang.org/reference/keywords.html +keywords = { + "as", + "break", + "const", + "continue", + "crate", + "else", + "enum", + "extern", + "false", + "fn", + "for", + "if", + "impl", + "in", + "let", + "loop", + "match", + "mod", + "move", + "mut", + "pub", + "ref", + "return", + "self", + "Self", + "static", + "struct", + "super", + "trait", + "true", + "type", + "unsafe", + "use", + "where", + "while", + "async", + "await", + "dyn", + "abstract", + "become", + "box", + "do", + "final", + "macro", + "override", + "priv", + "typeof", + "unsized", + "virtual", + "yield", + "try", +} + +_field_overrides = [ + ( + re.compile(r"(start|end)_(line|column)|(.*_)?index|width|num_.*"), + {"base_type": "usize"}, + ), + (re.compile(r"(.*)_"), lambda m: {"field_name": m[1]}), +] + + +def get_field_override(field: str): + for r, o in _field_overrides: + m = r.fullmatch(field) + if m: + return o(m) if callable(o) else o + return {} + + +@dataclasses.dataclass +class Field: + field_name: str + base_type: str + table_name: str = None + is_optional: bool = False + is_repeated: bool = False + is_unordered: bool = False + is_predicate: bool = False + first: bool = False + + def __post_init__(self): + if self.field_name in keywords: + self.field_name += "_" + + @property + def type(self) -> str: + type = self.base_type + if self.is_optional: + type = f"Option<{type}>" + if self.is_repeated: + type = f"Vec<{type}>" + return type + + # using @property breaks pystache internals here + def emitter(self): + if self.type == "String": + return lambda x: f"quoted(&{x})" + else: + return lambda x: x + + @property + def is_single(self): + return not (self.is_optional or self.is_repeated or self.is_predicate) + + @property + def is_label(self): + return self.base_type == "TrapLabel" + + +@dataclasses.dataclass +class Class: + name: str + table_name: str + fields: list[Field] = dataclasses.field(default_factory=list) + + @property + def single_fields(self): + return [f for f in self.fields if f.is_single] + + +@dataclasses.dataclass +class ClassList: + template: typing.ClassVar[str] = "rust_classes" + + classes: list[Class] + source: str + + +@dataclasses.dataclass +class ModuleList: + template: typing.ClassVar[str] = "rust_module" + + modules: list[str] + source: str diff --git a/swift/schema_documentation.md b/misc/codegen/schema_documentation.md similarity index 100% rename from swift/schema_documentation.md rename to misc/codegen/schema_documentation.md diff --git a/misc/codegen/templates/rust_classes.mustache b/misc/codegen/templates/rust_classes.mustache new file mode 100644 index 00000000000..ae3a7258648 --- /dev/null +++ b/misc/codegen/templates/rust_classes.mustache @@ -0,0 +1,54 @@ +// generated by {{generator}} + +use crate::trap::{TrapLabel, TrapEntry, quoted}; +use std::io::Write; + +{{#classes}} +#[derive(Debug)] +pub struct {{name}} { + pub key: Option, + {{#fields}} + pub {{field_name}}: {{type}}, + {{/fields}} +} + +impl TrapEntry for {{name}} { + type Label = TrapLabel; + + fn prefix() -> &'static str { "{{name}}_" } + + fn key(&self) -> Option<&str> { self.key.as_ref().map(String::as_str) } + + fn emit(&self, id: &Self::Label, out: &mut W) -> std::io::Result<()> { + write!(out, "{{table_name}}({id}{{#single_fields}}, {}{{/single_fields}})\n"{{#single_fields}}, {{#emitter}}self.{{field_name}}{{/emitter}}{{/single_fields}})?; + {{#fields}} + {{#is_predicate}} + if self.{{field_name}} { + write!(out, "{{table_name}}({id})\n")?; + } + {{/is_predicate}} + {{#is_optional}} + {{^is_repeated}} + if let Some(ref v) = &self.{{field_name}} { + write!(out, "{{table_name}}({id}, {})\n", {{#emitter}}v{{/emitter}})?; + } + {{/is_repeated}} + {{/is_optional}} + {{#is_repeated}} + for (i, &ref v) in self.{{field_name}}.iter().enumerate() { + {{^is_optional}} + write!(out, "{{table_name}}({id}, {{^is_unordered}}{}, {{/is_unordered}}{})\n", {{^is_unordered}}i, {{/is_unordered}}{{#emitter}}v{{/emitter}})?; + {{/is_optional}} + {{#is_optional}} + if let Some(ref vv) = &v { + write!(out, "{{table_name}}({id}, {{^is_unordered}}{}, {{/is_unordered}}{})\n", {{^is_unordered}}i, {{/is_unordered}}{{#emitter}}vv{{/emitter}})?; + } + {{/is_optional}} + } + {{/is_repeated}} + {{/fields}} + Ok(()) + } +} + +{{/classes}} diff --git a/misc/codegen/templates/rust_module.mustache b/misc/codegen/templates/rust_module.mustache new file mode 100644 index 00000000000..3908e166dfa --- /dev/null +++ b/misc/codegen/templates/rust_module.mustache @@ -0,0 +1,7 @@ +// generated by {{generator}} + +{{#modules}} +mod {{.}}; +pub use {{.}}::*; + +{{/modules}} diff --git a/rust/BUILD.bazel b/rust/BUILD.bazel new file mode 100644 index 00000000000..87aedadba29 --- /dev/null +++ b/rust/BUILD.bazel @@ -0,0 +1,4 @@ +exports_files([ + "codegen.conf", + "schema.py", +]) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 84d942c586f..cc9fc0c7f66 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -295,8 +295,9 @@ dependencies = [ "log", "num-traits", "ra_ap_base_db 0.0.231", - "ra_ap_hir", + "ra_ap_hir 0.0.229", "ra_ap_hir_def 0.0.231", + "ra_ap_ide_db 0.0.232", "ra_ap_load-cargo", "ra_ap_project_model", "serde", @@ -1069,6 +1070,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "ra-ap-rustc_pattern_analysis" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1709080fdeb5db630e1c2644026c2962aaa32416cd92f0190c04b0c21e114b91" +dependencies = [ + "ra-ap-rustc_index 0.63.0", + "rustc-hash", + "rustc_apfloat", + "smallvec", + "tracing", +] + [[package]] name = "ra_ap_base_db" version = "0.0.229" @@ -1111,6 +1125,27 @@ dependencies = [ "triomphe", ] +[[package]] +name = "ra_ap_base_db" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcb25fbab872d3f85798739db011212a98444e55163d71edb1dfdb509e616b3" +dependencies = [ + "la-arena", + "lz4_flex", + "ra_ap_cfg 0.0.232", + "ra_ap_intern 0.0.232", + "ra_ap_salsa 0.0.232", + "ra_ap_span 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_syntax 0.0.232", + "ra_ap_vfs 0.0.232", + "rustc-hash", + "semver", + "tracing", + "triomphe", +] + [[package]] name = "ra_ap_cfg" version = "0.0.229" @@ -1133,6 +1168,17 @@ dependencies = [ "rustc-hash", ] +[[package]] +name = "ra_ap_cfg" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbec14556d01bf34fb795d70941f929ed4c024dee11be9c99c712ea92225a20b" +dependencies = [ + "ra_ap_intern 0.0.232", + "ra_ap_tt 0.0.232", + "rustc-hash", +] + [[package]] name = "ra_ap_hir" version = "0.0.229" @@ -1147,7 +1193,7 @@ dependencies = [ "ra_ap_cfg 0.0.229", "ra_ap_hir_def 0.0.229", "ra_ap_hir_expand 0.0.229", - "ra_ap_hir_ty", + "ra_ap_hir_ty 0.0.229", "ra_ap_intern 0.0.229", "ra_ap_span 0.0.229", "ra_ap_stdx 0.0.229", @@ -1159,6 +1205,31 @@ dependencies = [ "triomphe", ] +[[package]] +name = "ra_ap_hir" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c38520eb4770af561c34b908431f4e548c3282093cf3daf3c6e566d99a2937" +dependencies = [ + "arrayvec", + "either", + "itertools", + "ra_ap_base_db 0.0.232", + "ra_ap_cfg 0.0.232", + "ra_ap_hir_def 0.0.232", + "ra_ap_hir_expand 0.0.232", + "ra_ap_hir_ty 0.0.232", + "ra_ap_intern 0.0.232", + "ra_ap_span 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_syntax 0.0.232", + "ra_ap_tt 0.0.232", + "rustc-hash", + "smallvec", + "tracing", + "triomphe", +] + [[package]] name = "ra_ap_hir_def" version = "0.0.229" @@ -1232,6 +1303,42 @@ dependencies = [ "triomphe", ] +[[package]] +name = "ra_ap_hir_def" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f00b546cacca816b94a12d51df076d50965d6bae411fd68f9024420bfa026e7b" +dependencies = [ + "arrayvec", + "bitflags 2.6.0", + "cov-mark", + "dashmap", + "drop_bomb", + "either", + "fst", + "hashbrown 0.14.5", + "indexmap 2.4.0", + "itertools", + "la-arena", + "ra-ap-rustc_abi 0.63.0", + "ra-ap-rustc_parse_format 0.63.0", + "ra_ap_base_db 0.0.232", + "ra_ap_cfg 0.0.232", + "ra_ap_hir_expand 0.0.232", + "ra_ap_intern 0.0.232", + "ra_ap_limit 0.0.232", + "ra_ap_mbe 0.0.232", + "ra_ap_span 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_syntax 0.0.232", + "ra_ap_tt 0.0.232", + "rustc-hash", + "rustc_apfloat", + "smallvec", + "tracing", + "triomphe", +] + [[package]] name = "ra_ap_hir_expand" version = "0.0.229" @@ -1288,6 +1395,34 @@ dependencies = [ "triomphe", ] +[[package]] +name = "ra_ap_hir_expand" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c9675e1331dadf43cbc807ae39d2c289b8ba2af33a8e197c0927d926a6610d" +dependencies = [ + "cov-mark", + "either", + "hashbrown 0.14.5", + "itertools", + "la-arena", + "ra_ap_base_db 0.0.232", + "ra_ap_cfg 0.0.232", + "ra_ap_intern 0.0.232", + "ra_ap_limit 0.0.232", + "ra_ap_mbe 0.0.232", + "ra_ap_parser 0.0.232", + "ra_ap_span 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_syntax 0.0.232", + "ra_ap_syntax-bridge 0.0.232", + "ra_ap_tt 0.0.232", + "rustc-hash", + "smallvec", + "tracing", + "triomphe", +] + [[package]] name = "ra_ap_hir_ty" version = "0.0.229" @@ -1311,7 +1446,7 @@ dependencies = [ "oorandom", "ra-ap-rustc_abi 0.53.0", "ra-ap-rustc_index 0.53.0", - "ra-ap-rustc_pattern_analysis", + "ra-ap-rustc_pattern_analysis 0.53.0", "ra_ap_base_db 0.0.229", "ra_ap_hir_def 0.0.229", "ra_ap_hir_expand 0.0.229", @@ -1329,6 +1464,46 @@ dependencies = [ "typed-arena", ] +[[package]] +name = "ra_ap_hir_ty" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e308aa1b956137c82547a8b46eb60c6ee295628322e00aa5266a1ea5ea8e522e" +dependencies = [ + "arrayvec", + "bitflags 2.6.0", + "chalk-derive", + "chalk-ir", + "chalk-recursive", + "chalk-solve", + "cov-mark", + "either", + "ena", + "indexmap 2.4.0", + "itertools", + "la-arena", + "nohash-hasher", + "oorandom", + "ra-ap-rustc_abi 0.63.0", + "ra-ap-rustc_index 0.63.0", + "ra-ap-rustc_pattern_analysis 0.63.0", + "ra_ap_base_db 0.0.232", + "ra_ap_hir_def 0.0.232", + "ra_ap_hir_expand 0.0.232", + "ra_ap_intern 0.0.232", + "ra_ap_limit 0.0.232", + "ra_ap_span 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_syntax 0.0.232", + "rustc-hash", + "rustc_apfloat", + "scoped-tls", + "smallvec", + "tracing", + "triomphe", + "typed-arena", +] + [[package]] name = "ra_ap_ide_db" version = "0.0.229" @@ -1348,10 +1523,10 @@ dependencies = [ "nohash-hasher", "once_cell", "ra_ap_base_db 0.0.229", - "ra_ap_hir", + "ra_ap_hir 0.0.229", "ra_ap_limit 0.0.229", "ra_ap_parser 0.0.229", - "ra_ap_profile", + "ra_ap_profile 0.0.229", "ra_ap_span 0.0.229", "ra_ap_stdx 0.0.229", "ra_ap_syntax 0.0.229", @@ -1362,6 +1537,38 @@ dependencies = [ "triomphe", ] +[[package]] +name = "ra_ap_ide_db" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ea9c17702025001c1672ab23bf9be3cf40785376c0f368a10fe812db1327eb" +dependencies = [ + "arrayvec", + "bitflags 2.6.0", + "cov-mark", + "crossbeam-channel", + "either", + "fst", + "indexmap 2.4.0", + "itertools", + "line-index", + "memchr", + "nohash-hasher", + "ra_ap_base_db 0.0.232", + "ra_ap_hir 0.0.232", + "ra_ap_limit 0.0.232", + "ra_ap_parser 0.0.232", + "ra_ap_profile 0.0.232", + "ra_ap_span 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_syntax 0.0.232", + "ra_ap_text_edit 0.0.232", + "rayon", + "rustc-hash", + "tracing", + "triomphe", +] + [[package]] name = "ra_ap_intern" version = "0.0.229" @@ -1388,6 +1595,19 @@ dependencies = [ "triomphe", ] +[[package]] +name = "ra_ap_intern" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78e0928f2c403ebea95f97a38a720900216ea896212347e893a37ae7c1419030" +dependencies = [ + "dashmap", + "hashbrown 0.14.5", + "rustc-hash", + "sptr", + "triomphe", +] + [[package]] name = "ra_ap_limit" version = "0.0.229" @@ -1400,6 +1620,12 @@ version = "0.0.231" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d20a0946a1510ddad977d54f2deab510e27d4e9a7406942152560312a9d14211" +[[package]] +name = "ra_ap_limit" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60972e02e4dfe05b2755e09a6b11b27db8a47cea01cd2697e77a34c4cf60b31c" + [[package]] name = "ra_ap_load-cargo" version = "0.0.229" @@ -1410,7 +1636,7 @@ dependencies = [ "crossbeam-channel", "itertools", "ra_ap_hir_expand 0.0.229", - "ra_ap_ide_db", + "ra_ap_ide_db 0.0.229", "ra_ap_intern 0.0.229", "ra_ap_paths 0.0.229", "ra_ap_proc_macro_api", @@ -1462,6 +1688,26 @@ dependencies = [ "tracing", ] +[[package]] +name = "ra_ap_mbe" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a0997373ff65e7748e7768186598c6831e95f71639f66c3f79ef591c9d496" +dependencies = [ + "arrayvec", + "cov-mark", + "ra_ap_intern 0.0.232", + "ra_ap_parser 0.0.232", + "ra_ap_span 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_syntax 0.0.232", + "ra_ap_syntax-bridge 0.0.232", + "ra_ap_tt 0.0.232", + "rustc-hash", + "smallvec", + "tracing", +] + [[package]] name = "ra_ap_parser" version = "0.0.229" @@ -1486,6 +1732,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "ra_ap_parser" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da0314db93eabbd2b92e13907690782688cfc8aaaf42b8e6726e7f5b338c2e3" +dependencies = [ + "drop_bomb", + "ra-ap-rustc_lexer 0.63.0", + "ra_ap_limit 0.0.232", + "tracing", +] + [[package]] name = "ra_ap_paths" version = "0.0.229" @@ -1505,6 +1763,15 @@ dependencies = [ "camino", ] +[[package]] +name = "ra_ap_paths" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc084003225204a9e5e50957a565f1cc23ebef18cd779f31563a8d2180f8940" +dependencies = [ + "camino", +] + [[package]] name = "ra_ap_proc_macro_api" version = "0.0.229" @@ -1536,6 +1803,18 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ra_ap_profile" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572193d698a8bc4245463688d10f20932ab04940d5b6c32be457bc45dc1e6ab0" +dependencies = [ + "cfg-if", + "libc", + "perf-event", + "windows-sys 0.52.0", +] + [[package]] name = "ra_ap_project_model" version = "0.0.229" @@ -1597,6 +1876,24 @@ dependencies = [ "triomphe", ] +[[package]] +name = "ra_ap_salsa" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370b302873eeafd07ccc6a714fc9395cae11e385955ccb78081093ee3b86f94e" +dependencies = [ + "indexmap 2.4.0", + "itertools", + "lock_api", + "oorandom", + "parking_lot", + "ra_ap_salsa-macros 0.0.232", + "rustc-hash", + "smallvec", + "tracing", + "triomphe", +] + [[package]] name = "ra_ap_salsa-macros" version = "0.0.229" @@ -1621,6 +1918,18 @@ dependencies = [ "syn", ] +[[package]] +name = "ra_ap_salsa-macros" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414ff383af5abdb731917ca46c1a0f6b291278430736fe1ff2430a8548206a62" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "ra_ap_span" version = "0.0.229" @@ -1653,6 +1962,22 @@ dependencies = [ "text-size", ] +[[package]] +name = "ra_ap_span" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b982f799c7a8051219902ff5c1974ee353ac6ca2aa5b17ab0e3db9b8d8a7bf" +dependencies = [ + "hashbrown 0.14.5", + "la-arena", + "ra_ap_salsa 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_syntax 0.0.232", + "ra_ap_vfs 0.0.232", + "rustc-hash", + "text-size", +] + [[package]] name = "ra_ap_stdx" version = "0.0.229" @@ -1683,6 +2008,21 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ra_ap_stdx" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb63ff9d6b11b4553fc0835f16705975258905e3b1230fcf1ddbf24c46aff69d" +dependencies = [ + "always-assert", + "crossbeam-channel", + "itertools", + "jod-thread", + "libc", + "miow", + "windows-sys 0.52.0", +] + [[package]] name = "ra_ap_syntax" version = "0.0.229" @@ -1726,6 +2066,27 @@ dependencies = [ "triomphe", ] +[[package]] +name = "ra_ap_syntax" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1ac12decfd5cadd880177316fc16afc1f2c67f241f6290b51fd6f222e2bd4d5" +dependencies = [ + "cov-mark", + "either", + "indexmap 2.4.0", + "itertools", + "ra-ap-rustc_lexer 0.63.0", + "ra_ap_parser 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_text_edit 0.0.232", + "rowan", + "rustc-hash", + "smol_str", + "tracing", + "triomphe", +] + [[package]] name = "ra_ap_syntax-bridge" version = "0.0.229" @@ -1758,6 +2119,22 @@ dependencies = [ "tracing", ] +[[package]] +name = "ra_ap_syntax-bridge" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d57ec874cf6d45d25ce5d63dbfdf60912d5a33138855c4ab7e4314cfd01f6fa" +dependencies = [ + "ra_ap_intern 0.0.232", + "ra_ap_parser 0.0.232", + "ra_ap_span 0.0.232", + "ra_ap_stdx 0.0.232", + "ra_ap_syntax 0.0.232", + "ra_ap_tt 0.0.232", + "rustc-hash", + "tracing", +] + [[package]] name = "ra_ap_text_edit" version = "0.0.229" @@ -1778,6 +2155,16 @@ dependencies = [ "text-size", ] +[[package]] +name = "ra_ap_text_edit" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb72ee1901baec556f4f2ef77e287d749ac0e973f063990672d6207b076aeac" +dependencies = [ + "itertools", + "text-size", +] + [[package]] name = "ra_ap_toolchain" version = "0.0.229" @@ -1814,6 +2201,19 @@ dependencies = [ "text-size", ] +[[package]] +name = "ra_ap_tt" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9730313c495e88a89ee33f6e34205a92652d9c9a5061ebaed59436058a33000" +dependencies = [ + "arrayvec", + "ra-ap-rustc_lexer 0.63.0", + "ra_ap_intern 0.0.232", + "ra_ap_stdx 0.0.232", + "text-size", +] + [[package]] name = "ra_ap_vfs" version = "0.0.229" @@ -1845,6 +2245,22 @@ dependencies = [ "tracing", ] +[[package]] +name = "ra_ap_vfs" +version = "0.0.232" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d833eaa5422de9bb51ab1841fe505ed00fb51e64cce397e21de6c324bbcbffa0" +dependencies = [ + "crossbeam-channel", + "fst", + "indexmap 2.4.0", + "nohash-hasher", + "ra_ap_paths 0.0.232", + "ra_ap_stdx 0.0.232", + "rustc-hash", + "tracing", +] + [[package]] name = "ra_ap_vfs-notify" version = "0.0.229" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 4f49f7fba09..d05e65ad881 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -12,6 +12,7 @@ num-traits = "0.2.19" ra_ap_base_db = "0.0.231" ra_ap_hir = "0.0.229" ra_ap_hir_def = "0.0.231" +ra_ap_ide_db = "0.0.232" ra_ap_load-cargo = "0.0.229" ra_ap_project_model = "0.0.229" serde = "1.0.209" diff --git a/rust/src/archive.rs b/rust/src/archive.rs new file mode 100644 index 00000000000..9f211d29fab --- /dev/null +++ b/rust/src/archive.rs @@ -0,0 +1,28 @@ +use std::path::{Path, PathBuf}; +use std::fs; +use crate::path; +use anyhow; +use log::{debug, warn}; + +pub struct Archiver { + pub root: PathBuf +} + +impl Archiver { + pub fn archive(&self, source: &Path) { + if let Err(e) = self.try_archive(source) { + warn!("unable to archive {}: {e}", source.display()); + } + } + + fn try_archive(&self, source: &Path) -> std::io::Result<()> { + let mut dest = self.root.clone(); + dest.push(path::key(source)); + let parent = dest.parent().unwrap(); + + fs::create_dir_all(parent)?; + fs::copy(source, dest)?; + debug!("archived {}", source.display()); + Ok(()) + } +} diff --git a/rust/src/generated/mod.rs b/rust/src/generated/mod.rs new file mode 100644 index 00000000000..1d605f8a0b0 --- /dev/null +++ b/rust/src/generated/mod.rs @@ -0,0 +1,4 @@ +// generated by codegen + +mod top; +pub use top::*; diff --git a/rust/src/main.rs b/rust/src/main.rs index b6c8b102032..b504cee2a81 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -1,14 +1,22 @@ +#![feature(path_add_extension)] + +use std::fs; use ra_ap_project_model::CargoConfig; use anyhow::Context; use log; use ra_ap_hir::db::DefDatabase; use ra_ap_hir::{ModuleDefId}; use ra_ap_hir::AdtId::{EnumId, UnionId, StructId}; +use ra_ap_hir::sym::ge; use ra_ap_load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice}; mod config; -mod trap; +pub mod trap; +mod generated; +mod translate; +mod archive; +pub mod path; fn main() -> anyhow::Result<()> { let cfg = config::Config::extract().context("failed to load configuration")?; @@ -17,6 +25,8 @@ fn main() -> anyhow::Result<()> { .verbosity(2 + cfg.verbose as usize) .init()?; log::info!("{cfg:?}"); + let traps = trap::TrapFileProvider::new(&cfg).context("failed to set up trap files")?; + let archiver = archive::Archiver{root: cfg.source_archive_dir}; let config = CargoConfig { ..Default::default() }; let no_progress = |_| (); @@ -25,50 +35,16 @@ fn main() -> anyhow::Result<()> { with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, }; - for manifest in cfg.inputs { - let (db, vfs, _macro_server) = load_workspace_at(&manifest, &config, &load_config, &no_progress)?; - let def_db: &dyn DefDatabase = &db; - let crates = def_db.crate_graph(); - for crate_id in crates.iter().take(1) { - let krate = &crates[crate_id]; - let file = vfs.file_path(krate.root_file_id); - println!("Crate: idx={:x} {}", crate_id.into_raw().into_u32(), file); - let def_map = def_db.crate_def_map(crate_id); - for (module_id, &ref module) in def_map.modules.iter() { - println!(" Module: idx={:x} {:?}", module_id.into_raw().into_u32(), module.origin); - for ref decl_id in module.scope.declarations() { - match decl_id { - ModuleDefId::ModuleId(id) => { - println!(" Module: idx={:x}", id.local_id.into_raw().into_u32()); - } - ModuleDefId::FunctionId(id) => { - let function = def_db.function_data(*id); - println!(" Function: {:?}", function); - } - ModuleDefId::AdtId(StructId(id)) => { - let s = def_db.struct_data(*id); - println!(" Struct: {:?}", s); - } - ModuleDefId::AdtId(EnumId(id)) => { - let e = def_db.enum_data(*id); - println!(" Enum: {:?}", e); - } - ModuleDefId::AdtId(UnionId(id)) => { - let u = def_db.union_data(*id); - println!(" Union: {:?}", u); - } - ModuleDefId::EnumVariantId(_) => {} - ModuleDefId::ConstId(_) => {} - ModuleDefId::StaticId(_) => {} - ModuleDefId::TraitId(_) => {} - ModuleDefId::TraitAliasId(_) => {} - ModuleDefId::TypeAliasId(_) => {} - ModuleDefId::BuiltinType(_) => {} - ModuleDefId::MacroId(_) => {} - } - } - } + for input in cfg.inputs { + let path = fs::canonicalize(input)?; + { + let mut trap = traps.create("input", &path)?; + let name= String::from(path.to_string_lossy()); + trap.emit(generated::DbFile{key: Some(name.clone()), name })?; + archiver.archive(&path); } + load_workspace_at(&path, &config, &load_config, &no_progress)?; + todo!() } Ok(()) } diff --git a/rust/src/path.rs b/rust/src/path.rs new file mode 100644 index 00000000000..f0710d07e36 --- /dev/null +++ b/rust/src/path.rs @@ -0,0 +1,8 @@ +use std::path::{absolute, Path, PathBuf}; +use std::fs::canonicalize; + +pub fn key(p: &Path) -> PathBuf { + let normalized = canonicalize(p).or_else(|_| absolute(p)).unwrap_or_else(|_| p.into()); + let root = normalized.ancestors().last().unwrap(); // ancestors always yields at least one + normalized.strip_prefix(root).unwrap().into() // stripping an ancestor always works +} diff --git a/rust/src/translate.rs b/rust/src/translate.rs new file mode 100644 index 00000000000..b944542116e --- /dev/null +++ b/rust/src/translate.rs @@ -0,0 +1,36 @@ +use crate::trap::TrapFile; +use ra_ap_hir::{ModuleDefId, db::{DefDatabase, ExpandDatabase}, AdtId::{EnumId, UnionId, StructId}}; +use ra_ap_ide_db::RootDatabase; +use anyhow; +use ra_ap_ide_db::base_db::Upcast; + +struct Translator<'a> { + pub db: &'a dyn DefDatabase, + pub trap: TrapFile, +} + +impl Translator<'_> { + pub fn emit_definition(&mut self, id: &ModuleDefId) -> anyhow::Result<()> { + match id { + ModuleDefId::FunctionId(id) => { + let function = self.db.function_data(*id); + let name = format!("{}", function.name.display(self.db.upcast())); + println!("function {name}"); + } + // ModuleDefId::AdtId(StructId(id)) => { + // let s = self.db.struct_data(*id); + // println!(" Struct: {:?}", s); + // } + // ModuleDefId::AdtId(EnumId(id)) => { + // let e = self.db.enum_data(*id); + // println!(" Enum: {:?}", e); + // } + // ModuleDefId::AdtId(UnionId(id)) => { + // let u = self.db.union_data(*id); + // println!(" Union: {:?}", u); + // } + _ => {} + } + Ok(()) + } +} diff --git a/rust/src/trap.rs b/rust/src/trap.rs index bfdfd728884..ffd8097f13f 100644 --- a/rust/src/trap.rs +++ b/rust/src/trap.rs @@ -1,53 +1,112 @@ -use std::fmt::Formatter; +use std::fmt::{Debug, Display, Formatter}; use std::fs::File; use std::io::Write; -use std::path::{PathBuf}; +use std::path::{Path, PathBuf}; +use log::{debug, trace}; +use crate::{config, path}; -#[derive(Debug)] -struct TrapLabel(u64); +#[derive(Debug, Clone, Copy)] +pub struct TrapLabel(u64); -impl std::fmt::Display for TrapLabel { +//TODO: typed labels + +impl From for TrapLabel { + fn from(value: u64) -> Self { + TrapLabel(value) + } +} + +pub fn escaped(s: &str) -> String { + s.replace("\"", "\"\"") +} + +pub fn quoted(s: &str) -> String { + format!("\"{}\"", escaped(s)) +} + +impl Display for TrapLabel { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "#{:x}", self.0) } } -trait TrapEntry: std::fmt::Display {} +pub trait TrapEntry: std::fmt::Debug { + type Label: Display + From; + + fn prefix() -> &'static str { "" } + + fn key(&self) -> Option<&str>; + + fn emit(&self, id: &Self::Label, out: &mut W) -> std::io::Result<()>; +} #[derive(Debug)] -struct TrapFile { +pub struct TrapFile { label_index: u64, file: File, + trap_name: String, } impl TrapFile { - pub fn new(path: &PathBuf) -> std::io::Result { - let file = File::create(path)?; - Ok(TrapFile { - label_index: 0, - file: file, - }) + pub fn comment(&mut self, message: &str) -> std::io::Result<()> { + for part in message.split("\n") { + trace!("emit -> {}: // {part}", self.trap_name); + write!(self.file, "// {part}\n")?; + } + Ok(()) } - pub fn insert_comment(&mut self, comment: &str) -> std::io::Result<()> { - write!(self.file, "/* {comment} */\n") + pub fn emit(&mut self, entry: T) -> std::io::Result { + let ret = match entry.key() { + None => self.create_star_label::()?, + Some(key) => self.create_key_label::(key)?, + }; + trace!("emit -> {}: {entry:?}", self.trap_name); + entry.emit(&ret, &mut self.file)?; + Ok(ret) } - pub fn allocate_label(&mut self) -> std::io::Result { - let ret = TrapLabel(self.label_index); + fn create_star_label(&mut self) -> std::io::Result { + let ret = T::Label::from(self.label_index); write!(self.file, "{ret}=*\n")?; self.label_index += 1; Ok(ret) } - pub fn allocate_label_for(&mut self, key: &str) -> std::io::Result { - let ret = TrapLabel(self.label_index); - write!(self.file, "{ret}=\"{}\"\n", key.replace("\"", "\"\""))?; + fn create_key_label(&mut self, key: &str) -> std::io::Result { + let ret = T::Label::from(self.label_index); + write!(self.file, "{ret}=@\"{}{}\"\n", T::prefix(), escaped(key))?; self.label_index += 1; Ok(ret) } +} - pub fn emit(&mut self, entry: T) -> std::io::Result<()> { - write!(self.file, "{entry}\n") +pub struct TrapFileProvider { + trap_dir: PathBuf, +} + +impl TrapFileProvider { + pub fn new(cfg: &config::Config) -> std::io::Result { + let trap_dir = cfg.trap_dir.clone(); + std::fs::create_dir_all(&trap_dir)?; + Ok(TrapFileProvider { + trap_dir + }) + } + + pub fn create(&self, category: &str, key: &Path) -> std::io::Result { + let mut path = PathBuf::from(category); + path.push(path::key(key)); + path.add_extension("trap"); + let trap_name = String::from(path.to_string_lossy()); + debug!("creating trap file {}", trap_name); + path = self.trap_dir.join(path); + std::fs::create_dir_all(path.parent().unwrap())?; + let file = File::create(path)?; + Ok(TrapFile { + label_index: 0, + file, + trap_name, + }) } } From 49a4f3a82fdac5c4ba4336cacc43b6700cebd55c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 27 Aug 2024 12:05:46 +0200 Subject: [PATCH 151/404] Data flow: Reduce non-linear recursion in `fwdFlow0` --- .../codeql/dataflow/internal/DataFlowImpl.qll | 204 +++++++++--------- 1 file changed, 106 insertions(+), 98 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 48d6ba61e2f..86bdd2d105d 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -1560,20 +1560,17 @@ module MakeImpl Lang> { apa = getApprox(ap) ) or - // flow into a callable - exists(boolean allowsFlowThrough | - fwdFlowIn(node, apa, state, cc, t, ap, allowsFlowThrough) and - if allowsFlowThrough = true - then ( - summaryCtx = TSummaryCtxSome(node, state, t, ap) - ) else ( - summaryCtx = TSummaryCtxNone() and - // When the call contexts of source and sink needs to match then there's - // never any reason to enter a callable except to find a summary. See also - // the comment in `PathNodeMid::isAtSink`. - not Config::getAFeature() instanceof FeatureEqualSourceSinkCallContext - ) - ) + // flow into a callable without summary context + fwdFlowInNoFlowThrough(node, apa, state, cc, t, ap) and + summaryCtx = TSummaryCtxNone() and + // When the call contexts of source and sink needs to match then there's + // never any reason to enter a callable except to find a summary. See also + // the comment in `PathNodeMid::isAtSink`. + not Config::getAFeature() instanceof FeatureEqualSourceSinkCallContext + or + // flow into a callable with summary context (non-linear recursion) + fwdFlowInFlowThrough(node, apa, state, cc, t, ap) and + summaryCtx = TSummaryCtxSome(node, state, t, ap) or // flow out of a callable fwdFlowOut(_, _, node, state, cc, summaryCtx, t, ap, apa) @@ -1593,7 +1590,7 @@ module MakeImpl Lang> { private newtype TSummaryCtx = TSummaryCtxNone() or TSummaryCtxSome(ParamNodeEx p, FlowState state, Typ t, Ap ap) { - fwdFlowIn(p, _, state, _, t, ap, true) + fwdFlowInFlowThrough(p, _, state, _, t, ap) } /** @@ -1721,12 +1718,10 @@ module MakeImpl Lang> { if ap instanceof ApNil then emptyAp = true else emptyAp = false } - private signature module FwdFlowInInputSig { - default predicate callRestriction(DataFlowCall call) { any() } - - bindingset[p, apa] - default predicate parameterRestriction(ParamNodeEx p, ApApprox apa) { any() } - } + bindingset[call, c, p, apa] + private signature predicate callRestrictionSig( + DataFlowCall call, DataFlowCallable c, ParamNodeEx p, ApApprox apa, boolean emptyAp + ); /** * Exposes the inlined predicate `fwdFlowIn`, which is used to calculate both @@ -1736,19 +1731,23 @@ module MakeImpl Lang> { * need to record the argument that flows into the parameter. * * For flow through, we do need to record the argument, however, we can restrict - * this to arguments that may actually flow through, using `callRestriction` and - * `parameterRestriction`, which reduces the argument-to-parameter fan-in - * significantly. + * this to arguments that may actually flow through, using `callRestrictionSig`, + * which reduces the argument-to-parameter fan-in significantly. */ - private module FwdFlowIn { + private module FwdFlowIn { pragma[nomagic] private predicate callEdgeArgParamRestricted( - DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, - boolean allowsFieldFlow, ApApprox apa + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp, + ApApprox apa ) { - PrevStage::callEdgeArgParam(call, c, arg, p, allowsFieldFlow, apa) and - I::callRestriction(call) and - I::parameterRestriction(p, apa) + exists(boolean allowsFieldFlow | + PrevStage::callEdgeArgParam(call, c, arg, p, allowsFieldFlow, apa) and + callRestriction(call, c, p, apa, emptyAp) + | + allowsFieldFlow = true + or + emptyAp = true + ) } pragma[nomagic] @@ -1780,10 +1779,10 @@ module MakeImpl Lang> { bindingset[call] pragma[inline_late] private predicate callEdgeArgParamRestrictedInlineLate( - DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, - boolean allowsFieldFlow, ApApprox apa + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp, + ApApprox apa ) { - callEdgeArgParamRestricted(call, c, arg, p, allowsFieldFlow, apa) + callEdgeArgParamRestricted(call, c, arg, p, emptyAp, apa) } bindingset[call, ctx] @@ -1807,44 +1806,35 @@ module MakeImpl Lang> { private predicate fwdFlowInCand( DataFlowCall call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, boolean emptyAp, ApApprox apa, - boolean cc, boolean allowsFlowThrough + boolean cc ) { - exists(boolean allowsFieldFlow | - fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, apa, cc) and - ( - inner = viableImplCallContextReducedInlineLate(call, arg, outercc) - or - viableImplArgNotCallContextReduced(call, arg, outercc) - ) and - not outBarrier(arg, state) and - not inBarrier(p, state) and - callEdgeArgParamRestrictedInlineLate(call, inner, arg, p, allowsFieldFlow, apa) and - (if allowsFieldFlow = false then emptyAp = true else any()) and - if allowsFieldFlowThrough(call, inner) - then allowsFlowThrough = true - else allowsFlowThrough = emptyAp - ) + fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, apa, cc) and + ( + inner = viableImplCallContextReducedInlineLate(call, arg, outercc) + or + viableImplArgNotCallContextReduced(call, arg, outercc) + ) and + not outBarrier(arg, state) and + not inBarrier(p, state) and + callEdgeArgParamRestrictedInlineLate(call, inner, arg, p, emptyAp, apa) } pragma[inline] private predicate fwdFlowInCandTypeFlowDisabled( DataFlowCall call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, - ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, boolean cc, - boolean allowsFlowThrough + ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, ApApprox apa, boolean cc ) { not enableTypeFlow() and - fwdFlowInCand(call, arg, state, outercc, inner, p, summaryCtx, t, ap, _, apa, cc, - allowsFlowThrough) + fwdFlowInCand(call, arg, state, outercc, inner, p, summaryCtx, t, ap, _, apa, cc) } pragma[nomagic] private predicate fwdFlowInCandTypeFlowEnabled( DataFlowCall call, ArgNodeEx arg, Cc outercc, DataFlowCallable inner, ParamNodeEx p, - boolean emptyAp, ApApprox apa, boolean cc, boolean allowsFlowThrough + boolean emptyAp, ApApprox apa, boolean cc ) { enableTypeFlow() and - fwdFlowInCand(call, arg, _, outercc, inner, p, _, _, _, emptyAp, apa, cc, - allowsFlowThrough) + fwdFlowInCand(call, arg, _, outercc, inner, p, _, _, _, emptyAp, apa, cc) } pragma[nomagic] @@ -1859,10 +1849,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInValidEdgeTypeFlowEnabled( DataFlowCall call, ArgNodeEx arg, Cc outercc, DataFlowCallable inner, ParamNodeEx p, - CcCall innercc, boolean emptyAp, ApApprox apa, boolean cc, boolean allowsFlowThrough + CcCall innercc, boolean emptyAp, ApApprox apa, boolean cc ) { - fwdFlowInCandTypeFlowEnabled(call, arg, outercc, inner, p, emptyAp, apa, cc, - allowsFlowThrough) and + fwdFlowInCandTypeFlowEnabled(call, arg, outercc, inner, p, emptyAp, apa, cc) and FwdTypeFlow::typeFlowValidEdgeIn(call, inner, cc) and innercc = getCallContextCall(call, inner) } @@ -1871,38 +1860,68 @@ module MakeImpl Lang> { predicate fwdFlowIn( DataFlowCall call, ArgNodeEx arg, DataFlowCallable inner, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, SummaryCtx summaryCtx, Typ t, Ap ap, - ApApprox apa, boolean cc, boolean allowsFlowThrough + ApApprox apa, boolean cc ) { // type flow disabled: linear recursion fwdFlowInCandTypeFlowDisabled(call, arg, state, outercc, inner, p, summaryCtx, t, ap, - apa, cc, allowsFlowThrough) and + apa, cc) and fwdFlowInValidEdgeTypeFlowDisabled(call, inner, innercc, pragma[only_bind_into](cc)) or // type flow enabled: non-linear recursion exists(boolean emptyAp | fwdFlowIntoArg(arg, state, outercc, summaryCtx, t, ap, emptyAp, apa, cc) and fwdFlowInValidEdgeTypeFlowEnabled(call, arg, outercc, inner, p, innercc, emptyAp, apa, - cc, allowsFlowThrough) + cc) ) } } - private module FwdFlowInNoRestriction implements FwdFlowInInputSig { } + bindingset[call, c, p, apa] + private predicate callRestrictionNoFlowThrough( + DataFlowCall call, DataFlowCallable c, ParamNodeEx p, ApApprox apa, boolean emptyAp + ) { + ( + if + PrevStage::callMayFlowThroughRev(call) and + PrevStage::parameterMayFlowThrough(p, apa) + then not allowsFieldFlowThrough(call, c) and emptyAp = false + else emptyAp = [false, true] + ) and + exists(c) + } + + private module FwdFlowInNoThrough = FwdFlowIn; pragma[nomagic] - private predicate fwdFlowIn( - ParamNodeEx p, ApApprox apa, FlowState state, CcCall innercc, Typ t, Ap ap, - boolean allowsFlowThrough + private predicate fwdFlowInNoFlowThrough( + ParamNodeEx p, ApApprox apa, FlowState state, CcCall innercc, Typ t, Ap ap ) { - exists(boolean allowsFlowThrough0 | - FwdFlowIn::fwdFlowIn(_, _, _, p, state, _, innercc, _, t, ap, - apa, _, allowsFlowThrough0) and - if PrevStage::parameterMayFlowThrough(p, apa) - then allowsFlowThrough = allowsFlowThrough0 - else allowsFlowThrough = false + FwdFlowInNoThrough::fwdFlowIn(_, _, _, p, state, _, innercc, _, t, ap, apa, _) + } + + bindingset[call, c, p, apa] + private predicate callRestrictionFlowThrough( + DataFlowCall call, DataFlowCallable c, ParamNodeEx p, ApApprox apa, boolean emptyAp + ) { + PrevStage::callMayFlowThroughRev(call) and + PrevStage::parameterMayFlowThrough(p, apa) and + ( + emptyAp = true + or + allowsFieldFlowThrough(call, c) and + emptyAp = false ) } + private module FwdFlowInThrough = FwdFlowIn; + + pragma[nomagic] + private predicate fwdFlowInFlowThrough( + ParamNodeEx p, ApApprox apa, FlowState state, CcCall innercc, Typ t, Ap ap + ) { + FwdFlowInThrough::fwdFlowIn(_, _, _, p, state, _, innercc, _, t, ap, apa, _) + } + pragma[nomagic] private DataFlowCall viableImplCallContextReducedReverseRestricted( DataFlowCallable c, CcNoCall ctx @@ -2000,8 +2019,9 @@ module MakeImpl Lang> { DataFlowCall call, DataFlowCallable c, ParamNodeEx p, FlowState state, CcCall innercc, Typ t, Ap ap, boolean cc ) { - FwdFlowIn::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, - _, cc, _) + FwdFlowInNoThrough::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, _, cc) + or + FwdFlowInThrough::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, _, cc) } pragma[nomagic] @@ -2104,19 +2124,12 @@ module MakeImpl Lang> { fwdFlowThrough0(call, _, cc, state, ccc, summaryCtx, t, ap, apa, ret, _, innerArgApa) } - private module FwdFlowThroughRestriction implements FwdFlowInInputSig { - predicate callRestriction = PrevStage::callMayFlowThroughRev/1; - - predicate parameterRestriction = PrevStage::parameterMayFlowThrough/2; - } - pragma[nomagic] private predicate fwdFlowIsEntered0( DataFlowCall call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, ParamNodeEx p, FlowState state, Typ t, Ap ap ) { - FwdFlowIn::fwdFlowIn(call, arg, _, p, state, cc, innerCc, - summaryCtx, t, ap, _, _, true) + FwdFlowInThrough::fwdFlowIn(call, arg, _, p, state, cc, innerCc, summaryCtx, t, ap, _, _) } /** @@ -3067,15 +3080,15 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInStep( ArgNodeEx arg, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, - SummaryCtx summaryCtx, Typ t, Ap ap, boolean allowsFlowThrough + SummaryCtx outerSummaryCtx, SummaryCtx innerSummaryCtx, Typ t, Ap ap ) { - exists(ApApprox apa, boolean allowsFlowThrough0 | - FwdFlowIn::fwdFlowIn(_, arg, _, p, state, outercc, innercc, - summaryCtx, t, ap, apa, _, allowsFlowThrough0) and - if PrevStage::parameterMayFlowThrough(p, apa) - then allowsFlowThrough = allowsFlowThrough0 - else allowsFlowThrough = false - ) + FwdFlowInNoThrough::fwdFlowIn(_, arg, _, p, state, outercc, innercc, outerSummaryCtx, t, + ap, _, _) and + innerSummaryCtx = TSummaryCtxNone() + or + FwdFlowInThrough::fwdFlowIn(_, arg, _, p, state, outercc, innercc, outerSummaryCtx, t, + ap, _, _) and + innerSummaryCtx = TSummaryCtxSome(p, state, t, ap) } pragma[nomagic] @@ -3239,15 +3252,10 @@ module MakeImpl Lang> { ) or // flow into a callable - exists( - ArgNodeEx arg, boolean allowsFlowThrough, Cc outercc, SummaryCtx outerSummaryCtx - | + exists(ArgNodeEx arg, Cc outercc, SummaryCtx outerSummaryCtx | pn1 = TPathNodeMid(arg, state, outercc, outerSummaryCtx, t, ap) and - fwdFlowInStep(arg, node, state, outercc, cc, outerSummaryCtx, t, ap, allowsFlowThrough) and - label = "" and - if allowsFlowThrough = true - then summaryCtx = TSummaryCtxSome(node, state, t, ap) - else summaryCtx = TSummaryCtxNone() + fwdFlowInStep(arg, node, state, outercc, cc, outerSummaryCtx, summaryCtx, t, ap) and + label = "" ) or // flow out of a callable From 53b2471c9d9066023a2b6762a526dbfb1ccdfed5 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 29 Aug 2024 09:03:46 +0200 Subject: [PATCH 152/404] Java: Update expected test output. --- .../library-tests/frameworks/apache-commons-lang3/flow.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected index 5c7448f4222..9031c242a1c 100644 --- a/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected +++ b/java/ql/test/library-tests/frameworks/apache-commons-lang3/flow.expected @@ -8,7 +8,7 @@ models | 7 | Summary: java.lang; String; false; toCharArray; ; ; Argument[this]; ReturnValue; taint; manual | | 8 | Summary: java.lang; StringBuffer; true; StringBuffer; (String); ; Argument[0]; Argument[this]; taint; manual | | 9 | Summary: java.lang; StringBuilder; true; StringBuilder; ; ; Argument[0]; Argument[this]; taint; manual | -| 10 | Summary: java.nio; CharBuffer; true; wrap; (char[]); ; Argument[0]; ReturnValue; taint; df-manual | +| 10 | Summary: java.nio; CharBuffer; true; wrap; (char[]); ; Argument[0]; ReturnValue; taint; manual | | 11 | Summary: java.util; Collection; true; add; ; ; Argument[0]; Argument[this].Element; value; manual | | 12 | Summary: java.util; Dictionary; true; put; (Object,Object); ; Argument[1]; Argument[this].MapValue; value; manual | | 13 | Summary: java.util; Iterator; true; next; ; ; Argument[this].Element; ReturnValue; value; manual | From e7f059ae555a8b9e1fa4131f8dad6a8266a3831c Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 29 Aug 2024 10:32:31 +0200 Subject: [PATCH 153/404] C++: Tweak the `bounded` barrier --- cpp/ql/src/Security/CWE/CWE-190/Bounded.qll | 44 +++---- .../ArithmeticUncontrolled.expected | 6 + .../semmle/ArithmeticUncontrolled/test.cpp | 2 +- .../TaintedAllocationSize.expected | 120 ++++++++++-------- .../semmle/TaintedAllocationSize/test.cpp | 17 ++- 5 files changed, 110 insertions(+), 79 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-190/Bounded.qll b/cpp/ql/src/Security/CWE/CWE-190/Bounded.qll index bb855da3f44..01f4f94d60e 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/Bounded.qll +++ b/cpp/ql/src/Security/CWE/CWE-190/Bounded.qll @@ -1,6 +1,6 @@ /** - * This file provides the `bounded` predicate that is used in both `cpp/uncontrolled-arithmetic` - * and `cpp/tainted-arithmetic`. + * This file provides the `bounded` predicate that is used in `cpp/uncontrolled-arithmetic`, + * `cpp/tainted-arithmetic` and `cpp/uncontrolled-allocation-size`. */ private import cpp @@ -8,20 +8,18 @@ private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils /** - * An operand `e` of a bitwise and expression `andExpr` (i.e., `andExpr` is either an `BitwiseAndExpr` - * or an `AssignAndExpr`) with operands `operand1` and `operand2` is the operand that is not `e` is upper - * bounded by some number that is less than the maximum integer allowed by the result type of `andExpr`. + * An operand `operand` of a bitwise and expression `andExpr` (i.e., `andExpr` is either a + * `BitwiseAndExpr` or an `AssignAndExpr`) is upper bounded by some number that is less than the + * maximum integer allowed by the result type of `andExpr`. */ pragma[inline] -private predicate boundedBitwiseAnd(Expr e, Expr andExpr, Expr operand1, Expr operand2) { - operand1 != operand2 and - e = operand1 and - upperBound(operand2.getFullyConverted()) < exprMaxVal(andExpr.getFullyConverted()) +private predicate boundedBitwiseAnd(Expr operand, Expr andExpr) { + upperBound(operand.getFullyConverted()) < exprMaxVal(andExpr.getFullyConverted()) } /** - * Holds if `e` is an arithmetic expression that cannot overflow, or if `e` is an operand of an - * operation that may greatly reduce the range of possible values. + * Holds if `e` is an arithmetic expression that cannot overflow, or if `e` is an operation that + * may greatly reduce the range of possible values. */ predicate bounded(Expr e) { // There can be two separate reasons for `convertedExprMightOverflow` not holding: @@ -35,25 +33,25 @@ predicate bounded(Expr e) { ) and not convertedExprMightOverflow(e) or - // Optimistically assume that a remainder expression always yields a much smaller value. - e = any(RemExpr rem).getLeftOperand() + // Optimistically assume that the following operations always yields a much smaller value. + e instanceof RemExpr or - e = any(AssignRemExpr rem).getLValue() + e instanceof DivExpr + or + e instanceof RShiftExpr or exists(BitwiseAndExpr andExpr | - boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand()) + e = andExpr and boundedBitwiseAnd(andExpr.getAnOperand(), andExpr) ) or - exists(AssignAndExpr andExpr | - boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand()) - ) - or - // Optimistically assume that a division always yields a much smaller value. - e = any(DivExpr div).getLeftOperand() + // For the assignment variant of the operations we place the barrier on the assigned lvalue. + e = any(AssignRemExpr rem).getLValue() or e = any(AssignDivExpr div).getLValue() or - e = any(RShiftExpr shift).getLeftOperand() - or e = any(AssignRShiftExpr div).getLValue() + or + exists(AssignAndExpr andExpr | + e = andExpr.getLValue() and boundedBitwiseAnd(andExpr.getRValue(), andExpr) + ) } diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected index c21f9c38855..97bd3603cd3 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected @@ -32,6 +32,8 @@ edges | test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r | provenance | | | test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r | provenance | | | test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r | provenance | | +| test.cpp:62:19:62:24 | call to rand | test.cpp:62:19:62:24 | call to rand | provenance | | +| test.cpp:62:19:62:24 | call to rand | test.cpp:65:9:65:9 | x | provenance | | | test.cpp:86:10:86:13 | call to rand | test.cpp:86:10:86:13 | call to rand | provenance | | | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | provenance | | | test.cpp:98:10:98:13 | call to rand | test.cpp:98:10:98:13 | call to rand | provenance | | @@ -105,6 +107,9 @@ nodes | test.cpp:31:7:31:7 | r | semmle.label | r | | test.cpp:36:13:36:13 | get_rand3 output argument | semmle.label | get_rand3 output argument | | test.cpp:37:7:37:7 | r | semmle.label | r | +| test.cpp:62:19:62:24 | call to rand | semmle.label | call to rand | +| test.cpp:62:19:62:24 | call to rand | semmle.label | call to rand | +| test.cpp:65:9:65:9 | x | semmle.label | x | | test.cpp:86:10:86:13 | call to rand | semmle.label | call to rand | | test.cpp:86:10:86:13 | call to rand | semmle.label | call to rand | | test.cpp:90:10:90:10 | x | semmle.label | x | @@ -156,6 +161,7 @@ subpaths | test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | uncontrolled value | | test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | uncontrolled value | | test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | uncontrolled value | +| test.cpp:65:9:65:9 | x | test.cpp:62:19:62:24 | call to rand | test.cpp:65:9:65:9 | x | This arithmetic expression depends on an $@, potentially causing an underflow. | test.cpp:62:19:62:22 | call to rand | uncontrolled value | | test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | uncontrolled value | | test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | uncontrolled value | | test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | uncontrolled value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/test.cpp index 6df97ef5452..f5e401c60cd 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/test.cpp @@ -62,7 +62,7 @@ unsigned int test_remainder_subtract_unsigned() unsigned int x = rand(); unsigned int y = x % 100; // y <= x - return x - y; // GOOD (as y <= x) + return x - y; // GOOD (as y <= x) [FALSE POSITIVE] } typedef unsigned long size_t; diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected index 9e5f61c7c88..4235033abcc 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected @@ -13,26 +13,30 @@ edges | test.cpp:133:19:133:32 | *call to getenv | test.cpp:133:14:133:17 | call to atoi | provenance | TaintFunction | | test.cpp:148:15:148:18 | call to atol | test.cpp:152:11:152:28 | ... * ... | provenance | | | test.cpp:148:20:148:33 | *call to getenv | test.cpp:148:15:148:18 | call to atol | provenance | TaintFunction | -| test.cpp:224:8:224:23 | *get_tainted_size | test.cpp:256:9:256:24 | call to get_tainted_size | provenance | | -| test.cpp:226:9:226:42 | ... * ... | test.cpp:224:8:224:23 | *get_tainted_size | provenance | | -| test.cpp:226:14:226:27 | *call to getenv | test.cpp:226:9:226:42 | ... * ... | provenance | TaintFunction | -| test.cpp:245:21:245:21 | s | test.cpp:246:21:246:21 | s | provenance | | -| test.cpp:252:19:252:52 | ... * ... | test.cpp:254:9:254:18 | local_size | provenance | | -| test.cpp:252:19:252:52 | ... * ... | test.cpp:260:11:260:20 | local_size | provenance | | -| test.cpp:252:19:252:52 | ... * ... | test.cpp:262:10:262:19 | local_size | provenance | | -| test.cpp:252:24:252:37 | *call to getenv | test.cpp:252:19:252:52 | ... * ... | provenance | TaintFunction | -| test.cpp:262:10:262:19 | local_size | test.cpp:245:21:245:21 | s | provenance | | -| test.cpp:265:20:265:27 | *out_size | test.cpp:304:17:304:20 | get_size output argument | provenance | | -| test.cpp:265:20:265:27 | *out_size | test.cpp:320:18:320:21 | get_size output argument | provenance | | -| test.cpp:266:2:266:32 | ... = ... | test.cpp:265:20:265:27 | *out_size | provenance | | -| test.cpp:266:18:266:31 | *call to getenv | test.cpp:266:2:266:32 | ... = ... | provenance | TaintFunction | -| test.cpp:274:15:274:18 | call to atoi | test.cpp:278:11:278:29 | ... * ... | provenance | | -| test.cpp:274:20:274:33 | *call to getenv | test.cpp:274:15:274:18 | call to atoi | provenance | TaintFunction | -| test.cpp:304:17:304:20 | get_size output argument | test.cpp:306:11:306:28 | ... * ... | provenance | | -| test.cpp:320:18:320:21 | get_size output argument | test.cpp:323:10:323:27 | ... * ... | provenance | | -| test.cpp:368:13:368:16 | call to atoi | test.cpp:370:35:370:38 | size | provenance | | -| test.cpp:368:13:368:16 | call to atoi | test.cpp:371:35:371:38 | size | provenance | | -| test.cpp:368:18:368:31 | *call to getenv | test.cpp:368:13:368:16 | call to atoi | provenance | TaintFunction | +| test.cpp:190:14:190:17 | call to atoi | test.cpp:194:11:194:28 | ... * ... | provenance | | +| test.cpp:190:19:190:32 | *call to getenv | test.cpp:190:14:190:17 | call to atoi | provenance | TaintFunction | +| test.cpp:205:14:205:17 | call to atoi | test.cpp:209:11:209:28 | ... * ... | provenance | | +| test.cpp:205:19:205:32 | *call to getenv | test.cpp:205:14:205:17 | call to atoi | provenance | TaintFunction | +| test.cpp:239:8:239:23 | *get_tainted_size | test.cpp:271:9:271:24 | call to get_tainted_size | provenance | | +| test.cpp:241:9:241:42 | ... * ... | test.cpp:239:8:239:23 | *get_tainted_size | provenance | | +| test.cpp:241:14:241:27 | *call to getenv | test.cpp:241:9:241:42 | ... * ... | provenance | TaintFunction | +| test.cpp:260:21:260:21 | s | test.cpp:261:21:261:21 | s | provenance | | +| test.cpp:267:19:267:52 | ... * ... | test.cpp:269:9:269:18 | local_size | provenance | | +| test.cpp:267:19:267:52 | ... * ... | test.cpp:275:11:275:20 | local_size | provenance | | +| test.cpp:267:19:267:52 | ... * ... | test.cpp:277:10:277:19 | local_size | provenance | | +| test.cpp:267:24:267:37 | *call to getenv | test.cpp:267:19:267:52 | ... * ... | provenance | TaintFunction | +| test.cpp:277:10:277:19 | local_size | test.cpp:260:21:260:21 | s | provenance | | +| test.cpp:280:20:280:27 | *out_size | test.cpp:319:17:319:20 | get_size output argument | provenance | | +| test.cpp:280:20:280:27 | *out_size | test.cpp:335:18:335:21 | get_size output argument | provenance | | +| test.cpp:281:2:281:32 | ... = ... | test.cpp:280:20:280:27 | *out_size | provenance | | +| test.cpp:281:18:281:31 | *call to getenv | test.cpp:281:2:281:32 | ... = ... | provenance | TaintFunction | +| test.cpp:289:15:289:18 | call to atoi | test.cpp:293:11:293:29 | ... * ... | provenance | | +| test.cpp:289:20:289:33 | *call to getenv | test.cpp:289:15:289:18 | call to atoi | provenance | TaintFunction | +| test.cpp:319:17:319:20 | get_size output argument | test.cpp:321:11:321:28 | ... * ... | provenance | | +| test.cpp:335:18:335:21 | get_size output argument | test.cpp:338:10:338:27 | ... * ... | provenance | | +| test.cpp:383:13:383:16 | call to atoi | test.cpp:385:35:385:38 | size | provenance | | +| test.cpp:383:13:383:16 | call to atoi | test.cpp:386:35:386:38 | size | provenance | | +| test.cpp:383:18:383:31 | *call to getenv | test.cpp:383:13:383:16 | call to atoi | provenance | TaintFunction | nodes | test.cpp:39:27:39:30 | **argv | semmle.label | **argv | | test.cpp:40:16:40:19 | call to atoi | semmle.label | call to atoi | @@ -52,31 +56,37 @@ nodes | test.cpp:148:15:148:18 | call to atol | semmle.label | call to atol | | test.cpp:148:20:148:33 | *call to getenv | semmle.label | *call to getenv | | test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... | -| test.cpp:224:8:224:23 | *get_tainted_size | semmle.label | *get_tainted_size | -| test.cpp:226:9:226:42 | ... * ... | semmle.label | ... * ... | -| test.cpp:226:14:226:27 | *call to getenv | semmle.label | *call to getenv | -| test.cpp:245:21:245:21 | s | semmle.label | s | -| test.cpp:246:21:246:21 | s | semmle.label | s | -| test.cpp:252:19:252:52 | ... * ... | semmle.label | ... * ... | -| test.cpp:252:24:252:37 | *call to getenv | semmle.label | *call to getenv | -| test.cpp:254:9:254:18 | local_size | semmle.label | local_size | -| test.cpp:256:9:256:24 | call to get_tainted_size | semmle.label | call to get_tainted_size | -| test.cpp:260:11:260:20 | local_size | semmle.label | local_size | -| test.cpp:262:10:262:19 | local_size | semmle.label | local_size | -| test.cpp:265:20:265:27 | *out_size | semmle.label | *out_size | -| test.cpp:266:2:266:32 | ... = ... | semmle.label | ... = ... | -| test.cpp:266:18:266:31 | *call to getenv | semmle.label | *call to getenv | -| test.cpp:274:15:274:18 | call to atoi | semmle.label | call to atoi | -| test.cpp:274:20:274:33 | *call to getenv | semmle.label | *call to getenv | -| test.cpp:278:11:278:29 | ... * ... | semmle.label | ... * ... | -| test.cpp:304:17:304:20 | get_size output argument | semmle.label | get_size output argument | -| test.cpp:306:11:306:28 | ... * ... | semmle.label | ... * ... | -| test.cpp:320:18:320:21 | get_size output argument | semmle.label | get_size output argument | -| test.cpp:323:10:323:27 | ... * ... | semmle.label | ... * ... | -| test.cpp:368:13:368:16 | call to atoi | semmle.label | call to atoi | -| test.cpp:368:18:368:31 | *call to getenv | semmle.label | *call to getenv | -| test.cpp:370:35:370:38 | size | semmle.label | size | -| test.cpp:371:35:371:38 | size | semmle.label | size | +| test.cpp:190:14:190:17 | call to atoi | semmle.label | call to atoi | +| test.cpp:190:19:190:32 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:194:11:194:28 | ... * ... | semmle.label | ... * ... | +| test.cpp:205:14:205:17 | call to atoi | semmle.label | call to atoi | +| test.cpp:205:19:205:32 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:209:11:209:28 | ... * ... | semmle.label | ... * ... | +| test.cpp:239:8:239:23 | *get_tainted_size | semmle.label | *get_tainted_size | +| test.cpp:241:9:241:42 | ... * ... | semmle.label | ... * ... | +| test.cpp:241:14:241:27 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:260:21:260:21 | s | semmle.label | s | +| test.cpp:261:21:261:21 | s | semmle.label | s | +| test.cpp:267:19:267:52 | ... * ... | semmle.label | ... * ... | +| test.cpp:267:24:267:37 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:269:9:269:18 | local_size | semmle.label | local_size | +| test.cpp:271:9:271:24 | call to get_tainted_size | semmle.label | call to get_tainted_size | +| test.cpp:275:11:275:20 | local_size | semmle.label | local_size | +| test.cpp:277:10:277:19 | local_size | semmle.label | local_size | +| test.cpp:280:20:280:27 | *out_size | semmle.label | *out_size | +| test.cpp:281:2:281:32 | ... = ... | semmle.label | ... = ... | +| test.cpp:281:18:281:31 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:289:15:289:18 | call to atoi | semmle.label | call to atoi | +| test.cpp:289:20:289:33 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:293:11:293:29 | ... * ... | semmle.label | ... * ... | +| test.cpp:319:17:319:20 | get_size output argument | semmle.label | get_size output argument | +| test.cpp:321:11:321:28 | ... * ... | semmle.label | ... * ... | +| test.cpp:335:18:335:21 | get_size output argument | semmle.label | get_size output argument | +| test.cpp:338:10:338:27 | ... * ... | semmle.label | ... * ... | +| test.cpp:383:13:383:16 | call to atoi | semmle.label | call to atoi | +| test.cpp:383:18:383:31 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:385:35:385:38 | size | semmle.label | size | +| test.cpp:386:35:386:38 | size | semmle.label | size | subpaths #select | test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | **argv | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:39:27:39:30 | **argv | user input (a command-line argument) | @@ -88,12 +98,14 @@ subpaths | test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:31 | *call to getenv | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:124:18:124:31 | *call to getenv | user input (an environment variable) | | test.cpp:135:3:135:8 | call to malloc | test.cpp:133:19:133:32 | *call to getenv | test.cpp:135:10:135:27 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:133:19:133:32 | *call to getenv | user input (an environment variable) | | test.cpp:152:4:152:9 | call to malloc | test.cpp:148:20:148:33 | *call to getenv | test.cpp:152:11:152:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:148:20:148:33 | *call to getenv | user input (an environment variable) | -| test.cpp:246:14:246:19 | call to malloc | test.cpp:252:24:252:37 | *call to getenv | test.cpp:246:21:246:21 | s | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:252:24:252:37 | *call to getenv | user input (an environment variable) | -| test.cpp:254:2:254:7 | call to malloc | test.cpp:252:24:252:37 | *call to getenv | test.cpp:254:9:254:18 | local_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:252:24:252:37 | *call to getenv | user input (an environment variable) | -| test.cpp:256:2:256:7 | call to malloc | test.cpp:226:14:226:27 | *call to getenv | test.cpp:256:9:256:24 | call to get_tainted_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:226:14:226:27 | *call to getenv | user input (an environment variable) | -| test.cpp:260:2:260:9 | call to my_alloc | test.cpp:252:24:252:37 | *call to getenv | test.cpp:260:11:260:20 | local_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:252:24:252:37 | *call to getenv | user input (an environment variable) | -| test.cpp:278:4:278:9 | call to malloc | test.cpp:274:20:274:33 | *call to getenv | test.cpp:278:11:278:29 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:274:20:274:33 | *call to getenv | user input (an environment variable) | -| test.cpp:306:4:306:9 | call to malloc | test.cpp:266:18:266:31 | *call to getenv | test.cpp:306:11:306:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:266:18:266:31 | *call to getenv | user input (an environment variable) | -| test.cpp:323:3:323:8 | call to malloc | test.cpp:266:18:266:31 | *call to getenv | test.cpp:323:10:323:27 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:266:18:266:31 | *call to getenv | user input (an environment variable) | -| test.cpp:370:25:370:33 | call to MyMalloc1 | test.cpp:368:18:368:31 | *call to getenv | test.cpp:370:35:370:38 | size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:368:18:368:31 | *call to getenv | user input (an environment variable) | -| test.cpp:371:25:371:33 | call to MyMalloc2 | test.cpp:368:18:368:31 | *call to getenv | test.cpp:371:35:371:38 | size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:368:18:368:31 | *call to getenv | user input (an environment variable) | +| test.cpp:194:4:194:9 | call to malloc | test.cpp:190:19:190:32 | *call to getenv | test.cpp:194:11:194:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:190:19:190:32 | *call to getenv | user input (an environment variable) | +| test.cpp:209:4:209:9 | call to malloc | test.cpp:205:19:205:32 | *call to getenv | test.cpp:209:11:209:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:205:19:205:32 | *call to getenv | user input (an environment variable) | +| test.cpp:261:14:261:19 | call to malloc | test.cpp:267:24:267:37 | *call to getenv | test.cpp:261:21:261:21 | s | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:267:24:267:37 | *call to getenv | user input (an environment variable) | +| test.cpp:269:2:269:7 | call to malloc | test.cpp:267:24:267:37 | *call to getenv | test.cpp:269:9:269:18 | local_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:267:24:267:37 | *call to getenv | user input (an environment variable) | +| test.cpp:271:2:271:7 | call to malloc | test.cpp:241:14:241:27 | *call to getenv | test.cpp:271:9:271:24 | call to get_tainted_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:241:14:241:27 | *call to getenv | user input (an environment variable) | +| test.cpp:275:2:275:9 | call to my_alloc | test.cpp:267:24:267:37 | *call to getenv | test.cpp:275:11:275:20 | local_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:267:24:267:37 | *call to getenv | user input (an environment variable) | +| test.cpp:293:4:293:9 | call to malloc | test.cpp:289:20:289:33 | *call to getenv | test.cpp:293:11:293:29 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:289:20:289:33 | *call to getenv | user input (an environment variable) | +| test.cpp:321:4:321:9 | call to malloc | test.cpp:281:18:281:31 | *call to getenv | test.cpp:321:11:321:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:281:18:281:31 | *call to getenv | user input (an environment variable) | +| test.cpp:338:3:338:8 | call to malloc | test.cpp:281:18:281:31 | *call to getenv | test.cpp:338:10:338:27 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:281:18:281:31 | *call to getenv | user input (an environment variable) | +| test.cpp:385:25:385:33 | call to MyMalloc1 | test.cpp:383:18:383:31 | *call to getenv | test.cpp:385:35:385:38 | size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:383:18:383:31 | *call to getenv | user input (an environment variable) | +| test.cpp:386:25:386:33 | call to MyMalloc2 | test.cpp:383:18:383:31 | *call to getenv | test.cpp:386:35:386:38 | size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:383:18:383:31 | *call to getenv | user input (an environment variable) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp index f262d1943d0..e13c50a960b 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp @@ -191,7 +191,22 @@ void more_bounded_tests() { if (size % 100) { - malloc(size * sizeof(int)); // BAD [NOT DETECTED] + malloc(size * sizeof(int)); // BAD + } + } + + { + int size = atoi(getenv("USER")); + int size2 = size & 7; // Pick the first three bits of size + malloc(size2 * sizeof(int)); // GOOD + } + + { + int size = atoi(getenv("USER")); + + if (size & 7) + { + malloc(size * sizeof(int)); // BAD } } From 5494389c4b79c3c3b584157d2bb2bcb71d44efc4 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 29 Aug 2024 09:44:23 +0100 Subject: [PATCH 154/404] Update changenote Co-authored-by: Sid Shankar --- python/ql/src/change-notes/2024-08-27-sensitive-certificate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/change-notes/2024-08-27-sensitive-certificate.md b/python/ql/src/change-notes/2024-08-27-sensitive-certificate.md index 9db609ebbe6..eee82db8cde 100644 --- a/python/ql/src/change-notes/2024-08-27-sensitive-certificate.md +++ b/python/ql/src/change-notes/2024-08-27-sensitive-certificate.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* The `py/clear-text-logging-sensitive-data` and `py/clear-text-storage-sensitive-data` queries have been updated to exclude the `certificate` classification of of sensitive sources, which often do not actually contain sensitive data. \ No newline at end of file +* The `py/clear-text-logging-sensitive-data` and `py/clear-text-storage-sensitive-data` queries have been updated to exclude the `certificate` classification of sensitive sources, which often do not contain sensitive data. \ No newline at end of file From ff31aa540c45aef55cbbe3f0815f522aaa4f1127 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 29 Aug 2024 15:54:04 +0200 Subject: [PATCH 155/404] Address review comments. --- .../dataflow/internal/ContentDataFlowImpl.qll | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll index f4b4b9655e4..f413c6dd7ad 100644 --- a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll @@ -51,11 +51,6 @@ module MakeImplContentDataFlow Lang> { */ default predicate isAdditionalFlowStep(Node node1, Node node2) { none() } - /** - * Holds if taint may propagate from `node1` to `node2` in addition to the normal data-flow steps. - */ - default predicate isAdditionalTaintStep(Node node1, Node node2) { none() } - /** Holds if data flow into `node` is prohibited. */ default predicate isBarrier(Node node) { none() } @@ -106,11 +101,9 @@ module MakeImplContentDataFlow Lang> { predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) { storeStep(node1, state1, _, node2, state2) or readStep(node1, state1, _, node2, state2) or - additionalTaintStep(node1, state1, node2, state2) + additionalStep(node1, state1, node2, state2) } - predicate isAdditionalFlowStep = ContentConfig::isAdditionalFlowStep/2; - predicate isBarrier = ContentConfig::isBarrier/1; FlowFeature getAFeature() { result = ContentConfig::getAFeature() } @@ -234,8 +227,8 @@ module MakeImplContentDataFlow Lang> { ) } - private predicate additionalTaintStep(Node node1, State state1, Node node2, State state2) { - ContentConfig::isAdditionalTaintStep(node1, node2) and + private predicate additionalStep(Node node1, State state1, Node node2, State state2) { + ContentConfig::isAdditionalFlowStep(node1, node2) and ( state1 instanceof InitState and state2.(InitState).decode(false) From dd7f757281876c257862885ee205c739916b1774 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Thu, 29 Aug 2024 16:43:27 +0200 Subject: [PATCH 156/404] Address review. --- .../java/multi-release-jar-java11/test.py | 17 ++--------------- .../java/multi-release-jar-java17/test.py | 17 ++--------------- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py b/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py index d67602f8bcb..fafe3e16fdd 100644 --- a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py +++ b/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py @@ -2,22 +2,9 @@ import commands def test(codeql, use_java_11, java): - commands.run(["javac", "mod1/module-info.java", "mod1/mod1pkg/Mod1Class.java", "-d", "mod1obj"]) commands.run( - [ - "jar", - "-c", - "-f", - "mod1.jar", - "-C", - "mod1obj", - "mod1pkg/Mod1Class.class", - "--release", - "9", - "-C", - "mod1obj", - "module-info.class", - ] + "javac mod1/module-info.java mod1/mod1pkg/Mod1Class.java -d mod1obj", + "jar -c -f mod1.jar -C mod1obj mod1pkg/Mod1Class.class --release 9 -C mod1obj module-info.class", ) codeql.database.create( command="javac mod2/mod2pkg/User.java mod2/module-info.java -d mod2obj -p mod1.jar" diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py b/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py index 567cd51bef2..195ed61fadd 100644 --- a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py +++ b/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py @@ -2,22 +2,9 @@ import commands def test(codeql, java): - commands.run(["javac", "mod1/module-info.java", "mod1/mod1pkg/Mod1Class.java", "-d", "mod1obj"]) commands.run( - [ - "jar", - "-c", - "-f", - "mod1.jar", - "-C", - "mod1obj", - "mod1pkg/Mod1Class.class", - "--release", - "9", - "-C", - "mod1obj", - "module-info.class", - ] + "javac mod1/module-info.java mod1/mod1pkg/Mod1Class.java -d mod1obj", + "jar -c -f mod1.jar -C mod1obj mod1pkg/Mod1Class.class --release 9 -C mod1obj module-info.class", ) codeql.database.create( command="javac mod2/mod2pkg/User.java mod2/module-info.java -d mod2obj -p mod1.jar" From 590a146b49d5887879fa1da5bab435938686401f Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 29 Aug 2024 17:03:19 +0200 Subject: [PATCH 157/404] Rust: some basic extraction of function names (with locations!) --- .pre-commit-config.yaml | 4 +- misc/codegen/lib/rust.py | 2 +- misc/codegen/templates/rust_classes.mustache | 17 +- misc/codegen/templates/rust_module.mustache | 3 +- rust/.generated.list | 35 + rust/.gitattributes | 37 + rust/Cargo.lock | 1075 +++-------------- rust/Cargo.toml | 13 +- rust/codegen.conf | 9 + rust/codegen/BUILD.bazel | 15 + rust/codegen/README.md | 6 + rust/prefix.dbscheme | 6 + rust/ql/lib/codeql/rust/elements.qll | 16 + rust/ql/lib/codeql/rust/elements/DbFile.qll | 8 + .../rust/elements/DbFileConstructor.qll | 14 + .../lib/codeql/rust/elements/DbLocation.qll | 8 + .../rust/elements/DbLocationConstructor.qll | 14 + .../lib/codeql/rust/elements/Declaration.qll | 8 + rust/ql/lib/codeql/rust/elements/Element.qll | 8 + rust/ql/lib/codeql/rust/elements/File.qll | 8 + rust/ql/lib/codeql/rust/elements/Function.qll | 8 + .../rust/elements/FunctionConstructor.qll | 14 + .../ql/lib/codeql/rust/elements/Locatable.qll | 8 + rust/ql/lib/codeql/rust/elements/Location.qll | 8 + rust/ql/lib/codeql/rust/elements/Module.qll | 8 + .../rust/elements/ModuleConstructor.qll | 14 + .../lib/codeql/rust/elements/UnknownFile.qll | 8 + .../codeql/rust/elements/UnknownLocation.qll | 8 + rust/ql/lib/codeql/rust/generated/DbFile.qll | 23 + .../lib/codeql/rust/generated/DbLocation.qll | 23 + .../lib/codeql/rust/generated/Declaration.qll | 21 + rust/ql/lib/codeql/rust/generated/Element.qll | 57 + rust/ql/lib/codeql/rust/generated/File.qll | 26 + .../ql/lib/codeql/rust/generated/Function.qll | 28 + .../lib/codeql/rust/generated/Locatable.qll | 37 + .../ql/lib/codeql/rust/generated/Location.qll | 52 + rust/ql/lib/codeql/rust/generated/Module.qll | 43 + .../lib/codeql/rust/generated/ParentChild.qll | 203 ++++ .../rust/generated/PureSynthConstructors.qll | 5 + rust/ql/lib/codeql/rust/generated/Raw.qll | 105 ++ rust/ql/lib/codeql/rust/generated/Synth.qll | 252 ++++ .../rust/generated/SynthConstructors.qll | 9 + .../lib/codeql/rust/generated/UnknownFile.qll | 23 + .../codeql/rust/generated/UnknownLocation.qll | 23 + rust/ql/lib/rust.dbscheme | 81 ++ .../generated/File/MISSING_SOURCE.txt | 4 + .../generated/Function/MISSING_SOURCE.txt | 4 + .../generated/Module/MISSING_SOURCE.txt | 4 + rust/schema.py | 60 + rust/src/archive.rs | 4 +- rust/src/generated/top.rs | 87 ++ rust/src/main.rs | 29 +- rust/src/translate.rs | 171 ++- rust/src/trap.rs | 118 +- 54 files changed, 1867 insertions(+), 1007 deletions(-) create mode 100644 rust/.generated.list create mode 100644 rust/.gitattributes create mode 100644 rust/codegen.conf create mode 100644 rust/codegen/BUILD.bazel create mode 100644 rust/codegen/README.md create mode 100644 rust/prefix.dbscheme create mode 100644 rust/ql/lib/codeql/rust/elements.qll create mode 100644 rust/ql/lib/codeql/rust/elements/DbFile.qll create mode 100644 rust/ql/lib/codeql/rust/elements/DbFileConstructor.qll create mode 100644 rust/ql/lib/codeql/rust/elements/DbLocation.qll create mode 100644 rust/ql/lib/codeql/rust/elements/DbLocationConstructor.qll create mode 100644 rust/ql/lib/codeql/rust/elements/Declaration.qll create mode 100644 rust/ql/lib/codeql/rust/elements/Element.qll create mode 100644 rust/ql/lib/codeql/rust/elements/File.qll create mode 100644 rust/ql/lib/codeql/rust/elements/Function.qll create mode 100644 rust/ql/lib/codeql/rust/elements/FunctionConstructor.qll create mode 100644 rust/ql/lib/codeql/rust/elements/Locatable.qll create mode 100644 rust/ql/lib/codeql/rust/elements/Location.qll create mode 100644 rust/ql/lib/codeql/rust/elements/Module.qll create mode 100644 rust/ql/lib/codeql/rust/elements/ModuleConstructor.qll create mode 100644 rust/ql/lib/codeql/rust/elements/UnknownFile.qll create mode 100644 rust/ql/lib/codeql/rust/elements/UnknownLocation.qll create mode 100644 rust/ql/lib/codeql/rust/generated/DbFile.qll create mode 100644 rust/ql/lib/codeql/rust/generated/DbLocation.qll create mode 100644 rust/ql/lib/codeql/rust/generated/Declaration.qll create mode 100644 rust/ql/lib/codeql/rust/generated/Element.qll create mode 100644 rust/ql/lib/codeql/rust/generated/File.qll create mode 100644 rust/ql/lib/codeql/rust/generated/Function.qll create mode 100644 rust/ql/lib/codeql/rust/generated/Locatable.qll create mode 100644 rust/ql/lib/codeql/rust/generated/Location.qll create mode 100644 rust/ql/lib/codeql/rust/generated/Module.qll create mode 100644 rust/ql/lib/codeql/rust/generated/ParentChild.qll create mode 100644 rust/ql/lib/codeql/rust/generated/PureSynthConstructors.qll create mode 100644 rust/ql/lib/codeql/rust/generated/Raw.qll create mode 100644 rust/ql/lib/codeql/rust/generated/Synth.qll create mode 100644 rust/ql/lib/codeql/rust/generated/SynthConstructors.qll create mode 100644 rust/ql/lib/codeql/rust/generated/UnknownFile.qll create mode 100644 rust/ql/lib/codeql/rust/generated/UnknownLocation.qll create mode 100644 rust/ql/lib/rust.dbscheme create mode 100644 rust/ql/test/extractor-tests/generated/File/MISSING_SOURCE.txt create mode 100644 rust/ql/test/extractor-tests/generated/Function/MISSING_SOURCE.txt create mode 100644 rust/ql/test/extractor-tests/generated/Module/MISSING_SOURCE.txt create mode 100644 rust/schema.py create mode 100644 rust/src/generated/top.rs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 62ac0d95779..1a794108bc3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,9 +5,9 @@ repos: rev: v3.2.0 hooks: - id: trailing-whitespace - exclude: /test/.*$(?, + pub id: TrapId, {{#fields}} pub {{field_name}}: {{type}}, {{/fields}} } impl TrapEntry for {{name}} { - type Label = TrapLabel; + fn extract_id(&mut self) -> TrapId { + std::mem::replace(&mut self.id, TrapId::Star) + } - fn prefix() -> &'static str { "{{name}}_" } - - fn key(&self) -> Option<&str> { self.key.as_ref().map(String::as_str) } - - fn emit(&self, id: &Self::Label, out: &mut W) -> std::io::Result<()> { + fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { write!(out, "{{table_name}}({id}{{#single_fields}}, {}{{/single_fields}})\n"{{#single_fields}}, {{#emitter}}self.{{field_name}}{{/emitter}}{{/single_fields}})?; {{#fields}} {{#is_predicate}} @@ -50,5 +48,4 @@ impl TrapEntry for {{name}} { Ok(()) } } - {{/classes}} diff --git a/misc/codegen/templates/rust_module.mustache b/misc/codegen/templates/rust_module.mustache index 3908e166dfa..bc7fb3158c6 100644 --- a/misc/codegen/templates/rust_module.mustache +++ b/misc/codegen/templates/rust_module.mustache @@ -1,7 +1,6 @@ // generated by {{generator}} - {{#modules}} + mod {{.}}; pub use {{.}}::*; - {{/modules}} diff --git a/rust/.generated.list b/rust/.generated.list new file mode 100644 index 00000000000..9f13a9da75a --- /dev/null +++ b/rust/.generated.list @@ -0,0 +1,35 @@ +ql/lib/codeql/rust/elements/DbFile.qll 056d363e1ba5ec08cacb2e90b8a7a3b47f52ded5dc2289edd4e85921fc50f37e 18e6926f77265a3a6319ca2f3bf3d529d17d46cebdd2ef6753357fdc53c22c70 +ql/lib/codeql/rust/elements/DbFileConstructor.qll ea93dc49b23b1c6d800ab9d0b9cacfa9dc661bfdb04b9e6efcad2bdb050fb0ab f7a891b1786604eee57a784733555b677e2580770d51d18073b59e7ca65df1d4 +ql/lib/codeql/rust/elements/DbLocation.qll 1f694594e8e4ab65a8781cd443ad4f864447ca88e2cb65504aee5a779393c84d 003ec72275406eb8f5ddd6ccc2b258fb7c906d4bb2c0ef1ba235f291624321ca +ql/lib/codeql/rust/elements/DbLocationConstructor.qll 8848abace985818a5d3a6eddfc4cb200795970146d282b037b4f22ae6230b894 44dba880e17bb1072fa12451ccaae4830fd04dcc61f7403d35510309fde6906e +ql/lib/codeql/rust/elements/Declaration.qll d4ec5c83728f1837243caf2f27d06fd05ecdd2ca440112accff99bfd37b45e5f c1cd9b297be8b69207e75d24b29949b9f71c78406ee0ffd38d0b0810288d6140 +ql/lib/codeql/rust/elements/Element.qll 2bffdeb8863a9853d019e56afa268b3d39fb3687785ad636b159656c199997ca 18020582c7d1b89f4073b6deaf793c3072fdc52503a6cc53172c96282f141de4 +ql/lib/codeql/rust/elements/File.qll 75144234638417347107b75db80c561379e6372859ebc463276aef716e0ed42b 55bb468873acf24e6828faf7be3ff8963c9a4eb344bfedd95328a51b6f00a226 +ql/lib/codeql/rust/elements/Function.qll 220eb1d0e6b49e83b7674a9f505d3f529cf7f4d022ddca44fa6367e0d75daa0f d156cff59ecdcffc0d62041b801025b1aaedbc92d44efd107f93f6fd06c34a6d +ql/lib/codeql/rust/elements/FunctionConstructor.qll a9269b37182c0bf432f9b2b015691da5dbd64819b9bd25445af229d873014a91 69107a7503af14a51e091e6918094a4e9fc316a72de2e1514f001872ce0f2c0c +ql/lib/codeql/rust/elements/Locatable.qll dfc0235cf5aff0ec91d85375ac03998b0e6a69f3722b099330ab0a2161af988a bb1055f59ef7e95e89748765c79f1b5832aa18226f227e689a6801adfc6247ad +ql/lib/codeql/rust/elements/Location.qll 17a222ffe30ecfa252bfd2a5d6ef668f9579824b78d241d576c8c0112a9f93f0 9ae822cd9ce3c70824cccae500651f0cba70ad9c9195b611e7542cb928093b0b +ql/lib/codeql/rust/elements/Module.qll d8995b361cc672f86a314bd53bd3e4d1ddb26b6afde62eb7c380923810785af0 3c10180c812d89a8116ac6e32cbd4d7ac2f549c8a76d327ed75c764b09251d52 +ql/lib/codeql/rust/elements/ModuleConstructor.qll 109ed8c1b5c61cc1d3e8613aa8bb8c168dc1943c93b5b622fa79665751b78318 601526c7f56578883d261d14653fdad08329f80fea71de14a5ac5ce671a8d436 +ql/lib/codeql/rust/elements/UnknownFile.qll 638ac1c5baef4ab8eb98ef4a37202334290001ca183dab769f729b61f9fc0aa9 fae24f8b29c3e5a124e6c71c9bcb0e2bf4bb033eaf3348fd2db3644ce2803b43 +ql/lib/codeql/rust/elements/UnknownLocation.qll eaadf1702e2f5df0c0917dd9e452a3ceb81e5c2d182675c32e988d826ac3fc71 9bf63fbd74c6114678189a62f63795156c0e5b9ad467c020f16842038e84a226 +ql/lib/codeql/rust/elements.qll 658d3d26ac2685a077714d41d83ac47f87b0df1c4f0cc7d099c96e06bd1f9d0e 658d3d26ac2685a077714d41d83ac47f87b0df1c4f0cc7d099c96e06bd1f9d0e +ql/lib/codeql/rust/generated/DbFile.qll 4dbf1931124291e0d6a958ae882f8aeef006642f72adc7ff86cffd3a4e9a970a 4dbf1931124291e0d6a958ae882f8aeef006642f72adc7ff86cffd3a4e9a970a +ql/lib/codeql/rust/generated/DbLocation.qll 735d9351b5eb46a3231b528600dddec3a4122c18c210d4d632a8d4ceaf7f02e9 735d9351b5eb46a3231b528600dddec3a4122c18c210d4d632a8d4ceaf7f02e9 +ql/lib/codeql/rust/generated/Declaration.qll 4487ac3f5ffa5b92e8628bc04b51e818d4ea1c9a333375cf1b729428d36a4ee7 6481d5e2d99a548f857213a283da75d45db8b3adac949e90fd5d17ceb5e22b54 +ql/lib/codeql/rust/generated/Element.qll 21567fa7348dccdf69dd34e73cb6de7cc9c7e0f3f7bb419a1abd787f7dc851a1 21567fa7348dccdf69dd34e73cb6de7cc9c7e0f3f7bb419a1abd787f7dc851a1 +ql/lib/codeql/rust/generated/File.qll 2eff5c882d044d2e360fe6382fb55e5a45f6ccb9df323cfa1fae41eae9d2a47f 87e7a906b3a1b4de056952e288ddd7f69fa7cb1bd9dc7dd3972868a9002ac1e4 +ql/lib/codeql/rust/generated/Function.qll 6429619a284cadaf64d74ab408f57a399c7e5df2ad182bd38f77b580879d9e33 8c4cfa4f23b5ed461f0f8aa40c5833a953fc9ba3f99584f0f05cf7d7d6a9b617 +ql/lib/codeql/rust/generated/Locatable.qll 9e9685bba50ad2220701f3465e63af9331f7f9dc548ad906ff954fc2ce0a4400 78c89b2cc78a357d682ab65310dd474603071f07c1eaaab07711714ce17549f2 +ql/lib/codeql/rust/generated/Location.qll bce4c72988ec6fedd1439c60a37c45aa6147c962904709ef9f12206937174be4 d57000571771a2d997c50d9a43ef1c2f075960f847effa0e80ea91fd4c6b4d6c +ql/lib/codeql/rust/generated/Module.qll 2a931a4f2cdb2fee00ed83af045ea63d36b7dbd708e58c30445b5610feaae333 cd62add5c31a509f965aa294f44a1607ec7c62e3a9e3fe9ee063b3c814f4eb62 +ql/lib/codeql/rust/generated/ParentChild.qll b44f149bff05a96ee16c88883f06d5d2c159a89423ec32b00765da6964af029e 1d13e54fbc27d9cc29405a21c2f4a63043cbb7aade317184f440a17d3f5645c4 +ql/lib/codeql/rust/generated/PureSynthConstructors.qll 5eb1fc4f6a04172c34ae31e4931e4bf1f8b72fbe414c5f644731a45372d13573 5eb1fc4f6a04172c34ae31e4931e4bf1f8b72fbe414c5f644731a45372d13573 +ql/lib/codeql/rust/generated/Raw.qll 921cb1afb5c1c3177acb557151755d4f97e7c65f656c5069d6f095b0e078074f a25fdad01e70bbab2d2663b152a4a5844677edcf0a0af2ec93c42dc3248ac9b2 +ql/lib/codeql/rust/generated/Synth.qll d278de9c2d06cb7549cd8f2e10ed186827a2ceab6ff46725ca76e78e7fecac72 acacd9afc5ca4a288e037a43375d933c3ba3cd8d08ef122b31695e74be260eb2 +ql/lib/codeql/rust/generated/SynthConstructors.qll 35b36df0c4fff05bcbd4ed10b1e6fa2e58fe8d8c818e7805111044825788fc01 35b36df0c4fff05bcbd4ed10b1e6fa2e58fe8d8c818e7805111044825788fc01 +ql/lib/codeql/rust/generated/UnknownFile.qll ec9d1a3f15ecbf1743d4e39cb3b2f217aa9b54951c93302c2c4c238c3f0ce595 ec9d1a3f15ecbf1743d4e39cb3b2f217aa9b54951c93302c2c4c238c3f0ce595 +ql/lib/codeql/rust/generated/UnknownLocation.qll a19e2838c52d702d268ae530f3dbd6fcd8bb28a237a52636a960f225454103cf a19e2838c52d702d268ae530f3dbd6fcd8bb28a237a52636a960f225454103cf +ql/test/extractor-tests/generated/File/MISSING_SOURCE.txt cc7c395e7c651d62596826b1a0bedf10f35d01b8afeef47600b4ddaf804f406e cc7c395e7c651d62596826b1a0bedf10f35d01b8afeef47600b4ddaf804f406e +ql/test/extractor-tests/generated/Function/MISSING_SOURCE.txt cc7c395e7c651d62596826b1a0bedf10f35d01b8afeef47600b4ddaf804f406e cc7c395e7c651d62596826b1a0bedf10f35d01b8afeef47600b4ddaf804f406e +ql/test/extractor-tests/generated/Module/MISSING_SOURCE.txt cc7c395e7c651d62596826b1a0bedf10f35d01b8afeef47600b4ddaf804f406e cc7c395e7c651d62596826b1a0bedf10f35d01b8afeef47600b4ddaf804f406e diff --git a/rust/.gitattributes b/rust/.gitattributes new file mode 100644 index 00000000000..ebd94575437 --- /dev/null +++ b/rust/.gitattributes @@ -0,0 +1,37 @@ +/.generated.list linguist-generated +/.gitattributes linguist-generated +/ql/lib/codeql/rust/elements/DbFile.qll linguist-generated +/ql/lib/codeql/rust/elements/DbFileConstructor.qll linguist-generated +/ql/lib/codeql/rust/elements/DbLocation.qll linguist-generated +/ql/lib/codeql/rust/elements/DbLocationConstructor.qll linguist-generated +/ql/lib/codeql/rust/elements/Declaration.qll linguist-generated +/ql/lib/codeql/rust/elements/Element.qll linguist-generated +/ql/lib/codeql/rust/elements/File.qll linguist-generated +/ql/lib/codeql/rust/elements/Function.qll linguist-generated +/ql/lib/codeql/rust/elements/FunctionConstructor.qll linguist-generated +/ql/lib/codeql/rust/elements/Locatable.qll linguist-generated +/ql/lib/codeql/rust/elements/Location.qll linguist-generated +/ql/lib/codeql/rust/elements/Module.qll linguist-generated +/ql/lib/codeql/rust/elements/ModuleConstructor.qll linguist-generated +/ql/lib/codeql/rust/elements/UnknownFile.qll linguist-generated +/ql/lib/codeql/rust/elements/UnknownLocation.qll linguist-generated +/ql/lib/codeql/rust/elements.qll linguist-generated +/ql/lib/codeql/rust/generated/DbFile.qll linguist-generated +/ql/lib/codeql/rust/generated/DbLocation.qll linguist-generated +/ql/lib/codeql/rust/generated/Declaration.qll linguist-generated +/ql/lib/codeql/rust/generated/Element.qll linguist-generated +/ql/lib/codeql/rust/generated/File.qll linguist-generated +/ql/lib/codeql/rust/generated/Function.qll linguist-generated +/ql/lib/codeql/rust/generated/Locatable.qll linguist-generated +/ql/lib/codeql/rust/generated/Location.qll linguist-generated +/ql/lib/codeql/rust/generated/Module.qll linguist-generated +/ql/lib/codeql/rust/generated/ParentChild.qll linguist-generated +/ql/lib/codeql/rust/generated/PureSynthConstructors.qll linguist-generated +/ql/lib/codeql/rust/generated/Raw.qll linguist-generated +/ql/lib/codeql/rust/generated/Synth.qll linguist-generated +/ql/lib/codeql/rust/generated/SynthConstructors.qll linguist-generated +/ql/lib/codeql/rust/generated/UnknownFile.qll linguist-generated +/ql/lib/codeql/rust/generated/UnknownLocation.qll linguist-generated +/ql/test/extractor-tests/generated/File/MISSING_SOURCE.txt linguist-generated +/ql/test/extractor-tests/generated/Function/MISSING_SOURCE.txt linguist-generated +/ql/test/extractor-tests/generated/Module/MISSING_SOURCE.txt linguist-generated diff --git a/rust/Cargo.lock b/rust/Cargo.lock index cc9fc0c7f66..35f700fa120 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -83,9 +83,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "atomic" @@ -128,15 +128,15 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" +checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2" [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] @@ -294,15 +294,18 @@ dependencies = [ "figment", "log", "num-traits", - "ra_ap_base_db 0.0.231", - "ra_ap_hir 0.0.229", - "ra_ap_hir_def 0.0.231", - "ra_ap_ide_db 0.0.232", + "ra_ap_base_db", + "ra_ap_hir", + "ra_ap_hir_def", + "ra_ap_ide_db", "ra_ap_load-cargo", "ra_ap_project_model", + "ra_ap_syntax", + "ra_ap_vfs", "serde", "serde_with", "stderrlog", + "triomphe", ] [[package]] @@ -463,9 +466,9 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -697,9 +700,9 @@ checksum = "3752f229dcc5a481d60f385fa479ff46818033d881d2d801aa27dffcfb5e8306" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libredox" @@ -943,24 +946,13 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] -[[package]] -name = "ra-ap-rustc_abi" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80b1d613eee933486c0613a7bc26e515e46f43adf479d1edd5e537f983e9ce46" -dependencies = [ - "bitflags 2.6.0", - "ra-ap-rustc_index 0.53.0", - "tracing", -] - [[package]] name = "ra-ap-rustc_abi" version = "0.63.0" @@ -968,21 +960,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b011c39d409940a890414e3a7b239762ac16d88029ad71b050a8374831b93790" dependencies = [ "bitflags 2.6.0", - "ra-ap-rustc_index 0.63.0", + "ra-ap-rustc_index", "tracing", ] -[[package]] -name = "ra-ap-rustc_index" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f072060ac77e9e1a02cc20028095993af7e72cc0804779c68bcbf47b16de49c9" -dependencies = [ - "arrayvec", - "ra-ap-rustc_index_macros 0.53.0", - "smallvec", -] - [[package]] name = "ra-ap-rustc_index" version = "0.63.0" @@ -990,22 +971,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9027acdee649b0b27eb10b7db5be833efee3362d394935c5eed8f0745a9d43ce" dependencies = [ "arrayvec", - "ra-ap-rustc_index_macros 0.63.0", + "ra-ap-rustc_index_macros", "smallvec", ] -[[package]] -name = "ra-ap-rustc_index_macros" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82f3d6dcb30a66905388e14756b8f2216131d9f8004922c07f13335840e058d1" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "ra-ap-rustc_index_macros" version = "0.63.0" @@ -1017,16 +986,6 @@ dependencies = [ "syn", ] -[[package]] -name = "ra-ap-rustc_lexer" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd8a2b0bdcba9892cbce0b25f6c953d31b0febc1f3420fc692884fce5a23ad8" -dependencies = [ - "unicode-properties", - "unicode-xid", -] - [[package]] name = "ra-ap-rustc_lexer" version = "0.63.0" @@ -1037,37 +996,14 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "ra-ap-rustc_parse_format" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dad7a491c2554590222e0c9212dcb7c2e7aceb668875075012a35ea780d135" -dependencies = [ - "ra-ap-rustc_index 0.53.0", - "ra-ap-rustc_lexer 0.53.0", -] - [[package]] name = "ra-ap-rustc_parse_format" version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8fe3556ab6311bb775220563a300e2bf62ec56404521fe0c511a583937683d5" dependencies = [ - "ra-ap-rustc_index 0.63.0", - "ra-ap-rustc_lexer 0.63.0", -] - -[[package]] -name = "ra-ap-rustc_pattern_analysis" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34768e1faf88c31f2e9ad57b48318a52b507dafac0cddbf01b5d63bfc0b0a365" -dependencies = [ - "ra-ap-rustc_index 0.53.0", - "rustc-hash", - "rustc_apfloat", - "smallvec", - "tracing", + "ra-ap-rustc_index", + "ra-ap-rustc_lexer", ] [[package]] @@ -1076,55 +1012,13 @@ version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1709080fdeb5db630e1c2644026c2962aaa32416cd92f0190c04b0c21e114b91" dependencies = [ - "ra-ap-rustc_index 0.63.0", + "ra-ap-rustc_index", "rustc-hash", "rustc_apfloat", "smallvec", "tracing", ] -[[package]] -name = "ra_ap_base_db" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aae8f3b0315876c1aa11dc0aac7795b27cb9e21a2a870667842e97e6b7dc3b5" -dependencies = [ - "la-arena", - "lz4_flex", - "ra_ap_cfg 0.0.229", - "ra_ap_intern 0.0.229", - "ra_ap_salsa 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_syntax 0.0.229", - "ra_ap_vfs 0.0.229", - "rustc-hash", - "semver", - "tracing", - "triomphe", -] - -[[package]] -name = "ra_ap_base_db" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f98f5aab31c0667a8c892e91ba22140af28ba1ef364120a2e3a13e6e39a3aa6" -dependencies = [ - "la-arena", - "lz4_flex", - "ra_ap_cfg 0.0.231", - "ra_ap_intern 0.0.231", - "ra_ap_salsa 0.0.231", - "ra_ap_span 0.0.231", - "ra_ap_stdx 0.0.231", - "ra_ap_syntax 0.0.231", - "ra_ap_vfs 0.0.231", - "rustc-hash", - "semver", - "tracing", - "triomphe", -] - [[package]] name = "ra_ap_base_db" version = "0.0.232" @@ -1133,78 +1027,30 @@ checksum = "3bcb25fbab872d3f85798739db011212a98444e55163d71edb1dfdb509e616b3" dependencies = [ "la-arena", "lz4_flex", - "ra_ap_cfg 0.0.232", - "ra_ap_intern 0.0.232", - "ra_ap_salsa 0.0.232", - "ra_ap_span 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_syntax 0.0.232", - "ra_ap_vfs 0.0.232", + "ra_ap_cfg", + "ra_ap_intern", + "ra_ap_salsa", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_vfs", "rustc-hash", "semver", "tracing", "triomphe", ] -[[package]] -name = "ra_ap_cfg" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac59191045154789b3b3f9f8c67f35439c3cbd9e36107dd62d04d4a4b2c95322" -dependencies = [ - "ra_ap_intern 0.0.229", - "ra_ap_tt 0.0.229", - "rustc-hash", -] - -[[package]] -name = "ra_ap_cfg" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e1d1365f6d9b9712678f19781af1d0b348fd08f5117fb0788d0aedf28b1e39" -dependencies = [ - "ra_ap_intern 0.0.231", - "ra_ap_tt 0.0.231", - "rustc-hash", -] - [[package]] name = "ra_ap_cfg" version = "0.0.232" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbec14556d01bf34fb795d70941f929ed4c024dee11be9c99c712ea92225a20b" dependencies = [ - "ra_ap_intern 0.0.232", - "ra_ap_tt 0.0.232", + "ra_ap_intern", + "ra_ap_tt", "rustc-hash", ] -[[package]] -name = "ra_ap_hir" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b321e9c63fd434ac7b1617d6ddaed7329b8e21f6cae06ca05fec91c6361bb40d" -dependencies = [ - "arrayvec", - "either", - "itertools", - "once_cell", - "ra_ap_base_db 0.0.229", - "ra_ap_cfg 0.0.229", - "ra_ap_hir_def 0.0.229", - "ra_ap_hir_expand 0.0.229", - "ra_ap_hir_ty 0.0.229", - "ra_ap_intern 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_syntax 0.0.229", - "ra_ap_tt 0.0.229", - "rustc-hash", - "smallvec", - "tracing", - "triomphe", -] - [[package]] name = "ra_ap_hir" version = "0.0.232" @@ -1214,95 +1060,22 @@ dependencies = [ "arrayvec", "either", "itertools", - "ra_ap_base_db 0.0.232", - "ra_ap_cfg 0.0.232", - "ra_ap_hir_def 0.0.232", - "ra_ap_hir_expand 0.0.232", - "ra_ap_hir_ty 0.0.232", - "ra_ap_intern 0.0.232", - "ra_ap_span 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_syntax 0.0.232", - "ra_ap_tt 0.0.232", + "ra_ap_base_db", + "ra_ap_cfg", + "ra_ap_hir_def", + "ra_ap_hir_expand", + "ra_ap_hir_ty", + "ra_ap_intern", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_tt", "rustc-hash", "smallvec", "tracing", "triomphe", ] -[[package]] -name = "ra_ap_hir_def" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e2dd39d1162650dd6668f1e179d24aec336e3ff12aae9f0e50c10928d1158" -dependencies = [ - "arrayvec", - "bitflags 2.6.0", - "cov-mark", - "dashmap", - "drop_bomb", - "either", - "fst", - "hashbrown 0.14.5", - "indexmap 2.4.0", - "itertools", - "la-arena", - "once_cell", - "ra-ap-rustc_abi 0.53.0", - "ra-ap-rustc_parse_format 0.53.0", - "ra_ap_base_db 0.0.229", - "ra_ap_cfg 0.0.229", - "ra_ap_hir_expand 0.0.229", - "ra_ap_intern 0.0.229", - "ra_ap_limit 0.0.229", - "ra_ap_mbe 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_syntax 0.0.229", - "ra_ap_tt 0.0.229", - "rustc-hash", - "rustc_apfloat", - "smallvec", - "tracing", - "triomphe", -] - -[[package]] -name = "ra_ap_hir_def" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f1f7b81fc94e9753859e6f5525307e1bfe9e9149e1404bdd405fa8f3e7b509" -dependencies = [ - "arrayvec", - "bitflags 2.6.0", - "cov-mark", - "dashmap", - "drop_bomb", - "either", - "fst", - "hashbrown 0.14.5", - "indexmap 2.4.0", - "itertools", - "la-arena", - "ra-ap-rustc_abi 0.63.0", - "ra-ap-rustc_parse_format 0.63.0", - "ra_ap_base_db 0.0.231", - "ra_ap_cfg 0.0.231", - "ra_ap_hir_expand 0.0.231", - "ra_ap_intern 0.0.231", - "ra_ap_limit 0.0.231", - "ra_ap_mbe 0.0.231", - "ra_ap_span 0.0.231", - "ra_ap_stdx 0.0.231", - "ra_ap_syntax 0.0.231", - "ra_ap_tt 0.0.231", - "rustc-hash", - "rustc_apfloat", - "smallvec", - "tracing", - "triomphe", -] - [[package]] name = "ra_ap_hir_def" version = "0.0.232" @@ -1320,18 +1093,18 @@ dependencies = [ "indexmap 2.4.0", "itertools", "la-arena", - "ra-ap-rustc_abi 0.63.0", - "ra-ap-rustc_parse_format 0.63.0", - "ra_ap_base_db 0.0.232", - "ra_ap_cfg 0.0.232", - "ra_ap_hir_expand 0.0.232", - "ra_ap_intern 0.0.232", - "ra_ap_limit 0.0.232", - "ra_ap_mbe 0.0.232", - "ra_ap_span 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_syntax 0.0.232", - "ra_ap_tt 0.0.232", + "ra-ap-rustc_abi", + "ra-ap-rustc_parse_format", + "ra_ap_base_db", + "ra_ap_cfg", + "ra_ap_hir_expand", + "ra_ap_intern", + "ra_ap_limit", + "ra_ap_mbe", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_tt", "rustc-hash", "rustc_apfloat", "smallvec", @@ -1339,62 +1112,6 @@ dependencies = [ "triomphe", ] -[[package]] -name = "ra_ap_hir_expand" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e3c27bb239be9c6f835790f32d1a6e82345713c2ea63605d3270f06daf5caf" -dependencies = [ - "cov-mark", - "either", - "hashbrown 0.14.5", - "itertools", - "la-arena", - "ra_ap_base_db 0.0.229", - "ra_ap_cfg 0.0.229", - "ra_ap_intern 0.0.229", - "ra_ap_limit 0.0.229", - "ra_ap_mbe 0.0.229", - "ra_ap_parser 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_syntax 0.0.229", - "ra_ap_syntax-bridge 0.0.229", - "ra_ap_tt 0.0.229", - "rustc-hash", - "smallvec", - "tracing", - "triomphe", -] - -[[package]] -name = "ra_ap_hir_expand" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e10670696adf8b7c930f02d16326b397288ce0ef02676e41dd142817badc7b" -dependencies = [ - "cov-mark", - "either", - "hashbrown 0.14.5", - "itertools", - "la-arena", - "ra_ap_base_db 0.0.231", - "ra_ap_cfg 0.0.231", - "ra_ap_intern 0.0.231", - "ra_ap_limit 0.0.231", - "ra_ap_mbe 0.0.231", - "ra_ap_parser 0.0.231", - "ra_ap_span 0.0.231", - "ra_ap_stdx 0.0.231", - "ra_ap_syntax 0.0.231", - "ra_ap_syntax-bridge 0.0.231", - "ra_ap_tt 0.0.231", - "rustc-hash", - "smallvec", - "tracing", - "triomphe", -] - [[package]] name = "ra_ap_hir_expand" version = "0.0.232" @@ -1406,64 +1123,23 @@ dependencies = [ "hashbrown 0.14.5", "itertools", "la-arena", - "ra_ap_base_db 0.0.232", - "ra_ap_cfg 0.0.232", - "ra_ap_intern 0.0.232", - "ra_ap_limit 0.0.232", - "ra_ap_mbe 0.0.232", - "ra_ap_parser 0.0.232", - "ra_ap_span 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_syntax 0.0.232", - "ra_ap_syntax-bridge 0.0.232", - "ra_ap_tt 0.0.232", + "ra_ap_base_db", + "ra_ap_cfg", + "ra_ap_intern", + "ra_ap_limit", + "ra_ap_mbe", + "ra_ap_parser", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_syntax-bridge", + "ra_ap_tt", "rustc-hash", "smallvec", "tracing", "triomphe", ] -[[package]] -name = "ra_ap_hir_ty" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c437b9971d421dea75d72f137ccd49612cff401b9118da0d5b31c033ea0bcf3d" -dependencies = [ - "arrayvec", - "bitflags 2.6.0", - "chalk-derive", - "chalk-ir", - "chalk-recursive", - "chalk-solve", - "cov-mark", - "either", - "ena", - "indexmap 2.4.0", - "itertools", - "la-arena", - "nohash-hasher", - "once_cell", - "oorandom", - "ra-ap-rustc_abi 0.53.0", - "ra-ap-rustc_index 0.53.0", - "ra-ap-rustc_pattern_analysis 0.53.0", - "ra_ap_base_db 0.0.229", - "ra_ap_hir_def 0.0.229", - "ra_ap_hir_expand 0.0.229", - "ra_ap_intern 0.0.229", - "ra_ap_limit 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_syntax 0.0.229", - "rustc-hash", - "rustc_apfloat", - "scoped-tls", - "smallvec", - "tracing", - "triomphe", - "typed-arena", -] - [[package]] name = "ra_ap_hir_ty" version = "0.0.232" @@ -1484,17 +1160,17 @@ dependencies = [ "la-arena", "nohash-hasher", "oorandom", - "ra-ap-rustc_abi 0.63.0", - "ra-ap-rustc_index 0.63.0", - "ra-ap-rustc_pattern_analysis 0.63.0", - "ra_ap_base_db 0.0.232", - "ra_ap_hir_def 0.0.232", - "ra_ap_hir_expand 0.0.232", - "ra_ap_intern 0.0.232", - "ra_ap_limit 0.0.232", - "ra_ap_span 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_syntax 0.0.232", + "ra-ap-rustc_abi", + "ra-ap-rustc_index", + "ra-ap-rustc_pattern_analysis", + "ra_ap_base_db", + "ra_ap_hir_def", + "ra_ap_hir_expand", + "ra_ap_intern", + "ra_ap_limit", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", "rustc-hash", "rustc_apfloat", "scoped-tls", @@ -1504,39 +1180,6 @@ dependencies = [ "typed-arena", ] -[[package]] -name = "ra_ap_ide_db" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa72d28b51a29efd6416979b43976663708894cee98fb44cabaa222cb049417" -dependencies = [ - "arrayvec", - "bitflags 2.6.0", - "cov-mark", - "crossbeam-channel", - "either", - "fst", - "indexmap 2.4.0", - "itertools", - "line-index", - "memchr", - "nohash-hasher", - "once_cell", - "ra_ap_base_db 0.0.229", - "ra_ap_hir 0.0.229", - "ra_ap_limit 0.0.229", - "ra_ap_parser 0.0.229", - "ra_ap_profile 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_syntax 0.0.229", - "ra_ap_text_edit 0.0.229", - "rayon", - "rustc-hash", - "tracing", - "triomphe", -] - [[package]] name = "ra_ap_ide_db" version = "0.0.232" @@ -1554,47 +1197,21 @@ dependencies = [ "line-index", "memchr", "nohash-hasher", - "ra_ap_base_db 0.0.232", - "ra_ap_hir 0.0.232", - "ra_ap_limit 0.0.232", - "ra_ap_parser 0.0.232", - "ra_ap_profile 0.0.232", - "ra_ap_span 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_syntax 0.0.232", - "ra_ap_text_edit 0.0.232", + "ra_ap_base_db", + "ra_ap_hir", + "ra_ap_limit", + "ra_ap_parser", + "ra_ap_profile", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_text_edit", "rayon", "rustc-hash", "tracing", "triomphe", ] -[[package]] -name = "ra_ap_intern" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeec56dfe875fd865cc9afb7d0a0a6af832bf323b6db461844ba1de2fa7006b" -dependencies = [ - "dashmap", - "hashbrown 0.14.5", - "rustc-hash", - "sptr", - "triomphe", -] - -[[package]] -name = "ra_ap_intern" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3376767f47bb4f16cf14a54dad0fe4058d3baac6f9394662cd026a4b572e0a6a" -dependencies = [ - "dashmap", - "hashbrown 0.14.5", - "rustc-hash", - "sptr", - "triomphe", -] - [[package]] name = "ra_ap_intern" version = "0.0.232" @@ -1608,18 +1225,6 @@ dependencies = [ "triomphe", ] -[[package]] -name = "ra_ap_limit" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d33f2d8eda04460315de38992e3681dd799c27e712788a7aeee9909bc1c0f5" - -[[package]] -name = "ra_ap_limit" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20a0946a1510ddad977d54f2deab510e27d4e9a7406942152560312a9d14211" - [[package]] name = "ra_ap_limit" version = "0.0.232" @@ -1628,66 +1233,26 @@ checksum = "60972e02e4dfe05b2755e09a6b11b27db8a47cea01cd2697e77a34c4cf60b31c" [[package]] name = "ra_ap_load-cargo" -version = "0.0.229" +version = "0.0.232" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b7a4626cb8477733b02d836a7215db629249dd0076b2c9edcfe3f3a4e639f33" +checksum = "82e6f24b61f1ef1f3a756493d1fb7e711b69b2e4d5f4746fcb959313dfd41471" dependencies = [ "anyhow", "crossbeam-channel", "itertools", - "ra_ap_hir_expand 0.0.229", - "ra_ap_ide_db 0.0.229", - "ra_ap_intern 0.0.229", - "ra_ap_paths 0.0.229", + "ra_ap_hir_expand", + "ra_ap_ide_db", + "ra_ap_intern", + "ra_ap_paths", "ra_ap_proc_macro_api", "ra_ap_project_model", - "ra_ap_span 0.0.229", - "ra_ap_tt 0.0.229", - "ra_ap_vfs 0.0.229", + "ra_ap_span", + "ra_ap_tt", + "ra_ap_vfs", "ra_ap_vfs-notify", "tracing", ] -[[package]] -name = "ra_ap_mbe" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e45337e002d5c0efcba96769da0bd2d94c4e66e2d315f627fea7c877380141" -dependencies = [ - "arrayvec", - "cov-mark", - "ra_ap_intern 0.0.229", - "ra_ap_parser 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_syntax 0.0.229", - "ra_ap_syntax-bridge 0.0.229", - "ra_ap_tt 0.0.229", - "rustc-hash", - "smallvec", - "tracing", -] - -[[package]] -name = "ra_ap_mbe" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1b121f5ccf31043a05a45c713f230adec971a81eb391a003ffdf0122c4982bc" -dependencies = [ - "arrayvec", - "cov-mark", - "ra_ap_intern 0.0.231", - "ra_ap_parser 0.0.231", - "ra_ap_span 0.0.231", - "ra_ap_stdx 0.0.231", - "ra_ap_syntax 0.0.231", - "ra_ap_syntax-bridge 0.0.231", - "ra_ap_tt 0.0.231", - "rustc-hash", - "smallvec", - "tracing", -] - [[package]] name = "ra_ap_mbe" version = "0.0.232" @@ -1696,42 +1261,18 @@ checksum = "714a0997373ff65e7748e7768186598c6831e95f71639f66c3f79ef591c9d496" dependencies = [ "arrayvec", "cov-mark", - "ra_ap_intern 0.0.232", - "ra_ap_parser 0.0.232", - "ra_ap_span 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_syntax 0.0.232", - "ra_ap_syntax-bridge 0.0.232", - "ra_ap_tt 0.0.232", + "ra_ap_intern", + "ra_ap_parser", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_syntax-bridge", + "ra_ap_tt", "rustc-hash", "smallvec", "tracing", ] -[[package]] -name = "ra_ap_parser" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094cb41571e0c97501e1171f638bfdf4edb5f376d283b1ab04f3411aa3a44f51" -dependencies = [ - "drop_bomb", - "ra-ap-rustc_lexer 0.53.0", - "ra_ap_limit 0.0.229", - "tracing", -] - -[[package]] -name = "ra_ap_parser" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bba94511bed529739ab103ecf42248bb2a348f26c6a77365cc0f64e7995ff7" -dependencies = [ - "drop_bomb", - "ra-ap-rustc_lexer 0.63.0", - "ra_ap_limit 0.0.231", - "tracing", -] - [[package]] name = "ra_ap_parser" version = "0.0.232" @@ -1739,30 +1280,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da0314db93eabbd2b92e13907690782688cfc8aaaf42b8e6726e7f5b338c2e3" dependencies = [ "drop_bomb", - "ra-ap-rustc_lexer 0.63.0", - "ra_ap_limit 0.0.232", + "ra-ap-rustc_lexer", + "ra_ap_limit", "tracing", ] -[[package]] -name = "ra_ap_paths" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6602581f62922de09c93fdf3d6ddffa3f4fdcafba6c9dd08827951fb5ad511cc" -dependencies = [ - "camino", - "serde", -] - -[[package]] -name = "ra_ap_paths" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cf2e1472a025d3110ce176757ae60b550003ab492ed835abcc95964b2dd3ec8" -dependencies = [ - "camino", -] - [[package]] name = "ra_ap_paths" version = "0.0.232" @@ -1770,39 +1292,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cc084003225204a9e5e50957a565f1cc23ebef18cd779f31563a8d2180f8940" dependencies = [ "camino", + "serde", ] [[package]] name = "ra_ap_proc_macro_api" -version = "0.0.229" +version = "0.0.232" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2480058c6228d6ccdd6cfe1fa01c081f081ec6a6ea1a241b88618576ae6eff" +checksum = "809670622e93f105abc60ea0cb371cfaff990beae7ce534b127fb39b423b4b92" dependencies = [ "indexmap 2.4.0", - "ra_ap_base_db 0.0.229", - "ra_ap_intern 0.0.229", - "ra_ap_paths 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_tt 0.0.229", + "ra_ap_base_db", + "ra_ap_intern", + "ra_ap_paths", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_tt", "rustc-hash", "serde", "serde_json", "tracing", ] -[[package]] -name = "ra_ap_profile" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60263554aef637b9143a2d480a7fa93661297d795f7c46108386454a86885d49" -dependencies = [ - "cfg-if", - "libc", - "perf-event", - "windows-sys 0.52.0", -] - [[package]] name = "ra_ap_profile" version = "0.0.232" @@ -1817,20 +1328,20 @@ dependencies = [ [[package]] name = "ra_ap_project_model" -version = "0.0.229" +version = "0.0.232" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff3383dcd32a63b914c59f42f38e81ebfa5d5d921067ca0d1b01585aed1a4bd" +checksum = "db83d1844c74b22c110c4b8e8f2519be2b1723964008527281a11c3398749756" dependencies = [ "anyhow", "cargo_metadata", "itertools", "la-arena", - "ra_ap_base_db 0.0.229", - "ra_ap_cfg 0.0.229", - "ra_ap_intern 0.0.229", - "ra_ap_paths 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", + "ra_ap_base_db", + "ra_ap_cfg", + "ra_ap_intern", + "ra_ap_paths", + "ra_ap_span", + "ra_ap_stdx", "ra_ap_toolchain", "rustc-hash", "semver", @@ -1840,42 +1351,6 @@ dependencies = [ "triomphe", ] -[[package]] -name = "ra_ap_salsa" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f6e29648a086801b2bd047a88e9b73782c354fca9117d1208bebbfd6a849a61" -dependencies = [ - "indexmap 2.4.0", - "itertools", - "lock_api", - "oorandom", - "parking_lot", - "ra_ap_salsa-macros 0.0.229", - "rustc-hash", - "smallvec", - "tracing", - "triomphe", -] - -[[package]] -name = "ra_ap_salsa" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90a0c97538b300ac985999b68b797e9097f68069b91682029b98df15ffd005b5" -dependencies = [ - "indexmap 2.4.0", - "itertools", - "lock_api", - "oorandom", - "parking_lot", - "ra_ap_salsa-macros 0.0.231", - "rustc-hash", - "smallvec", - "tracing", - "triomphe", -] - [[package]] name = "ra_ap_salsa" version = "0.0.232" @@ -1887,37 +1362,13 @@ dependencies = [ "lock_api", "oorandom", "parking_lot", - "ra_ap_salsa-macros 0.0.232", + "ra_ap_salsa-macros", "rustc-hash", "smallvec", "tracing", "triomphe", ] -[[package]] -name = "ra_ap_salsa-macros" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d104209e089a63a1aa8f9a5f06c6350b1508d856fca4c25002f1d8e7c04a685b" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "ra_ap_salsa-macros" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79745f516e5963a928aa2bc87d273c39a9bc3661283fe42103987c6d0da66d89" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "ra_ap_salsa-macros" version = "0.0.232" @@ -1930,38 +1381,6 @@ dependencies = [ "syn", ] -[[package]] -name = "ra_ap_span" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d30beb9ac55357e4c56f8f8e5c84571ce204f10ba43b55640c51053e806e6b8" -dependencies = [ - "hashbrown 0.14.5", - "la-arena", - "ra_ap_salsa 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_syntax 0.0.229", - "ra_ap_vfs 0.0.229", - "rustc-hash", - "text-size", -] - -[[package]] -name = "ra_ap_span" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be5a26bfa587bd20da97371a406e4b2139c153dd7a4b6f1509e9a7d42dcbf22" -dependencies = [ - "hashbrown 0.14.5", - "la-arena", - "ra_ap_salsa 0.0.231", - "ra_ap_stdx 0.0.231", - "ra_ap_syntax 0.0.231", - "ra_ap_vfs 0.0.231", - "rustc-hash", - "text-size", -] - [[package]] name = "ra_ap_span" version = "0.0.232" @@ -1970,44 +1389,14 @@ checksum = "e1b982f799c7a8051219902ff5c1974ee353ac6ca2aa5b17ab0e3db9b8d8a7bf" dependencies = [ "hashbrown 0.14.5", "la-arena", - "ra_ap_salsa 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_syntax 0.0.232", - "ra_ap_vfs 0.0.232", + "ra_ap_salsa", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_vfs", "rustc-hash", "text-size", ] -[[package]] -name = "ra_ap_stdx" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51c29e7dfc7282ed14e91419d09b59e8dca27e7cc10c3cfcbf1964d7db0bef34" -dependencies = [ - "always-assert", - "crossbeam-channel", - "itertools", - "jod-thread", - "libc", - "miow", - "windows-sys 0.52.0", -] - -[[package]] -name = "ra_ap_stdx" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca9d3c7ff6fdc0ffd392ea4a33d7ec295eeab11943883c4c1089e006f4c760bb" -dependencies = [ - "always-assert", - "crossbeam-channel", - "itertools", - "jod-thread", - "libc", - "miow", - "windows-sys 0.52.0", -] - [[package]] name = "ra_ap_stdx" version = "0.0.232" @@ -2023,49 +1412,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "ra_ap_syntax" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575c1e3deb1cb39e0939a95a4cb4339ee95b1283157cf03bc1bdaf76e6ebca8d" -dependencies = [ - "cov-mark", - "either", - "indexmap 2.4.0", - "itertools", - "once_cell", - "ra-ap-rustc_lexer 0.53.0", - "ra_ap_parser 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_text_edit 0.0.229", - "rowan", - "rustc-hash", - "smol_str", - "tracing", - "triomphe", -] - -[[package]] -name = "ra_ap_syntax" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81403d6261c22d4407f25023c2140c04ae66fb27cb370afd096bc3d1dd9884ba" -dependencies = [ - "cov-mark", - "either", - "indexmap 2.4.0", - "itertools", - "ra-ap-rustc_lexer 0.63.0", - "ra_ap_parser 0.0.231", - "ra_ap_stdx 0.0.231", - "ra_ap_text_edit 0.0.231", - "rowan", - "rustc-hash", - "smol_str", - "tracing", - "triomphe", -] - [[package]] name = "ra_ap_syntax" version = "0.0.232" @@ -2076,10 +1422,10 @@ dependencies = [ "either", "indexmap 2.4.0", "itertools", - "ra-ap-rustc_lexer 0.63.0", - "ra_ap_parser 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_text_edit 0.0.232", + "ra-ap-rustc_lexer", + "ra_ap_parser", + "ra_ap_stdx", + "ra_ap_text_edit", "rowan", "rustc-hash", "smol_str", @@ -2087,74 +1433,22 @@ dependencies = [ "triomphe", ] -[[package]] -name = "ra_ap_syntax-bridge" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f19c53a1f9f50d76f50b7c0c83cda0fa5de09a182d8f4ae3575ea986a24fa234" -dependencies = [ - "ra_ap_intern 0.0.229", - "ra_ap_parser 0.0.229", - "ra_ap_span 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_syntax 0.0.229", - "ra_ap_tt 0.0.229", - "rustc-hash", - "tracing", -] - -[[package]] -name = "ra_ap_syntax-bridge" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2c55c65a50855847be853e3572381b53b5faf2527f954024d06e0f7c6898c26" -dependencies = [ - "ra_ap_intern 0.0.231", - "ra_ap_parser 0.0.231", - "ra_ap_span 0.0.231", - "ra_ap_stdx 0.0.231", - "ra_ap_syntax 0.0.231", - "ra_ap_tt 0.0.231", - "rustc-hash", - "tracing", -] - [[package]] name = "ra_ap_syntax-bridge" version = "0.0.232" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d57ec874cf6d45d25ce5d63dbfdf60912d5a33138855c4ab7e4314cfd01f6fa" dependencies = [ - "ra_ap_intern 0.0.232", - "ra_ap_parser 0.0.232", - "ra_ap_span 0.0.232", - "ra_ap_stdx 0.0.232", - "ra_ap_syntax 0.0.232", - "ra_ap_tt 0.0.232", + "ra_ap_intern", + "ra_ap_parser", + "ra_ap_span", + "ra_ap_stdx", + "ra_ap_syntax", + "ra_ap_tt", "rustc-hash", "tracing", ] -[[package]] -name = "ra_ap_text_edit" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b38bb92b8924b2267d84524f09cc31851f7f93741811e5374701ceb2be47d0b" -dependencies = [ - "itertools", - "text-size", -] - -[[package]] -name = "ra_ap_text_edit" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4916f05a8a78db53248a5ce0aa49167013d7dd7e7e59df82aaf284f5febd24f6" -dependencies = [ - "itertools", - "text-size", -] - [[package]] name = "ra_ap_text_edit" version = "0.0.232" @@ -2167,40 +1461,14 @@ dependencies = [ [[package]] name = "ra_ap_toolchain" -version = "0.0.229" +version = "0.0.232" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18076d6d6b2ef93a9d0396b06d58369231e50916456d2fa4488bc78c97ea6714" +checksum = "897200f5ab09335a77e9c8344fd8d5fd67f312c402179a378613421b4dec8d8f" dependencies = [ "camino", "home", ] -[[package]] -name = "ra_ap_tt" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "851bc23c870c67bd729e33056e001a2e07b16a31da13affe73d78e77049b12b8" -dependencies = [ - "arrayvec", - "ra-ap-rustc_lexer 0.53.0", - "ra_ap_intern 0.0.229", - "ra_ap_stdx 0.0.229", - "text-size", -] - -[[package]] -name = "ra_ap_tt" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7214288c8c784a5ac6db30d9043f9d20602354478228ae5b21dc773434ea75c" -dependencies = [ - "arrayvec", - "ra-ap-rustc_lexer 0.63.0", - "ra_ap_intern 0.0.231", - "ra_ap_stdx 0.0.231", - "text-size", -] - [[package]] name = "ra_ap_tt" version = "0.0.232" @@ -2208,43 +1476,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9730313c495e88a89ee33f6e34205a92652d9c9a5061ebaed59436058a33000" dependencies = [ "arrayvec", - "ra-ap-rustc_lexer 0.63.0", - "ra_ap_intern 0.0.232", - "ra_ap_stdx 0.0.232", + "ra-ap-rustc_lexer", + "ra_ap_intern", + "ra_ap_stdx", "text-size", ] -[[package]] -name = "ra_ap_vfs" -version = "0.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b152d631514508b7322cda383a454e2a56b0b5ecd8562a8f1e40aabe9fb236" -dependencies = [ - "fst", - "indexmap 2.4.0", - "nohash-hasher", - "ra_ap_paths 0.0.229", - "ra_ap_stdx 0.0.229", - "rustc-hash", - "tracing", -] - -[[package]] -name = "ra_ap_vfs" -version = "0.0.231" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "636c6c02fddbfe8af3cd47056794d9ad10fc2241381851e970f6319c21bc86fb" -dependencies = [ - "crossbeam-channel", - "fst", - "indexmap 2.4.0", - "nohash-hasher", - "ra_ap_paths 0.0.231", - "ra_ap_stdx 0.0.231", - "rustc-hash", - "tracing", -] - [[package]] name = "ra_ap_vfs" version = "0.0.232" @@ -2255,23 +1492,23 @@ dependencies = [ "fst", "indexmap 2.4.0", "nohash-hasher", - "ra_ap_paths 0.0.232", - "ra_ap_stdx 0.0.232", + "ra_ap_paths", + "ra_ap_stdx", "rustc-hash", "tracing", ] [[package]] name = "ra_ap_vfs-notify" -version = "0.0.229" +version = "0.0.232" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e516915fb4822a3d480404d35c20f240ae16a297ef52a68dc8cff748093f3abd" +checksum = "388ea8af458d6f06ed6b67c8e3dcf634a798cb3f4e62df51bd6be00c2b219bca" dependencies = [ "crossbeam-channel", "notify", - "ra_ap_paths 0.0.229", - "ra_ap_stdx 0.0.229", - "ra_ap_vfs 0.0.229", + "ra_ap_paths", + "ra_ap_stdx", + "ra_ap_vfs", "rayon", "rustc-hash", "tracing", @@ -2394,9 +1631,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ "itoa", "memchr", @@ -2488,9 +1725,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.74" +version = "2.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" dependencies = [ "proc-macro2", "quote", @@ -2648,15 +1885,15 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-properties" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" +checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" [[package]] name = "utf8parse" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d05e65ad881..716a506edc6 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -9,12 +9,15 @@ clap = { version = "4.5.16", features = ["derive"] } figment = { version = "0.10.19", features = ["env"]} log = "0.4.22" num-traits = "0.2.19" -ra_ap_base_db = "0.0.231" -ra_ap_hir = "0.0.229" -ra_ap_hir_def = "0.0.231" +ra_ap_base_db = "0.0.232" +ra_ap_hir = "0.0.232" +ra_ap_hir_def = "0.0.232" ra_ap_ide_db = "0.0.232" -ra_ap_load-cargo = "0.0.229" -ra_ap_project_model = "0.0.229" +ra_ap_load-cargo = "0.0.232" +ra_ap_project_model = "0.0.232" +ra_ap_syntax = "0.0.232" +ra_ap_vfs = "0.0.232" serde = "1.0.209" serde_with = "3.9.0" stderrlog = "0.6.0" +triomphe = "0.1.13" diff --git a/rust/codegen.conf b/rust/codegen.conf new file mode 100644 index 00000000000..df2f6270a9a --- /dev/null +++ b/rust/codegen.conf @@ -0,0 +1,9 @@ +# configuration file for Swift code generation default options +--generate=dbscheme,ql,rust +--dbscheme=ql/lib/rust.dbscheme +--ql-output=ql/lib/codeql/rust/generated +--ql-stub-output=ql/lib/codeql/rust/elements +--ql-test-output=ql/test/extractor-tests/generated +--rust-output=src/generated +--generated-registry=.generated.list +--script-name=codegen diff --git a/rust/codegen/BUILD.bazel b/rust/codegen/BUILD.bazel new file mode 100644 index 00000000000..82ac81abab0 --- /dev/null +++ b/rust/codegen/BUILD.bazel @@ -0,0 +1,15 @@ +load("@bazel_skylib//rules:native_binary.bzl", "native_binary") + +native_binary( + name = "codegen", + src = "//misc/codegen", + out = "codegen", + args = [ + "--configuration-file=$(location //rust:codegen.conf)", + ], + data = [ + "//rust:codegen.conf", + "//rust:schema.py", + ], + visibility = ["//rust:__subpackages__"], +) diff --git a/rust/codegen/README.md b/rust/codegen/README.md new file mode 100644 index 00000000000..66a811b5f41 --- /dev/null +++ b/rust/codegen/README.md @@ -0,0 +1,6 @@ +This package aliases [`misc/codegen`](../misc/codegen) providing the Rust-specific options +in [`rust/codegen.conf`](../codegen.conf). + +Running `bazel run //rust/codegen` will generate all checked in +files ([dbscheme](../ql/lib/swift.dbscheme), [QL generated code](../ql/lib/codeql/swift/generated), +[generated QL stubs](../ql/lib/codeql/swift/elements), [generated QL tests](../ql/test/extractor-tests/generated)). diff --git a/rust/prefix.dbscheme b/rust/prefix.dbscheme new file mode 100644 index 00000000000..b422464bb90 --- /dev/null +++ b/rust/prefix.dbscheme @@ -0,0 +1,6 @@ +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); diff --git a/rust/ql/lib/codeql/rust/elements.qll b/rust/ql/lib/codeql/rust/elements.qll new file mode 100644 index 00000000000..8752dbe0fb5 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements.qll @@ -0,0 +1,16 @@ +// generated by codegen +/** + * This module exports all modules providing `Element` subclasses. + */ + +import codeql.rust.elements.DbFile +import codeql.rust.elements.DbLocation +import codeql.rust.elements.Declaration +import codeql.rust.elements.Element +import codeql.rust.elements.File +import codeql.rust.elements.Function +import codeql.rust.elements.Locatable +import codeql.rust.elements.Location +import codeql.rust.elements.Module +import codeql.rust.elements.UnknownFile +import codeql.rust.elements.UnknownLocation diff --git a/rust/ql/lib/codeql/rust/elements/DbFile.qll b/rust/ql/lib/codeql/rust/elements/DbFile.qll new file mode 100644 index 00000000000..d1659d5206d --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/DbFile.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `DbFile`. + */ + +private import codeql.rust.generated.DbFile + +class DbFile extends Generated::DbFile { } diff --git a/rust/ql/lib/codeql/rust/elements/DbFileConstructor.qll b/rust/ql/lib/codeql/rust/elements/DbFileConstructor.qll new file mode 100644 index 00000000000..974a4f8ceef --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/DbFileConstructor.qll @@ -0,0 +1,14 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module defines the hook used internally to tweak the characteristic predicate of + * `DbFile` synthesized instances. + * INTERNAL: Do not use. + */ + +private import codeql.rust.generated.Raw + +/** + * The characteristic predicate of `DbFile` synthesized instances. + * INTERNAL: Do not use. + */ +predicate constructDbFile(Raw::DbFile id) { any() } diff --git a/rust/ql/lib/codeql/rust/elements/DbLocation.qll b/rust/ql/lib/codeql/rust/elements/DbLocation.qll new file mode 100644 index 00000000000..727e4e8790f --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/DbLocation.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `DbLocation`. + */ + +private import codeql.rust.generated.DbLocation + +class DbLocation extends Generated::DbLocation { } diff --git a/rust/ql/lib/codeql/rust/elements/DbLocationConstructor.qll b/rust/ql/lib/codeql/rust/elements/DbLocationConstructor.qll new file mode 100644 index 00000000000..af8518a06d2 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/DbLocationConstructor.qll @@ -0,0 +1,14 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module defines the hook used internally to tweak the characteristic predicate of + * `DbLocation` synthesized instances. + * INTERNAL: Do not use. + */ + +private import codeql.rust.generated.Raw + +/** + * The characteristic predicate of `DbLocation` synthesized instances. + * INTERNAL: Do not use. + */ +predicate constructDbLocation(Raw::DbLocation id) { any() } diff --git a/rust/ql/lib/codeql/rust/elements/Declaration.qll b/rust/ql/lib/codeql/rust/elements/Declaration.qll new file mode 100644 index 00000000000..b4e0971d591 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Declaration.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `Declaration`. + */ + +private import codeql.rust.generated.Declaration + +class Declaration extends Generated::Declaration { } diff --git a/rust/ql/lib/codeql/rust/elements/Element.qll b/rust/ql/lib/codeql/rust/elements/Element.qll new file mode 100644 index 00000000000..bfdfcad58ae --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Element.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `Element`. + */ + +private import codeql.rust.generated.Element + +class Element extends Generated::Element { } diff --git a/rust/ql/lib/codeql/rust/elements/File.qll b/rust/ql/lib/codeql/rust/elements/File.qll new file mode 100644 index 00000000000..eb7dd68c051 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/File.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `File`. + */ + +private import codeql.rust.generated.File + +class File extends Generated::File { } diff --git a/rust/ql/lib/codeql/rust/elements/Function.qll b/rust/ql/lib/codeql/rust/elements/Function.qll new file mode 100644 index 00000000000..0b6e85fccff --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Function.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `Function`. + */ + +private import codeql.rust.generated.Function + +class Function extends Generated::Function { } diff --git a/rust/ql/lib/codeql/rust/elements/FunctionConstructor.qll b/rust/ql/lib/codeql/rust/elements/FunctionConstructor.qll new file mode 100644 index 00000000000..706a72d58ab --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/FunctionConstructor.qll @@ -0,0 +1,14 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module defines the hook used internally to tweak the characteristic predicate of + * `Function` synthesized instances. + * INTERNAL: Do not use. + */ + +private import codeql.rust.generated.Raw + +/** + * The characteristic predicate of `Function` synthesized instances. + * INTERNAL: Do not use. + */ +predicate constructFunction(Raw::Function id) { any() } diff --git a/rust/ql/lib/codeql/rust/elements/Locatable.qll b/rust/ql/lib/codeql/rust/elements/Locatable.qll new file mode 100644 index 00000000000..ce2128d0ea6 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Locatable.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `Locatable`. + */ + +private import codeql.rust.generated.Locatable + +class Locatable extends Generated::Locatable { } diff --git a/rust/ql/lib/codeql/rust/elements/Location.qll b/rust/ql/lib/codeql/rust/elements/Location.qll new file mode 100644 index 00000000000..420e91a1c8d --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Location.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `Location`. + */ + +private import codeql.rust.generated.Location + +class Location extends Generated::Location { } diff --git a/rust/ql/lib/codeql/rust/elements/Module.qll b/rust/ql/lib/codeql/rust/elements/Module.qll new file mode 100644 index 00000000000..a001bb4edb8 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Module.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `Module`. + */ + +private import codeql.rust.generated.Module + +class Module extends Generated::Module { } diff --git a/rust/ql/lib/codeql/rust/elements/ModuleConstructor.qll b/rust/ql/lib/codeql/rust/elements/ModuleConstructor.qll new file mode 100644 index 00000000000..eb6258f95dc --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/ModuleConstructor.qll @@ -0,0 +1,14 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module defines the hook used internally to tweak the characteristic predicate of + * `Module` synthesized instances. + * INTERNAL: Do not use. + */ + +private import codeql.rust.generated.Raw + +/** + * The characteristic predicate of `Module` synthesized instances. + * INTERNAL: Do not use. + */ +predicate constructModule(Raw::Module id) { any() } diff --git a/rust/ql/lib/codeql/rust/elements/UnknownFile.qll b/rust/ql/lib/codeql/rust/elements/UnknownFile.qll new file mode 100644 index 00000000000..8378e9b21dd --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/UnknownFile.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `UnknownFile`. + */ + +private import codeql.rust.generated.UnknownFile + +class UnknownFile extends Generated::UnknownFile { } diff --git a/rust/ql/lib/codeql/rust/elements/UnknownLocation.qll b/rust/ql/lib/codeql/rust/elements/UnknownLocation.qll new file mode 100644 index 00000000000..64cc97dc9b6 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/UnknownLocation.qll @@ -0,0 +1,8 @@ +// generated by codegen, remove this comment if you wish to edit this file +/** + * This module provides a hand-modifiable wrapper around the generated class `UnknownLocation`. + */ + +private import codeql.rust.generated.UnknownLocation + +class UnknownLocation extends Generated::UnknownLocation { } diff --git a/rust/ql/lib/codeql/rust/generated/DbFile.qll b/rust/ql/lib/codeql/rust/generated/DbFile.qll new file mode 100644 index 00000000000..7128045152c --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/DbFile.qll @@ -0,0 +1,23 @@ +// generated by codegen +/** + * This module provides the generated definition of `DbFile`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.File + +/** + * INTERNAL: This module contains the fully generated definition of `DbFile` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::DbFile` class directly. + * Use the subclass `DbFile`, where the following predicates are available. + */ + class DbFile extends Synth::TDbFile, File { + override string getAPrimaryQlClass() { result = "DbFile" } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/DbLocation.qll b/rust/ql/lib/codeql/rust/generated/DbLocation.qll new file mode 100644 index 00000000000..a0944fa4b6d --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/DbLocation.qll @@ -0,0 +1,23 @@ +// generated by codegen +/** + * This module provides the generated definition of `DbLocation`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.Location + +/** + * INTERNAL: This module contains the fully generated definition of `DbLocation` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::DbLocation` class directly. + * Use the subclass `DbLocation`, where the following predicates are available. + */ + class DbLocation extends Synth::TDbLocation, Location { + override string getAPrimaryQlClass() { result = "DbLocation" } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/Declaration.qll b/rust/ql/lib/codeql/rust/generated/Declaration.qll new file mode 100644 index 00000000000..62e9f185387 --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/Declaration.qll @@ -0,0 +1,21 @@ +// generated by codegen +/** + * This module provides the generated definition of `Declaration`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.Locatable + +/** + * INTERNAL: This module contains the fully generated definition of `Declaration` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::Declaration` class directly. + * Use the subclass `Declaration`, where the following predicates are available. + */ + class Declaration extends Synth::TDeclaration, Locatable { } +} diff --git a/rust/ql/lib/codeql/rust/generated/Element.qll b/rust/ql/lib/codeql/rust/generated/Element.qll new file mode 100644 index 00000000000..19dbb9edb14 --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/Element.qll @@ -0,0 +1,57 @@ +// generated by codegen +/** + * This module provides the generated definition of `Element`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw + +/** + * INTERNAL: This module contains the fully generated definition of `Element` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::Element` class directly. + * Use the subclass `Element`, where the following predicates are available. + */ + class Element extends Synth::TElement { + /** + * Gets the string representation of this element. + */ + string toString() { none() } // overridden by subclasses + + /** + * Gets the name of a primary CodeQL class to which this element belongs. + * + * This is the most precise syntactic category to which they belong; for + * example, `CallExpr` is a primary class, but `ApplyExpr` is not. + * + * There might be some corner cases when this returns multiple classes, or none. + */ + string getAPrimaryQlClass() { none() } // overridden by subclasses + + /** + * Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs. + */ + final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") } + + /** + * Gets the most immediate element that should substitute this element in the explicit AST, if any. + * Classes can override this to indicate this node should be in the "hidden" AST, mostly reserved + * for conversions and syntactic sugar nodes like parentheses. + */ + Element getResolveStep() { none() } // overridden by subclasses + + /** + * Gets the element that should substitute this element in the explicit AST, applying `getResolveStep` + * transitively. + */ + final Element resolve() { + not exists(this.getResolveStep()) and result = this + or + result = this.getResolveStep().resolve() + } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/File.qll b/rust/ql/lib/codeql/rust/generated/File.qll new file mode 100644 index 00000000000..c5ebe20092c --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/File.qll @@ -0,0 +1,26 @@ +// generated by codegen +/** + * This module provides the generated definition of `File`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.Element + +/** + * INTERNAL: This module contains the fully generated definition of `File` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::File` class directly. + * Use the subclass `File`, where the following predicates are available. + */ + class File extends Synth::TFile, Element { + /** + * Gets the name of this file. + */ + string getName() { result = Synth::convertFileToRaw(this).(Raw::File).getName() } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/Function.qll b/rust/ql/lib/codeql/rust/generated/Function.qll new file mode 100644 index 00000000000..8eb15f35078 --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/Function.qll @@ -0,0 +1,28 @@ +// generated by codegen +/** + * This module provides the generated definition of `Function`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.Declaration + +/** + * INTERNAL: This module contains the fully generated definition of `Function` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::Function` class directly. + * Use the subclass `Function`, where the following predicates are available. + */ + class Function extends Synth::TFunction, Declaration { + override string getAPrimaryQlClass() { result = "Function" } + + /** + * Gets the name of this function. + */ + string getName() { result = Synth::convertFunctionToRaw(this).(Raw::Function).getName() } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/Locatable.qll b/rust/ql/lib/codeql/rust/generated/Locatable.qll new file mode 100644 index 00000000000..a0cdb9a007b --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/Locatable.qll @@ -0,0 +1,37 @@ +// generated by codegen +/** + * This module provides the generated definition of `Locatable`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.Element +import codeql.rust.elements.Location + +/** + * INTERNAL: This module contains the fully generated definition of `Locatable` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::Locatable` class directly. + * Use the subclass `Locatable`, where the following predicates are available. + */ + class Locatable extends Synth::TLocatable, Element { + /** + * Gets the location of this locatable, if it exists. + */ + Location getLocation() { + result = + Synth::convertLocationFromRaw(Synth::convertLocatableToRaw(this) + .(Raw::Locatable) + .getLocation()) + } + + /** + * Holds if `getLocation()` exists. + */ + final predicate hasLocation() { exists(this.getLocation()) } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/Location.qll b/rust/ql/lib/codeql/rust/generated/Location.qll new file mode 100644 index 00000000000..dac13d4a418 --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/Location.qll @@ -0,0 +1,52 @@ +// generated by codegen +/** + * This module provides the generated definition of `Location`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.Element +import codeql.rust.elements.File + +/** + * INTERNAL: This module contains the fully generated definition of `Location` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::Location` class directly. + * Use the subclass `Location`, where the following predicates are available. + */ + class Location extends Synth::TLocation, Element { + /** + * Gets the file of this location. + */ + File getFile() { + result = + Synth::convertFileFromRaw(Synth::convertLocationToRaw(this).(Raw::Location).getFile()) + } + + /** + * Gets the start line of this location. + */ + int getStartLine() { result = Synth::convertLocationToRaw(this).(Raw::Location).getStartLine() } + + /** + * Gets the start column of this location. + */ + int getStartColumn() { + result = Synth::convertLocationToRaw(this).(Raw::Location).getStartColumn() + } + + /** + * Gets the end line of this location. + */ + int getEndLine() { result = Synth::convertLocationToRaw(this).(Raw::Location).getEndLine() } + + /** + * Gets the end column of this location. + */ + int getEndColumn() { result = Synth::convertLocationToRaw(this).(Raw::Location).getEndColumn() } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/Module.qll b/rust/ql/lib/codeql/rust/generated/Module.qll new file mode 100644 index 00000000000..ae5100ee9d8 --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/Module.qll @@ -0,0 +1,43 @@ +// generated by codegen +/** + * This module provides the generated definition of `Module`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.Declaration + +/** + * INTERNAL: This module contains the fully generated definition of `Module` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::Module` class directly. + * Use the subclass `Module`, where the following predicates are available. + */ + class Module extends Synth::TModule, Declaration { + override string getAPrimaryQlClass() { result = "Module" } + + /** + * Gets the `index`th declaration of this module (0-based). + */ + Declaration getDeclaration(int index) { + result = + Synth::convertDeclarationFromRaw(Synth::convertModuleToRaw(this) + .(Raw::Module) + .getDeclaration(index)) + } + + /** + * Gets any of the declarations of this module. + */ + final Declaration getADeclaration() { result = this.getDeclaration(_) } + + /** + * Gets the number of declarations of this module. + */ + final int getNumberOfDeclarations() { result = count(int i | exists(this.getDeclaration(i))) } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/generated/ParentChild.qll new file mode 100644 index 00000000000..f45adf66642 --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/ParentChild.qll @@ -0,0 +1,203 @@ +// generated by codegen +/** + * This module provides the generated parent/child relationship. + */ + +import codeql.rust.elements + +private module Impl { + private Element getImmediateChildOfElement(Element e, int index, string partialPredicateCall) { + none() + } + + private Element getImmediateChildOfFile(File e, int index, string partialPredicateCall) { + exists(int b, int bElement, int n | + b = 0 and + bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and + n = bElement and + ( + none() + or + result = getImmediateChildOfElement(e, index - b, partialPredicateCall) + ) + ) + } + + private Element getImmediateChildOfLocatable(Locatable e, int index, string partialPredicateCall) { + exists(int b, int bElement, int n | + b = 0 and + bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and + n = bElement and + ( + none() + or + result = getImmediateChildOfElement(e, index - b, partialPredicateCall) + ) + ) + } + + private Element getImmediateChildOfLocation(Location e, int index, string partialPredicateCall) { + exists(int b, int bElement, int n | + b = 0 and + bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and + n = bElement and + ( + none() + or + result = getImmediateChildOfElement(e, index - b, partialPredicateCall) + ) + ) + } + + private Element getImmediateChildOfDbFile(DbFile e, int index, string partialPredicateCall) { + exists(int b, int bFile, int n | + b = 0 and + bFile = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfFile(e, i, _)) | i) and + n = bFile and + ( + none() + or + result = getImmediateChildOfFile(e, index - b, partialPredicateCall) + ) + ) + } + + private Element getImmediateChildOfDbLocation(DbLocation e, int index, string partialPredicateCall) { + exists(int b, int bLocation, int n | + b = 0 and + bLocation = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLocation(e, i, _)) | i) and + n = bLocation and + ( + none() + or + result = getImmediateChildOfLocation(e, index - b, partialPredicateCall) + ) + ) + } + + private Element getImmediateChildOfDeclaration( + Declaration e, int index, string partialPredicateCall + ) { + exists(int b, int bLocatable, int n | + b = 0 and + bLocatable = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLocatable(e, i, _)) | i) and + n = bLocatable and + ( + none() + or + result = getImmediateChildOfLocatable(e, index - b, partialPredicateCall) + ) + ) + } + + private Element getImmediateChildOfUnknownFile( + UnknownFile e, int index, string partialPredicateCall + ) { + exists(int b, int bFile, int n | + b = 0 and + bFile = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfFile(e, i, _)) | i) and + n = bFile and + ( + none() + or + result = getImmediateChildOfFile(e, index - b, partialPredicateCall) + ) + ) + } + + private Element getImmediateChildOfUnknownLocation( + UnknownLocation e, int index, string partialPredicateCall + ) { + exists(int b, int bLocation, int n | + b = 0 and + bLocation = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLocation(e, i, _)) | i) and + n = bLocation and + ( + none() + or + result = getImmediateChildOfLocation(e, index - b, partialPredicateCall) + ) + ) + } + + private Element getImmediateChildOfFunction(Function e, int index, string partialPredicateCall) { + exists(int b, int bDeclaration, int n | + b = 0 and + bDeclaration = + b + 1 + max(int i | i = -1 or exists(getImmediateChildOfDeclaration(e, i, _)) | i) and + n = bDeclaration and + ( + none() + or + result = getImmediateChildOfDeclaration(e, index - b, partialPredicateCall) + ) + ) + } + + private Element getImmediateChildOfModule(Module e, int index, string partialPredicateCall) { + exists(int b, int bDeclaration, int n, int nDeclaration | + b = 0 and + bDeclaration = + b + 1 + max(int i | i = -1 or exists(getImmediateChildOfDeclaration(e, i, _)) | i) and + n = bDeclaration and + nDeclaration = n + 1 + max(int i | i = -1 or exists(e.getDeclaration(i)) | i) and + ( + none() + or + result = getImmediateChildOfDeclaration(e, index - b, partialPredicateCall) + or + result = e.getDeclaration(index - n) and + partialPredicateCall = "Declaration(" + (index - n).toString() + ")" + ) + ) + } + + cached + Element getImmediateChild(Element e, int index, string partialAccessor) { + // why does this look more complicated than it should? + // * none() simplifies generation, as we can append `or ...` without a special case for the first item + none() + or + result = getImmediateChildOfDbFile(e, index, partialAccessor) + or + result = getImmediateChildOfDbLocation(e, index, partialAccessor) + or + result = getImmediateChildOfUnknownFile(e, index, partialAccessor) + or + result = getImmediateChildOfUnknownLocation(e, index, partialAccessor) + or + result = getImmediateChildOfFunction(e, index, partialAccessor) + or + result = getImmediateChildOfModule(e, index, partialAccessor) + } +} + +/** + * Gets the "immediate" parent of `e`. "Immediate" means not taking into account node resolution: for example + * if `e` has conversions, `getImmediateParent(e)` will give the innermost conversion in the hidden AST. + */ +Element getImmediateParent(Element e) { + // `unique` is used here to tell the optimizer that there is in fact only one result + // this is tested by the `library-tests/parent/no_double_parents.ql` test + result = unique(Element x | e = Impl::getImmediateChild(x, _, _) | x) +} + +/** + * Gets the immediate child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child. + */ +Element getImmediateChildAndAccessor(Element e, int index, string accessor) { + exists(string partialAccessor | + result = Impl::getImmediateChild(e, index, partialAccessor) and + accessor = "get" + partialAccessor + ) +} + +/** + * Gets the child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child. + */ +Element getChildAndAccessor(Element e, int index, string accessor) { + exists(string partialAccessor | + result = Impl::getImmediateChild(e, index, partialAccessor).resolve() and + accessor = "get" + partialAccessor + ) +} diff --git a/rust/ql/lib/codeql/rust/generated/PureSynthConstructors.qll b/rust/ql/lib/codeql/rust/generated/PureSynthConstructors.qll new file mode 100644 index 00000000000..db7165ee779 --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/PureSynthConstructors.qll @@ -0,0 +1,5 @@ +// generated by codegen +/** + * This module exports all modules providing `Element` subclasses. + */ + diff --git a/rust/ql/lib/codeql/rust/generated/Raw.qll b/rust/ql/lib/codeql/rust/generated/Raw.qll new file mode 100644 index 00000000000..7f7aaba7ae2 --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/Raw.qll @@ -0,0 +1,105 @@ +/** + * INTERNAL: Do not use. + * This module holds thin fully generated class definitions around DB entities. + */ +module Raw { + /** + * INTERNAL: Do not use. + */ + class Element extends @element { + string toString() { none() } + } + + /** + * INTERNAL: Do not use. + */ + class File extends @file, Element { + /** + * Gets the name of this file. + */ + string getName() { files(this, result) } + } + + /** + * INTERNAL: Do not use. + */ + class Locatable extends @locatable, Element { + /** + * Gets the location of this locatable, if it exists. + */ + Location getLocation() { locatable_locations(this, result) } + } + + /** + * INTERNAL: Do not use. + */ + class Location extends @location, Element { + /** + * Gets the file of this location. + */ + File getFile() { locations(this, result, _, _, _, _) } + + /** + * Gets the start line of this location. + */ + int getStartLine() { locations(this, _, result, _, _, _) } + + /** + * Gets the start column of this location. + */ + int getStartColumn() { locations(this, _, _, result, _, _) } + + /** + * Gets the end line of this location. + */ + int getEndLine() { locations(this, _, _, _, result, _) } + + /** + * Gets the end column of this location. + */ + int getEndColumn() { locations(this, _, _, _, _, result) } + } + + /** + * INTERNAL: Do not use. + */ + class DbFile extends @db_file, File { + override string toString() { result = "DbFile" } + } + + /** + * INTERNAL: Do not use. + */ + class DbLocation extends @db_location, Location { + override string toString() { result = "DbLocation" } + } + + /** + * INTERNAL: Do not use. + */ + class Declaration extends @declaration, Locatable { } + + /** + * INTERNAL: Do not use. + */ + class Function extends @function, Declaration { + override string toString() { result = "Function" } + + /** + * Gets the name of this function. + */ + string getName() { functions(this, result) } + } + + /** + * INTERNAL: Do not use. + */ + class Module extends @module, Declaration { + override string toString() { result = "Module" } + + /** + * Gets the `index`th declaration of this module (0-based). + */ + Declaration getDeclaration(int index) { module_declarations(this, index, result) } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/Synth.qll b/rust/ql/lib/codeql/rust/generated/Synth.qll new file mode 100644 index 00000000000..c9ab652304b --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/Synth.qll @@ -0,0 +1,252 @@ +/** + * INTERNAL: Do not use. + * This module defines the IPA layer on top of raw DB entities, and the conversions between the two + * layers. + */ + +private import codeql.rust.generated.SynthConstructors +private import codeql.rust.generated.Raw + +cached +module Synth { + /** + * INTERNAL: Do not use. + * The synthesized type of all elements. + */ + cached + newtype TElement = + /** + * INTERNAL: Do not use. + */ + TDbFile(Raw::DbFile id) { constructDbFile(id) } or + /** + * INTERNAL: Do not use. + */ + TDbLocation(Raw::DbLocation id) { constructDbLocation(id) } or + /** + * INTERNAL: Do not use. + */ + TFunction(Raw::Function id) { constructFunction(id) } or + /** + * INTERNAL: Do not use. + */ + TModule(Raw::Module id) { constructModule(id) } or + /** + * INTERNAL: Do not use. + */ + TUnknownFile() or + /** + * INTERNAL: Do not use. + */ + TUnknownLocation() + + /** + * INTERNAL: Do not use. + */ + class TDeclaration = TFunction or TModule; + + /** + * INTERNAL: Do not use. + */ + class TFile = TDbFile or TUnknownFile; + + /** + * INTERNAL: Do not use. + */ + class TLocatable = TDeclaration; + + /** + * INTERNAL: Do not use. + */ + class TLocation = TDbLocation or TUnknownLocation; + + /** + * INTERNAL: Do not use. + * Converts a raw element to a synthesized `TDbFile`, if possible. + */ + cached + TDbFile convertDbFileFromRaw(Raw::Element e) { result = TDbFile(e) } + + /** + * INTERNAL: Do not use. + * Converts a raw element to a synthesized `TDbLocation`, if possible. + */ + cached + TDbLocation convertDbLocationFromRaw(Raw::Element e) { result = TDbLocation(e) } + + /** + * INTERNAL: Do not use. + * Converts a raw element to a synthesized `TFunction`, if possible. + */ + cached + TFunction convertFunctionFromRaw(Raw::Element e) { result = TFunction(e) } + + /** + * INTERNAL: Do not use. + * Converts a raw element to a synthesized `TModule`, if possible. + */ + cached + TModule convertModuleFromRaw(Raw::Element e) { result = TModule(e) } + + /** + * INTERNAL: Do not use. + * Converts a raw element to a synthesized `TUnknownFile`, if possible. + */ + cached + TUnknownFile convertUnknownFileFromRaw(Raw::Element e) { none() } + + /** + * INTERNAL: Do not use. + * Converts a raw element to a synthesized `TUnknownLocation`, if possible. + */ + cached + TUnknownLocation convertUnknownLocationFromRaw(Raw::Element e) { none() } + + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `TDeclaration`, if possible. + */ + cached + TDeclaration convertDeclarationFromRaw(Raw::Element e) { + result = convertFunctionFromRaw(e) + or + result = convertModuleFromRaw(e) + } + + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `TElement`, if possible. + */ + cached + TElement convertElementFromRaw(Raw::Element e) { + result = convertFileFromRaw(e) + or + result = convertLocatableFromRaw(e) + or + result = convertLocationFromRaw(e) + } + + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `TFile`, if possible. + */ + cached + TFile convertFileFromRaw(Raw::Element e) { + result = convertDbFileFromRaw(e) + or + result = convertUnknownFileFromRaw(e) + } + + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `TLocatable`, if possible. + */ + cached + TLocatable convertLocatableFromRaw(Raw::Element e) { result = convertDeclarationFromRaw(e) } + + /** + * INTERNAL: Do not use. + * Converts a raw DB element to a synthesized `TLocation`, if possible. + */ + cached + TLocation convertLocationFromRaw(Raw::Element e) { + result = convertDbLocationFromRaw(e) + or + result = convertUnknownLocationFromRaw(e) + } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TDbFile` to a raw DB element, if possible. + */ + cached + Raw::Element convertDbFileToRaw(TDbFile e) { e = TDbFile(result) } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TDbLocation` to a raw DB element, if possible. + */ + cached + Raw::Element convertDbLocationToRaw(TDbLocation e) { e = TDbLocation(result) } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TFunction` to a raw DB element, if possible. + */ + cached + Raw::Element convertFunctionToRaw(TFunction e) { e = TFunction(result) } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TModule` to a raw DB element, if possible. + */ + cached + Raw::Element convertModuleToRaw(TModule e) { e = TModule(result) } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TUnknownFile` to a raw DB element, if possible. + */ + cached + Raw::Element convertUnknownFileToRaw(TUnknownFile e) { none() } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TUnknownLocation` to a raw DB element, if possible. + */ + cached + Raw::Element convertUnknownLocationToRaw(TUnknownLocation e) { none() } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TDeclaration` to a raw DB element, if possible. + */ + cached + Raw::Element convertDeclarationToRaw(TDeclaration e) { + result = convertFunctionToRaw(e) + or + result = convertModuleToRaw(e) + } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TElement` to a raw DB element, if possible. + */ + cached + Raw::Element convertElementToRaw(TElement e) { + result = convertFileToRaw(e) + or + result = convertLocatableToRaw(e) + or + result = convertLocationToRaw(e) + } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TFile` to a raw DB element, if possible. + */ + cached + Raw::Element convertFileToRaw(TFile e) { + result = convertDbFileToRaw(e) + or + result = convertUnknownFileToRaw(e) + } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TLocatable` to a raw DB element, if possible. + */ + cached + Raw::Element convertLocatableToRaw(TLocatable e) { result = convertDeclarationToRaw(e) } + + /** + * INTERNAL: Do not use. + * Converts a synthesized `TLocation` to a raw DB element, if possible. + */ + cached + Raw::Element convertLocationToRaw(TLocation e) { + result = convertDbLocationToRaw(e) + or + result = convertUnknownLocationToRaw(e) + } +} diff --git a/rust/ql/lib/codeql/rust/generated/SynthConstructors.qll b/rust/ql/lib/codeql/rust/generated/SynthConstructors.qll new file mode 100644 index 00000000000..4ca28a77c5f --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/SynthConstructors.qll @@ -0,0 +1,9 @@ +// generated by codegen +/** + * This module exports all modules providing `Element` subclasses. + */ + +import codeql.rust.elements.DbFileConstructor +import codeql.rust.elements.DbLocationConstructor +import codeql.rust.elements.FunctionConstructor +import codeql.rust.elements.ModuleConstructor diff --git a/rust/ql/lib/codeql/rust/generated/UnknownFile.qll b/rust/ql/lib/codeql/rust/generated/UnknownFile.qll new file mode 100644 index 00000000000..4b5ce7cc81e --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/UnknownFile.qll @@ -0,0 +1,23 @@ +// generated by codegen +/** + * This module provides the generated definition of `UnknownFile`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.File + +/** + * INTERNAL: This module contains the fully generated definition of `UnknownFile` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::UnknownFile` class directly. + * Use the subclass `UnknownFile`, where the following predicates are available. + */ + class UnknownFile extends Synth::TUnknownFile, File { + override string getAPrimaryQlClass() { result = "UnknownFile" } + } +} diff --git a/rust/ql/lib/codeql/rust/generated/UnknownLocation.qll b/rust/ql/lib/codeql/rust/generated/UnknownLocation.qll new file mode 100644 index 00000000000..5adaae87e7f --- /dev/null +++ b/rust/ql/lib/codeql/rust/generated/UnknownLocation.qll @@ -0,0 +1,23 @@ +// generated by codegen +/** + * This module provides the generated definition of `UnknownLocation`. + * INTERNAL: Do not import directly. + */ + +private import codeql.rust.generated.Synth +private import codeql.rust.generated.Raw +import codeql.rust.elements.Location + +/** + * INTERNAL: This module contains the fully generated definition of `UnknownLocation` and should not + * be referenced directly. + */ +module Generated { + /** + * INTERNAL: Do not reference the `Generated::UnknownLocation` class directly. + * Use the subclass `UnknownLocation`, where the following predicates are available. + */ + class UnknownLocation extends Synth::TUnknownLocation, Location { + override string getAPrimaryQlClass() { result = "UnknownLocation" } + } +} diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme new file mode 100644 index 00000000000..4ebc9480c4e --- /dev/null +++ b/rust/ql/lib/rust.dbscheme @@ -0,0 +1,81 @@ +// generated by codegen + +// from prefix.dbscheme +/** + * The source location of the snapshot. + */ +sourceLocationPrefix( + string prefix: string ref +); + + +// from schema.py + +@element = + @file +| @locatable +| @location +; + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +@locatable = + @declaration +; + +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location ref +); + +@location = + @db_location +; + +#keyset[id] +locations( + int id: @location ref, + int file: @file ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +db_files( + unique int id: @db_file +); + +db_locations( + unique int id: @db_location +); + +@declaration = + @function +| @module +; + +functions( + unique int id: @function, + string name: string ref +); + +modules( + unique int id: @module +); + +#keyset[id, index] +module_declarations( + int id: @module ref, + int index: int ref, + int declaration: @declaration ref +); diff --git a/rust/ql/test/extractor-tests/generated/File/MISSING_SOURCE.txt b/rust/ql/test/extractor-tests/generated/File/MISSING_SOURCE.txt new file mode 100644 index 00000000000..9cb54ddd059 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/File/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen + +After a source file is added in this directory and codegen is run again, test queries +will appear and this file will be deleted diff --git a/rust/ql/test/extractor-tests/generated/Function/MISSING_SOURCE.txt b/rust/ql/test/extractor-tests/generated/Function/MISSING_SOURCE.txt new file mode 100644 index 00000000000..9cb54ddd059 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Function/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen + +After a source file is added in this directory and codegen is run again, test queries +will appear and this file will be deleted diff --git a/rust/ql/test/extractor-tests/generated/Module/MISSING_SOURCE.txt b/rust/ql/test/extractor-tests/generated/Module/MISSING_SOURCE.txt new file mode 100644 index 00000000000..9cb54ddd059 --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/Module/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen + +After a source file is added in this directory and codegen is run again, test queries +will appear and this file will be deleted diff --git a/rust/schema.py b/rust/schema.py new file mode 100644 index 00000000000..ae05c0f9ac0 --- /dev/null +++ b/rust/schema.py @@ -0,0 +1,60 @@ +""" +Schema description + +This file should be kept simple: +* no flow control +* no aliases +* only class definitions with annotations and `include` calls + +For how documentation of generated QL code works, please read `misc/codegen/schema_documentation.md`. +""" + +from misc.codegen.lib.schemadefs import * + +include("prefix.dbscheme") + +@qltest.skip +class Element: + pass + + +@qltest.collapse_hierarchy +class File(Element): + name: string + +@qltest.skip +@qltest.collapse_hierarchy +class Location(Element): + file: File + start_line: int + start_column: int + end_line: int + end_column: int + +class DbFile(File): + pass + +class DbLocation(Location): + pass + +@synth.on_arguments() +class UnknownFile(File): + pass + +@synth.on_arguments() +class UnknownLocation(Location): + pass + +@qltest.skip +class Locatable(Element): + location: optional[Location] + +class Declaration(Locatable): + pass + +class Module(Declaration): + # TODO name + declarations: list[Declaration] | child + +class Function(Declaration): + name: string diff --git a/rust/src/archive.rs b/rust/src/archive.rs index 9f211d29fab..09847ac85d6 100644 --- a/rust/src/archive.rs +++ b/rust/src/archive.rs @@ -19,7 +19,9 @@ impl Archiver { let mut dest = self.root.clone(); dest.push(path::key(source)); let parent = dest.parent().unwrap(); - + if fs::exists(&dest)? { + return Ok(()) + } fs::create_dir_all(parent)?; fs::copy(source, dest)?; debug!("archived {}", source.display()); diff --git a/rust/src/generated/top.rs b/rust/src/generated/top.rs new file mode 100644 index 00000000000..d58970b23bc --- /dev/null +++ b/rust/src/generated/top.rs @@ -0,0 +1,87 @@ +// generated by codegen + +use crate::trap::{TrapLabel, TrapId, TrapEntry, quoted}; +use std::io::Write; + +#[derive(Debug)] +pub struct DbFile { + pub id: TrapId, + pub name: String, +} + +impl TrapEntry for DbFile { + fn extract_id(&mut self) -> TrapId { + std::mem::replace(&mut self.id, TrapId::Star) + } + + fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { + write!(out, "db_files({id}, {})\n", quoted(&self.name))?; + Ok(()) + } +} + +#[derive(Debug)] +pub struct DbLocation { + pub id: TrapId, + pub file: TrapLabel, + pub start_line: u32, + pub start_column: u32, + pub end_line: u32, + pub end_column: u32, +} + +impl TrapEntry for DbLocation { + fn extract_id(&mut self) -> TrapId { + std::mem::replace(&mut self.id, TrapId::Star) + } + + fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { + write!(out, "db_locations({id}, {}, {}, {}, {}, {})\n", self.file, self.start_line, self.start_column, self.end_line, self.end_column)?; + Ok(()) + } +} + +#[derive(Debug)] +pub struct Function { + pub id: TrapId, + pub location: Option, + pub name: String, +} + +impl TrapEntry for Function { + fn extract_id(&mut self) -> TrapId { + std::mem::replace(&mut self.id, TrapId::Star) + } + + fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { + write!(out, "functions({id}, {})\n", quoted(&self.name))?; + if let Some(ref v) = &self.location { + write!(out, "function_locations({id}, {})\n", v)?; + } + Ok(()) + } +} + +#[derive(Debug)] +pub struct Module { + pub id: TrapId, + pub location: Option, + pub declarations: Vec, +} + +impl TrapEntry for Module { + fn extract_id(&mut self) -> TrapId { + std::mem::replace(&mut self.id, TrapId::Star) + } + + fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { + write!(out, "modules({id})\n")?; + if let Some(ref v) = &self.location { + write!(out, "module_locations({id}, {})\n", v)?; + } + for (i, &ref v) in self.declarations.iter().enumerate() { + write!(out, "module_declarations({id}, {}, {})\n", i, v)?; + } + Ok(()) + } +} diff --git a/rust/src/main.rs b/rust/src/main.rs index b504cee2a81..016c948739b 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -1,19 +1,20 @@ #![feature(path_add_extension)] use std::fs; +use std::path::{PathBuf, Path}; use ra_ap_project_model::CargoConfig; use anyhow::Context; use log; use ra_ap_hir::db::DefDatabase; -use ra_ap_hir::{ModuleDefId}; +use ra_ap_hir::{Crate, ModuleDefId}; use ra_ap_hir::AdtId::{EnumId, UnionId, StructId}; use ra_ap_hir::sym::ge; use ra_ap_load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice}; - +use crate::trap::{TrapId}; mod config; pub mod trap; -mod generated; +pub mod generated; mod translate; mod archive; pub mod path; @@ -26,7 +27,7 @@ fn main() -> anyhow::Result<()> { .init()?; log::info!("{cfg:?}"); let traps = trap::TrapFileProvider::new(&cfg).context("failed to set up trap files")?; - let archiver = archive::Archiver{root: cfg.source_archive_dir}; + let archiver = archive::Archiver { root: cfg.source_archive_dir }; let config = CargoConfig { ..Default::default() }; let no_progress = |_| (); @@ -39,12 +40,26 @@ fn main() -> anyhow::Result<()> { let path = fs::canonicalize(input)?; { let mut trap = traps.create("input", &path)?; - let name= String::from(path.to_string_lossy()); - trap.emit(generated::DbFile{key: Some(name.clone()), name })?; + let name = String::from(path.to_string_lossy()); + trap.emit(generated::DbFile { id: name.clone().into(), name })?; archiver.archive(&path); } load_workspace_at(&path, &config, &load_config, &no_progress)?; - todo!() + let (db, vfs, _macro_server) = load_workspace_at(&path, &config, &load_config, &no_progress)?; + let crates = ::crate_graph(&db); + for crate_id in crates.iter().take(1) { + let krate = Crate::from(crate_id); + let name = krate.display_name(&db); + let crate_name = name.as_ref().map(|n| n.canonical_name().as_str()).unwrap_or(""); + let trap = traps.create("crates", &PathBuf::from(format!("/{}_{}", crate_name, crate_id.into_raw().into_u32())))?; + translate::CrateTranslator::new( + &db, + trap, + &krate, + &vfs, + &archiver, + ).emit_crate()?; + } } Ok(()) } diff --git a/rust/src/translate.rs b/rust/src/translate.rs index b944542116e..29c4488ddb0 100644 --- a/rust/src/translate.rs +++ b/rust/src/translate.rs @@ -1,35 +1,152 @@ -use crate::trap::TrapFile; -use ra_ap_hir::{ModuleDefId, db::{DefDatabase, ExpandDatabase}, AdtId::{EnumId, UnionId, StructId}}; -use ra_ap_ide_db::RootDatabase; +use std::collections::HashMap; +use std::fs; +use std::path::{PathBuf}; +use crate::trap::{KeyPart, TrapFile, TrapId, TrapLabel}; +use crate::{generated, trap_key}; +use ra_ap_hir::{Crate, Module, ModuleDef}; use anyhow; -use ra_ap_ide_db::base_db::Upcast; +use ra_ap_base_db::{CrateId}; +use ra_ap_hir::{HasSource}; +use ra_ap_vfs::{AbsPath, FileId, Vfs}; +use ra_ap_syntax::ast::HasName; +use crate::archive::Archiver; +use std::io::Result; +use triomphe::Arc; +use ra_ap_ide_db::{LineIndexDatabase, RootDatabase}; +use ra_ap_ide_db::line_index::LineIndex; +use ra_ap_syntax::AstNode; -struct Translator<'a> { - pub db: &'a dyn DefDatabase, - pub trap: TrapFile, +#[derive(Clone)] +struct FileData { + label: TrapLabel, + line_index: Arc, +} +pub struct CrateTranslator<'a> { + db: &'a RootDatabase, + trap: TrapFile, + krate: &'a Crate, + vfs: &'a Vfs, + archiver: &'a Archiver, + file_labels: HashMap, } -impl Translator<'_> { - pub fn emit_definition(&mut self, id: &ModuleDefId) -> anyhow::Result<()> { - match id { - ModuleDefId::FunctionId(id) => { - let function = self.db.function_data(*id); - let name = format!("{}", function.name.display(self.db.upcast())); - println!("function {name}"); + +impl CrateTranslator<'_> { + pub fn new<'a>( + db: &'a RootDatabase, + trap: TrapFile, + krate: &'a Crate, + vfs: &'a Vfs, + archiver: &'a Archiver, + ) -> CrateTranslator<'a> { + CrateTranslator { + db, + trap, + krate, + vfs, + archiver, + file_labels: HashMap::new(), + } + } + + fn emit_file(&mut self, file_id: FileId) -> Result> { + if let Some(abs_path) = self.vfs.file_path(file_id).as_path() { + let mut canonical = PathBuf::from(abs_path.as_str()); + if !self.file_labels.contains_key(&canonical) { + self.archiver.archive(&canonical); + canonical = fs::canonicalize(&canonical).unwrap_or(canonical); + let name = canonical.to_string_lossy(); + let label = self.trap.emit(generated::DbFile { id: trap_key!["DbFile@", name.as_ref()], name: String::from(name) })?; + let line_index = ::line_index(self.db, file_id); + self.file_labels.insert(canonical.clone(), FileData { label, line_index }); } - // ModuleDefId::AdtId(StructId(id)) => { - // let s = self.db.struct_data(*id); - // println!(" Struct: {:?}", s); - // } - // ModuleDefId::AdtId(EnumId(id)) => { - // let e = self.db.enum_data(*id); - // println!(" Enum: {:?}", e); - // } - // ModuleDefId::AdtId(UnionId(id)) => { - // let u = self.db.union_data(*id); - // println!(" Union: {:?}", u); - // } - _ => {} + Ok(self.file_labels.get(&canonical).cloned()) + } else { + Ok(None) + } + } + + fn emit_location(&mut self, entity: T) -> Result> where T::Ast: AstNode { + if let Some(source) = entity.source(self.db) { + if let Some(file_id) = source.file_id.file_id().map(|f| f.file_id()) { + if let Some(data) = self.emit_file(file_id)? { + let range = source.value.syntax().text_range(); + let start = data.line_index.line_col(range.start()); + let end = data.line_index.line_col(range.end()); + return Ok(Some(self.trap.emit(generated::DbLocation { + id: trap_key![data.label, format!(":{}:{}:{}:{}", start.line, start.col, end.line, end.col)], + file: data.label, + start_line: start.line, + start_column: start.col, + end_line: end.line, + end_column: end.col, + })?)); + } + } + } + Ok(None) + } + + fn emit_definition(&mut self, module_label: TrapLabel, id: ModuleDef, labels: &mut Vec) -> Result<()> { + match id { + ModuleDef::Module(_) => {} + ModuleDef::Function(function) => { + let name = function.name(self.db); + let location = self.emit_location(function)?; + labels.push(self.trap.emit(generated::Function { + id: trap_key![module_label, name.as_str()], + location, + name: name.as_str().into(), + })?); + } + ModuleDef::Adt(_) => {} + ModuleDef::Variant(_) => {} + ModuleDef::Const(_) => {} + ModuleDef::Static(_) => {} + ModuleDef::Trait(_) => {} + ModuleDef::TraitAlias(_) => {} + ModuleDef::TypeAlias(_) => {} + ModuleDef::BuiltinType(_) => {} + ModuleDef::Macro(_) => {} + } + Ok(()) + } + + fn emit_module(&mut self, label: TrapLabel, module: Module) -> Result<()> { + let mut children = Vec::new(); + for id in module.declarations(self.db) { + self.emit_definition(label, id, &mut children)?; + } + self.trap.emit(generated::Module { + id: label.into(), + location: None, + declarations: children, + })?; + Ok(()) + } + + pub fn emit_crate(&mut self) -> Result<()> { + self.emit_file(self.krate.root_file(self.db))?; + let mut map = HashMap::::new(); + for module in self.krate.modules(self.db) { + let mut key = Vec::::new(); + if let Some(parent) = module.parent(self.db) { + // assumption: parent was already listed + let parent_label = *map.get(&parent).unwrap(); + key.push(parent_label.into()); + } + let def = module.definition_source(self.db); + if let Some(file) = def.file_id.file_id() { + if let Some(data) = self.emit_file(file.file_id())? { + key.push(data.label.into()); + } + } + if let Some(name) = module.name(self.db) { + key.push(name.as_str().into()); + } + let label = self.trap.label(TrapId::Key(key))?; + map.insert(module, label); + self.emit_module(label, module)?; } Ok(()) } diff --git a/rust/src/trap.rs b/rust/src/trap.rs index ffd8097f13f..35d8aac244f 100644 --- a/rust/src/trap.rs +++ b/rust/src/trap.rs @@ -8,11 +8,74 @@ use crate::{config, path}; #[derive(Debug, Clone, Copy)] pub struct TrapLabel(u64); +impl Display for TrapLabel { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "#{:x}", self.0) + } +} + //TODO: typed labels -impl From for TrapLabel { - fn from(value: u64) -> Self { - TrapLabel(value) +#[derive(Debug, Clone)] +pub enum KeyPart { + Label(TrapLabel), + Text(String), +} + +impl From for KeyPart { + fn from(value: String) -> Self { + KeyPart::Text(value) + } +} + +impl From<&str> for KeyPart { + fn from(value: &str) -> Self { + KeyPart::Text(value.into()) + } +} + +impl From for KeyPart { + fn from(value: TrapLabel) -> Self { + KeyPart::Label(value) + } +} + +#[derive(Debug, Clone)] +pub enum TrapId { + Star, + Key(Vec), + Label(TrapLabel), +} + +impl> From for TrapId { + fn from(value: T) -> Self { + TrapId::Key(vec![value.into()]) + } +} + +#[macro_export] +macro_rules! trap_key { + ($($x:expr),+ $(,)?) => ( + $crate::trap::TrapId::Key(vec![$($x.into()),+]) + ); +} + +impl Display for TrapId { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + TrapId::Star => write!(f, "*"), + TrapId::Key(k) => { + f.write_str("@\"")?; + for p in k { + match p { + KeyPart::Label(l) => write!(f, "{{{l}}}")?, + KeyPart::Text(s) => f.write_str(&escaped(s))?, + } + } + f.write_str("\"") + } + TrapId::Label(l) => Display::fmt(&l, f) + } } } @@ -24,20 +87,10 @@ pub fn quoted(s: &str) -> String { format!("\"{}\"", escaped(s)) } -impl Display for TrapLabel { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "#{:x}", self.0) - } -} pub trait TrapEntry: std::fmt::Debug { - type Label: Display + From; - - fn prefix() -> &'static str { "" } - - fn key(&self) -> Option<&str>; - - fn emit(&self, id: &Self::Label, out: &mut W) -> std::io::Result<()>; + fn extract_id(&mut self) -> TrapId; + fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()>; } #[derive(Debug)] @@ -56,28 +109,27 @@ impl TrapFile { Ok(()) } - pub fn emit(&mut self, entry: T) -> std::io::Result { - let ret = match entry.key() { - None => self.create_star_label::()?, - Some(key) => self.create_key_label::(key)?, - }; + pub fn label(&mut self, id: TrapId) -> std::io::Result { + if let TrapId::Label(l) = id { + return Ok(l); + } + let ret = self.create_label(); + trace!("emit -> {}: {ret:?} = {id:?}", self.trap_name); + write!(self.file, "{ret}={id}\n")?; + Ok(ret) + } + + pub fn emit(&mut self, mut entry: T) -> std::io::Result { trace!("emit -> {}: {entry:?}", self.trap_name); - entry.emit(&ret, &mut self.file)?; - Ok(ret) + let id = self.label(entry.extract_id())?; + entry.emit(id, &mut self.file)?; + Ok(id) } - fn create_star_label(&mut self) -> std::io::Result { - let ret = T::Label::from(self.label_index); - write!(self.file, "{ret}=*\n")?; + fn create_label(&mut self) -> TrapLabel { + let ret = TrapLabel(self.label_index); self.label_index += 1; - Ok(ret) - } - - fn create_key_label(&mut self, key: &str) -> std::io::Result { - let ret = T::Label::from(self.label_index); - write!(self.file, "{ret}=@\"{}{}\"\n", T::prefix(), escaped(key))?; - self.label_index += 1; - Ok(ret) + ret } } From 092ce01d939cdaffec4f0a947e4034adb76bf8f0 Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Thu, 29 Aug 2024 19:06:56 +0200 Subject: [PATCH 158/404] C#: Rename integration test directories. We are no longer bound to the platform-specific directories, so simplify the test organization. If you don't want this change, just skip merging this PR. It's purely optional. This is not very invasive for C#, I'm just dropping the `only` suffix. You could also merge all the platform-specific test dirs, or all test dirs into the top-level directory. I'll leave that up to you. --- .../{linux-only => linux}/compiler_args/CompilerArgs.expected | 0 .../{linux-only => linux}/compiler_args/CompilerArgs.ql | 0 .../{linux-only => linux}/compiler_args/Program.cs | 0 .../{linux-only => linux}/compiler_args/global.json | 0 .../{linux-only => linux}/compiler_args/test.csproj | 0 .../integration-tests/{linux-only => linux}/compiler_args/test.py | 0 .../standalone_dependencies_non_utf8_filename/Program.cs | 0 .../standalone_dependencies_non_utf8_filename/global.json | 0 .../standalone_dependencies_non_utf8_filename/test.csproj | 0 .../standalone_dependencies_non_utf8_filename/test.py | 0 .../{posix-only => posix}/diag_autobuild_script/build.sh | 0 .../diag_autobuild_script/diagnostics.expected | 0 .../{posix-only => posix}/diag_autobuild_script/test.py | 0 .../{posix-only => posix}/diag_multiple_scripts/build.sh | 0 .../diag_multiple_scripts/diagnostics.expected | 0 .../{posix-only => posix}/diag_multiple_scripts/scripts/build.sh | 0 .../{posix-only => posix}/diag_multiple_scripts/test.py | 0 .../{posix-only => posix}/dotnet_test/UnitTest1.cs | 0 .../{posix-only => posix}/dotnet_test/diagnostics.expected | 0 .../{posix-only => posix}/dotnet_test/dotnet_test.csproj | 0 .../{posix-only => posix}/dotnet_test/global.json | 0 .../integration-tests/{posix-only => posix}/dotnet_test/test.py | 0 .../{posix-only => posix}/dotnet_test_mstest/UnitTest1.cs | 0 .../{posix-only => posix}/dotnet_test_mstest/Usings.cs | 0 .../{posix-only => posix}/dotnet_test_mstest/diagnostics.expected | 0 .../dotnet_test_mstest/dotnet_test_mstest.csproj | 0 .../{posix-only => posix}/dotnet_test_mstest/global.json | 0 .../{posix-only => posix}/dotnet_test_mstest/test.py | 0 .../{posix-only => posix}/inherit-env-vars/Program.cs | 0 .../{posix-only => posix}/inherit-env-vars/build.sh | 0 .../{posix-only => posix}/inherit-env-vars/diagnostics.expected | 0 .../{posix-only => posix}/inherit-env-vars/global.json | 0 .../{posix-only => posix}/inherit-env-vars/proj.csproj.no_auto | 0 .../{posix-only => posix}/inherit-env-vars/test.py | 0 .../standalone_dependencies/Assemblies.expected | 0 .../{posix-only => posix}/standalone_dependencies/Assemblies.ql | 0 .../{posix-only => posix}/standalone_dependencies/Program.cs | 0 .../{posix-only => posix}/standalone_dependencies/global.json | 0 .../standalone_dependencies/standalone.csproj | 0 .../{posix-only => posix}/standalone_dependencies/test.py | 0 .../standalone_dependencies_executing_runtime/Assemblies.expected | 0 .../standalone_dependencies_executing_runtime/Assemblies.ql | 0 .../standalone_dependencies_executing_runtime/Program.cs | 0 .../standalone_dependencies_executing_runtime/test.py | 0 .../standalone_dependencies_multi_project/Assemblies.expected | 0 .../standalone_dependencies_multi_project/Assemblies.ql | 0 .../standalone_dependencies_multi_project/Program.cs | 0 .../standalone_dependencies_multi_project/global.json | 0 .../standalone_dependencies_multi_project/standalone1.csproj | 0 .../standalone_dependencies_multi_project/standalone2.csproj | 0 .../standalone_dependencies_multi_project/test.py | 0 .../standalone_dependencies_multi_target/Assemblies.expected | 0 .../standalone_dependencies_multi_target/Assemblies.ql | 0 .../standalone_dependencies_multi_target/Program.cs | 0 .../standalone_dependencies_multi_target/global.json | 0 .../standalone_dependencies_multi_target/net48.csproj | 0 .../standalone_dependencies_multi_target/net70.csproj | 0 .../standalone_dependencies_multi_target/test.py | 0 .../standalone_dependencies_no_framework/Assemblies.expected | 0 .../standalone_dependencies_no_framework/Assemblies.ql | 0 .../standalone_dependencies_no_framework/Program.cs | 0 .../standalone_dependencies_no_framework/global.json | 0 .../standalone_dependencies_no_framework/packages.config | 0 .../standalone_dependencies_no_framework/test.py | 0 .../standalone_dependencies_no_framework/test_old.csproj | 0 .../standalone_dependencies_no_framework/test_sdk.csproj | 0 .../standalone_dependencies_nuget with_space/Assemblies.expected | 0 .../standalone_dependencies_nuget with_space/Assemblies.ql | 0 .../standalone_dependencies_nuget with_space/Program.cs | 0 .../standalone_dependencies_nuget with_space/global.json | 0 .../standalone_dependencies_nuget with_space/packages.config | 0 .../standalone_dependencies_nuget with_space/test.csproj | 0 .../standalone_dependencies_nuget with_space/test.py | 0 .../standalone_dependencies_nuget/Assemblies.expected | 0 .../standalone_dependencies_nuget/Assemblies.ql | 0 .../standalone_dependencies_nuget/Program.cs | 0 .../standalone_dependencies_nuget/global.json | 0 .../standalone_dependencies_nuget/packages.config | 0 .../standalone_dependencies_nuget/test.csproj | 0 .../{posix-only => posix}/standalone_dependencies_nuget/test.py | 0 .../Assemblies.expected | 0 .../standalone_dependencies_nuget_config_error/Assemblies.ql | 0 .../CompilationInfo.expected | 0 .../standalone_dependencies_nuget_config_error/CompilationInfo.ql | 0 .../standalone_dependencies_nuget_config_error/proj/Program.cs | 0 .../standalone_dependencies_nuget_config_error/proj/nuget.config | 0 .../standalone_dependencies_nuget_config_error/proj/proj.csproj | 0 .../standalone_dependencies_nuget_config_error/standalone.sln | 0 .../standalone_dependencies_nuget_config_error/test.py | 0 .../Assemblies.expected | 0 .../Assemblies.ql | 0 .../CompilationInfo.expected | 0 .../CompilationInfo.ql | 0 .../diagnostics.expected | 0 .../proj/Program.cs | 0 .../proj/nuget.config | 0 .../proj/proj.csproj | 0 .../standalone.sln | 0 .../standalone_dependencies_nuget_config_error_timeout/test.py | 0 .../Assemblies.expected | 0 .../standalone_dependencies_nuget_config_fallback/Assemblies.ql | 0 .../CompilationInfo.expected | 0 .../CompilationInfo.ql | 0 .../diagnostics.expected | 0 .../standalone_dependencies_nuget_config_fallback/proj/Program.cs | 0 .../proj/nuget.config | 0 .../proj/proj.csproj | 0 .../standalone_dependencies_nuget_config_fallback/standalone.sln | 0 .../standalone_dependencies_nuget_config_fallback/test.py | 0 .../standalone_dependencies_nuget_no_sources/Assemblies.expected | 0 .../standalone_dependencies_nuget_no_sources/Assemblies.ql | 0 .../standalone_dependencies_nuget_no_sources/nuget.config | 0 .../standalone_dependencies_nuget_no_sources/proj/Program.cs | 0 .../standalone_dependencies_nuget_no_sources/proj/global.json | 0 .../standalone_dependencies_nuget_no_sources/proj/packages.config | 0 .../standalone_dependencies_nuget_no_sources/proj/test.csproj | 0 .../standalone_dependencies_nuget_no_sources/test.py | 0 .../standalone_dependencies_nuget_versions/Assemblies.expected | 0 .../standalone_dependencies_nuget_versions/Assemblies.ql | 0 .../standalone_dependencies_nuget_versions/Program.cs | 0 .../standalone_dependencies_nuget_versions/d1/test1.csproj | 0 .../standalone_dependencies_nuget_versions/d2/test2.csproj | 0 .../standalone_dependencies_nuget_versions/global.json | 0 .../standalone_dependencies_nuget_versions/test.py | 0 .../{posix-only => posix}/warn_as_error/Errors.expected | 0 .../{posix-only => posix}/warn_as_error/Errors.ql | 0 .../{posix-only => posix}/warn_as_error/Program.cs | 0 .../{posix-only => posix}/warn_as_error/WarnAsError.csproj | 0 .../{posix-only => posix}/warn_as_error/build.sh | 0 .../{posix-only => posix}/warn_as_error/global.json | 0 .../integration-tests/{posix-only => posix}/warn_as_error/test.py | 0 .../{windows-only => windows}/diag_autobuild_script/build.bat | 0 .../diag_autobuild_script/diagnostics.expected | 0 .../{windows-only => windows}/diag_autobuild_script/test.py | 0 .../{windows-only => windows}/diag_multiple_scripts/build.bat | 0 .../diag_multiple_scripts/diagnostics.expected | 0 .../diag_multiple_scripts/scripts/build.bat | 0 .../{windows-only => windows}/diag_multiple_scripts/test.py | 0 .../standalone_dependencies/Assemblies.expected | 0 .../standalone_dependencies/Assemblies.ql | 0 .../{windows-only => windows}/standalone_dependencies/Program.cs | 0 .../{windows-only => windows}/standalone_dependencies/global.json | 0 .../standalone_dependencies/standalone.csproj | 0 .../{windows-only => windows}/standalone_dependencies/test.py | 0 144 files changed, 0 insertions(+), 0 deletions(-) rename csharp/ql/integration-tests/{linux-only => linux}/compiler_args/CompilerArgs.expected (100%) rename csharp/ql/integration-tests/{linux-only => linux}/compiler_args/CompilerArgs.ql (100%) rename csharp/ql/integration-tests/{linux-only => linux}/compiler_args/Program.cs (100%) rename csharp/ql/integration-tests/{linux-only => linux}/compiler_args/global.json (100%) rename csharp/ql/integration-tests/{linux-only => linux}/compiler_args/test.csproj (100%) rename csharp/ql/integration-tests/{linux-only => linux}/compiler_args/test.py (100%) rename csharp/ql/integration-tests/{linux-only => linux}/standalone_dependencies_non_utf8_filename/Program.cs (100%) rename csharp/ql/integration-tests/{linux-only => linux}/standalone_dependencies_non_utf8_filename/global.json (100%) rename csharp/ql/integration-tests/{linux-only => linux}/standalone_dependencies_non_utf8_filename/test.csproj (100%) rename csharp/ql/integration-tests/{linux-only => linux}/standalone_dependencies_non_utf8_filename/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/diag_autobuild_script/build.sh (100%) rename csharp/ql/integration-tests/{posix-only => posix}/diag_autobuild_script/diagnostics.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/diag_autobuild_script/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/diag_multiple_scripts/build.sh (100%) rename csharp/ql/integration-tests/{posix-only => posix}/diag_multiple_scripts/diagnostics.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/diag_multiple_scripts/scripts/build.sh (100%) rename csharp/ql/integration-tests/{posix-only => posix}/diag_multiple_scripts/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test/UnitTest1.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test/diagnostics.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test/dotnet_test.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test_mstest/UnitTest1.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test_mstest/Usings.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test_mstest/diagnostics.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test_mstest/dotnet_test_mstest.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test_mstest/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/dotnet_test_mstest/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/inherit-env-vars/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/inherit-env-vars/build.sh (100%) rename csharp/ql/integration-tests/{posix-only => posix}/inherit-env-vars/diagnostics.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/inherit-env-vars/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/inherit-env-vars/proj.csproj.no_auto (100%) rename csharp/ql/integration-tests/{posix-only => posix}/inherit-env-vars/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies/standalone.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_executing_runtime/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_executing_runtime/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_executing_runtime/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_executing_runtime/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_project/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_project/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_project/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_project/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_project/standalone1.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_project/standalone2.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_project/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_target/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_target/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_target/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_target/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_target/net48.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_target/net70.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_multi_target/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_no_framework/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_no_framework/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_no_framework/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_no_framework/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_no_framework/packages.config (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_no_framework/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_no_framework/test_old.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_no_framework/test_sdk.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget with_space/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget with_space/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget with_space/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget with_space/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget with_space/packages.config (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget with_space/test.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget with_space/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget/packages.config (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget/test.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error/CompilationInfo.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error/CompilationInfo.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error/proj/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error/proj/nuget.config (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error/proj/proj.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error/standalone.sln (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/diagnostics.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/proj/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/proj/nuget.config (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/proj/proj.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/standalone.sln (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_error_timeout/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/CompilationInfo.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/diagnostics.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/proj/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/proj/nuget.config (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/proj/proj.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/standalone.sln (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_config_fallback/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_no_sources/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_no_sources/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_no_sources/nuget.config (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_no_sources/proj/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_no_sources/proj/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_no_sources/proj/packages.config (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_no_sources/proj/test.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_no_sources/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_versions/Assemblies.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_versions/Assemblies.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_versions/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_versions/d1/test1.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_versions/d2/test2.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_versions/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/standalone_dependencies_nuget_versions/test.py (100%) rename csharp/ql/integration-tests/{posix-only => posix}/warn_as_error/Errors.expected (100%) rename csharp/ql/integration-tests/{posix-only => posix}/warn_as_error/Errors.ql (100%) rename csharp/ql/integration-tests/{posix-only => posix}/warn_as_error/Program.cs (100%) rename csharp/ql/integration-tests/{posix-only => posix}/warn_as_error/WarnAsError.csproj (100%) rename csharp/ql/integration-tests/{posix-only => posix}/warn_as_error/build.sh (100%) rename csharp/ql/integration-tests/{posix-only => posix}/warn_as_error/global.json (100%) rename csharp/ql/integration-tests/{posix-only => posix}/warn_as_error/test.py (100%) rename csharp/ql/integration-tests/{windows-only => windows}/diag_autobuild_script/build.bat (100%) rename csharp/ql/integration-tests/{windows-only => windows}/diag_autobuild_script/diagnostics.expected (100%) rename csharp/ql/integration-tests/{windows-only => windows}/diag_autobuild_script/test.py (100%) rename csharp/ql/integration-tests/{windows-only => windows}/diag_multiple_scripts/build.bat (100%) rename csharp/ql/integration-tests/{windows-only => windows}/diag_multiple_scripts/diagnostics.expected (100%) rename csharp/ql/integration-tests/{windows-only => windows}/diag_multiple_scripts/scripts/build.bat (100%) rename csharp/ql/integration-tests/{windows-only => windows}/diag_multiple_scripts/test.py (100%) rename csharp/ql/integration-tests/{windows-only => windows}/standalone_dependencies/Assemblies.expected (100%) rename csharp/ql/integration-tests/{windows-only => windows}/standalone_dependencies/Assemblies.ql (100%) rename csharp/ql/integration-tests/{windows-only => windows}/standalone_dependencies/Program.cs (100%) rename csharp/ql/integration-tests/{windows-only => windows}/standalone_dependencies/global.json (100%) rename csharp/ql/integration-tests/{windows-only => windows}/standalone_dependencies/standalone.csproj (100%) rename csharp/ql/integration-tests/{windows-only => windows}/standalone_dependencies/test.py (100%) diff --git a/csharp/ql/integration-tests/linux-only/compiler_args/CompilerArgs.expected b/csharp/ql/integration-tests/linux/compiler_args/CompilerArgs.expected similarity index 100% rename from csharp/ql/integration-tests/linux-only/compiler_args/CompilerArgs.expected rename to csharp/ql/integration-tests/linux/compiler_args/CompilerArgs.expected diff --git a/csharp/ql/integration-tests/linux-only/compiler_args/CompilerArgs.ql b/csharp/ql/integration-tests/linux/compiler_args/CompilerArgs.ql similarity index 100% rename from csharp/ql/integration-tests/linux-only/compiler_args/CompilerArgs.ql rename to csharp/ql/integration-tests/linux/compiler_args/CompilerArgs.ql diff --git a/csharp/ql/integration-tests/linux-only/compiler_args/Program.cs b/csharp/ql/integration-tests/linux/compiler_args/Program.cs similarity index 100% rename from csharp/ql/integration-tests/linux-only/compiler_args/Program.cs rename to csharp/ql/integration-tests/linux/compiler_args/Program.cs diff --git a/csharp/ql/integration-tests/linux-only/compiler_args/global.json b/csharp/ql/integration-tests/linux/compiler_args/global.json similarity index 100% rename from csharp/ql/integration-tests/linux-only/compiler_args/global.json rename to csharp/ql/integration-tests/linux/compiler_args/global.json diff --git a/csharp/ql/integration-tests/linux-only/compiler_args/test.csproj b/csharp/ql/integration-tests/linux/compiler_args/test.csproj similarity index 100% rename from csharp/ql/integration-tests/linux-only/compiler_args/test.csproj rename to csharp/ql/integration-tests/linux/compiler_args/test.csproj diff --git a/csharp/ql/integration-tests/linux-only/compiler_args/test.py b/csharp/ql/integration-tests/linux/compiler_args/test.py similarity index 100% rename from csharp/ql/integration-tests/linux-only/compiler_args/test.py rename to csharp/ql/integration-tests/linux/compiler_args/test.py diff --git a/csharp/ql/integration-tests/linux-only/standalone_dependencies_non_utf8_filename/Program.cs b/csharp/ql/integration-tests/linux/standalone_dependencies_non_utf8_filename/Program.cs similarity index 100% rename from csharp/ql/integration-tests/linux-only/standalone_dependencies_non_utf8_filename/Program.cs rename to csharp/ql/integration-tests/linux/standalone_dependencies_non_utf8_filename/Program.cs diff --git a/csharp/ql/integration-tests/linux-only/standalone_dependencies_non_utf8_filename/global.json b/csharp/ql/integration-tests/linux/standalone_dependencies_non_utf8_filename/global.json similarity index 100% rename from csharp/ql/integration-tests/linux-only/standalone_dependencies_non_utf8_filename/global.json rename to csharp/ql/integration-tests/linux/standalone_dependencies_non_utf8_filename/global.json diff --git a/csharp/ql/integration-tests/linux-only/standalone_dependencies_non_utf8_filename/test.csproj b/csharp/ql/integration-tests/linux/standalone_dependencies_non_utf8_filename/test.csproj similarity index 100% rename from csharp/ql/integration-tests/linux-only/standalone_dependencies_non_utf8_filename/test.csproj rename to csharp/ql/integration-tests/linux/standalone_dependencies_non_utf8_filename/test.csproj diff --git a/csharp/ql/integration-tests/linux-only/standalone_dependencies_non_utf8_filename/test.py b/csharp/ql/integration-tests/linux/standalone_dependencies_non_utf8_filename/test.py similarity index 100% rename from csharp/ql/integration-tests/linux-only/standalone_dependencies_non_utf8_filename/test.py rename to csharp/ql/integration-tests/linux/standalone_dependencies_non_utf8_filename/test.py diff --git a/csharp/ql/integration-tests/posix-only/diag_autobuild_script/build.sh b/csharp/ql/integration-tests/posix/diag_autobuild_script/build.sh similarity index 100% rename from csharp/ql/integration-tests/posix-only/diag_autobuild_script/build.sh rename to csharp/ql/integration-tests/posix/diag_autobuild_script/build.sh diff --git a/csharp/ql/integration-tests/posix-only/diag_autobuild_script/diagnostics.expected b/csharp/ql/integration-tests/posix/diag_autobuild_script/diagnostics.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/diag_autobuild_script/diagnostics.expected rename to csharp/ql/integration-tests/posix/diag_autobuild_script/diagnostics.expected diff --git a/csharp/ql/integration-tests/posix-only/diag_autobuild_script/test.py b/csharp/ql/integration-tests/posix/diag_autobuild_script/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/diag_autobuild_script/test.py rename to csharp/ql/integration-tests/posix/diag_autobuild_script/test.py diff --git a/csharp/ql/integration-tests/posix-only/diag_multiple_scripts/build.sh b/csharp/ql/integration-tests/posix/diag_multiple_scripts/build.sh similarity index 100% rename from csharp/ql/integration-tests/posix-only/diag_multiple_scripts/build.sh rename to csharp/ql/integration-tests/posix/diag_multiple_scripts/build.sh diff --git a/csharp/ql/integration-tests/posix-only/diag_multiple_scripts/diagnostics.expected b/csharp/ql/integration-tests/posix/diag_multiple_scripts/diagnostics.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/diag_multiple_scripts/diagnostics.expected rename to csharp/ql/integration-tests/posix/diag_multiple_scripts/diagnostics.expected diff --git a/csharp/ql/integration-tests/posix-only/diag_multiple_scripts/scripts/build.sh b/csharp/ql/integration-tests/posix/diag_multiple_scripts/scripts/build.sh similarity index 100% rename from csharp/ql/integration-tests/posix-only/diag_multiple_scripts/scripts/build.sh rename to csharp/ql/integration-tests/posix/diag_multiple_scripts/scripts/build.sh diff --git a/csharp/ql/integration-tests/posix-only/diag_multiple_scripts/test.py b/csharp/ql/integration-tests/posix/diag_multiple_scripts/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/diag_multiple_scripts/test.py rename to csharp/ql/integration-tests/posix/diag_multiple_scripts/test.py diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/UnitTest1.cs b/csharp/ql/integration-tests/posix/dotnet_test/UnitTest1.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test/UnitTest1.cs rename to csharp/ql/integration-tests/posix/dotnet_test/UnitTest1.cs diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/diagnostics.expected b/csharp/ql/integration-tests/posix/dotnet_test/diagnostics.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test/diagnostics.expected rename to csharp/ql/integration-tests/posix/dotnet_test/diagnostics.expected diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj b/csharp/ql/integration-tests/posix/dotnet_test/dotnet_test.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj rename to csharp/ql/integration-tests/posix/dotnet_test/dotnet_test.csproj diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/global.json b/csharp/ql/integration-tests/posix/dotnet_test/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test/global.json rename to csharp/ql/integration-tests/posix/dotnet_test/global.json diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/test.py b/csharp/ql/integration-tests/posix/dotnet_test/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test/test.py rename to csharp/ql/integration-tests/posix/dotnet_test/test.py diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/UnitTest1.cs b/csharp/ql/integration-tests/posix/dotnet_test_mstest/UnitTest1.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test_mstest/UnitTest1.cs rename to csharp/ql/integration-tests/posix/dotnet_test_mstest/UnitTest1.cs diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/Usings.cs b/csharp/ql/integration-tests/posix/dotnet_test_mstest/Usings.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test_mstest/Usings.cs rename to csharp/ql/integration-tests/posix/dotnet_test_mstest/Usings.cs diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/diagnostics.expected b/csharp/ql/integration-tests/posix/dotnet_test_mstest/diagnostics.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test_mstest/diagnostics.expected rename to csharp/ql/integration-tests/posix/dotnet_test_mstest/diagnostics.expected diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj b/csharp/ql/integration-tests/posix/dotnet_test_mstest/dotnet_test_mstest.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj rename to csharp/ql/integration-tests/posix/dotnet_test_mstest/dotnet_test_mstest.csproj diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/global.json b/csharp/ql/integration-tests/posix/dotnet_test_mstest/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test_mstest/global.json rename to csharp/ql/integration-tests/posix/dotnet_test_mstest/global.json diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py b/csharp/ql/integration-tests/posix/dotnet_test_mstest/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/dotnet_test_mstest/test.py rename to csharp/ql/integration-tests/posix/dotnet_test_mstest/test.py diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/Program.cs b/csharp/ql/integration-tests/posix/inherit-env-vars/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/inherit-env-vars/Program.cs rename to csharp/ql/integration-tests/posix/inherit-env-vars/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/build.sh b/csharp/ql/integration-tests/posix/inherit-env-vars/build.sh similarity index 100% rename from csharp/ql/integration-tests/posix-only/inherit-env-vars/build.sh rename to csharp/ql/integration-tests/posix/inherit-env-vars/build.sh diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/diagnostics.expected b/csharp/ql/integration-tests/posix/inherit-env-vars/diagnostics.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/inherit-env-vars/diagnostics.expected rename to csharp/ql/integration-tests/posix/inherit-env-vars/diagnostics.expected diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/global.json b/csharp/ql/integration-tests/posix/inherit-env-vars/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/inherit-env-vars/global.json rename to csharp/ql/integration-tests/posix/inherit-env-vars/global.json diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/proj.csproj.no_auto b/csharp/ql/integration-tests/posix/inherit-env-vars/proj.csproj.no_auto similarity index 100% rename from csharp/ql/integration-tests/posix-only/inherit-env-vars/proj.csproj.no_auto rename to csharp/ql/integration-tests/posix/inherit-env-vars/proj.csproj.no_auto diff --git a/csharp/ql/integration-tests/posix-only/inherit-env-vars/test.py b/csharp/ql/integration-tests/posix/inherit-env-vars/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/inherit-env-vars/test.py rename to csharp/ql/integration-tests/posix/inherit-env-vars/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies/global.json b/csharp/ql/integration-tests/posix/standalone_dependencies/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies/global.json rename to csharp/ql/integration-tests/posix/standalone_dependencies/global.json diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies/standalone.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies/standalone.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies/standalone.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies/standalone.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_executing_runtime/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_executing_runtime/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_executing_runtime/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_executing_runtime/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_executing_runtime/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_executing_runtime/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_executing_runtime/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_executing_runtime/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_executing_runtime/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/global.json b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/global.json rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/global.json diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone1.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/standalone1.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone1.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/standalone1.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone2.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/standalone2.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/standalone2.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/standalone2.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_project/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_project/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/global.json b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/global.json rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/global.json diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/net48.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/net48.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/net48.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/net48.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/net70.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/net70.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/net70.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/net70.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_multi_target/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_multi_target/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/global.json b/csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/global.json rename to csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/global.json diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/packages.config b/csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/packages.config similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/packages.config rename to csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/packages.config diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/test_old.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/test_old.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/test_old.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/test_old.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/test_sdk.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/test_sdk.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_no_framework/test_sdk.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_no_framework/test_sdk.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/global.json b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/global.json rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/global.json diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/packages.config b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/packages.config similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/packages.config rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/packages.config diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/test.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/test.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/test.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/test.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget with_space/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget with_space/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/global.json b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/global.json rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget/global.json diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/packages.config b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget/packages.config similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/packages.config rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget/packages.config diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/test.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget/test.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/test.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget/test.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/CompilationInfo.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/proj/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/proj/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/proj/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/proj/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/proj/nuget.config b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/proj/nuget.config similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/proj/nuget.config rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/proj/nuget.config diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/proj/proj.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/proj/proj.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/proj/proj.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/proj/proj.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/standalone.sln b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/standalone.sln similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/standalone.sln rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/standalone.sln diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/diagnostics.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/diagnostics.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/diagnostics.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/diagnostics.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/proj/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/proj/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/proj/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/proj/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/proj/nuget.config b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/proj/nuget.config similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/proj/nuget.config rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/proj/nuget.config diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/proj/proj.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/proj/proj.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/proj/proj.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/proj/proj.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/standalone.sln b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/standalone.sln similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/standalone.sln rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/standalone.sln diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_error_timeout/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/CompilationInfo.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/CompilationInfo.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/diagnostics.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/diagnostics.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/diagnostics.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/diagnostics.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/proj/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/proj/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/proj/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/proj/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/proj/nuget.config b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/proj/nuget.config similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/proj/nuget.config rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/proj/nuget.config diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/proj/proj.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/proj/proj.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/proj/proj.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/proj/proj.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/standalone.sln b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/standalone.sln similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/standalone.sln rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/standalone.sln diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_config_fallback/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/nuget.config b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/nuget.config similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/nuget.config rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/nuget.config diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/proj/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/proj/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/proj/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/proj/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/proj/global.json b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/proj/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/proj/global.json rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/proj/global.json diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/proj/packages.config b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/proj/packages.config similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/proj/packages.config rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/proj/packages.config diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/proj/test.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/proj/test.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/proj/test.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/proj/test.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_no_sources/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_no_sources/test.py diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/Assemblies.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/Assemblies.expected rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/Assemblies.expected diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/Assemblies.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/Assemblies.ql rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/Assemblies.ql diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/Program.cs b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/Program.cs rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/d1/test1.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/d1/test1.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/d1/test1.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/d1/test1.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/d2/test2.csproj b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/d2/test2.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/d2/test2.csproj rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/d2/test2.csproj diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/global.json b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/global.json rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/global.json diff --git a/csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/test.py b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/standalone_dependencies_nuget_versions/test.py rename to csharp/ql/integration-tests/posix/standalone_dependencies_nuget_versions/test.py diff --git a/csharp/ql/integration-tests/posix-only/warn_as_error/Errors.expected b/csharp/ql/integration-tests/posix/warn_as_error/Errors.expected similarity index 100% rename from csharp/ql/integration-tests/posix-only/warn_as_error/Errors.expected rename to csharp/ql/integration-tests/posix/warn_as_error/Errors.expected diff --git a/csharp/ql/integration-tests/posix-only/warn_as_error/Errors.ql b/csharp/ql/integration-tests/posix/warn_as_error/Errors.ql similarity index 100% rename from csharp/ql/integration-tests/posix-only/warn_as_error/Errors.ql rename to csharp/ql/integration-tests/posix/warn_as_error/Errors.ql diff --git a/csharp/ql/integration-tests/posix-only/warn_as_error/Program.cs b/csharp/ql/integration-tests/posix/warn_as_error/Program.cs similarity index 100% rename from csharp/ql/integration-tests/posix-only/warn_as_error/Program.cs rename to csharp/ql/integration-tests/posix/warn_as_error/Program.cs diff --git a/csharp/ql/integration-tests/posix-only/warn_as_error/WarnAsError.csproj b/csharp/ql/integration-tests/posix/warn_as_error/WarnAsError.csproj similarity index 100% rename from csharp/ql/integration-tests/posix-only/warn_as_error/WarnAsError.csproj rename to csharp/ql/integration-tests/posix/warn_as_error/WarnAsError.csproj diff --git a/csharp/ql/integration-tests/posix-only/warn_as_error/build.sh b/csharp/ql/integration-tests/posix/warn_as_error/build.sh similarity index 100% rename from csharp/ql/integration-tests/posix-only/warn_as_error/build.sh rename to csharp/ql/integration-tests/posix/warn_as_error/build.sh diff --git a/csharp/ql/integration-tests/posix-only/warn_as_error/global.json b/csharp/ql/integration-tests/posix/warn_as_error/global.json similarity index 100% rename from csharp/ql/integration-tests/posix-only/warn_as_error/global.json rename to csharp/ql/integration-tests/posix/warn_as_error/global.json diff --git a/csharp/ql/integration-tests/posix-only/warn_as_error/test.py b/csharp/ql/integration-tests/posix/warn_as_error/test.py similarity index 100% rename from csharp/ql/integration-tests/posix-only/warn_as_error/test.py rename to csharp/ql/integration-tests/posix/warn_as_error/test.py diff --git a/csharp/ql/integration-tests/windows-only/diag_autobuild_script/build.bat b/csharp/ql/integration-tests/windows/diag_autobuild_script/build.bat similarity index 100% rename from csharp/ql/integration-tests/windows-only/diag_autobuild_script/build.bat rename to csharp/ql/integration-tests/windows/diag_autobuild_script/build.bat diff --git a/csharp/ql/integration-tests/windows-only/diag_autobuild_script/diagnostics.expected b/csharp/ql/integration-tests/windows/diag_autobuild_script/diagnostics.expected similarity index 100% rename from csharp/ql/integration-tests/windows-only/diag_autobuild_script/diagnostics.expected rename to csharp/ql/integration-tests/windows/diag_autobuild_script/diagnostics.expected diff --git a/csharp/ql/integration-tests/windows-only/diag_autobuild_script/test.py b/csharp/ql/integration-tests/windows/diag_autobuild_script/test.py similarity index 100% rename from csharp/ql/integration-tests/windows-only/diag_autobuild_script/test.py rename to csharp/ql/integration-tests/windows/diag_autobuild_script/test.py diff --git a/csharp/ql/integration-tests/windows-only/diag_multiple_scripts/build.bat b/csharp/ql/integration-tests/windows/diag_multiple_scripts/build.bat similarity index 100% rename from csharp/ql/integration-tests/windows-only/diag_multiple_scripts/build.bat rename to csharp/ql/integration-tests/windows/diag_multiple_scripts/build.bat diff --git a/csharp/ql/integration-tests/windows-only/diag_multiple_scripts/diagnostics.expected b/csharp/ql/integration-tests/windows/diag_multiple_scripts/diagnostics.expected similarity index 100% rename from csharp/ql/integration-tests/windows-only/diag_multiple_scripts/diagnostics.expected rename to csharp/ql/integration-tests/windows/diag_multiple_scripts/diagnostics.expected diff --git a/csharp/ql/integration-tests/windows-only/diag_multiple_scripts/scripts/build.bat b/csharp/ql/integration-tests/windows/diag_multiple_scripts/scripts/build.bat similarity index 100% rename from csharp/ql/integration-tests/windows-only/diag_multiple_scripts/scripts/build.bat rename to csharp/ql/integration-tests/windows/diag_multiple_scripts/scripts/build.bat diff --git a/csharp/ql/integration-tests/windows-only/diag_multiple_scripts/test.py b/csharp/ql/integration-tests/windows/diag_multiple_scripts/test.py similarity index 100% rename from csharp/ql/integration-tests/windows-only/diag_multiple_scripts/test.py rename to csharp/ql/integration-tests/windows/diag_multiple_scripts/test.py diff --git a/csharp/ql/integration-tests/windows-only/standalone_dependencies/Assemblies.expected b/csharp/ql/integration-tests/windows/standalone_dependencies/Assemblies.expected similarity index 100% rename from csharp/ql/integration-tests/windows-only/standalone_dependencies/Assemblies.expected rename to csharp/ql/integration-tests/windows/standalone_dependencies/Assemblies.expected diff --git a/csharp/ql/integration-tests/windows-only/standalone_dependencies/Assemblies.ql b/csharp/ql/integration-tests/windows/standalone_dependencies/Assemblies.ql similarity index 100% rename from csharp/ql/integration-tests/windows-only/standalone_dependencies/Assemblies.ql rename to csharp/ql/integration-tests/windows/standalone_dependencies/Assemblies.ql diff --git a/csharp/ql/integration-tests/windows-only/standalone_dependencies/Program.cs b/csharp/ql/integration-tests/windows/standalone_dependencies/Program.cs similarity index 100% rename from csharp/ql/integration-tests/windows-only/standalone_dependencies/Program.cs rename to csharp/ql/integration-tests/windows/standalone_dependencies/Program.cs diff --git a/csharp/ql/integration-tests/windows-only/standalone_dependencies/global.json b/csharp/ql/integration-tests/windows/standalone_dependencies/global.json similarity index 100% rename from csharp/ql/integration-tests/windows-only/standalone_dependencies/global.json rename to csharp/ql/integration-tests/windows/standalone_dependencies/global.json diff --git a/csharp/ql/integration-tests/windows-only/standalone_dependencies/standalone.csproj b/csharp/ql/integration-tests/windows/standalone_dependencies/standalone.csproj similarity index 100% rename from csharp/ql/integration-tests/windows-only/standalone_dependencies/standalone.csproj rename to csharp/ql/integration-tests/windows/standalone_dependencies/standalone.csproj diff --git a/csharp/ql/integration-tests/windows-only/standalone_dependencies/test.py b/csharp/ql/integration-tests/windows/standalone_dependencies/test.py similarity index 100% rename from csharp/ql/integration-tests/windows-only/standalone_dependencies/test.py rename to csharp/ql/integration-tests/windows/standalone_dependencies/test.py From d5bccd537305b864faea8979e76ceed22465a34a Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Thu, 29 Aug 2024 19:47:53 +0100 Subject: [PATCH 159/404] Reapply "C#: Add support for flow through side-effects on static fields" This reverts commit ea6092ad3fc5e7a516862773d1eb9be1c8ed607d. --- .../dataflow/internal/DataFlowPrivate.qll | 6 +++-- .../dataflow/fields/FieldFlow.expected | 24 +++++++++++++++++++ .../test/library-tests/dataflow/fields/K.cs | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index f1c51f222d5..fef73365de0 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -2170,9 +2170,11 @@ predicate jumpStep(Node pred, Node succ) { f.getAnAssignedValue() = pred.asExpr() and succ = TFlowInsensitiveFieldNode(f) or - exists(FieldOrPropertyRead fr | + exists(FieldOrPropertyRead fr | f.getAnAccess() = fr | + fr = pred.(PostUpdateNode).getPreUpdateNode().asExpr() and + succ = TFlowInsensitiveFieldNode(f) + or pred = TFlowInsensitiveFieldNode(f) and - f.getAnAccess() = fr and fr = succ.asExpr() and fr.hasNonlocalValue() ) diff --git a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected index 0317da509bb..e4cf0bb2673 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected @@ -1152,6 +1152,16 @@ edges | J.cs:125:14:125:14 | access to local variable a : Int32[] [element] : Int32 | J.cs:125:14:125:17 | access to array element : Int32 | provenance | | | J.cs:125:14:125:17 | access to array element : Int32 | J.cs:125:14:125:17 | (...) ... | provenance | | | J.cs:125:14:125:17 | access to array element : Int32 | J.cs:125:14:125:17 | (...) ... | provenance | | +| K.cs:7:13:7:13 | access to local variable o : String | K.cs:8:22:8:22 | access to local variable o : String | provenance | | +| K.cs:7:13:7:13 | access to local variable o : String | K.cs:8:22:8:22 | access to local variable o : String | provenance | | +| K.cs:7:17:7:33 | call to method Source : String | K.cs:7:13:7:13 | access to local variable o : String | provenance | | +| K.cs:7:17:7:33 | call to method Source : String | K.cs:7:13:7:13 | access to local variable o : String | provenance | | +| K.cs:8:9:8:15 | [post] access to field Strings : String[] [element] : String | K.cs:13:14:13:20 | access to field Strings : String[] [element] : String | provenance | | +| K.cs:8:9:8:15 | [post] access to field Strings : String[] [element] : String | K.cs:13:14:13:20 | access to field Strings : String[] [element] : String | provenance | | +| K.cs:8:22:8:22 | access to local variable o : String | K.cs:8:9:8:15 | [post] access to field Strings : String[] [element] : String | provenance | | +| K.cs:8:22:8:22 | access to local variable o : String | K.cs:8:9:8:15 | [post] access to field Strings : String[] [element] : String | provenance | | +| K.cs:13:14:13:20 | access to field Strings : String[] [element] : String | K.cs:13:14:13:23 | access to array element | provenance | | +| K.cs:13:14:13:20 | access to field Strings : String[] [element] : String | K.cs:13:14:13:23 | access to array element | provenance | | nodes | A.cs:5:13:5:13 | access to local variable c : C | semmle.label | access to local variable c : C | | A.cs:5:13:5:13 | access to local variable c : C | semmle.label | access to local variable c : C | @@ -2393,6 +2403,18 @@ nodes | J.cs:125:14:125:17 | (...) ... | semmle.label | (...) ... | | J.cs:125:14:125:17 | access to array element : Int32 | semmle.label | access to array element : Int32 | | J.cs:125:14:125:17 | access to array element : Int32 | semmle.label | access to array element : Int32 | +| K.cs:7:13:7:13 | access to local variable o : String | semmle.label | access to local variable o : String | +| K.cs:7:13:7:13 | access to local variable o : String | semmle.label | access to local variable o : String | +| K.cs:7:17:7:33 | call to method Source : String | semmle.label | call to method Source : String | +| K.cs:7:17:7:33 | call to method Source : String | semmle.label | call to method Source : String | +| K.cs:8:9:8:15 | [post] access to field Strings : String[] [element] : String | semmle.label | [post] access to field Strings : String[] [element] : String | +| K.cs:8:9:8:15 | [post] access to field Strings : String[] [element] : String | semmle.label | [post] access to field Strings : String[] [element] : String | +| K.cs:8:22:8:22 | access to local variable o : String | semmle.label | access to local variable o : String | +| K.cs:8:22:8:22 | access to local variable o : String | semmle.label | access to local variable o : String | +| K.cs:13:14:13:20 | access to field Strings : String[] [element] : String | semmle.label | access to field Strings : String[] [element] : String | +| K.cs:13:14:13:20 | access to field Strings : String[] [element] : String | semmle.label | access to field Strings : String[] [element] : String | +| K.cs:13:14:13:23 | access to array element | semmle.label | access to array element | +| K.cs:13:14:13:23 | access to array element | semmle.label | access to array element | subpaths | A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | A.cs:6:17:6:25 | call to method Make : B [field c] : C | | A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | A.cs:6:17:6:25 | call to method Make : B [field c] : C | @@ -2648,3 +2670,5 @@ testFailures | J.cs:107:14:107:17 | access to property Y | J.cs:105:32:105:48 | call to method Source : Object | J.cs:107:14:107:17 | access to property Y | $@ | J.cs:105:32:105:48 | call to method Source : Object | call to method Source : Object | | J.cs:125:14:125:17 | (...) ... | J.cs:119:20:119:34 | call to method Source : Int32 | J.cs:125:14:125:17 | (...) ... | $@ | J.cs:119:20:119:34 | call to method Source : Int32 | call to method Source : Int32 | | J.cs:125:14:125:17 | (...) ... | J.cs:119:20:119:34 | call to method Source : Int32 | J.cs:125:14:125:17 | (...) ... | $@ | J.cs:119:20:119:34 | call to method Source : Int32 | call to method Source : Int32 | +| K.cs:13:14:13:23 | access to array element | K.cs:7:17:7:33 | call to method Source : String | K.cs:13:14:13:23 | access to array element | $@ | K.cs:7:17:7:33 | call to method Source : String | call to method Source : String | +| K.cs:13:14:13:23 | access to array element | K.cs:7:17:7:33 | call to method Source : String | K.cs:13:14:13:23 | access to array element | $@ | K.cs:7:17:7:33 | call to method Source : String | call to method Source : String | diff --git a/csharp/ql/test/library-tests/dataflow/fields/K.cs b/csharp/ql/test/library-tests/dataflow/fields/K.cs index f8e79b6af54..cdefa485852 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/K.cs +++ b/csharp/ql/test/library-tests/dataflow/fields/K.cs @@ -10,7 +10,7 @@ public class K private void M2() { - Sink(Strings[0]); // $ MISSING: hasValueFlow=1 + Sink(Strings[0]); // $ hasValueFlow=1 } public static void Sink(object o) { } From 13705531b5725b8b5bb89d54baacd0645808a869 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Thu, 29 Aug 2024 14:47:54 -0700 Subject: [PATCH 160/404] Update .github/pull_request_template.md Co-authored-by: Aditya Sharad <6874315+adityasharad@users.noreply.github.com> --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9d6ec6cb4f5..ef7e5b92ebb 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -3,7 +3,7 @@ #### All query authors - [ ] Add a change note if necessary. See [the documentation](https://github.com/github/codeql/blob/main/docs/change-notes.md) in this repository. -- [ ] All new queries have appropriate `.qhelp`. See [the documentation](https://github.com/github/codeql/blob/mainπ /docs/query-help-style-guide.md) in this repository. +- [ ] All new queries have appropriate `.qhelp`. See [the documentation](https://github.com/github/codeql/blob/main/docs/query-help-style-guide.md) in this repository. - [ ] QL tests are added if necessary. See [Testing custom queries](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/testing-custom-queries) in the GitHub documentation. - [ ] New and changed queries have correct query metadata. See [the documentation](https://github.com/github/codeql/blob/main/docs/query-metadata-style-guide.md) in this repository. From 04753b286ff91b5d03c53c58ce0ae512269d4141 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 30 Aug 2024 10:12:20 +0200 Subject: [PATCH 161/404] Rust: tweak `trap_key` --- rust/src/translate.rs | 12 +++--- rust/src/trap.rs | 93 ++++++++++++++++++++++++------------------- 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/rust/src/translate.rs b/rust/src/translate.rs index 29c4488ddb0..b30ff5f8acc 100644 --- a/rust/src/translate.rs +++ b/rust/src/translate.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::fs; use std::path::{PathBuf}; -use crate::trap::{KeyPart, TrapFile, TrapId, TrapLabel}; +use crate::trap::{TrapFile, TrapId, TrapLabel}; use crate::{generated, trap_key}; use ra_ap_hir::{Crate, Module, ModuleDef}; use anyhow; @@ -74,7 +74,7 @@ impl CrateTranslator<'_> { let start = data.line_index.line_col(range.start()); let end = data.line_index.line_col(range.end()); return Ok(Some(self.trap.emit(generated::DbLocation { - id: trap_key![data.label, format!(":{}:{}:{}:{}", start.line, start.col, end.line, end.col)], + id: trap_key![data.label, ":", start.line, ":", start.col, ":", end.line, ":", end.col], file: data.label, start_line: start.line, start_column: start.col, @@ -129,20 +129,20 @@ impl CrateTranslator<'_> { self.emit_file(self.krate.root_file(self.db))?; let mut map = HashMap::::new(); for module in self.krate.modules(self.db) { - let mut key = Vec::::new(); + let mut key = String::new(); if let Some(parent) = module.parent(self.db) { // assumption: parent was already listed let parent_label = *map.get(&parent).unwrap(); - key.push(parent_label.into()); + key.push_str(&parent_label.as_key_part()); } let def = module.definition_source(self.db); if let Some(file) = def.file_id.file_id() { if let Some(data) = self.emit_file(file.file_id())? { - key.push(data.label.into()); + key.push_str(&data.label.as_key_part()); } } if let Some(name) = module.name(self.db) { - key.push(name.as_str().into()); + key.push_str(name.as_str()); } let label = self.trap.label(TrapId::Key(key))?; map.insert(module, label); diff --git a/rust/src/trap.rs b/rust/src/trap.rs index 35d8aac244f..d74f252577a 100644 --- a/rust/src/trap.rs +++ b/rust/src/trap.rs @@ -5,9 +5,15 @@ use std::path::{Path, PathBuf}; use log::{debug, trace}; use crate::{config, path}; -#[derive(Debug, Clone, Copy)] +#[derive(Clone, Copy)] pub struct TrapLabel(u64); +impl Debug for TrapLabel { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "TrapLabel({:x})", self.0) + } +} + impl Display for TrapLabel { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "#{:x}", self.0) @@ -16,64 +22,59 @@ impl Display for TrapLabel { //TODO: typed labels -#[derive(Debug, Clone)] -pub enum KeyPart { - Label(TrapLabel), - Text(String), -} - -impl From for KeyPart { - fn from(value: String) -> Self { - KeyPart::Text(value) - } -} - -impl From<&str> for KeyPart { - fn from(value: &str) -> Self { - KeyPart::Text(value.into()) - } -} - -impl From for KeyPart { - fn from(value: TrapLabel) -> Self { - KeyPart::Label(value) +impl TrapLabel { + pub fn as_key_part(&self) -> String { + format!("{{{}}}", self) } } #[derive(Debug, Clone)] pub enum TrapId { Star, - Key(Vec), + Key(String), Label(TrapLabel), } -impl> From for TrapId { - fn from(value: T) -> Self { - TrapId::Key(vec![value.into()]) +impl From for TrapId { + fn from(value: String) -> Self { + TrapId::Key(value) + } +} + +impl From<&str> for TrapId { + fn from(value: &str) -> Self { + TrapId::Key(value.into()) + } +} + +impl From for TrapId { + fn from(value: TrapLabel) -> Self { + TrapId::Label(value) } } #[macro_export] macro_rules! trap_key { - ($($x:expr),+ $(,)?) => ( - $crate::trap::TrapId::Key(vec![$($x.into()),+]) - ); + ($($x:expr),+ $(,)?) => {{ + trait BlanketKeyPart: std::fmt::Display { + fn as_key_part(&self) -> String { + format!("{}", self) + } + } + impl BlanketKeyPart for T {} + let mut key = String::new(); + $( + key.push_str(&$x.as_key_part()); + )* + $crate::TrapId::Key(key) + }}; } impl Display for TrapId { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { TrapId::Star => write!(f, "*"), - TrapId::Key(k) => { - f.write_str("@\"")?; - for p in k { - match p { - KeyPart::Label(l) => write!(f, "{{{l}}}")?, - KeyPart::Text(s) => f.write_str(&escaped(s))?, - } - } - f.write_str("\"") - } + TrapId::Key(k) => write!(f, "@{}", quoted(k)), TrapId::Label(l) => Display::fmt(&l, f) } } @@ -109,9 +110,17 @@ impl TrapFile { Ok(()) } - pub fn label(&mut self, id: TrapId) -> std::io::Result { - if let TrapId::Label(l) = id { - return Ok(l); + pub fn label(&mut self, mut id: TrapId) -> std::io::Result { + match id { + TrapId::Star => {} + TrapId::Key(ref s) => { + if s.is_empty() { + id = TrapId::Star; + } + } + TrapId::Label(l) => { + return Ok(l); + } } let ret = self.create_label(); trace!("emit -> {}: {ret:?} = {id:?}", self.trap_name); From 321820e758b86827f6e19ab3d7226d70f9ad982c Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Thu, 29 Aug 2024 19:13:17 +0200 Subject: [PATCH 162/404] Java: Rename integration test directories. We are no longer bound to the platform-specific directories, so simplify the test organization. If you don't want this change, just skip merging this PR. It's purely optional. I kept the platform-specific directories around under `kotlin`, but you could also easily merge all these together if you find them unhelpful. I'll leave that change to you. --- .../java/android-8-sample/build.gradle | 0 .../java/android-8-sample/project/build.gradle | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../java/android-8-sample/settings.gradle | 0 .../java/android-8-sample/source_archive.expected | 0 .../java/android-8-sample/test.py | 0 .../build.gradle.kts | 0 .../project/build.gradle.kts | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../settings.gradle.kts | 0 .../source_archive.expected | 0 .../test.py | 0 .../build.gradle.kts | 0 .../project/build.gradle.kts | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../settings.gradle.kts | 0 .../source_archive.expected | 0 .../java/android-sample-kotlin-build-script/test.py | 0 .../java/android-sample-no-wrapper/build.gradle | 0 .../android-sample-no-wrapper/project/build.gradle | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../java/android-sample-no-wrapper/settings.gradle | 0 .../source_archive.expected | 0 .../java/android-sample-no-wrapper/test.py | 0 .../README | 0 .../build.gradle.kts | 0 .../project/build.gradle.kts | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../settings.gradle.kts | 0 .../source_archive.expected | 0 .../test.py | 0 .../.gitattributes | 0 .../README | 0 .../build.gradle.kts | 0 .../project/build.gradle.kts | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../settings.gradle.kts | 0 .../source_archive.expected | 0 .../test.py | 0 .../java/android-sample-old-style-no-wrapper/README | 0 .../build.gradle | 0 .../project/build.gradle | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../settings.gradle | 0 .../source_archive.expected | 0 .../android-sample-old-style-no-wrapper/test.py | 0 .../java/android-sample-old-style/README | 0 .../java/android-sample-old-style/build.gradle | 0 .../android-sample-old-style/project/build.gradle | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../java/android-sample-old-style/settings.gradle | 0 .../source_archive.expected | 0 .../java/android-sample-old-style/test.py | 0 .../java/android-sample/build.gradle | 0 .../java/android-sample/project/build.gradle | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../java/android-sample/settings.gradle | 0 .../java/android-sample/source_archive.expected | 0 .../{all-platforms => }/java/android-sample/test.py | 0 .../{all-platforms => }/java/ant-sample/build.xml | 0 .../ant-sample/src/main/java/com/example/App.java | 0 .../java/ant-sample/test.expected | 0 .../{all-platforms => }/java/ant-sample/test.py | 0 .../{all-platforms => }/java/ant-sample/test.ql | 0 .../buildless-fetches.expected | 0 .../pom.xml | 0 .../otherreleasetest/1.0/otherreleasetest-1.0.jar | Bin .../1.0/otherreleasetest-1.0.jar.md5 | 0 .../1.0/otherreleasetest-1.0.jar.sha1 | 0 .../otherreleasetest/1.0/otherreleasetest-1.0.pom | 0 .../1.0/otherreleasetest-1.0.pom.md5 | 0 .../1.0/otherreleasetest-1.0.pom.sha1 | 0 .../repo/test/inotherrepo/1.0/inotherrepo-1.0.jar | Bin .../test/inotherrepo/1.0/inotherrepo-1.0.jar.md5 | 0 .../test/inotherrepo/1.0/inotherrepo-1.0.jar.sha1 | 0 .../repo/test/inotherrepo/1.0/inotherrepo-1.0.pom | 0 .../test/inotherrepo/1.0/inotherrepo-1.0.pom.md5 | 0 .../test/inotherrepo/1.0/inotherrepo-1.0.pom.sha1 | 0 .../src/main/java/Test.java | 0 .../test.expected | 0 .../test.py | 0 .../test.ql | 0 .../DatabaseQualityDiagnostics.expected | 0 .../DatabaseQualityDiagnostics.qlref | 0 .../ExtractorInformation.expected | 0 .../buildless-erroneous/ExtractorInformation.qlref | 0 .../java/buildless-erroneous/Test.java | 0 .../java/buildless-erroneous/diagnostics.expected | 0 .../java/buildless-erroneous/test.py | 0 .../java/buildless-gradle-classifiers/build.gradle | 0 .../buildless-fetches.expected | 0 .../diagnostics.expected | 0 .../buildless-gradle-classifiers/settings.gradle | 0 .../source_archive.expected | 0 .../src/main/java/com/fractestexample/Test.java | 0 .../java/buildless-gradle-classifiers/test.py | 0 .../java/buildless-gradle-timeout/.gitattributes | 0 .../java/buildless-gradle-timeout/.gitignore | 0 .../java/buildless-gradle-timeout/build.gradle | 0 .../buildless-gradle-timeout/diagnostics.expected | 0 .../gradle/verification-metadata.xml | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../java/buildless-gradle-timeout/gradlew | 0 .../java/buildless-gradle-timeout/gradlew.bat | 0 .../java/buildless-gradle-timeout/settings.gradle | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/buildless-gradle-timeout/test.py | 0 .../java/buildless-gradle/build.gradle | 0 .../buildless-gradle/buildless-fetches.expected | 0 .../java/buildless-gradle/diagnostics.expected | 0 .../java/buildless-gradle/settings.gradle | 0 .../java/buildless-gradle/source_archive.expected | 0 .../src/main/java/com/fractestexample/Test.java | 0 .../java/buildless-gradle/test.py | 0 .../buildless-fetches.expected | 0 .../java/buildless-inherit-trust-store/cert.pem | 0 .../diagnostics.expected | 0 .../jdk8_shipped_cacerts_plus_cert_pem | Bin .../java/buildless-inherit-trust-store/key.pem | 0 .../java/buildless-inherit-trust-store/pom.xml | 0 .../snapshottest/1.0-SNAPSHOT/maven-metadata.xml | 0 .../1.0-SNAPSHOT/maven-metadata.xml.md5 | 0 .../1.0-SNAPSHOT/maven-metadata.xml.sha1 | 0 .../snapshottest-1.0-20230901.050514-100.jar | Bin .../snapshottest-1.0-20230901.050514-100.jar.md5 | 0 .../snapshottest-1.0-20230901.050514-100.jar.sha1 | 0 .../snapshottest-1.0-20230901.050514-100.pom | 0 .../snapshottest-1.0-20230901.050514-100.pom.md5 | 0 .../snapshottest-1.0-20230901.050514-100.pom.sha1 | 0 .../java/buildless-inherit-trust-store/server.py | 0 .../src/main/java/Test.java | 0 .../buildless-inherit-trust-store/test.expected | 0 .../java/buildless-inherit-trust-store/test.py | 0 .../java/buildless-inherit-trust-store/test.ql | 0 .../buildless-fetches.expected | 0 .../diagnostics.expected | 0 .../java/buildless-maven-executable-war/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/buildless-maven-executable-war/test.py | 0 .../buildless-fetches.expected | 0 .../diagnostics.expected | 0 .../java/buildless-maven-multimodule/pom.xml | 0 .../source_archive.expected | 0 .../buildless-maven-multimodule/submod1/pom.xml | 0 .../submod1/src/main/java/com/example/App.java | 0 .../submod1/src/main/resources/my-app.properties | 0 .../submod1/src/main/resources/page.xml | 0 .../submod1/src/main/resources/struts.xml | 0 .../submod1/src/test/java/com/example/AppTest.java | 0 .../buildless-maven-multimodule/submod2/pom.xml | 0 .../submod2/src/main/java/com/example/App2.java | 0 .../submod2/src/main/resources/my-app.properties | 0 .../submod2/src/main/resources/page.xml | 0 .../submod2/src/main/resources/struts.xml | 0 .../submod2/src/test/java/com/example/AppTest2.java | 0 .../java/buildless-maven-multimodule/test.py | 0 .../java/buildless-maven-timeout/.gitattributes | 0 .../.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 .../buildless-maven-timeout/diagnostics.expected | 0 .../java/buildless-maven-timeout/mvnw | 0 .../java/buildless-maven-timeout/mvnw.cmd | 0 .../java/buildless-maven-timeout/pom.xml | 0 .../buildless-maven-timeout/source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/buildless-maven-timeout/test.py | 0 .../buildless-fetches.expected | 0 .../diagnostics.expected | 0 .../pom.xml | 0 .../src/main/java/dlfs/App.java | 0 .../src/site/site.xml | 0 .../src/test/java/dlfs/AppTest.java | 0 .../test.py | 0 .../java/buildless-maven/buildless-fetches.expected | 0 .../java/buildless-maven/diagnostics.expected | 0 .../java/buildless-maven/pom.xml | 0 .../java/buildless-maven/source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../buildless-maven/src/main/resources/page.xml | 0 .../buildless-maven/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/buildless-maven/test.py | 0 .../PrintAst.expected | 0 .../PrintAst.qlref | 0 .../Test.java | 0 .../Test2.java | 0 .../test.py | 0 .../java/buildless-proxy-gradle/build.gradle | 0 .../buildless-fetches.expected | 0 .../buildless-proxy-gradle/diagnostics.expected | 0 .../java/buildless-proxy-gradle/settings.gradle | 0 .../buildless-proxy-gradle/source_archive.expected | 0 .../src/main/java/com/fractestexample/Test.java | 0 .../java/buildless-proxy-gradle/test.py | 0 .../buildless-fetches.expected | 0 .../java/buildless-proxy-maven/diagnostics.expected | 0 .../java/buildless-proxy-maven/pom.xml | 0 .../buildless-proxy-maven/source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/buildless-proxy-maven/test.py | 0 .../buildless-fetches.expected | 0 .../buildless-sibling-projects/diagnostics.expected | 0 .../gradle-sample/.gitattributes | 0 .../gradle-sample/.gitignore | 0 .../gradle-sample/build.gradle | 0 .../gradle-sample/gradle/verification-metadata.xml | 0 .../gradle-sample/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../gradle-sample/gradlew | 0 .../gradle-sample/gradlew.bat | 0 .../gradle-sample/settings.gradle | 0 .../src/main/java/com/example/App.java | 0 .../src/test/java/com/example/AppTest.java | 0 .../gradle-sample2/.gitattributes | 0 .../gradle-sample2/.gitignore | 0 .../gradle-sample2/build.gradle | 0 .../gradle-sample2/gradle/verification-metadata.xml | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../gradle-sample2/gradlew | 0 .../gradle-sample2/gradlew.bat | 0 .../gradle-sample2/settings.gradle | 0 .../src/main/java/com/example/App2.java | 0 .../src/test/java/com/example/AppTest2.java | 0 .../maven-project-1/pom.xml | 0 .../src/main/java/com/example/App3.java | 0 .../src/main/resources/my-app.properties | 0 .../maven-project-1/src/main/resources/page.xml | 0 .../maven-project-1/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest3.java | 0 .../maven-project-2/pom.xml | 0 .../src/main/java/com/example/App4.java | 0 .../src/main/resources/my-app.properties | 0 .../maven-project-2/src/main/resources/page.xml | 0 .../maven-project-2/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest4.java | 0 .../source_archive.expected | 0 .../java/buildless-sibling-projects/test.py | 0 .../buildless-fetches.expected | 0 .../java/buildless-snapshot-repository/pom.xml | 0 .../snapshottest/1.0-SNAPSHOT/maven-metadata.xml | 0 .../1.0-SNAPSHOT/maven-metadata.xml.md5 | 0 .../1.0-SNAPSHOT/maven-metadata.xml.sha1 | 0 .../snapshottest-1.0-20230901.050514-100.jar | Bin .../snapshottest-1.0-20230901.050514-100.jar.md5 | 0 .../snapshottest-1.0-20230901.050514-100.jar.sha1 | 0 .../snapshottest-1.0-20230901.050514-100.pom | 0 .../snapshottest-1.0-20230901.050514-100.pom.md5 | 0 .../snapshottest-1.0-20230901.050514-100.pom.sha1 | 0 .../src/main/java/Test.java | 0 .../buildless-snapshot-repository/test.expected | 0 .../java/buildless-snapshot-repository/test.py | 0 .../java/buildless-snapshot-repository/test.ql | 0 .../java/buildless/diagnostics.expected | 0 .../java/buildless/source_archive.expected | 0 .../buildless/src/main/java/com/example/App.java | 0 .../buildless/src/main/resources/my-app.properties | 0 .../java/buildless/src/main/resources/page.xml | 0 .../java/buildless/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../{all-platforms => }/java/buildless/test.py | 0 .../android-gradle-incompatibility/build.gradle | 0 .../diagnostics.expected | 0 .../project/build.gradle | 0 .../project/src/main/AndroidManifest.xml | 0 .../main/java/com/github/androidsample/Main.java | 0 .../android-gradle-incompatibility/settings.gradle | 0 .../android-gradle-incompatibility/test.py | 0 .../compilation-error/diagnostics.expected | 0 .../java/diagnostics/compilation-error/pom.xml | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../compilation-error/src/main/resources/page.xml | 0 .../compilation-error/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/diagnostics/compilation-error/test.py | 0 .../dependency-error/diagnostics.expected | 0 .../java/diagnostics/dependency-error/pom.xml | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../dependency-error/src/main/resources/page.xml | 0 .../dependency-error/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/diagnostics/dependency-error/test.py | 0 .../diagnostics/java-version-too-old/build.gradle | 0 .../java-version-too-old/diagnostics.expected | 0 .../java-version-too-old/settings.gradle | 0 .../src/main/java/com/example/App.java | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/diagnostics/java-version-too-old/test.py | 0 .../diagnostics/java-version-too-old/toolchains.xml | 0 .../maven-http-repository/.gitattributes | 0 .../.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 .../maven-http-repository/diagnostics.expected | 0 .../java/diagnostics/maven-http-repository/mvnw | 0 .../java/diagnostics/maven-http-repository/mvnw.cmd | 0 .../java/diagnostics/maven-http-repository/pom.xml | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/diagnostics/maven-http-repository/test.py | 0 .../multiple-candidate-builds/diagnostics.expected | 0 .../maven-project-1/pom.xml | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../maven-project-1/src/main/resources/page.xml | 0 .../maven-project-1/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../maven-project-2/pom.xml | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../maven-project-2/src/main/resources/page.xml | 0 .../maven-project-2/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../diagnostics/multiple-candidate-builds/test.py | 0 .../java/diagnostics/no-build-system/Test.java | 0 .../no-build-system/diagnostics.expected | 0 .../java/diagnostics/no-build-system/test.py | 0 .../diagnostics/no-gradle-test-classes/build.gradle | 0 .../no-gradle-test-classes/diagnostics.expected | 0 .../no-gradle-test-classes/settings.gradle | 0 .../java/diagnostics/no-gradle-test-classes/test.py | 0 .../diagnostics/no-gradle-wrapper/.gitattributes | 0 .../java/diagnostics/no-gradle-wrapper/.gitignore | 0 .../java/diagnostics/no-gradle-wrapper/build.gradle | 0 .../no-gradle-wrapper/diagnostics.expected | 0 .../diagnostics/no-gradle-wrapper/settings.gradle | 0 .../src/main/java/com/example/App.java | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/diagnostics/no-gradle-wrapper/test.py | 0 .../java/ecj-sample-noexit/Test.java | 0 .../java/ecj-sample-noexit/source_archive.expected | 0 .../java/ecj-sample-noexit/test.py | 0 .../{all-platforms => }/java/ecj-sample/Test.java | 0 .../java/ecj-sample/source_archive.expected | 0 .../{all-platforms => }/java/ecj-sample/test.py | 0 .../ecj-tolerate-enum-annotations/Diag.expected | 0 .../java/ecj-tolerate-enum-annotations/Diag.ql | 0 .../java/ecj-tolerate-enum-annotations/Test.java | 0 .../java/ecj-tolerate-enum-annotations/Test2.java | 0 .../ecj-tolerate-enum-annotations/test.expected | 0 .../java/ecj-tolerate-enum-annotations/test.py | 0 .../java/ecj-tolerate-enum-annotations/test.ql | 0 .../gradle-sample-kotlin-script}/.gitattributes | 0 .../app/build.gradle.kts | 0 .../app/src/main/java/test/App.java | 0 .../app/src/test/java/test/AppTest.java | 0 .../java/gradle-sample-kotlin-script/gradlew | 0 .../java/gradle-sample-kotlin-script/gradlew.bat | 0 .../gradle-sample-kotlin-script/settings.gradle.kts | 0 .../source_archive.expected | 0 .../java/gradle-sample-kotlin-script/test.py | 0 .../java/gradle-sample/build.gradle | 0 .../java/gradle-sample/settings.gradle | 0 .../java/gradle-sample/source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/test/java/com/example/AppTest.java | 0 .../{all-platforms => }/java/gradle-sample/test.py | 0 .../java/java-web-jsp/.gitignore | 0 .../java/java-web-jsp/README.txt | 0 .../{all-platforms => }/java/java-web-jsp/pom.xml | 0 .../java/java-web-jsp/spotbugs-security-exclude.xml | 0 .../java/java-web-jsp/spotbugs-security-include.xml | 0 .../src/main/java/com/acme/Counter.java | 0 .../src/main/java/com/acme/Date2Tag.java | 0 .../src/main/java/com/acme/DateServlet.java | 0 .../src/main/java/com/acme/DateTag.java | 0 .../src/main/java/com/acme/TagListener.java | 0 .../java/org/eclipse/jetty/demo/LoggingUtil.java | 0 .../src/main/java/org/eclipse/jetty/demo/Main.java | 0 .../org/eclipse/jetty/demo/SystemOutHandler.java | 0 .../src/main/resources/jetty-logging.properties | 0 .../src/main/resources/logging.properties | 0 .../src/main/webapp/WEB-INF/acme-taglib.tld | 0 .../src/main/webapp/WEB-INF/acme-taglib2.tld | 0 .../src/main/webapp/WEB-INF/applicationContext.xml | 0 .../java-web-jsp/src/main/webapp/WEB-INF/secret.jsp | 0 .../java-web-jsp/src/main/webapp/WEB-INF/spring.tld | 0 .../src/main/webapp/WEB-INF/tags/panel.tag | 0 .../java-web-jsp/src/main/webapp/WEB-INF/web.xml | 0 .../src/main/webapp/WEB-INF/weblogic.xml | 0 .../main/webapp/include/${param.secret_param}.jsp | 0 .../src/main/webapp/include/jsp_include_1.jsp | 0 .../src/main/webapp/include/jsp_include_2_safe.jsp | 0 .../src/main/webapp/include/jsp_include_3.jsp | 0 .../java/java-web-jsp/src/main/webapp/index.jsp | 0 .../src/main/webapp/jstl/jstl_escape_1.jsp | 0 .../src/main/webapp/jstl/jstl_escape_2.jsp | 0 .../src/main/webapp/jstl/jstl_escape_3.jsp | 0 .../java/java-web-jsp/src/main/webapp/random.jsp | 0 .../src/main/webapp/spring/spring_eval_1.jsp | 0 .../src/main/webapp/spring/spring_eval_2.jsp | 0 .../src/main/webapp/spring/spring_eval_3.jsp | 0 .../src/main/webapp/spring/spring_eval_4_safe.jsp | 0 .../java-web-jsp/src/main/webapp/test/bean1.jsp | 0 .../java-web-jsp/src/main/webapp/test/bean2.jsp | 0 .../java/java-web-jsp/src/main/webapp/test/dump.jsp | 0 .../java/java-web-jsp/src/main/webapp/test/expr.jsp | 0 .../java-web-jsp/src/main/webapp/test/foo/foo.jsp | 0 .../java/java-web-jsp/src/main/webapp/test/jstl.jsp | 0 .../java/java-web-jsp/src/main/webapp/test/tag.jsp | 0 .../java/java-web-jsp/src/main/webapp/test/tag2.jsp | 0 .../java-web-jsp/src/main/webapp/test/tagfile.jsp | 0 .../java/java-web-jsp/src/main/webapp/various.jsp | 0 .../java/java-web-jsp/src/main/webapp/xml/xml1.jsp | 0 .../java/java-web-jsp/src/main/webapp/xml/xml2.jsp | 0 .../java/java-web-jsp/src/main/webapp/xsl/xsl1.jsp | 0 .../java/java-web-jsp/src/main/webapp/xsl/xsl2.jsp | 0 .../java/java-web-jsp/src/main/webapp/xsl/xsl3.jsp | 0 .../java/java-web-jsp/src/main/webapp/xsl/xsl4.jsp | 0 .../java/java-web-jsp/src/main/webapp/xss/xss0.jsp | 0 .../java/java-web-jsp/src/main/webapp/xss/xss1.jsp | 0 .../java/java-web-jsp/src/main/webapp/xss/xss2.jsp | 0 .../java/java-web-jsp/src/main/webapp/xss/xss3.jsp | 0 .../java/java-web-jsp/src/main/webapp/xss/xss4.jsp | 0 .../java/java-web-jsp/src/main/webapp/xss/xss5.jsp | 0 .../java/java-web-jsp/test.expected | 0 .../{all-platforms => }/java/java-web-jsp/test.py | 0 .../{all-platforms => }/java/java-web-jsp/test.ql | 0 .../{all-platforms => }/java/maven-enforcer/pom.xml | 0 .../java/maven-enforcer/source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../java/maven-enforcer/src/main/resources/page.xml | 0 .../maven-enforcer/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../{all-platforms => }/java/maven-enforcer/test.py | 0 .../java/maven-sample-extract-properties/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/maven-sample-extract-properties/test.py | 0 .../java/maven-sample-large-xml-files/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/maven-sample-large-xml-files/test.py | 0 .../java/maven-sample-small-xml-files/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/maven-sample-small-xml-files/test.py | 0 .../java/maven-sample-xml-mode-all/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/maven-sample-xml-mode-all/test.py | 0 .../java/maven-sample-xml-mode-byname/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/maven-sample-xml-mode-byname/test.py | 0 .../java/maven-sample-xml-mode-disabled/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/maven-sample-xml-mode-disabled/test.py | 0 .../java/maven-sample-xml-mode-smart/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/maven-sample-xml-mode-smart/test.py | 0 .../{all-platforms => }/java/maven-sample/pom.xml | 0 .../java/maven-sample/source_archive.expected | 0 .../maven-sample/src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../java/maven-sample/src/main/resources/page.xml | 0 .../java/maven-sample/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../{all-platforms => }/java/maven-sample/test.py | 0 .../java/maven-wrapper-script-only/.gitattributes | 0 .../.mvn/wrapper/maven-wrapper.properties | 0 .../java/maven-wrapper-script-only/mvnw | 0 .../java/maven-wrapper-script-only/mvnw.cmd | 0 .../java/maven-wrapper-script-only/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/maven-wrapper-script-only/test.py | 0 .../java/maven-wrapper-source-only/.gitattributes | 0 .../.mvn/wrapper/MavenWrapperDownloader.java | 0 .../.mvn/wrapper/maven-wrapper.properties | 0 .../java/maven-wrapper-source-only/mvnw | 0 .../java/maven-wrapper-source-only/mvnw.cmd | 0 .../java/maven-wrapper-source-only/pom.xml | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../src/main/resources/page.xml | 0 .../src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/maven-wrapper-source-only/test.py | 0 .../java/maven-wrapper/.gitattributes | 0 .../maven-wrapper/.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 .../{all-platforms => }/java/maven-wrapper/mvnw | 0 .../{all-platforms => }/java/maven-wrapper/mvnw.cmd | 0 .../{all-platforms => }/java/maven-wrapper/pom.xml | 0 .../java/maven-wrapper/source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/main/resources/my-app.properties | 0 .../java/maven-wrapper/src/main/resources/page.xml | 0 .../maven-wrapper/src/main/resources/struts.xml | 0 .../src/test/java/com/example/AppTest.java | 0 .../{all-platforms => }/java/maven-wrapper/test.py | 0 .../ExtractorInformation.expected | 0 .../ExtractorInformation.qlref | 0 .../mod1/mod1pkg/Mod1Class.java | 0 .../multi-release-jar-java11/mod1/module-info.java | 0 .../multi-release-jar-java11/mod2/mod2pkg/User.java | 0 .../multi-release-jar-java11/mod2/module-info.java | 0 .../java/multi-release-jar-java11/test.py | 0 .../ExtractorInformation.expected | 0 .../ExtractorInformation.qlref | 0 .../mod1/mod1pkg/Mod1Class.java | 0 .../multi-release-jar-java17/mod1/module-info.java | 0 .../multi-release-jar-java17/mod2/mod2pkg/User.java | 0 .../multi-release-jar-java17/mod2/module-info.java | 0 .../java/multi-release-jar-java17/test.py | 0 .../.gitattributes | 0 .../partial-gradle-sample-without-gradle/.gitignore | 0 .../build.gradle | 0 .../gradle/verification-metadata.xml | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../partial-gradle-sample-without-gradle/gradlew | 0 .../gradlew.bat | 0 .../settings.gradle | 0 .../source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/test/java/com/example/AppTest.java | 0 .../partial-gradle-sample-without-gradle/test.py | 0 .../java/partial-gradle-sample/.gitattributes | 6 ++++++ .../java/partial-gradle-sample/build.gradle | 0 .../gradle/verification-metadata.xml | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../java/partial-gradle-sample/gradlew | 0 .../java/partial-gradle-sample/gradlew.bat | 0 .../java/partial-gradle-sample/settings.gradle | 0 .../partial-gradle-sample/source_archive.expected | 0 .../src/main/java/com/example/App.java | 0 .../src/test/java/com/example/AppTest.java | 0 .../java/partial-gradle-sample/test.py | 0 .../java/spring-boot-sample/README | 0 .../java/spring-boot-sample/build.gradle | 0 .../java/spring-boot-sample/settings.gradle | 0 .../java/spring-boot-sample/source_archive.expected | 0 .../SpringBootSampleApplication.java | 0 .../src/main/resources/application.properties | 0 .../SpringBootSampleApplicationTests.java | 0 .../java/spring-boot-sample/test.py | 0 .../annotation-id-consistency/PrintAst.expected | 0 .../annotation-id-consistency/PrintAst.qlref | 0 .../annotation-id-consistency/User.java | 0 .../deprecatedAnnotationTypes.expected | 0 .../deprecatedAnnotationTypes.ql | 0 .../annotation-id-consistency/ktUser.kt | 0 .../annotation-id-consistency/qlpack.yml | 0 .../annotation-id-consistency/test.ext.yml | 0 .../annotation-id-consistency/test.kt | 0 .../annotation-id-consistency/test.py | 0 .../compiler_arguments/app/build.gradle | 0 .../app/src/main/kotlin/testProject/App.kt | 0 .../compiler_arguments/compArgs.expected | 0 .../all-platforms}/compiler_arguments/compArgs.ql | 0 .../compiler_arguments/settings.gradle | 0 .../all-platforms}/compiler_arguments/test.py | 0 .../default-parameter-mad-flow/lib.kt | 0 .../default-parameter-mad-flow/qlpack.yml | 0 .../default-parameter-mad-flow/test.expected | 0 .../default-parameter-mad-flow/test.ext.yml | 0 .../default-parameter-mad-flow/test.py | 0 .../default-parameter-mad-flow/test.ql | 0 .../default-parameter-mad-flow/user.kt | 0 .../kotlin-version-too-new/diagnostics.expected | 0 .../com/intellij/mock/MockProject.java | 0 .../com/intellij/openapi/Disposable.java | 0 .../fake-kotlinc-source/driver/Main.java | 0 .../fake-kotlinc-source/kotlin/KotlinVersion.java | 0 .../org/jetbrains/kotlin/cli/common/ExitCode.java | 0 .../cli/common/arguments/CommonToolArguments.java | 0 .../common/arguments/K2JVMCompilerArguments.java | 0 .../arguments/ParseCommandLineArgumentsKt.java | 0 .../org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java | 0 .../kotlin/config/CompilerConfiguration.java | 0 .../org/jetbrains/kotlin/utils/KotlinPaths.java | 0 .../diagnostics/kotlin-version-too-new/test.py | 0 .../all-platforms}/enabling/KotlinDefault.kt | 0 .../all-platforms}/enabling/KotlinDisabled.kt | 0 .../all-platforms}/enabling/KotlinEnabled.kt | 0 .../all-platforms}/enabling/source_archive.expected | 0 .../all-platforms}/enabling/test.py | 0 .../enhanced-nullability/NotNull.java | 0 .../all-platforms}/enhanced-nullability/Test.java | 0 .../enhanced-nullability/test.expected | 0 .../all-platforms}/enhanced-nullability/test.py | 0 .../all-platforms}/enhanced-nullability/test.ql | 0 .../all-platforms}/enhanced-nullability/user.kt | 0 .../external-property-overloads/test.expected | 0 .../external-property-overloads/test.kt | 0 .../external-property-overloads/test.py | 0 .../external-property-overloads/test.ql | 0 .../external-property-overloads/user.kt | 0 .../all-platforms}/extractor_crash/classes.expected | 0 .../all-platforms}/extractor_crash/classes.ql | 0 .../all-platforms}/extractor_crash/code/A.kt | 0 .../all-platforms}/extractor_crash/code/B.kt | 0 .../all-platforms}/extractor_crash/code/C.kt | 0 .../extractor_crash/compilationFiles.expected | 0 .../extractor_crash/compilationFiles.ql | 0 .../extractor_crash/compilations.expected | 0 .../all-platforms}/extractor_crash/compilations.ql | 0 .../all-platforms}/extractor_crash/test.py | 0 .../ExtractorInformation.expected | 0 .../ExtractorInformation.ext.yml | 0 .../ExtractorInformation.qlref | 0 .../extractor_information_kotlin1/SomeClass.kt | 0 .../extractor_information_kotlin1/test.py | 0 .../ExtractorInformation.expected | 0 .../ExtractorInformation.ext.yml | 0 .../ExtractorInformation.qlref | 0 .../extractor_information_kotlin2/SomeClass.kt | 0 .../extractor_information_kotlin2/test.py | 0 .../all-platforms}/file_classes/A.kt | 0 .../all-platforms}/file_classes/B.kt | 0 .../all-platforms}/file_classes/C.kt | 0 .../all-platforms}/file_classes/classes.expected | 0 .../all-platforms}/file_classes/classes.ql | 0 .../all-platforms}/file_classes/test.py | 0 .../gradle_groovy_app/app/build.gradle | 0 .../app/src/main/kotlin/testProject/App.kt | 0 .../gradle_groovy_app/compilations.expected | 0 .../gradle_groovy_app/compilations.ql | 0 .../gradle_groovy_app/methods.expected | 0 .../all-platforms}/gradle_groovy_app/methods.ql | 0 .../gradle_groovy_app/settings.gradle | 0 .../all-platforms}/gradle_groovy_app/test.py | 0 .../ConstantExpAppearsNonConstant.expected | 0 .../ConstantExpAppearsNonConstant.qlref | 0 .../gradle_kotlinx_serialization/PrintAst.expected | 0 .../gradle_kotlinx_serialization/PrintAst.qlref | 0 .../gradle_kotlinx_serialization/app/build.gradle | 0 .../app/src/main/kotlin/testProject/App.kt | 0 .../gradle_kotlinx_serialization/diag.expected | 0 .../gradle_kotlinx_serialization/diag.ql | 0 .../gradle_kotlinx_serialization/settings.gradle | 0 .../gradle_kotlinx_serialization/test.py | 0 .../java-interface-redeclares-tostring/Test.java | 0 .../test.expected | 0 .../java-interface-redeclares-tostring/test.py | 0 .../java-interface-redeclares-tostring/test.ql | 0 .../java-interface-redeclares-tostring/user.kt | 0 .../java_modifiers/libsrc/extlib/A.java | 0 .../all-platforms}/java_modifiers/test.expected | 0 .../all-platforms}/java_modifiers/test.kt | 0 .../all-platforms}/java_modifiers/test.py | 0 .../all-platforms}/java_modifiers/test.ql | 0 .../jvmoverloads-external-class/User.java | 0 .../jvmoverloads-external-class/test.expected | 0 .../jvmoverloads-external-class/test.kt | 0 .../jvmoverloads-external-class/test.py | 0 .../jvmoverloads-external-class/test.ql | 0 .../jvmoverloads-external-class/user.kt | 0 .../kotlin-interface-inherited-default/User.java | 0 .../noforwards.kt | 0 .../test.expected | 0 .../kotlin-interface-inherited-default/test.kt | 0 .../kotlin-interface-inherited-default/test.py | 0 .../kotlin-interface-inherited-default/test.ql | 0 .../kotlin_compiler_java_source/J.java | 0 .../all-platforms}/kotlin_compiler_java_source/K.kt | 0 .../kotlin_compiler_java_source/K2.kt | 0 .../kotlin_compiler_java_source/jlocs.expected | 0 .../kotlin_compiler_java_source/jlocs.ql | 0 .../kotlin_compiler_java_source/test.py | 0 .../kotlin_file_import/libsrc/longsig.kt | 0 .../all-platforms}/kotlin_file_import/test.expected | 0 .../all-platforms}/kotlin_file_import/test.py | 0 .../all-platforms}/kotlin_file_import/test.ql | 0 .../all-platforms}/kotlin_file_import/user.kt | 0 .../kotlin_java_lowering_wildcards/JavaDefns.java | 0 .../kotlin_java_lowering_wildcards/JavaDefns2.java | 0 .../kotlin_java_lowering_wildcards/JavaUser.java | 0 .../kotlin_java_lowering_wildcards/kotlindefns.kt | 0 .../kotlin_java_lowering_wildcards/kotlinuser.kt | 0 .../kotlin_java_lowering_wildcards/test.expected | 0 .../kotlin_java_lowering_wildcards/test.py | 0 .../kotlin_java_lowering_wildcards/test.ql | 0 .../kotlin_java_static_fields/ReadsFields.java | 0 .../kotlin_java_static_fields/hasFields.kt | 0 .../kotlin_java_static_fields/test.expected | 0 .../kotlin_java_static_fields/test.py | 0 .../kotlin_java_static_fields/test.ql | 0 .../kotlin_kfunction/app/build.gradle | 0 .../app/src/main/kotlin/testProject/App.kt | 0 .../all-platforms}/kotlin_kfunction/diag.expected | 0 .../all-platforms}/kotlin_kfunction/diag.ql | 0 .../all-platforms}/kotlin_kfunction/settings.gradle | 0 .../all-platforms}/kotlin_kfunction/test.py | 0 .../all-platforms}/kotlinc_multi/FileA.kt | 0 .../all-platforms}/kotlinc_multi/FileB.kt | 0 .../kotlinc_multi/compilations.expected | 0 .../all-platforms}/kotlinc_multi/compilations.ql | 0 .../all-platforms}/kotlinc_multi/methods.expected | 0 .../all-platforms}/kotlinc_multi/methods.ql | 0 .../all-platforms}/kotlinc_multi/test.py | 0 .../all-platforms}/logs/logs.expected | 0 .../kotlin => kotlin/all-platforms}/logs/test.kt | 0 .../kotlin => kotlin/all-platforms}/logs/test.py | 0 .../nested_generic_types/JavaUser.java | 0 .../nested_generic_types/KotlinUser.kt | 0 .../libsrc/extlib/OuterGeneric.java | 0 .../libsrc/extlib/OuterManyParams.java | 0 .../libsrc/extlib/OuterNotGeneric.java | 0 .../libsrc/extlib/TypeParamVisibility.java | 0 .../nested_generic_types/test.expected | 0 .../all-platforms}/nested_generic_types/test.py | 0 .../all-platforms}/nested_generic_types/test.ql | 0 .../nullability-annotations/AnnotatedInterface.java | 0 .../nullability-annotations/AnnotatedMethods.java | 0 .../nullability-annotations/JavaUser.java | 0 .../nullability-annotations/ktUser.kt | 0 .../org/jetbrains/annotations/NotNull.java | 0 .../org/jetbrains/annotations/Nullable.java | 0 .../nullability-annotations/test.expected | 0 .../all-platforms}/nullability-annotations/test.py | 0 .../all-platforms}/nullability-annotations/test.ql | 0 .../nullability-annotations/zpkg/A.java | 0 .../path_transformer/classes.expected | 0 .../all-platforms}/path_transformer/classes.ql | 0 .../path_transformer/kotlin_source.kt | 0 .../all-platforms}/path_transformer/test.py | 0 .../private_property_accessors/hasprops.kt | 0 .../private_property_accessors/test.expected | 0 .../private_property_accessors/test.py | 0 .../private_property_accessors/test.ql | 0 .../private_property_accessors/usesprops.kt | 0 .../all-platforms}/raw_generic_types/JavaUser.java | 0 .../all-platforms}/raw_generic_types/KotlinUser.kt | 0 .../libsrc/extlib/GenericTypeJava.java | 0 .../libsrc/extlib/GenericTypeKotlin.java | 0 .../libsrc/extlib/RawTypesInSignatureJava.java | 0 .../libsrc/extlib/RawTypesInSignatureKotlin.java | 0 .../all-platforms}/raw_generic_types/test.expected | 0 .../all-platforms}/raw_generic_types/test.py | 0 .../all-platforms}/raw_generic_types/test.ql | 0 .../JavaDefinedContainer.java | 0 .../JavaDefinedRepeatable.java | 0 .../repeatable-annotations/JavaUser.java | 0 .../all-platforms}/repeatable-annotations/lib.kt | 0 .../repeatable-annotations/test.expected | 0 .../all-platforms}/repeatable-annotations/test.kt | 0 .../all-platforms}/repeatable-annotations/test.py | 0 .../all-platforms}/repeatable-annotations/test.ql | 0 .../all-platforms}/trap_compression/test.kt | 0 .../all-platforms}/trap_compression/test.py | 0 .../linux}/custom_plugin/PrintAst.expected | 0 .../linux}/custom_plugin/PrintAst.qlref | 0 .../kotlin => kotlin/linux}/custom_plugin/a.kt | 0 .../kotlin => kotlin/linux}/custom_plugin/b.kt | 0 .../kotlin => kotlin/linux}/custom_plugin/c.kt | 0 .../kotlin => kotlin/linux}/custom_plugin/d.kt | 0 .../linux}/custom_plugin/diag.expected | 0 .../kotlin => kotlin/linux}/custom_plugin/diag.ql | 0 .../kotlin => kotlin/linux}/custom_plugin/e.kt | 0 .../linux}/custom_plugin/methods.expected | 0 .../linux}/custom_plugin/methods.ql | 0 .../linux}/custom_plugin/plugin/BUILD.bazel | 0 .../linux}/custom_plugin/plugin/Plugin.kt | 0 ...brains.kotlin.compiler.plugin.ComponentRegistrar | 0 .../linux}/custom_plugin/qlpack.yml | 0 .../linux}/custom_plugin/rootClasses.expected | 0 .../linux}/custom_plugin/rootClasses.ql | 0 .../linux}/custom_plugin/staticinit.expected | 0 .../linux}/custom_plugin/staticinit.ql | 0 .../kotlin => kotlin/linux}/custom_plugin/test.py | 4 ++-- .../javasrc/extlib/BoundedGenericTest.java | 0 .../javasrc/extlib/ComplexBoundedGenericTest.java | 0 .../javasrc/extlib/GenericTest.java | 0 .../linux}/use_java_library/javasrc/extlib/Lib.java | 0 .../linux}/use_java_library/parameterTypes.expected | 0 .../linux}/use_java_library/parameterTypes.ql | 0 .../linux}/use_java_library/test.py | 0 .../linux}/use_java_library/user.kt | 0 .../posix}/generic-extension-property/User.java | 0 .../posix}/generic-extension-property/test.expected | 0 .../posix}/generic-extension-property/test.kt | 0 .../posix}/generic-extension-property/test.py | 0 .../posix}/generic-extension-property/test.ql | 0 .../java_kotlin_extraction_orders/test.expected | 0 .../posix}/java_kotlin_extraction_orders/test.py | 0 .../posix}/java_kotlin_extraction_orders/test.ql | 0 .../code/doubleIntercepted.kt | 0 .../kotlin_double_interception/code/manual.kt | 0 .../code/manuallyIntercepted.kt | 0 .../kotlin_double_interception/code/normal.kt | 0 .../kotlin_double_interception/code/notSeen.kt | 0 .../kotlin_double_interception/files.expected | 0 .../posix}/kotlin_double_interception/files.ql | 0 .../posix}/kotlin_double_interception/test.py | 0 .../posix}/module_mangled_names/User.java | 0 .../posix}/module_mangled_names/test.expected | 0 .../posix}/module_mangled_names/test.py | 0 .../posix}/module_mangled_names/test.ql | 0 .../posix}/module_mangled_names/test1.kt | 0 .../posix}/module_mangled_names/test2.kt | 0 .../posix}/module_mangled_names/test3.kt | 0 .../posix}/needless-java-wildcards/Test.java | 0 .../posix}/needless-java-wildcards/kConsumer.kt | 0 .../posix}/needless-java-wildcards/test.expected | 0 .../posix}/needless-java-wildcards/test.py | 0 .../posix}/needless-java-wildcards/test.ql | 0 .../posix}/needless-java-wildcards/user.kt | 0 865 files changed, 8 insertions(+), 2 deletions(-) rename java/ql/integration-tests/{all-platforms => }/java/android-8-sample/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-8-sample/project/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-8-sample/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-8-sample/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-8-sample/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-8-sample/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-8-sample/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script-no-wrapper/build.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script-no-wrapper/project/build.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script-no-wrapper/settings.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script-no-wrapper/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script-no-wrapper/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script/build.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script/project/build.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script/settings.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-kotlin-build-script/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-no-wrapper/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-no-wrapper/project/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-no-wrapper/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-no-wrapper/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-no-wrapper/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-no-wrapper/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-no-wrapper/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script-no-wrapper/README (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script-no-wrapper/build.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/build.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script-no-wrapper/settings.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script-no-wrapper/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script/README (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script/build.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script/project/build.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script/settings.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-kotlin-build-script/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-no-wrapper/README (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-no-wrapper/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-no-wrapper/project/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-no-wrapper/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-no-wrapper/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-no-wrapper/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-no-wrapper/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style-no-wrapper/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style/README (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style/project/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample-old-style/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample/project/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/android-sample/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/ant-sample/build.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/ant-sample/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/ant-sample/test.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/ant-sample/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/ant-sample/test.ql (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/src/main/java/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/test.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-dependency-different-repository/test.ql (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-erroneous/DatabaseQualityDiagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-erroneous/DatabaseQualityDiagnostics.qlref (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-erroneous/ExtractorInformation.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-erroneous/ExtractorInformation.qlref (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-erroneous/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-erroneous/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-erroneous/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-classifiers/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-classifiers/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-classifiers/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-classifiers/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-classifiers/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-classifiers/src/main/java/com/fractestexample/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-classifiers/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/.gitignore (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/gradle/verification-metadata.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/gradlew (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/gradlew.bat (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle-timeout/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle/src/main/java/com/fractestexample/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-gradle/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/cert.pem (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/jdk8_shipped_cacerts_plus_cert_pem (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/key.pem (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/server.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/src/main/java/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/test.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-inherit-trust-store/test.ql (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-executable-war/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod1/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod1/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod1/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod1/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod1/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod1/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod2/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod2/src/main/java/com/example/App2.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod2/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod2/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod2/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/submod2/src/test/java/com/example/AppTest2.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-multimodule/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/mvnw (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/mvnw.cmd (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-timeout/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-tolerate-unavailable-dependency/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-tolerate-unavailable-dependency/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-tolerate-unavailable-dependency/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-tolerate-unavailable-dependency/src/main/java/dlfs/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-tolerate-unavailable-dependency/src/site/site.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-tolerate-unavailable-dependency/src/test/java/dlfs/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven-tolerate-unavailable-dependency/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-maven/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-module-definition-not-in-module-info-file/PrintAst.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-module-definition-not-in-module-info-file/PrintAst.qlref (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-module-definition-not-in-module-info-file/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-module-definition-not-in-module-info-file/Test2.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-module-definition-not-in-module-info-file/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-gradle/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-gradle/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-gradle/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-gradle/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-gradle/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-gradle/src/main/java/com/fractestexample/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-gradle/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-proxy-maven/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/.gitignore (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/gradle/verification-metadata.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/gradlew (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/gradlew.bat (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/.gitignore (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/gradle/verification-metadata.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/gradlew (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/gradlew.bat (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/src/main/java/com/example/App2.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/gradle-sample2/src/test/java/com/example/AppTest2.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-1/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-1/src/main/java/com/example/App3.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-1/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-1/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-1/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-1/src/test/java/com/example/AppTest3.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-2/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-2/src/main/java/com/example/App4.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-2/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-2/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-2/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/maven-project-2/src/test/java/com/example/AppTest4.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-sibling-projects/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/buildless-fetches.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/src/main/java/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/test.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless-snapshot-repository/test.ql (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/buildless/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/android-gradle-incompatibility/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/android-gradle-incompatibility/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/android-gradle-incompatibility/project/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/android-gradle-incompatibility/project/src/main/AndroidManifest.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/android-gradle-incompatibility/project/src/main/java/com/github/androidsample/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/android-gradle-incompatibility/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/android-gradle-incompatibility/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/compilation-error/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/compilation-error/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/compilation-error/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/compilation-error/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/compilation-error/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/compilation-error/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/compilation-error/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/compilation-error/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/dependency-error/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/dependency-error/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/dependency-error/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/dependency-error/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/dependency-error/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/dependency-error/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/dependency-error/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/dependency-error/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/java-version-too-old/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/java-version-too-old/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/java-version-too-old/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/java-version-too-old/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/java-version-too-old/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/java-version-too-old/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/java-version-too-old/toolchains.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/mvnw (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/mvnw.cmd (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/maven-http-repository/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-1/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-1/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-2/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/maven-project-2/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/multiple-candidate-builds/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-build-system/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-build-system/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-build-system/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-test-classes/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-test-classes/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-test-classes/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-test-classes/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-wrapper/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-wrapper/.gitignore (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-wrapper/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-wrapper/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-wrapper/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-wrapper/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-wrapper/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/diagnostics/no-gradle-wrapper/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-sample-noexit/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-sample-noexit/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-sample-noexit/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-sample/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-sample/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-sample/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-tolerate-enum-annotations/Diag.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-tolerate-enum-annotations/Diag.ql (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-tolerate-enum-annotations/Test.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-tolerate-enum-annotations/Test2.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-tolerate-enum-annotations/test.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-tolerate-enum-annotations/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/ecj-tolerate-enum-annotations/test.ql (100%) rename java/ql/integration-tests/{all-platforms/java/partial-gradle-sample-without-gradle => java/gradle-sample-kotlin-script}/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample-kotlin-script/app/build.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample-kotlin-script/app/src/main/java/test/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample-kotlin-script/app/src/test/java/test/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample-kotlin-script/gradlew (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample-kotlin-script/gradlew.bat (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample-kotlin-script/settings.gradle.kts (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample-kotlin-script/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample-kotlin-script/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/gradle-sample/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/.gitignore (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/README.txt (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/spotbugs-security-exclude.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/spotbugs-security-include.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/java/com/acme/Counter.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/java/com/acme/Date2Tag.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/java/com/acme/DateServlet.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/java/com/acme/DateTag.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/java/com/acme/TagListener.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/LoggingUtil.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/Main.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/SystemOutHandler.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/resources/jetty-logging.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/resources/logging.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib.tld (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib2.tld (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/WEB-INF/applicationContext.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/WEB-INF/secret.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/WEB-INF/spring.tld (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/WEB-INF/tags/panel.tag (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/WEB-INF/web.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/WEB-INF/weblogic.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/include/${param.secret_param}.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/include/jsp_include_1.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/include/jsp_include_2_safe.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/include/jsp_include_3.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/index.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_1.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_2.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_3.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/random.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/spring/spring_eval_1.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/spring/spring_eval_2.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/spring/spring_eval_3.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/spring/spring_eval_4_safe.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/test/bean1.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/test/bean2.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/test/dump.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/test/expr.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/test/foo/foo.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/test/jstl.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/test/tag.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/test/tag2.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/test/tagfile.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/various.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xml/xml1.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xml/xml2.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xsl/xsl1.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xsl/xsl2.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xsl/xsl3.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xsl/xsl4.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xss/xss0.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xss/xss1.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xss/xss2.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xss/xss3.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xss/xss4.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/src/main/webapp/xss/xss5.jsp (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/test.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/java-web-jsp/test.ql (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-enforcer/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-enforcer/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-enforcer/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-enforcer/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-enforcer/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-enforcer/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-enforcer/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-enforcer/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-extract-properties/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-extract-properties/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-extract-properties/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-extract-properties/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-extract-properties/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-extract-properties/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-extract-properties/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-extract-properties/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-large-xml-files/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-large-xml-files/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-large-xml-files/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-large-xml-files/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-large-xml-files/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-large-xml-files/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-large-xml-files/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-large-xml-files/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-small-xml-files/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-small-xml-files/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-small-xml-files/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-small-xml-files/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-small-xml-files/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-small-xml-files/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-small-xml-files/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-small-xml-files/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-all/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-all/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-all/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-all/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-all/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-all/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-all/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-all/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-byname/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-byname/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-byname/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-byname/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-byname/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-byname/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-byname/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-byname/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-disabled/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-disabled/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-disabled/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-disabled/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-disabled/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-disabled/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-disabled/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-disabled/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-smart/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-smart/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-smart/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-smart/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-smart/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-smart/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-smart/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample-xml-mode-smart/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-sample/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/.mvn/wrapper/maven-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/mvnw (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/mvnw.cmd (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-script-only/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/.mvn/wrapper/MavenWrapperDownloader.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/.mvn/wrapper/maven-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/mvnw (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/mvnw.cmd (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper-source-only/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/.mvn/wrapper/maven-wrapper.jar (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/.mvn/wrapper/maven-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/mvnw (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/mvnw.cmd (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/pom.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/src/main/resources/my-app.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/src/main/resources/page.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/src/main/resources/struts.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/maven-wrapper/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java11/ExtractorInformation.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java11/ExtractorInformation.qlref (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java11/mod1/mod1pkg/Mod1Class.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java11/mod1/module-info.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java11/mod2/mod2pkg/User.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java11/mod2/module-info.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java11/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java17/ExtractorInformation.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java17/ExtractorInformation.qlref (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java17/mod1/mod1pkg/Mod1Class.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java17/mod1/module-info.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java17/mod2/mod2pkg/User.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java17/mod2/module-info.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/multi-release-jar-java17/test.py (100%) rename java/ql/integration-tests/{all-platforms/java/partial-gradle-sample => java/partial-gradle-sample-without-gradle}/.gitattributes (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/.gitignore (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/gradle/verification-metadata.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/gradle/wrapper/gradle-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/gradlew (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/gradlew.bat (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample-without-gradle/test.py (100%) create mode 100644 java/ql/integration-tests/java/partial-gradle-sample/.gitattributes rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/gradle/verification-metadata.xml (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/gradle/wrapper/gradle-wrapper.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/gradlew (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/gradlew.bat (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/src/main/java/com/example/App.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/src/test/java/com/example/AppTest.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/partial-gradle-sample/test.py (100%) rename java/ql/integration-tests/{all-platforms => }/java/spring-boot-sample/README (100%) rename java/ql/integration-tests/{all-platforms => }/java/spring-boot-sample/build.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/spring-boot-sample/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms => }/java/spring-boot-sample/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms => }/java/spring-boot-sample/src/main/java/com/github/springbootsample/SpringBootSampleApplication.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/spring-boot-sample/src/main/resources/application.properties (100%) rename java/ql/integration-tests/{all-platforms => }/java/spring-boot-sample/src/test/java/com/github/springbootsample/SpringBootSampleApplicationTests.java (100%) rename java/ql/integration-tests/{all-platforms => }/java/spring-boot-sample/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/PrintAst.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/PrintAst.qlref (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/User.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/deprecatedAnnotationTypes.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/deprecatedAnnotationTypes.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/ktUser.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/qlpack.yml (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/test.ext.yml (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/test.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/annotation-id-consistency/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/compiler_arguments/app/build.gradle (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/compiler_arguments/app/src/main/kotlin/testProject/App.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/compiler_arguments/compArgs.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/compiler_arguments/compArgs.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/compiler_arguments/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/compiler_arguments/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/default-parameter-mad-flow/lib.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/default-parameter-mad-flow/qlpack.yml (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/default-parameter-mad-flow/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/default-parameter-mad-flow/test.ext.yml (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/default-parameter-mad-flow/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/default-parameter-mad-flow/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/default-parameter-mad-flow/user.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/diagnostics.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/mock/MockProject.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/openapi/Disposable.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/driver/Main.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/kotlin/KotlinVersion.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/ExitCode.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/ParseCommandLineArgumentsKt.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/config/CompilerConfiguration.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/utils/KotlinPaths.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/diagnostics/kotlin-version-too-new/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enabling/KotlinDefault.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enabling/KotlinDisabled.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enabling/KotlinEnabled.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enabling/source_archive.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enabling/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enhanced-nullability/NotNull.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enhanced-nullability/Test.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enhanced-nullability/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enhanced-nullability/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enhanced-nullability/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/enhanced-nullability/user.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/external-property-overloads/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/external-property-overloads/test.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/external-property-overloads/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/external-property-overloads/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/external-property-overloads/user.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/classes.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/classes.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/code/A.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/code/B.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/code/C.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/compilationFiles.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/compilationFiles.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/compilations.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/compilations.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_crash/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin1/ExtractorInformation.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin1/ExtractorInformation.ext.yml (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin1/ExtractorInformation.qlref (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin1/SomeClass.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin1/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin2/ExtractorInformation.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin2/ExtractorInformation.ext.yml (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin2/ExtractorInformation.qlref (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin2/SomeClass.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/extractor_information_kotlin2/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/file_classes/A.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/file_classes/B.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/file_classes/C.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/file_classes/classes.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/file_classes/classes.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/file_classes/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_groovy_app/app/build.gradle (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_groovy_app/app/src/main/kotlin/testProject/App.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_groovy_app/compilations.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_groovy_app/compilations.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_groovy_app/methods.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_groovy_app/methods.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_groovy_app/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_groovy_app/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.qlref (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/PrintAst.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/PrintAst.qlref (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/app/build.gradle (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/app/src/main/kotlin/testProject/App.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/diag.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/diag.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/gradle_kotlinx_serialization/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java-interface-redeclares-tostring/Test.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java-interface-redeclares-tostring/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java-interface-redeclares-tostring/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java-interface-redeclares-tostring/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java-interface-redeclares-tostring/user.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java_modifiers/libsrc/extlib/A.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java_modifiers/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java_modifiers/test.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java_modifiers/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/java_modifiers/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/jvmoverloads-external-class/User.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/jvmoverloads-external-class/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/jvmoverloads-external-class/test.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/jvmoverloads-external-class/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/jvmoverloads-external-class/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/jvmoverloads-external-class/user.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin-interface-inherited-default/User.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin-interface-inherited-default/noforwards.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin-interface-inherited-default/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin-interface-inherited-default/test.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin-interface-inherited-default/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin-interface-inherited-default/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_compiler_java_source/J.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_compiler_java_source/K.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_compiler_java_source/K2.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_compiler_java_source/jlocs.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_compiler_java_source/jlocs.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_compiler_java_source/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_file_import/libsrc/longsig.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_file_import/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_file_import/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_file_import/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_file_import/user.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_lowering_wildcards/JavaDefns.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_lowering_wildcards/JavaDefns2.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_lowering_wildcards/JavaUser.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_lowering_wildcards/kotlindefns.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_lowering_wildcards/kotlinuser.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_lowering_wildcards/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_lowering_wildcards/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_lowering_wildcards/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_static_fields/ReadsFields.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_static_fields/hasFields.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_static_fields/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_static_fields/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_java_static_fields/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_kfunction/app/build.gradle (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_kfunction/app/src/main/kotlin/testProject/App.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_kfunction/diag.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_kfunction/diag.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_kfunction/settings.gradle (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlin_kfunction/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlinc_multi/FileA.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlinc_multi/FileB.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlinc_multi/compilations.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlinc_multi/compilations.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlinc_multi/methods.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlinc_multi/methods.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/kotlinc_multi/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/logs/logs.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/logs/test.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/logs/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nested_generic_types/JavaUser.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nested_generic_types/KotlinUser.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nested_generic_types/libsrc/extlib/OuterGeneric.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nested_generic_types/libsrc/extlib/OuterManyParams.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nested_generic_types/libsrc/extlib/OuterNotGeneric.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nested_generic_types/libsrc/extlib/TypeParamVisibility.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nested_generic_types/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nested_generic_types/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nested_generic_types/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/AnnotatedInterface.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/AnnotatedMethods.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/JavaUser.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/ktUser.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/org/jetbrains/annotations/NotNull.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/org/jetbrains/annotations/Nullable.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/nullability-annotations/zpkg/A.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/path_transformer/classes.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/path_transformer/classes.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/path_transformer/kotlin_source.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/path_transformer/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/private_property_accessors/hasprops.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/private_property_accessors/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/private_property_accessors/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/private_property_accessors/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/private_property_accessors/usesprops.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/raw_generic_types/JavaUser.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/raw_generic_types/KotlinUser.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/raw_generic_types/libsrc/extlib/GenericTypeJava.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/raw_generic_types/libsrc/extlib/GenericTypeKotlin.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/raw_generic_types/libsrc/extlib/RawTypesInSignatureJava.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/raw_generic_types/libsrc/extlib/RawTypesInSignatureKotlin.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/raw_generic_types/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/raw_generic_types/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/raw_generic_types/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/repeatable-annotations/JavaDefinedContainer.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/repeatable-annotations/JavaDefinedRepeatable.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/repeatable-annotations/JavaUser.java (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/repeatable-annotations/lib.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/repeatable-annotations/test.expected (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/repeatable-annotations/test.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/repeatable-annotations/test.py (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/repeatable-annotations/test.ql (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/trap_compression/test.kt (100%) rename java/ql/integration-tests/{all-platforms/kotlin => kotlin/all-platforms}/trap_compression/test.py (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/PrintAst.expected (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/PrintAst.qlref (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/a.kt (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/b.kt (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/c.kt (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/d.kt (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/diag.expected (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/diag.ql (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/e.kt (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/methods.expected (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/methods.ql (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/plugin/BUILD.bazel (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/plugin/Plugin.kt (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/qlpack.yml (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/rootClasses.expected (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/rootClasses.ql (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/staticinit.expected (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/staticinit.ql (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/custom_plugin/test.py (82%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/use_java_library/javasrc/extlib/BoundedGenericTest.java (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/use_java_library/javasrc/extlib/ComplexBoundedGenericTest.java (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/use_java_library/javasrc/extlib/GenericTest.java (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/use_java_library/javasrc/extlib/Lib.java (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/use_java_library/parameterTypes.expected (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/use_java_library/parameterTypes.ql (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/use_java_library/test.py (100%) rename java/ql/integration-tests/{linux-only/kotlin => kotlin/linux}/use_java_library/user.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/generic-extension-property/User.java (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/generic-extension-property/test.expected (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/generic-extension-property/test.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/generic-extension-property/test.py (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/generic-extension-property/test.ql (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/java_kotlin_extraction_orders/test.expected (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/java_kotlin_extraction_orders/test.py (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/java_kotlin_extraction_orders/test.ql (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/kotlin_double_interception/code/doubleIntercepted.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/kotlin_double_interception/code/manual.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/kotlin_double_interception/code/manuallyIntercepted.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/kotlin_double_interception/code/normal.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/kotlin_double_interception/code/notSeen.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/kotlin_double_interception/files.expected (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/kotlin_double_interception/files.ql (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/kotlin_double_interception/test.py (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/module_mangled_names/User.java (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/module_mangled_names/test.expected (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/module_mangled_names/test.py (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/module_mangled_names/test.ql (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/module_mangled_names/test1.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/module_mangled_names/test2.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/module_mangled_names/test3.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/needless-java-wildcards/Test.java (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/needless-java-wildcards/kConsumer.kt (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/needless-java-wildcards/test.expected (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/needless-java-wildcards/test.py (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/needless-java-wildcards/test.ql (100%) rename java/ql/integration-tests/{posix-only/kotlin => kotlin/posix}/needless-java-wildcards/user.kt (100%) diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/build.gradle b/java/ql/integration-tests/java/android-8-sample/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-8-sample/build.gradle rename to java/ql/integration-tests/java/android-8-sample/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/project/build.gradle b/java/ql/integration-tests/java/android-8-sample/project/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-8-sample/project/build.gradle rename to java/ql/integration-tests/java/android-8-sample/project/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/android-8-sample/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-8-sample/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/android-8-sample/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/android-8-sample/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-8-sample/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/android-8-sample/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/settings.gradle b/java/ql/integration-tests/java/android-8-sample/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-8-sample/settings.gradle rename to java/ql/integration-tests/java/android-8-sample/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/source_archive.expected b/java/ql/integration-tests/java/android-8-sample/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-8-sample/source_archive.expected rename to java/ql/integration-tests/java/android-8-sample/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/android-8-sample/test.py b/java/ql/integration-tests/java/android-8-sample/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-8-sample/test.py rename to java/ql/integration-tests/java/android-8-sample/test.py diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/build.gradle.kts b/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/build.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/build.gradle.kts rename to java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/build.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/project/build.gradle.kts b/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/project/build.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/project/build.gradle.kts rename to java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/project/build.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/settings.gradle.kts b/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/settings.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/settings.gradle.kts rename to java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/settings.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/source_archive.expected b/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/source_archive.expected rename to java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.py b/java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script-no-wrapper/test.py rename to java/ql/integration-tests/java/android-sample-kotlin-build-script-no-wrapper/test.py diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/build.gradle.kts b/java/ql/integration-tests/java/android-sample-kotlin-build-script/build.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/build.gradle.kts rename to java/ql/integration-tests/java/android-sample-kotlin-build-script/build.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/project/build.gradle.kts b/java/ql/integration-tests/java/android-sample-kotlin-build-script/project/build.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/project/build.gradle.kts rename to java/ql/integration-tests/java/android-sample-kotlin-build-script/project/build.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/android-sample-kotlin-build-script/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/android-sample-kotlin-build-script/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/android-sample-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/android-sample-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/settings.gradle.kts b/java/ql/integration-tests/java/android-sample-kotlin-build-script/settings.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/settings.gradle.kts rename to java/ql/integration-tests/java/android-sample-kotlin-build-script/settings.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/source_archive.expected b/java/ql/integration-tests/java/android-sample-kotlin-build-script/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/source_archive.expected rename to java/ql/integration-tests/java/android-sample-kotlin-build-script/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.py b/java/ql/integration-tests/java/android-sample-kotlin-build-script/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-kotlin-build-script/test.py rename to java/ql/integration-tests/java/android-sample-kotlin-build-script/test.py diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/build.gradle b/java/ql/integration-tests/java/android-sample-no-wrapper/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/build.gradle rename to java/ql/integration-tests/java/android-sample-no-wrapper/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/project/build.gradle b/java/ql/integration-tests/java/android-sample-no-wrapper/project/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/project/build.gradle rename to java/ql/integration-tests/java/android-sample-no-wrapper/project/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/android-sample-no-wrapper/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/android-sample-no-wrapper/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/android-sample-no-wrapper/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/android-sample-no-wrapper/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/settings.gradle b/java/ql/integration-tests/java/android-sample-no-wrapper/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/settings.gradle rename to java/ql/integration-tests/java/android-sample-no-wrapper/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/source_archive.expected b/java/ql/integration-tests/java/android-sample-no-wrapper/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/source_archive.expected rename to java/ql/integration-tests/java/android-sample-no-wrapper/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.py b/java/ql/integration-tests/java/android-sample-no-wrapper/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-no-wrapper/test.py rename to java/ql/integration-tests/java/android-sample-no-wrapper/test.py diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/README b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/README similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/README rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/README diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/build.gradle.kts b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/build.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/build.gradle.kts rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/build.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/build.gradle.kts b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/build.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/build.gradle.kts rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/build.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/settings.gradle.kts b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/settings.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/settings.gradle.kts rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/settings.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/source_archive.expected b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/source_archive.expected rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script-no-wrapper/test.py diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/.gitattributes b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/.gitattributes rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/README b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/README similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/README rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/README diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/build.gradle.kts b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/build.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/build.gradle.kts rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/build.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/project/build.gradle.kts b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/project/build.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/project/build.gradle.kts rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/project/build.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/settings.gradle.kts b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/settings.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/settings.gradle.kts rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/settings.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/source_archive.expected b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/source_archive.expected rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.py b/java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-kotlin-build-script/test.py rename to java/ql/integration-tests/java/android-sample-old-style-kotlin-build-script/test.py diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/README b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/README similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/README rename to java/ql/integration-tests/java/android-sample-old-style-no-wrapper/README diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/build.gradle b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/build.gradle rename to java/ql/integration-tests/java/android-sample-old-style-no-wrapper/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/project/build.gradle b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/project/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/project/build.gradle rename to java/ql/integration-tests/java/android-sample-old-style-no-wrapper/project/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/android-sample-old-style-no-wrapper/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/android-sample-old-style-no-wrapper/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/settings.gradle b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/settings.gradle rename to java/ql/integration-tests/java/android-sample-old-style-no-wrapper/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/source_archive.expected b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/source_archive.expected rename to java/ql/integration-tests/java/android-sample-old-style-no-wrapper/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.py b/java/ql/integration-tests/java/android-sample-old-style-no-wrapper/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style-no-wrapper/test.py rename to java/ql/integration-tests/java/android-sample-old-style-no-wrapper/test.py diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/README b/java/ql/integration-tests/java/android-sample-old-style/README similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style/README rename to java/ql/integration-tests/java/android-sample-old-style/README diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/build.gradle b/java/ql/integration-tests/java/android-sample-old-style/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style/build.gradle rename to java/ql/integration-tests/java/android-sample-old-style/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/project/build.gradle b/java/ql/integration-tests/java/android-sample-old-style/project/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style/project/build.gradle rename to java/ql/integration-tests/java/android-sample-old-style/project/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/android-sample-old-style/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/android-sample-old-style/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/android-sample-old-style/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/android-sample-old-style/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/settings.gradle b/java/ql/integration-tests/java/android-sample-old-style/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style/settings.gradle rename to java/ql/integration-tests/java/android-sample-old-style/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/source_archive.expected b/java/ql/integration-tests/java/android-sample-old-style/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style/source_archive.expected rename to java/ql/integration-tests/java/android-sample-old-style/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.py b/java/ql/integration-tests/java/android-sample-old-style/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample-old-style/test.py rename to java/ql/integration-tests/java/android-sample-old-style/test.py diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/build.gradle b/java/ql/integration-tests/java/android-sample/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample/build.gradle rename to java/ql/integration-tests/java/android-sample/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/project/build.gradle b/java/ql/integration-tests/java/android-sample/project/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample/project/build.gradle rename to java/ql/integration-tests/java/android-sample/project/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/android-sample/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/android-sample/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/android-sample/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/android-sample/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/settings.gradle b/java/ql/integration-tests/java/android-sample/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample/settings.gradle rename to java/ql/integration-tests/java/android-sample/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/source_archive.expected b/java/ql/integration-tests/java/android-sample/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample/source_archive.expected rename to java/ql/integration-tests/java/android-sample/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/android-sample/test.py b/java/ql/integration-tests/java/android-sample/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/android-sample/test.py rename to java/ql/integration-tests/java/android-sample/test.py diff --git a/java/ql/integration-tests/all-platforms/java/ant-sample/build.xml b/java/ql/integration-tests/java/ant-sample/build.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ant-sample/build.xml rename to java/ql/integration-tests/java/ant-sample/build.xml diff --git a/java/ql/integration-tests/all-platforms/java/ant-sample/src/main/java/com/example/App.java b/java/ql/integration-tests/java/ant-sample/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ant-sample/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/ant-sample/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/ant-sample/test.expected b/java/ql/integration-tests/java/ant-sample/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ant-sample/test.expected rename to java/ql/integration-tests/java/ant-sample/test.expected diff --git a/java/ql/integration-tests/all-platforms/java/ant-sample/test.py b/java/ql/integration-tests/java/ant-sample/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ant-sample/test.py rename to java/ql/integration-tests/java/ant-sample/test.py diff --git a/java/ql/integration-tests/all-platforms/java/ant-sample/test.ql b/java/ql/integration-tests/java/ant-sample/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ant-sample/test.ql rename to java/ql/integration-tests/java/ant-sample/test.ql diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-dependency-different-repository/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-dependency-different-repository/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/pom.xml b/java/ql/integration-tests/java/buildless-dependency-different-repository/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/pom.xml rename to java/ql/integration-tests/java/buildless-dependency-different-repository/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.md5 b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.md5 rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.sha1 b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.sha1 rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.jar.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.md5 b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.md5 rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.sha1 b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.sha1 rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo/releases/com/github/my/other/repo/test/otherreleasetest/1.0/otherreleasetest-1.0.pom.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.md5 b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.md5 rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.sha1 b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.sha1 rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.jar.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.md5 b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.md5 rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.sha1 b/java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.sha1 rename to java/ql/integration-tests/java/buildless-dependency-different-repository/repo2/releases/com/github/hosted/in/other/repo/test/inotherrepo/1.0/inotherrepo-1.0.pom.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/src/main/java/Test.java b/java/ql/integration-tests/java/buildless-dependency-different-repository/src/main/java/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/src/main/java/Test.java rename to java/ql/integration-tests/java/buildless-dependency-different-repository/src/main/java/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.expected b/java/ql/integration-tests/java/buildless-dependency-different-repository/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.expected rename to java/ql/integration-tests/java/buildless-dependency-different-repository/test.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.py b/java/ql/integration-tests/java/buildless-dependency-different-repository/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.py rename to java/ql/integration-tests/java/buildless-dependency-different-repository/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.ql b/java/ql/integration-tests/java/buildless-dependency-different-repository/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-dependency-different-repository/test.ql rename to java/ql/integration-tests/java/buildless-dependency-different-repository/test.ql diff --git a/java/ql/integration-tests/all-platforms/java/buildless-erroneous/DatabaseQualityDiagnostics.expected b/java/ql/integration-tests/java/buildless-erroneous/DatabaseQualityDiagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-erroneous/DatabaseQualityDiagnostics.expected rename to java/ql/integration-tests/java/buildless-erroneous/DatabaseQualityDiagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-erroneous/DatabaseQualityDiagnostics.qlref b/java/ql/integration-tests/java/buildless-erroneous/DatabaseQualityDiagnostics.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-erroneous/DatabaseQualityDiagnostics.qlref rename to java/ql/integration-tests/java/buildless-erroneous/DatabaseQualityDiagnostics.qlref diff --git a/java/ql/integration-tests/all-platforms/java/buildless-erroneous/ExtractorInformation.expected b/java/ql/integration-tests/java/buildless-erroneous/ExtractorInformation.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-erroneous/ExtractorInformation.expected rename to java/ql/integration-tests/java/buildless-erroneous/ExtractorInformation.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-erroneous/ExtractorInformation.qlref b/java/ql/integration-tests/java/buildless-erroneous/ExtractorInformation.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-erroneous/ExtractorInformation.qlref rename to java/ql/integration-tests/java/buildless-erroneous/ExtractorInformation.qlref diff --git a/java/ql/integration-tests/all-platforms/java/buildless-erroneous/Test.java b/java/ql/integration-tests/java/buildless-erroneous/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-erroneous/Test.java rename to java/ql/integration-tests/java/buildless-erroneous/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-erroneous/diagnostics.expected b/java/ql/integration-tests/java/buildless-erroneous/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-erroneous/diagnostics.expected rename to java/ql/integration-tests/java/buildless-erroneous/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-erroneous/test.py b/java/ql/integration-tests/java/buildless-erroneous/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-erroneous/test.py rename to java/ql/integration-tests/java/buildless-erroneous/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/build.gradle b/java/ql/integration-tests/java/buildless-gradle-classifiers/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/build.gradle rename to java/ql/integration-tests/java/buildless-gradle-classifiers/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-gradle-classifiers/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-gradle-classifiers/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/diagnostics.expected b/java/ql/integration-tests/java/buildless-gradle-classifiers/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/diagnostics.expected rename to java/ql/integration-tests/java/buildless-gradle-classifiers/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/settings.gradle b/java/ql/integration-tests/java/buildless-gradle-classifiers/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/settings.gradle rename to java/ql/integration-tests/java/buildless-gradle-classifiers/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/source_archive.expected b/java/ql/integration-tests/java/buildless-gradle-classifiers/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/source_archive.expected rename to java/ql/integration-tests/java/buildless-gradle-classifiers/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/src/main/java/com/fractestexample/Test.java b/java/ql/integration-tests/java/buildless-gradle-classifiers/src/main/java/com/fractestexample/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/src/main/java/com/fractestexample/Test.java rename to java/ql/integration-tests/java/buildless-gradle-classifiers/src/main/java/com/fractestexample/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.py b/java/ql/integration-tests/java/buildless-gradle-classifiers/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-classifiers/test.py rename to java/ql/integration-tests/java/buildless-gradle-classifiers/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/.gitattributes b/java/ql/integration-tests/java/buildless-gradle-timeout/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/.gitattributes rename to java/ql/integration-tests/java/buildless-gradle-timeout/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/.gitignore b/java/ql/integration-tests/java/buildless-gradle-timeout/.gitignore similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/.gitignore rename to java/ql/integration-tests/java/buildless-gradle-timeout/.gitignore diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/build.gradle b/java/ql/integration-tests/java/buildless-gradle-timeout/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/build.gradle rename to java/ql/integration-tests/java/buildless-gradle-timeout/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/diagnostics.expected b/java/ql/integration-tests/java/buildless-gradle-timeout/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/diagnostics.expected rename to java/ql/integration-tests/java/buildless-gradle-timeout/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradle/verification-metadata.xml b/java/ql/integration-tests/java/buildless-gradle-timeout/gradle/verification-metadata.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradle/verification-metadata.xml rename to java/ql/integration-tests/java/buildless-gradle-timeout/gradle/verification-metadata.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.jar rename to java/ql/integration-tests/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.jar diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.properties rename to java/ql/integration-tests/java/buildless-gradle-timeout/gradle/wrapper/gradle-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradlew b/java/ql/integration-tests/java/buildless-gradle-timeout/gradlew similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradlew rename to java/ql/integration-tests/java/buildless-gradle-timeout/gradlew diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradlew.bat b/java/ql/integration-tests/java/buildless-gradle-timeout/gradlew.bat similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/gradlew.bat rename to java/ql/integration-tests/java/buildless-gradle-timeout/gradlew.bat diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/settings.gradle b/java/ql/integration-tests/java/buildless-gradle-timeout/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/settings.gradle rename to java/ql/integration-tests/java/buildless-gradle-timeout/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/source_archive.expected b/java/ql/integration-tests/java/buildless-gradle-timeout/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/source_archive.expected rename to java/ql/integration-tests/java/buildless-gradle-timeout/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/src/main/java/com/example/App.java b/java/ql/integration-tests/java/buildless-gradle-timeout/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/buildless-gradle-timeout/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/buildless-gradle-timeout/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/buildless-gradle-timeout/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.py b/java/ql/integration-tests/java/buildless-gradle-timeout/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle-timeout/test.py rename to java/ql/integration-tests/java/buildless-gradle-timeout/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/build.gradle b/java/ql/integration-tests/java/buildless-gradle/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle/build.gradle rename to java/ql/integration-tests/java/buildless-gradle/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-gradle/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-gradle/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/diagnostics.expected b/java/ql/integration-tests/java/buildless-gradle/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle/diagnostics.expected rename to java/ql/integration-tests/java/buildless-gradle/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/settings.gradle b/java/ql/integration-tests/java/buildless-gradle/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle/settings.gradle rename to java/ql/integration-tests/java/buildless-gradle/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/source_archive.expected b/java/ql/integration-tests/java/buildless-gradle/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle/source_archive.expected rename to java/ql/integration-tests/java/buildless-gradle/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/src/main/java/com/fractestexample/Test.java b/java/ql/integration-tests/java/buildless-gradle/src/main/java/com/fractestexample/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle/src/main/java/com/fractestexample/Test.java rename to java/ql/integration-tests/java/buildless-gradle/src/main/java/com/fractestexample/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-gradle/test.py b/java/ql/integration-tests/java/buildless-gradle/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-gradle/test.py rename to java/ql/integration-tests/java/buildless-gradle/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-inherit-trust-store/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-inherit-trust-store/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/cert.pem b/java/ql/integration-tests/java/buildless-inherit-trust-store/cert.pem similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/cert.pem rename to java/ql/integration-tests/java/buildless-inherit-trust-store/cert.pem diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/diagnostics.expected b/java/ql/integration-tests/java/buildless-inherit-trust-store/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/diagnostics.expected rename to java/ql/integration-tests/java/buildless-inherit-trust-store/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/jdk8_shipped_cacerts_plus_cert_pem b/java/ql/integration-tests/java/buildless-inherit-trust-store/jdk8_shipped_cacerts_plus_cert_pem similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/jdk8_shipped_cacerts_plus_cert_pem rename to java/ql/integration-tests/java/buildless-inherit-trust-store/jdk8_shipped_cacerts_plus_cert_pem diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/key.pem b/java/ql/integration-tests/java/buildless-inherit-trust-store/key.pem similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/key.pem rename to java/ql/integration-tests/java/buildless-inherit-trust-store/key.pem diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/pom.xml b/java/ql/integration-tests/java/buildless-inherit-trust-store/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/pom.xml rename to java/ql/integration-tests/java/buildless-inherit-trust-store/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml b/java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml rename to java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 b/java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 rename to java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 b/java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 rename to java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar b/java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar rename to java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 b/java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 rename to java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 b/java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 rename to java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom b/java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom rename to java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 b/java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 rename to java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 b/java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 rename to java/ql/integration-tests/java/buildless-inherit-trust-store/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/server.py b/java/ql/integration-tests/java/buildless-inherit-trust-store/server.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/server.py rename to java/ql/integration-tests/java/buildless-inherit-trust-store/server.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/src/main/java/Test.java b/java/ql/integration-tests/java/buildless-inherit-trust-store/src/main/java/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/src/main/java/Test.java rename to java/ql/integration-tests/java/buildless-inherit-trust-store/src/main/java/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.expected b/java/ql/integration-tests/java/buildless-inherit-trust-store/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.expected rename to java/ql/integration-tests/java/buildless-inherit-trust-store/test.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.py b/java/ql/integration-tests/java/buildless-inherit-trust-store/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.py rename to java/ql/integration-tests/java/buildless-inherit-trust-store/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.ql b/java/ql/integration-tests/java/buildless-inherit-trust-store/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-inherit-trust-store/test.ql rename to java/ql/integration-tests/java/buildless-inherit-trust-store/test.ql diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-maven-executable-war/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-maven-executable-war/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/diagnostics.expected b/java/ql/integration-tests/java/buildless-maven-executable-war/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/diagnostics.expected rename to java/ql/integration-tests/java/buildless-maven-executable-war/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/pom.xml b/java/ql/integration-tests/java/buildless-maven-executable-war/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/pom.xml rename to java/ql/integration-tests/java/buildless-maven-executable-war/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/source_archive.expected b/java/ql/integration-tests/java/buildless-maven-executable-war/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/source_archive.expected rename to java/ql/integration-tests/java/buildless-maven-executable-war/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/main/java/com/example/App.java b/java/ql/integration-tests/java/buildless-maven-executable-war/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/buildless-maven-executable-war/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/main/resources/my-app.properties b/java/ql/integration-tests/java/buildless-maven-executable-war/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/buildless-maven-executable-war/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/main/resources/page.xml b/java/ql/integration-tests/java/buildless-maven-executable-war/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/main/resources/page.xml rename to java/ql/integration-tests/java/buildless-maven-executable-war/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/main/resources/struts.xml b/java/ql/integration-tests/java/buildless-maven-executable-war/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/main/resources/struts.xml rename to java/ql/integration-tests/java/buildless-maven-executable-war/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/buildless-maven-executable-war/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/buildless-maven-executable-war/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.py b/java/ql/integration-tests/java/buildless-maven-executable-war/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-executable-war/test.py rename to java/ql/integration-tests/java/buildless-maven-executable-war/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-maven-multimodule/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-maven-multimodule/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/diagnostics.expected b/java/ql/integration-tests/java/buildless-maven-multimodule/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/diagnostics.expected rename to java/ql/integration-tests/java/buildless-maven-multimodule/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/pom.xml b/java/ql/integration-tests/java/buildless-maven-multimodule/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/pom.xml rename to java/ql/integration-tests/java/buildless-maven-multimodule/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/source_archive.expected b/java/ql/integration-tests/java/buildless-maven-multimodule/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/source_archive.expected rename to java/ql/integration-tests/java/buildless-maven-multimodule/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/pom.xml b/java/ql/integration-tests/java/buildless-maven-multimodule/submod1/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/pom.xml rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod1/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/main/java/com/example/App.java b/java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/main/resources/my-app.properties b/java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/main/resources/page.xml b/java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/main/resources/page.xml rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/main/resources/struts.xml b/java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/main/resources/struts.xml rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod1/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod1/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/pom.xml b/java/ql/integration-tests/java/buildless-maven-multimodule/submod2/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/pom.xml rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod2/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/main/java/com/example/App2.java b/java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/main/java/com/example/App2.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/main/java/com/example/App2.java rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/main/java/com/example/App2.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/main/resources/my-app.properties b/java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/main/resources/page.xml b/java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/main/resources/page.xml rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/main/resources/struts.xml b/java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/main/resources/struts.xml rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/test/java/com/example/AppTest2.java b/java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/test/java/com/example/AppTest2.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/submod2/src/test/java/com/example/AppTest2.java rename to java/ql/integration-tests/java/buildless-maven-multimodule/submod2/src/test/java/com/example/AppTest2.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.py b/java/ql/integration-tests/java/buildless-maven-multimodule/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-multimodule/test.py rename to java/ql/integration-tests/java/buildless-maven-multimodule/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/.gitattributes b/java/ql/integration-tests/java/buildless-maven-timeout/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/.gitattributes rename to java/ql/integration-tests/java/buildless-maven-timeout/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.jar b/java/ql/integration-tests/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.jar rename to java/ql/integration-tests/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.jar diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.properties b/java/ql/integration-tests/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.properties rename to java/ql/integration-tests/java/buildless-maven-timeout/.mvn/wrapper/maven-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/diagnostics.expected b/java/ql/integration-tests/java/buildless-maven-timeout/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/diagnostics.expected rename to java/ql/integration-tests/java/buildless-maven-timeout/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/mvnw b/java/ql/integration-tests/java/buildless-maven-timeout/mvnw similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/mvnw rename to java/ql/integration-tests/java/buildless-maven-timeout/mvnw diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/mvnw.cmd b/java/ql/integration-tests/java/buildless-maven-timeout/mvnw.cmd similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/mvnw.cmd rename to java/ql/integration-tests/java/buildless-maven-timeout/mvnw.cmd diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/pom.xml b/java/ql/integration-tests/java/buildless-maven-timeout/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/pom.xml rename to java/ql/integration-tests/java/buildless-maven-timeout/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/source_archive.expected b/java/ql/integration-tests/java/buildless-maven-timeout/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/source_archive.expected rename to java/ql/integration-tests/java/buildless-maven-timeout/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/main/java/com/example/App.java b/java/ql/integration-tests/java/buildless-maven-timeout/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/buildless-maven-timeout/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/main/resources/my-app.properties b/java/ql/integration-tests/java/buildless-maven-timeout/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/buildless-maven-timeout/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/main/resources/page.xml b/java/ql/integration-tests/java/buildless-maven-timeout/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/main/resources/page.xml rename to java/ql/integration-tests/java/buildless-maven-timeout/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/main/resources/struts.xml b/java/ql/integration-tests/java/buildless-maven-timeout/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/main/resources/struts.xml rename to java/ql/integration-tests/java/buildless-maven-timeout/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/buildless-maven-timeout/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/buildless-maven-timeout/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.py b/java/ql/integration-tests/java/buildless-maven-timeout/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-timeout/test.py rename to java/ql/integration-tests/java/buildless-maven-timeout/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/diagnostics.expected b/java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/diagnostics.expected rename to java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/pom.xml b/java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/pom.xml rename to java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/src/main/java/dlfs/App.java b/java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/src/main/java/dlfs/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/src/main/java/dlfs/App.java rename to java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/src/main/java/dlfs/App.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/src/site/site.xml b/java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/src/site/site.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/src/site/site.xml rename to java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/src/site/site.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/src/test/java/dlfs/AppTest.java b/java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/src/test/java/dlfs/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/src/test/java/dlfs/AppTest.java rename to java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/src/test/java/dlfs/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/test.py b/java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven-tolerate-unavailable-dependency/test.py rename to java/ql/integration-tests/java/buildless-maven-tolerate-unavailable-dependency/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-maven/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-maven/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/diagnostics.expected b/java/ql/integration-tests/java/buildless-maven/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/diagnostics.expected rename to java/ql/integration-tests/java/buildless-maven/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/pom.xml b/java/ql/integration-tests/java/buildless-maven/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/pom.xml rename to java/ql/integration-tests/java/buildless-maven/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/source_archive.expected b/java/ql/integration-tests/java/buildless-maven/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/source_archive.expected rename to java/ql/integration-tests/java/buildless-maven/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/src/main/java/com/example/App.java b/java/ql/integration-tests/java/buildless-maven/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/buildless-maven/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/src/main/resources/my-app.properties b/java/ql/integration-tests/java/buildless-maven/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/buildless-maven/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/src/main/resources/page.xml b/java/ql/integration-tests/java/buildless-maven/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/src/main/resources/page.xml rename to java/ql/integration-tests/java/buildless-maven/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/src/main/resources/struts.xml b/java/ql/integration-tests/java/buildless-maven/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/src/main/resources/struts.xml rename to java/ql/integration-tests/java/buildless-maven/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/buildless-maven/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/buildless-maven/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-maven/test.py b/java/ql/integration-tests/java/buildless-maven/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-maven/test.py rename to java/ql/integration-tests/java/buildless-maven/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/PrintAst.expected b/java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/PrintAst.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/PrintAst.expected rename to java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/PrintAst.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/PrintAst.qlref b/java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/PrintAst.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/PrintAst.qlref rename to java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/PrintAst.qlref diff --git a/java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/Test.java b/java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/Test.java rename to java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/Test2.java b/java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/Test2.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/Test2.java rename to java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/Test2.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/test.py b/java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-module-definition-not-in-module-info-file/test.py rename to java/ql/integration-tests/java/buildless-module-definition-not-in-module-info-file/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/build.gradle b/java/ql/integration-tests/java/buildless-proxy-gradle/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/build.gradle rename to java/ql/integration-tests/java/buildless-proxy-gradle/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-proxy-gradle/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-proxy-gradle/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/diagnostics.expected b/java/ql/integration-tests/java/buildless-proxy-gradle/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/diagnostics.expected rename to java/ql/integration-tests/java/buildless-proxy-gradle/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/settings.gradle b/java/ql/integration-tests/java/buildless-proxy-gradle/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/settings.gradle rename to java/ql/integration-tests/java/buildless-proxy-gradle/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/source_archive.expected b/java/ql/integration-tests/java/buildless-proxy-gradle/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/source_archive.expected rename to java/ql/integration-tests/java/buildless-proxy-gradle/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/src/main/java/com/fractestexample/Test.java b/java/ql/integration-tests/java/buildless-proxy-gradle/src/main/java/com/fractestexample/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/src/main/java/com/fractestexample/Test.java rename to java/ql/integration-tests/java/buildless-proxy-gradle/src/main/java/com/fractestexample/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.py b/java/ql/integration-tests/java/buildless-proxy-gradle/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-gradle/test.py rename to java/ql/integration-tests/java/buildless-proxy-gradle/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-proxy-maven/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-proxy-maven/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/diagnostics.expected b/java/ql/integration-tests/java/buildless-proxy-maven/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/diagnostics.expected rename to java/ql/integration-tests/java/buildless-proxy-maven/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/pom.xml b/java/ql/integration-tests/java/buildless-proxy-maven/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/pom.xml rename to java/ql/integration-tests/java/buildless-proxy-maven/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/source_archive.expected b/java/ql/integration-tests/java/buildless-proxy-maven/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/source_archive.expected rename to java/ql/integration-tests/java/buildless-proxy-maven/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/main/java/com/example/App.java b/java/ql/integration-tests/java/buildless-proxy-maven/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/buildless-proxy-maven/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/main/resources/my-app.properties b/java/ql/integration-tests/java/buildless-proxy-maven/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/buildless-proxy-maven/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/main/resources/page.xml b/java/ql/integration-tests/java/buildless-proxy-maven/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/main/resources/page.xml rename to java/ql/integration-tests/java/buildless-proxy-maven/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/main/resources/struts.xml b/java/ql/integration-tests/java/buildless-proxy-maven/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/main/resources/struts.xml rename to java/ql/integration-tests/java/buildless-proxy-maven/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/buildless-proxy-maven/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/buildless-proxy-maven/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.py b/java/ql/integration-tests/java/buildless-proxy-maven/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-proxy-maven/test.py rename to java/ql/integration-tests/java/buildless-proxy-maven/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-sibling-projects/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-sibling-projects/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/diagnostics.expected b/java/ql/integration-tests/java/buildless-sibling-projects/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/diagnostics.expected rename to java/ql/integration-tests/java/buildless-sibling-projects/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/.gitattributes b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/.gitattributes rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/.gitignore b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/.gitignore similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/.gitignore rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/.gitignore diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/build.gradle b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/build.gradle rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradle/verification-metadata.xml b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradle/verification-metadata.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradle/verification-metadata.xml rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradle/verification-metadata.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.jar rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.jar diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.properties rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradle/wrapper/gradle-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradlew b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradlew similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradlew rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradlew diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradlew.bat b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradlew.bat similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/gradlew.bat rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/gradlew.bat diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/settings.gradle b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/settings.gradle rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/src/main/java/com/example/App.java b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/.gitattributes b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/.gitattributes rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/.gitignore b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/.gitignore similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/.gitignore rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/.gitignore diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/build.gradle b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/build.gradle rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradle/verification-metadata.xml b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradle/verification-metadata.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradle/verification-metadata.xml rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradle/verification-metadata.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.jar b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.jar rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.jar diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.properties rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradle/wrapper/gradle-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradlew b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradlew similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradlew rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradlew diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradlew.bat b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradlew.bat similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/gradlew.bat rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/gradlew.bat diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/settings.gradle b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/settings.gradle rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/src/main/java/com/example/App2.java b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/src/main/java/com/example/App2.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/src/main/java/com/example/App2.java rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/src/main/java/com/example/App2.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/src/test/java/com/example/AppTest2.java b/java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/src/test/java/com/example/AppTest2.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/gradle-sample2/src/test/java/com/example/AppTest2.java rename to java/ql/integration-tests/java/buildless-sibling-projects/gradle-sample2/src/test/java/com/example/AppTest2.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/pom.xml b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/pom.xml rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/main/java/com/example/App3.java b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/main/java/com/example/App3.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/main/java/com/example/App3.java rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/main/java/com/example/App3.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/main/resources/my-app.properties b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/main/resources/page.xml b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/main/resources/page.xml rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/main/resources/struts.xml b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/main/resources/struts.xml rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/test/java/com/example/AppTest3.java b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/test/java/com/example/AppTest3.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-1/src/test/java/com/example/AppTest3.java rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-1/src/test/java/com/example/AppTest3.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/pom.xml b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/pom.xml rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/main/java/com/example/App4.java b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/main/java/com/example/App4.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/main/java/com/example/App4.java rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/main/java/com/example/App4.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/main/resources/my-app.properties b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/main/resources/page.xml b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/main/resources/page.xml rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/main/resources/struts.xml b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/main/resources/struts.xml rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/test/java/com/example/AppTest4.java b/java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/test/java/com/example/AppTest4.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/maven-project-2/src/test/java/com/example/AppTest4.java rename to java/ql/integration-tests/java/buildless-sibling-projects/maven-project-2/src/test/java/com/example/AppTest4.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/source_archive.expected b/java/ql/integration-tests/java/buildless-sibling-projects/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/source_archive.expected rename to java/ql/integration-tests/java/buildless-sibling-projects/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.py b/java/ql/integration-tests/java/buildless-sibling-projects/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-sibling-projects/test.py rename to java/ql/integration-tests/java/buildless-sibling-projects/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/buildless-fetches.expected b/java/ql/integration-tests/java/buildless-snapshot-repository/buildless-fetches.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/buildless-fetches.expected rename to java/ql/integration-tests/java/buildless-snapshot-repository/buildless-fetches.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/pom.xml b/java/ql/integration-tests/java/buildless-snapshot-repository/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/pom.xml rename to java/ql/integration-tests/java/buildless-snapshot-repository/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml b/java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml rename to java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 b/java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 rename to java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 b/java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 rename to java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/maven-metadata.xml.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar b/java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar rename to java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 b/java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 rename to java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 b/java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 rename to java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.jar.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom b/java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom rename to java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 b/java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 rename to java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.md5 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 b/java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 rename to java/ql/integration-tests/java/buildless-snapshot-repository/repo/snapshots/com/github/my/snapshot/test/snapshottest/1.0-SNAPSHOT/snapshottest-1.0-20230901.050514-100.pom.sha1 diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/src/main/java/Test.java b/java/ql/integration-tests/java/buildless-snapshot-repository/src/main/java/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/src/main/java/Test.java rename to java/ql/integration-tests/java/buildless-snapshot-repository/src/main/java/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.expected b/java/ql/integration-tests/java/buildless-snapshot-repository/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.expected rename to java/ql/integration-tests/java/buildless-snapshot-repository/test.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.py b/java/ql/integration-tests/java/buildless-snapshot-repository/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.py rename to java/ql/integration-tests/java/buildless-snapshot-repository/test.py diff --git a/java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.ql b/java/ql/integration-tests/java/buildless-snapshot-repository/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless-snapshot-repository/test.ql rename to java/ql/integration-tests/java/buildless-snapshot-repository/test.ql diff --git a/java/ql/integration-tests/all-platforms/java/buildless/diagnostics.expected b/java/ql/integration-tests/java/buildless/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless/diagnostics.expected rename to java/ql/integration-tests/java/buildless/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless/source_archive.expected b/java/ql/integration-tests/java/buildless/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless/source_archive.expected rename to java/ql/integration-tests/java/buildless/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/buildless/src/main/java/com/example/App.java b/java/ql/integration-tests/java/buildless/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/buildless/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless/src/main/resources/my-app.properties b/java/ql/integration-tests/java/buildless/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/buildless/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/buildless/src/main/resources/page.xml b/java/ql/integration-tests/java/buildless/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless/src/main/resources/page.xml rename to java/ql/integration-tests/java/buildless/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless/src/main/resources/struts.xml b/java/ql/integration-tests/java/buildless/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless/src/main/resources/struts.xml rename to java/ql/integration-tests/java/buildless/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/buildless/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/buildless/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/buildless/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/buildless/test.py b/java/ql/integration-tests/java/buildless/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/buildless/test.py rename to java/ql/integration-tests/java/buildless/test.py diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/build.gradle b/java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/build.gradle rename to java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/diagnostics.expected b/java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/diagnostics.expected rename to java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/project/build.gradle b/java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/project/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/project/build.gradle rename to java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/project/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/project/src/main/AndroidManifest.xml b/java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/project/src/main/AndroidManifest.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/project/src/main/AndroidManifest.xml rename to java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/project/src/main/AndroidManifest.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/project/src/main/java/com/github/androidsample/Main.java b/java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/project/src/main/java/com/github/androidsample/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/project/src/main/java/com/github/androidsample/Main.java rename to java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/project/src/main/java/com/github/androidsample/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/settings.gradle b/java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/settings.gradle rename to java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/test.py b/java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/android-gradle-incompatibility/test.py rename to java/ql/integration-tests/java/diagnostics/android-gradle-incompatibility/test.py diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/diagnostics.expected b/java/ql/integration-tests/java/diagnostics/compilation-error/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/diagnostics.expected rename to java/ql/integration-tests/java/diagnostics/compilation-error/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/pom.xml b/java/ql/integration-tests/java/diagnostics/compilation-error/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/pom.xml rename to java/ql/integration-tests/java/diagnostics/compilation-error/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/main/java/com/example/App.java b/java/ql/integration-tests/java/diagnostics/compilation-error/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/diagnostics/compilation-error/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/main/resources/my-app.properties b/java/ql/integration-tests/java/diagnostics/compilation-error/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/diagnostics/compilation-error/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/main/resources/page.xml b/java/ql/integration-tests/java/diagnostics/compilation-error/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/main/resources/page.xml rename to java/ql/integration-tests/java/diagnostics/compilation-error/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/main/resources/struts.xml b/java/ql/integration-tests/java/diagnostics/compilation-error/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/main/resources/struts.xml rename to java/ql/integration-tests/java/diagnostics/compilation-error/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/diagnostics/compilation-error/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/diagnostics/compilation-error/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/test.py b/java/ql/integration-tests/java/diagnostics/compilation-error/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/compilation-error/test.py rename to java/ql/integration-tests/java/diagnostics/compilation-error/test.py diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/diagnostics.expected b/java/ql/integration-tests/java/diagnostics/dependency-error/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/diagnostics.expected rename to java/ql/integration-tests/java/diagnostics/dependency-error/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/pom.xml b/java/ql/integration-tests/java/diagnostics/dependency-error/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/pom.xml rename to java/ql/integration-tests/java/diagnostics/dependency-error/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/main/java/com/example/App.java b/java/ql/integration-tests/java/diagnostics/dependency-error/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/diagnostics/dependency-error/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/main/resources/my-app.properties b/java/ql/integration-tests/java/diagnostics/dependency-error/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/diagnostics/dependency-error/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/main/resources/page.xml b/java/ql/integration-tests/java/diagnostics/dependency-error/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/main/resources/page.xml rename to java/ql/integration-tests/java/diagnostics/dependency-error/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/main/resources/struts.xml b/java/ql/integration-tests/java/diagnostics/dependency-error/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/main/resources/struts.xml rename to java/ql/integration-tests/java/diagnostics/dependency-error/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/diagnostics/dependency-error/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/diagnostics/dependency-error/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/test.py b/java/ql/integration-tests/java/diagnostics/dependency-error/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/dependency-error/test.py rename to java/ql/integration-tests/java/diagnostics/dependency-error/test.py diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/build.gradle b/java/ql/integration-tests/java/diagnostics/java-version-too-old/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/build.gradle rename to java/ql/integration-tests/java/diagnostics/java-version-too-old/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/diagnostics.expected b/java/ql/integration-tests/java/diagnostics/java-version-too-old/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/diagnostics.expected rename to java/ql/integration-tests/java/diagnostics/java-version-too-old/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/settings.gradle b/java/ql/integration-tests/java/diagnostics/java-version-too-old/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/settings.gradle rename to java/ql/integration-tests/java/diagnostics/java-version-too-old/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/src/main/java/com/example/App.java b/java/ql/integration-tests/java/diagnostics/java-version-too-old/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/diagnostics/java-version-too-old/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/diagnostics/java-version-too-old/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/diagnostics/java-version-too-old/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/test.py b/java/ql/integration-tests/java/diagnostics/java-version-too-old/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/test.py rename to java/ql/integration-tests/java/diagnostics/java-version-too-old/test.py diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/toolchains.xml b/java/ql/integration-tests/java/diagnostics/java-version-too-old/toolchains.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/java-version-too-old/toolchains.xml rename to java/ql/integration-tests/java/diagnostics/java-version-too-old/toolchains.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.gitattributes b/java/ql/integration-tests/java/diagnostics/maven-http-repository/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.gitattributes rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.jar b/java/ql/integration-tests/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.jar rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.jar diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.properties b/java/ql/integration-tests/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.properties rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/diagnostics.expected b/java/ql/integration-tests/java/diagnostics/maven-http-repository/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/diagnostics.expected rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw b/java/ql/integration-tests/java/diagnostics/maven-http-repository/mvnw similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/mvnw diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw.cmd b/java/ql/integration-tests/java/diagnostics/maven-http-repository/mvnw.cmd similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw.cmd rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/mvnw.cmd diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/pom.xml b/java/ql/integration-tests/java/diagnostics/maven-http-repository/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/pom.xml rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/main/java/com/example/App.java b/java/ql/integration-tests/java/diagnostics/maven-http-repository/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/main/resources/my-app.properties b/java/ql/integration-tests/java/diagnostics/maven-http-repository/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/main/resources/page.xml b/java/ql/integration-tests/java/diagnostics/maven-http-repository/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/main/resources/page.xml rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/main/resources/struts.xml b/java/ql/integration-tests/java/diagnostics/maven-http-repository/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/main/resources/struts.xml rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/diagnostics/maven-http-repository/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/test.py b/java/ql/integration-tests/java/diagnostics/maven-http-repository/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/test.py rename to java/ql/integration-tests/java/diagnostics/maven-http-repository/test.py diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/diagnostics.expected b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/diagnostics.expected rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/pom.xml b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/pom.xml rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/java/com/example/App.java b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/my-app.properties b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/page.xml b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/page.xml rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/struts.xml b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/struts.xml rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-1/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-1/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/pom.xml b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/pom.xml rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/java/com/example/App.java b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/my-app.properties b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/page.xml b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/page.xml rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/struts.xml b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/struts.xml rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/maven-project-2/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/maven-project-2/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/test.py b/java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/multiple-candidate-builds/test.py rename to java/ql/integration-tests/java/diagnostics/multiple-candidate-builds/test.py diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/Test.java b/java/ql/integration-tests/java/diagnostics/no-build-system/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/Test.java rename to java/ql/integration-tests/java/diagnostics/no-build-system/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/diagnostics.expected b/java/ql/integration-tests/java/diagnostics/no-build-system/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/diagnostics.expected rename to java/ql/integration-tests/java/diagnostics/no-build-system/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/test.py b/java/ql/integration-tests/java/diagnostics/no-build-system/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-build-system/test.py rename to java/ql/integration-tests/java/diagnostics/no-build-system/test.py diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/build.gradle b/java/ql/integration-tests/java/diagnostics/no-gradle-test-classes/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/build.gradle rename to java/ql/integration-tests/java/diagnostics/no-gradle-test-classes/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/diagnostics.expected b/java/ql/integration-tests/java/diagnostics/no-gradle-test-classes/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/diagnostics.expected rename to java/ql/integration-tests/java/diagnostics/no-gradle-test-classes/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/settings.gradle b/java/ql/integration-tests/java/diagnostics/no-gradle-test-classes/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/settings.gradle rename to java/ql/integration-tests/java/diagnostics/no-gradle-test-classes/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/test.py b/java/ql/integration-tests/java/diagnostics/no-gradle-test-classes/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-test-classes/test.py rename to java/ql/integration-tests/java/diagnostics/no-gradle-test-classes/test.py diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/.gitattributes b/java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/.gitattributes rename to java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/.gitignore b/java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/.gitignore similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/.gitignore rename to java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/.gitignore diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/build.gradle b/java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/build.gradle rename to java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/diagnostics.expected b/java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/diagnostics.expected rename to java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/settings.gradle b/java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/settings.gradle rename to java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/src/main/java/com/example/App.java b/java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/test.py b/java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/diagnostics/no-gradle-wrapper/test.py rename to java/ql/integration-tests/java/diagnostics/no-gradle-wrapper/test.py diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/Test.java b/java/ql/integration-tests/java/ecj-sample-noexit/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/Test.java rename to java/ql/integration-tests/java/ecj-sample-noexit/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/source_archive.expected b/java/ql/integration-tests/java/ecj-sample-noexit/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/source_archive.expected rename to java/ql/integration-tests/java/ecj-sample-noexit/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.py b/java/ql/integration-tests/java/ecj-sample-noexit/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-sample-noexit/test.py rename to java/ql/integration-tests/java/ecj-sample-noexit/test.py diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample/Test.java b/java/ql/integration-tests/java/ecj-sample/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-sample/Test.java rename to java/ql/integration-tests/java/ecj-sample/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample/source_archive.expected b/java/ql/integration-tests/java/ecj-sample/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-sample/source_archive.expected rename to java/ql/integration-tests/java/ecj-sample/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/ecj-sample/test.py b/java/ql/integration-tests/java/ecj-sample/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-sample/test.py rename to java/ql/integration-tests/java/ecj-sample/test.py diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diag.expected b/java/ql/integration-tests/java/ecj-tolerate-enum-annotations/Diag.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diag.expected rename to java/ql/integration-tests/java/ecj-tolerate-enum-annotations/Diag.expected diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diag.ql b/java/ql/integration-tests/java/ecj-tolerate-enum-annotations/Diag.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Diag.ql rename to java/ql/integration-tests/java/ecj-tolerate-enum-annotations/Diag.ql diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Test.java b/java/ql/integration-tests/java/ecj-tolerate-enum-annotations/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Test.java rename to java/ql/integration-tests/java/ecj-tolerate-enum-annotations/Test.java diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Test2.java b/java/ql/integration-tests/java/ecj-tolerate-enum-annotations/Test2.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/Test2.java rename to java/ql/integration-tests/java/ecj-tolerate-enum-annotations/Test2.java diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.expected b/java/ql/integration-tests/java/ecj-tolerate-enum-annotations/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.expected rename to java/ql/integration-tests/java/ecj-tolerate-enum-annotations/test.expected diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.py b/java/ql/integration-tests/java/ecj-tolerate-enum-annotations/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.py rename to java/ql/integration-tests/java/ecj-tolerate-enum-annotations/test.py diff --git a/java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.ql b/java/ql/integration-tests/java/ecj-tolerate-enum-annotations/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/java/ecj-tolerate-enum-annotations/test.ql rename to java/ql/integration-tests/java/ecj-tolerate-enum-annotations/test.ql diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/.gitattributes b/java/ql/integration-tests/java/gradle-sample-kotlin-script/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/.gitattributes rename to java/ql/integration-tests/java/gradle-sample-kotlin-script/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/app/build.gradle.kts b/java/ql/integration-tests/java/gradle-sample-kotlin-script/app/build.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/app/build.gradle.kts rename to java/ql/integration-tests/java/gradle-sample-kotlin-script/app/build.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/app/src/main/java/test/App.java b/java/ql/integration-tests/java/gradle-sample-kotlin-script/app/src/main/java/test/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/app/src/main/java/test/App.java rename to java/ql/integration-tests/java/gradle-sample-kotlin-script/app/src/main/java/test/App.java diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/app/src/test/java/test/AppTest.java b/java/ql/integration-tests/java/gradle-sample-kotlin-script/app/src/test/java/test/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/app/src/test/java/test/AppTest.java rename to java/ql/integration-tests/java/gradle-sample-kotlin-script/app/src/test/java/test/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/gradlew b/java/ql/integration-tests/java/gradle-sample-kotlin-script/gradlew similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/gradlew rename to java/ql/integration-tests/java/gradle-sample-kotlin-script/gradlew diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/gradlew.bat b/java/ql/integration-tests/java/gradle-sample-kotlin-script/gradlew.bat similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/gradlew.bat rename to java/ql/integration-tests/java/gradle-sample-kotlin-script/gradlew.bat diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/settings.gradle.kts b/java/ql/integration-tests/java/gradle-sample-kotlin-script/settings.gradle.kts similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/settings.gradle.kts rename to java/ql/integration-tests/java/gradle-sample-kotlin-script/settings.gradle.kts diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/source_archive.expected b/java/ql/integration-tests/java/gradle-sample-kotlin-script/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/source_archive.expected rename to java/ql/integration-tests/java/gradle-sample-kotlin-script/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/test.py b/java/ql/integration-tests/java/gradle-sample-kotlin-script/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample-kotlin-script/test.py rename to java/ql/integration-tests/java/gradle-sample-kotlin-script/test.py diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/build.gradle b/java/ql/integration-tests/java/gradle-sample/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample/build.gradle rename to java/ql/integration-tests/java/gradle-sample/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/settings.gradle b/java/ql/integration-tests/java/gradle-sample/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample/settings.gradle rename to java/ql/integration-tests/java/gradle-sample/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/source_archive.expected b/java/ql/integration-tests/java/gradle-sample/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample/source_archive.expected rename to java/ql/integration-tests/java/gradle-sample/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/src/main/java/com/example/App.java b/java/ql/integration-tests/java/gradle-sample/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/gradle-sample/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/gradle-sample/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/gradle-sample/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/gradle-sample/test.py b/java/ql/integration-tests/java/gradle-sample/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/gradle-sample/test.py rename to java/ql/integration-tests/java/gradle-sample/test.py diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/.gitignore b/java/ql/integration-tests/java/java-web-jsp/.gitignore similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/.gitignore rename to java/ql/integration-tests/java/java-web-jsp/.gitignore diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/README.txt b/java/ql/integration-tests/java/java-web-jsp/README.txt similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/README.txt rename to java/ql/integration-tests/java/java-web-jsp/README.txt diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/pom.xml b/java/ql/integration-tests/java/java-web-jsp/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/pom.xml rename to java/ql/integration-tests/java/java-web-jsp/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/spotbugs-security-exclude.xml b/java/ql/integration-tests/java/java-web-jsp/spotbugs-security-exclude.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/spotbugs-security-exclude.xml rename to java/ql/integration-tests/java/java-web-jsp/spotbugs-security-exclude.xml diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/spotbugs-security-include.xml b/java/ql/integration-tests/java/java-web-jsp/spotbugs-security-include.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/spotbugs-security-include.xml rename to java/ql/integration-tests/java/java-web-jsp/spotbugs-security-include.xml diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/Counter.java b/java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/Counter.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/Counter.java rename to java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/Counter.java diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/Date2Tag.java b/java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/Date2Tag.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/Date2Tag.java rename to java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/Date2Tag.java diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/DateServlet.java b/java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/DateServlet.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/DateServlet.java rename to java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/DateServlet.java diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/DateTag.java b/java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/DateTag.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/DateTag.java rename to java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/DateTag.java diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/TagListener.java b/java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/TagListener.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/com/acme/TagListener.java rename to java/ql/integration-tests/java/java-web-jsp/src/main/java/com/acme/TagListener.java diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/LoggingUtil.java b/java/ql/integration-tests/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/LoggingUtil.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/LoggingUtil.java rename to java/ql/integration-tests/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/LoggingUtil.java diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/Main.java b/java/ql/integration-tests/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/Main.java rename to java/ql/integration-tests/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/Main.java diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/SystemOutHandler.java b/java/ql/integration-tests/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/SystemOutHandler.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/SystemOutHandler.java rename to java/ql/integration-tests/java/java-web-jsp/src/main/java/org/eclipse/jetty/demo/SystemOutHandler.java diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/resources/jetty-logging.properties b/java/ql/integration-tests/java/java-web-jsp/src/main/resources/jetty-logging.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/resources/jetty-logging.properties rename to java/ql/integration-tests/java/java-web-jsp/src/main/resources/jetty-logging.properties diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/resources/logging.properties b/java/ql/integration-tests/java/java-web-jsp/src/main/resources/logging.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/resources/logging.properties rename to java/ql/integration-tests/java/java-web-jsp/src/main/resources/logging.properties diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib.tld b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib.tld similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib.tld rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib.tld diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib2.tld b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib2.tld similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib2.tld rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/acme-taglib2.tld diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/applicationContext.xml b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/applicationContext.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/applicationContext.xml rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/applicationContext.xml diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/secret.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/secret.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/secret.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/secret.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/spring.tld b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/spring.tld similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/spring.tld rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/spring.tld diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/tags/panel.tag b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/tags/panel.tag similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/tags/panel.tag rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/tags/panel.tag diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/web.xml b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/web.xml rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/web.xml diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/weblogic.xml b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/weblogic.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/WEB-INF/weblogic.xml rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/WEB-INF/weblogic.xml diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/include/${param.secret_param}.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/include/${param.secret_param}.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/include/${param.secret_param}.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/include/${param.secret_param}.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/include/jsp_include_1.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/include/jsp_include_1.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/include/jsp_include_1.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/include/jsp_include_1.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/include/jsp_include_2_safe.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/include/jsp_include_2_safe.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/include/jsp_include_2_safe.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/include/jsp_include_2_safe.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/include/jsp_include_3.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/include/jsp_include_3.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/include/jsp_include_3.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/include/jsp_include_3.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/index.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/index.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/index.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/index.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_1.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_1.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_1.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_1.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_2.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_2.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_2.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_2.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_3.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_3.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_3.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/jstl/jstl_escape_3.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/random.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/random.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/random.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/random.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/spring/spring_eval_1.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/spring/spring_eval_1.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/spring/spring_eval_1.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/spring/spring_eval_1.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/spring/spring_eval_2.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/spring/spring_eval_2.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/spring/spring_eval_2.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/spring/spring_eval_2.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/spring/spring_eval_3.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/spring/spring_eval_3.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/spring/spring_eval_3.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/spring/spring_eval_3.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/spring/spring_eval_4_safe.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/spring/spring_eval_4_safe.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/spring/spring_eval_4_safe.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/spring/spring_eval_4_safe.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/bean1.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/bean1.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/bean1.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/bean1.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/bean2.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/bean2.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/bean2.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/bean2.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/dump.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/dump.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/dump.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/dump.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/expr.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/expr.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/expr.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/expr.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/foo/foo.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/foo/foo.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/foo/foo.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/foo/foo.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/jstl.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/jstl.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/jstl.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/jstl.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/tag.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/tag.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/tag.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/tag.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/tag2.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/tag2.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/tag2.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/tag2.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/tagfile.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/tagfile.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/test/tagfile.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/test/tagfile.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/various.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/various.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/various.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/various.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xml/xml1.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xml/xml1.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xml/xml1.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xml/xml1.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xml/xml2.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xml/xml2.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xml/xml2.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xml/xml2.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xsl/xsl1.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xsl/xsl1.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xsl/xsl1.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xsl/xsl1.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xsl/xsl2.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xsl/xsl2.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xsl/xsl2.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xsl/xsl2.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xsl/xsl3.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xsl/xsl3.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xsl/xsl3.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xsl/xsl3.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xsl/xsl4.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xsl/xsl4.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xsl/xsl4.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xsl/xsl4.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss0.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss0.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss0.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss0.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss1.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss1.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss1.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss1.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss2.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss2.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss2.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss2.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss3.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss3.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss3.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss3.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss4.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss4.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss4.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss4.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss5.jsp b/java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss5.jsp similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/src/main/webapp/xss/xss5.jsp rename to java/ql/integration-tests/java/java-web-jsp/src/main/webapp/xss/xss5.jsp diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/test.expected b/java/ql/integration-tests/java/java-web-jsp/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/test.expected rename to java/ql/integration-tests/java/java-web-jsp/test.expected diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/test.py b/java/ql/integration-tests/java/java-web-jsp/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/test.py rename to java/ql/integration-tests/java/java-web-jsp/test.py diff --git a/java/ql/integration-tests/all-platforms/java/java-web-jsp/test.ql b/java/ql/integration-tests/java/java-web-jsp/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/java/java-web-jsp/test.ql rename to java/ql/integration-tests/java/java-web-jsp/test.ql diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/pom.xml b/java/ql/integration-tests/java/maven-enforcer/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-enforcer/pom.xml rename to java/ql/integration-tests/java/maven-enforcer/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/source_archive.expected b/java/ql/integration-tests/java/maven-enforcer/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-enforcer/source_archive.expected rename to java/ql/integration-tests/java/maven-enforcer/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-enforcer/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-enforcer/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-enforcer/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-enforcer/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-enforcer/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-enforcer/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-enforcer/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-enforcer/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-enforcer/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-enforcer/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-enforcer/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-enforcer/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-enforcer/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-enforcer/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-enforcer/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-enforcer/test.py b/java/ql/integration-tests/java/maven-enforcer/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-enforcer/test.py rename to java/ql/integration-tests/java/maven-enforcer/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/pom.xml b/java/ql/integration-tests/java/maven-sample-extract-properties/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/pom.xml rename to java/ql/integration-tests/java/maven-sample-extract-properties/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/source_archive.expected b/java/ql/integration-tests/java/maven-sample-extract-properties/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/source_archive.expected rename to java/ql/integration-tests/java/maven-sample-extract-properties/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-sample-extract-properties/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-sample-extract-properties/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-sample-extract-properties/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-sample-extract-properties/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-sample-extract-properties/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-sample-extract-properties/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-sample-extract-properties/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-sample-extract-properties/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-sample-extract-properties/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-sample-extract-properties/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.py b/java/ql/integration-tests/java/maven-sample-extract-properties/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-extract-properties/test.py rename to java/ql/integration-tests/java/maven-sample-extract-properties/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/pom.xml b/java/ql/integration-tests/java/maven-sample-large-xml-files/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/pom.xml rename to java/ql/integration-tests/java/maven-sample-large-xml-files/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/source_archive.expected b/java/ql/integration-tests/java/maven-sample-large-xml-files/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/source_archive.expected rename to java/ql/integration-tests/java/maven-sample-large-xml-files/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-sample-large-xml-files/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-sample-large-xml-files/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-sample-large-xml-files/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-sample-large-xml-files/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-sample-large-xml-files/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-sample-large-xml-files/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-sample-large-xml-files/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-sample-large-xml-files/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-sample-large-xml-files/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-sample-large-xml-files/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.py b/java/ql/integration-tests/java/maven-sample-large-xml-files/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-large-xml-files/test.py rename to java/ql/integration-tests/java/maven-sample-large-xml-files/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/pom.xml b/java/ql/integration-tests/java/maven-sample-small-xml-files/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/pom.xml rename to java/ql/integration-tests/java/maven-sample-small-xml-files/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/source_archive.expected b/java/ql/integration-tests/java/maven-sample-small-xml-files/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/source_archive.expected rename to java/ql/integration-tests/java/maven-sample-small-xml-files/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-sample-small-xml-files/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-sample-small-xml-files/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-sample-small-xml-files/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-sample-small-xml-files/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-sample-small-xml-files/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-sample-small-xml-files/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-sample-small-xml-files/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-sample-small-xml-files/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-sample-small-xml-files/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-sample-small-xml-files/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.py b/java/ql/integration-tests/java/maven-sample-small-xml-files/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-small-xml-files/test.py rename to java/ql/integration-tests/java/maven-sample-small-xml-files/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/pom.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-all/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/pom.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-all/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/source_archive.expected b/java/ql/integration-tests/java/maven-sample-xml-mode-all/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/source_archive.expected rename to java/ql/integration-tests/java/maven-sample-xml-mode-all/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-sample-xml-mode-all/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-sample-xml-mode-all/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-sample-xml-mode-all/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-sample-xml-mode-all/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-all/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-all/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-all/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-all/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-sample-xml-mode-all/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-sample-xml-mode-all/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.py b/java/ql/integration-tests/java/maven-sample-xml-mode-all/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-all/test.py rename to java/ql/integration-tests/java/maven-sample-xml-mode-all/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/pom.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-byname/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/pom.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-byname/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/source_archive.expected b/java/ql/integration-tests/java/maven-sample-xml-mode-byname/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/source_archive.expected rename to java/ql/integration-tests/java/maven-sample-xml-mode-byname/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-sample-xml-mode-byname/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.py b/java/ql/integration-tests/java/maven-sample-xml-mode-byname/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-byname/test.py rename to java/ql/integration-tests/java/maven-sample-xml-mode-byname/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/pom.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-disabled/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/pom.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-disabled/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/source_archive.expected b/java/ql/integration-tests/java/maven-sample-xml-mode-disabled/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/source_archive.expected rename to java/ql/integration-tests/java/maven-sample-xml-mode-disabled/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-sample-xml-mode-disabled/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.py b/java/ql/integration-tests/java/maven-sample-xml-mode-disabled/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-disabled/test.py rename to java/ql/integration-tests/java/maven-sample-xml-mode-disabled/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/pom.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-smart/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/pom.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-smart/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/source_archive.expected b/java/ql/integration-tests/java/maven-sample-xml-mode-smart/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/source_archive.expected rename to java/ql/integration-tests/java/maven-sample-xml-mode-smart/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-sample-xml-mode-smart/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.py b/java/ql/integration-tests/java/maven-sample-xml-mode-smart/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample-xml-mode-smart/test.py rename to java/ql/integration-tests/java/maven-sample-xml-mode-smart/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/pom.xml b/java/ql/integration-tests/java/maven-sample/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample/pom.xml rename to java/ql/integration-tests/java/maven-sample/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/source_archive.expected b/java/ql/integration-tests/java/maven-sample/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample/source_archive.expected rename to java/ql/integration-tests/java/maven-sample/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-sample/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-sample/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-sample/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-sample/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-sample/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-sample/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-sample/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-sample/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-sample/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-sample/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-sample/test.py b/java/ql/integration-tests/java/maven-sample/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-sample/test.py rename to java/ql/integration-tests/java/maven-sample/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/.gitattributes b/java/ql/integration-tests/java/maven-wrapper-script-only/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/.gitattributes rename to java/ql/integration-tests/java/maven-wrapper-script-only/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/.mvn/wrapper/maven-wrapper.properties b/java/ql/integration-tests/java/maven-wrapper-script-only/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/.mvn/wrapper/maven-wrapper.properties rename to java/ql/integration-tests/java/maven-wrapper-script-only/.mvn/wrapper/maven-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/mvnw b/java/ql/integration-tests/java/maven-wrapper-script-only/mvnw similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/mvnw rename to java/ql/integration-tests/java/maven-wrapper-script-only/mvnw diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/mvnw.cmd b/java/ql/integration-tests/java/maven-wrapper-script-only/mvnw.cmd similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/mvnw.cmd rename to java/ql/integration-tests/java/maven-wrapper-script-only/mvnw.cmd diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/pom.xml b/java/ql/integration-tests/java/maven-wrapper-script-only/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/pom.xml rename to java/ql/integration-tests/java/maven-wrapper-script-only/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/source_archive.expected b/java/ql/integration-tests/java/maven-wrapper-script-only/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/source_archive.expected rename to java/ql/integration-tests/java/maven-wrapper-script-only/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-wrapper-script-only/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-wrapper-script-only/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-wrapper-script-only/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-wrapper-script-only/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-wrapper-script-only/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-wrapper-script-only/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-wrapper-script-only/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-wrapper-script-only/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-wrapper-script-only/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-wrapper-script-only/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.py b/java/ql/integration-tests/java/maven-wrapper-script-only/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-script-only/test.py rename to java/ql/integration-tests/java/maven-wrapper-script-only/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/.gitattributes b/java/ql/integration-tests/java/maven-wrapper-source-only/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/.gitattributes rename to java/ql/integration-tests/java/maven-wrapper-source-only/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/.mvn/wrapper/MavenWrapperDownloader.java b/java/ql/integration-tests/java/maven-wrapper-source-only/.mvn/wrapper/MavenWrapperDownloader.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/.mvn/wrapper/MavenWrapperDownloader.java rename to java/ql/integration-tests/java/maven-wrapper-source-only/.mvn/wrapper/MavenWrapperDownloader.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/.mvn/wrapper/maven-wrapper.properties b/java/ql/integration-tests/java/maven-wrapper-source-only/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/.mvn/wrapper/maven-wrapper.properties rename to java/ql/integration-tests/java/maven-wrapper-source-only/.mvn/wrapper/maven-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/mvnw b/java/ql/integration-tests/java/maven-wrapper-source-only/mvnw similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/mvnw rename to java/ql/integration-tests/java/maven-wrapper-source-only/mvnw diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/mvnw.cmd b/java/ql/integration-tests/java/maven-wrapper-source-only/mvnw.cmd similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/mvnw.cmd rename to java/ql/integration-tests/java/maven-wrapper-source-only/mvnw.cmd diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/pom.xml b/java/ql/integration-tests/java/maven-wrapper-source-only/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/pom.xml rename to java/ql/integration-tests/java/maven-wrapper-source-only/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/source_archive.expected b/java/ql/integration-tests/java/maven-wrapper-source-only/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/source_archive.expected rename to java/ql/integration-tests/java/maven-wrapper-source-only/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-wrapper-source-only/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-wrapper-source-only/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-wrapper-source-only/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-wrapper-source-only/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-wrapper-source-only/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-wrapper-source-only/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-wrapper-source-only/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-wrapper-source-only/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-wrapper-source-only/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-wrapper-source-only/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.py b/java/ql/integration-tests/java/maven-wrapper-source-only/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper-source-only/test.py rename to java/ql/integration-tests/java/maven-wrapper-source-only/test.py diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/.gitattributes b/java/ql/integration-tests/java/maven-wrapper/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/.gitattributes rename to java/ql/integration-tests/java/maven-wrapper/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/.mvn/wrapper/maven-wrapper.jar b/java/ql/integration-tests/java/maven-wrapper/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/.mvn/wrapper/maven-wrapper.jar rename to java/ql/integration-tests/java/maven-wrapper/.mvn/wrapper/maven-wrapper.jar diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/.mvn/wrapper/maven-wrapper.properties b/java/ql/integration-tests/java/maven-wrapper/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/.mvn/wrapper/maven-wrapper.properties rename to java/ql/integration-tests/java/maven-wrapper/.mvn/wrapper/maven-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/mvnw b/java/ql/integration-tests/java/maven-wrapper/mvnw similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/mvnw rename to java/ql/integration-tests/java/maven-wrapper/mvnw diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/mvnw.cmd b/java/ql/integration-tests/java/maven-wrapper/mvnw.cmd similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/mvnw.cmd rename to java/ql/integration-tests/java/maven-wrapper/mvnw.cmd diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/pom.xml b/java/ql/integration-tests/java/maven-wrapper/pom.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/pom.xml rename to java/ql/integration-tests/java/maven-wrapper/pom.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/source_archive.expected b/java/ql/integration-tests/java/maven-wrapper/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/source_archive.expected rename to java/ql/integration-tests/java/maven-wrapper/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/src/main/java/com/example/App.java b/java/ql/integration-tests/java/maven-wrapper/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/maven-wrapper/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/src/main/resources/my-app.properties b/java/ql/integration-tests/java/maven-wrapper/src/main/resources/my-app.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/src/main/resources/my-app.properties rename to java/ql/integration-tests/java/maven-wrapper/src/main/resources/my-app.properties diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/src/main/resources/page.xml b/java/ql/integration-tests/java/maven-wrapper/src/main/resources/page.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/src/main/resources/page.xml rename to java/ql/integration-tests/java/maven-wrapper/src/main/resources/page.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/src/main/resources/struts.xml b/java/ql/integration-tests/java/maven-wrapper/src/main/resources/struts.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/src/main/resources/struts.xml rename to java/ql/integration-tests/java/maven-wrapper/src/main/resources/struts.xml diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/maven-wrapper/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/maven-wrapper/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/maven-wrapper/test.py b/java/ql/integration-tests/java/maven-wrapper/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/maven-wrapper/test.py rename to java/ql/integration-tests/java/maven-wrapper/test.py diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/ExtractorInformation.expected b/java/ql/integration-tests/java/multi-release-jar-java11/ExtractorInformation.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/ExtractorInformation.expected rename to java/ql/integration-tests/java/multi-release-jar-java11/ExtractorInformation.expected diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/ExtractorInformation.qlref b/java/ql/integration-tests/java/multi-release-jar-java11/ExtractorInformation.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/ExtractorInformation.qlref rename to java/ql/integration-tests/java/multi-release-jar-java11/ExtractorInformation.qlref diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/mod1/mod1pkg/Mod1Class.java b/java/ql/integration-tests/java/multi-release-jar-java11/mod1/mod1pkg/Mod1Class.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/mod1/mod1pkg/Mod1Class.java rename to java/ql/integration-tests/java/multi-release-jar-java11/mod1/mod1pkg/Mod1Class.java diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/mod1/module-info.java b/java/ql/integration-tests/java/multi-release-jar-java11/mod1/module-info.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/mod1/module-info.java rename to java/ql/integration-tests/java/multi-release-jar-java11/mod1/module-info.java diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/mod2/mod2pkg/User.java b/java/ql/integration-tests/java/multi-release-jar-java11/mod2/mod2pkg/User.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/mod2/mod2pkg/User.java rename to java/ql/integration-tests/java/multi-release-jar-java11/mod2/mod2pkg/User.java diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/mod2/module-info.java b/java/ql/integration-tests/java/multi-release-jar-java11/mod2/module-info.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/mod2/module-info.java rename to java/ql/integration-tests/java/multi-release-jar-java11/mod2/module-info.java diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py b/java/ql/integration-tests/java/multi-release-jar-java11/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java11/test.py rename to java/ql/integration-tests/java/multi-release-jar-java11/test.py diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/ExtractorInformation.expected b/java/ql/integration-tests/java/multi-release-jar-java17/ExtractorInformation.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/ExtractorInformation.expected rename to java/ql/integration-tests/java/multi-release-jar-java17/ExtractorInformation.expected diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/ExtractorInformation.qlref b/java/ql/integration-tests/java/multi-release-jar-java17/ExtractorInformation.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/ExtractorInformation.qlref rename to java/ql/integration-tests/java/multi-release-jar-java17/ExtractorInformation.qlref diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/mod1/mod1pkg/Mod1Class.java b/java/ql/integration-tests/java/multi-release-jar-java17/mod1/mod1pkg/Mod1Class.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/mod1/mod1pkg/Mod1Class.java rename to java/ql/integration-tests/java/multi-release-jar-java17/mod1/mod1pkg/Mod1Class.java diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/mod1/module-info.java b/java/ql/integration-tests/java/multi-release-jar-java17/mod1/module-info.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/mod1/module-info.java rename to java/ql/integration-tests/java/multi-release-jar-java17/mod1/module-info.java diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/mod2/mod2pkg/User.java b/java/ql/integration-tests/java/multi-release-jar-java17/mod2/mod2pkg/User.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/mod2/mod2pkg/User.java rename to java/ql/integration-tests/java/multi-release-jar-java17/mod2/mod2pkg/User.java diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/mod2/module-info.java b/java/ql/integration-tests/java/multi-release-jar-java17/mod2/module-info.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/mod2/module-info.java rename to java/ql/integration-tests/java/multi-release-jar-java17/mod2/module-info.java diff --git a/java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py b/java/ql/integration-tests/java/multi-release-jar-java17/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/multi-release-jar-java17/test.py rename to java/ql/integration-tests/java/multi-release-jar-java17/test.py diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/.gitattributes b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/.gitattributes similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/.gitattributes rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/.gitattributes diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/.gitignore b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/.gitignore similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/.gitignore rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/.gitignore diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/build.gradle b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/build.gradle rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/gradle/verification-metadata.xml b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/gradle/verification-metadata.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/gradle/verification-metadata.xml rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/gradle/verification-metadata.xml diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/gradle/wrapper/gradle-wrapper.properties rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/gradle/wrapper/gradle-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/gradlew b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/gradlew similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/gradlew rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/gradlew diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/gradlew.bat b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/gradlew.bat similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/gradlew.bat rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/gradlew.bat diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/settings.gradle b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/settings.gradle rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/source_archive.expected b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/source_archive.expected rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/src/main/java/com/example/App.java b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.py b/java/ql/integration-tests/java/partial-gradle-sample-without-gradle/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample-without-gradle/test.py rename to java/ql/integration-tests/java/partial-gradle-sample-without-gradle/test.py diff --git a/java/ql/integration-tests/java/partial-gradle-sample/.gitattributes b/java/ql/integration-tests/java/partial-gradle-sample/.gitattributes new file mode 100644 index 00000000000..00a51aff5e5 --- /dev/null +++ b/java/ql/integration-tests/java/partial-gradle-sample/.gitattributes @@ -0,0 +1,6 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# These are explicitly windows files and should use crlf +*.bat text eol=crlf + diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/build.gradle b/java/ql/integration-tests/java/partial-gradle-sample/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/build.gradle rename to java/ql/integration-tests/java/partial-gradle-sample/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/gradle/verification-metadata.xml b/java/ql/integration-tests/java/partial-gradle-sample/gradle/verification-metadata.xml similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/gradle/verification-metadata.xml rename to java/ql/integration-tests/java/partial-gradle-sample/gradle/verification-metadata.xml diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/gradle/wrapper/gradle-wrapper.properties b/java/ql/integration-tests/java/partial-gradle-sample/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/gradle/wrapper/gradle-wrapper.properties rename to java/ql/integration-tests/java/partial-gradle-sample/gradle/wrapper/gradle-wrapper.properties diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/gradlew b/java/ql/integration-tests/java/partial-gradle-sample/gradlew similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/gradlew rename to java/ql/integration-tests/java/partial-gradle-sample/gradlew diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/gradlew.bat b/java/ql/integration-tests/java/partial-gradle-sample/gradlew.bat similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/gradlew.bat rename to java/ql/integration-tests/java/partial-gradle-sample/gradlew.bat diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/settings.gradle b/java/ql/integration-tests/java/partial-gradle-sample/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/settings.gradle rename to java/ql/integration-tests/java/partial-gradle-sample/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/source_archive.expected b/java/ql/integration-tests/java/partial-gradle-sample/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/source_archive.expected rename to java/ql/integration-tests/java/partial-gradle-sample/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/src/main/java/com/example/App.java b/java/ql/integration-tests/java/partial-gradle-sample/src/main/java/com/example/App.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/src/main/java/com/example/App.java rename to java/ql/integration-tests/java/partial-gradle-sample/src/main/java/com/example/App.java diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/src/test/java/com/example/AppTest.java b/java/ql/integration-tests/java/partial-gradle-sample/src/test/java/com/example/AppTest.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/src/test/java/com/example/AppTest.java rename to java/ql/integration-tests/java/partial-gradle-sample/src/test/java/com/example/AppTest.java diff --git a/java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.py b/java/ql/integration-tests/java/partial-gradle-sample/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/partial-gradle-sample/test.py rename to java/ql/integration-tests/java/partial-gradle-sample/test.py diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/README b/java/ql/integration-tests/java/spring-boot-sample/README similarity index 100% rename from java/ql/integration-tests/all-platforms/java/spring-boot-sample/README rename to java/ql/integration-tests/java/spring-boot-sample/README diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/build.gradle b/java/ql/integration-tests/java/spring-boot-sample/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/spring-boot-sample/build.gradle rename to java/ql/integration-tests/java/spring-boot-sample/build.gradle diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/settings.gradle b/java/ql/integration-tests/java/spring-boot-sample/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/java/spring-boot-sample/settings.gradle rename to java/ql/integration-tests/java/spring-boot-sample/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/source_archive.expected b/java/ql/integration-tests/java/spring-boot-sample/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/java/spring-boot-sample/source_archive.expected rename to java/ql/integration-tests/java/spring-boot-sample/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/src/main/java/com/github/springbootsample/SpringBootSampleApplication.java b/java/ql/integration-tests/java/spring-boot-sample/src/main/java/com/github/springbootsample/SpringBootSampleApplication.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/spring-boot-sample/src/main/java/com/github/springbootsample/SpringBootSampleApplication.java rename to java/ql/integration-tests/java/spring-boot-sample/src/main/java/com/github/springbootsample/SpringBootSampleApplication.java diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/src/main/resources/application.properties b/java/ql/integration-tests/java/spring-boot-sample/src/main/resources/application.properties similarity index 100% rename from java/ql/integration-tests/all-platforms/java/spring-boot-sample/src/main/resources/application.properties rename to java/ql/integration-tests/java/spring-boot-sample/src/main/resources/application.properties diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/src/test/java/com/github/springbootsample/SpringBootSampleApplicationTests.java b/java/ql/integration-tests/java/spring-boot-sample/src/test/java/com/github/springbootsample/SpringBootSampleApplicationTests.java similarity index 100% rename from java/ql/integration-tests/all-platforms/java/spring-boot-sample/src/test/java/com/github/springbootsample/SpringBootSampleApplicationTests.java rename to java/ql/integration-tests/java/spring-boot-sample/src/test/java/com/github/springbootsample/SpringBootSampleApplicationTests.java diff --git a/java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.py b/java/ql/integration-tests/java/spring-boot-sample/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/java/spring-boot-sample/test.py rename to java/ql/integration-tests/java/spring-boot-sample/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/PrintAst.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/PrintAst.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.qlref b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/PrintAst.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.qlref rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/PrintAst.qlref diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/User.java b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/User.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/User.java rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/User.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.expected b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/deprecatedAnnotationTypes.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.expected rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/deprecatedAnnotationTypes.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.ql b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/deprecatedAnnotationTypes.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/deprecatedAnnotationTypes.ql rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/deprecatedAnnotationTypes.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/ktUser.kt b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/ktUser.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/ktUser.kt rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/ktUser.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/qlpack.yml b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/qlpack.yml similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/qlpack.yml rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/qlpack.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.ext.yml b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/test.ext.yml similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.ext.yml rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/test.ext.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.kt b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/test.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.kt rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/test.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.py b/java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/test.py rename to java/ql/integration-tests/kotlin/all-platforms/annotation-id-consistency/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/app/build.gradle b/java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/app/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/app/build.gradle rename to java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/app/build.gradle diff --git a/java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/app/src/main/kotlin/testProject/App.kt b/java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/app/src/main/kotlin/testProject/App.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/app/src/main/kotlin/testProject/App.kt rename to java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/app/src/main/kotlin/testProject/App.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/compArgs.expected b/java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/compArgs.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/compArgs.expected rename to java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/compArgs.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/compArgs.ql b/java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/compArgs.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/compArgs.ql rename to java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/compArgs.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/settings.gradle b/java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/settings.gradle rename to java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/test.py b/java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/compiler_arguments/test.py rename to java/ql/integration-tests/kotlin/all-platforms/compiler_arguments/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/lib.kt b/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/lib.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/lib.kt rename to java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/lib.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml b/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/qlpack.yml similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/qlpack.yml rename to java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/qlpack.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.expected b/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ext.yml b/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.ext.yml similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ext.yml rename to java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.ext.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.py b/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.py rename to java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql b/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/user.kt b/java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/user.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/user.kt rename to java/ql/integration-tests/kotlin/all-platforms/default-parameter-mad-flow/user.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/diagnostics.expected b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/diagnostics.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/diagnostics.expected rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/diagnostics.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/mock/MockProject.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/mock/MockProject.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/mock/MockProject.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/mock/MockProject.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/openapi/Disposable.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/openapi/Disposable.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/openapi/Disposable.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/com/intellij/openapi/Disposable.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/driver/Main.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/driver/Main.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/driver/Main.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/driver/Main.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/kotlin/KotlinVersion.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/kotlin/KotlinVersion.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/kotlin/KotlinVersion.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/kotlin/KotlinVersion.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/ExitCode.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/ExitCode.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/ExitCode.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/ExitCode.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/CommonToolArguments.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/ParseCommandLineArgumentsKt.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/ParseCommandLineArgumentsKt.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/ParseCommandLineArgumentsKt.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/common/arguments/ParseCommandLineArgumentsKt.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/config/CompilerConfiguration.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/config/CompilerConfiguration.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/config/CompilerConfiguration.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/config/CompilerConfiguration.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/utils/KotlinPaths.java b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/utils/KotlinPaths.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/utils/KotlinPaths.java rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/fake-kotlinc-source/org/jetbrains/kotlin/utils/KotlinPaths.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/test.py b/java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/diagnostics/kotlin-version-too-new/test.py rename to java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/enabling/KotlinDefault.kt b/java/ql/integration-tests/kotlin/all-platforms/enabling/KotlinDefault.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enabling/KotlinDefault.kt rename to java/ql/integration-tests/kotlin/all-platforms/enabling/KotlinDefault.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/enabling/KotlinDisabled.kt b/java/ql/integration-tests/kotlin/all-platforms/enabling/KotlinDisabled.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enabling/KotlinDisabled.kt rename to java/ql/integration-tests/kotlin/all-platforms/enabling/KotlinDisabled.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/enabling/KotlinEnabled.kt b/java/ql/integration-tests/kotlin/all-platforms/enabling/KotlinEnabled.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enabling/KotlinEnabled.kt rename to java/ql/integration-tests/kotlin/all-platforms/enabling/KotlinEnabled.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/enabling/source_archive.expected b/java/ql/integration-tests/kotlin/all-platforms/enabling/source_archive.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enabling/source_archive.expected rename to java/ql/integration-tests/kotlin/all-platforms/enabling/source_archive.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/enabling/test.py b/java/ql/integration-tests/kotlin/all-platforms/enabling/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enabling/test.py rename to java/ql/integration-tests/kotlin/all-platforms/enabling/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/NotNull.java b/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/NotNull.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/NotNull.java rename to java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/NotNull.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/Test.java b/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/Test.java rename to java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/Test.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected b/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.py b/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.py rename to java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.ql b/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/user.kt b/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/user.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/enhanced-nullability/user.kt rename to java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/user.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.expected b/java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.kt b/java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.kt rename to java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.py b/java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.py rename to java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.ql b/java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/user.kt b/java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/user.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/user.kt rename to java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/user.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/classes.expected b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/classes.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/classes.expected rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/classes.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/classes.ql b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/classes.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/classes.ql rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/classes.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/code/A.kt b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/code/A.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/code/A.kt rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/code/A.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/code/B.kt b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/code/B.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/code/B.kt rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/code/B.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/code/C.kt b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/code/C.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/code/C.kt rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/code/C.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/compilationFiles.expected b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/compilationFiles.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/compilationFiles.expected rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/compilationFiles.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/compilationFiles.ql b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/compilationFiles.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/compilationFiles.ql rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/compilationFiles.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/compilations.expected b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/compilations.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/compilations.expected rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/compilations.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/compilations.ql b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/compilations.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/compilations.ql rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/compilations.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_crash/test.py b/java/ql/integration-tests/kotlin/all-platforms/extractor_crash/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_crash/test.py rename to java/ql/integration-tests/kotlin/all-platforms/extractor_crash/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.expected b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.expected rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.ext.yml b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.ext.yml similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.ext.yml rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.ext.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.qlref b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.qlref rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.qlref diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/SomeClass.kt b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/SomeClass.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/SomeClass.kt rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/SomeClass.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/test.py b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/test.py rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.expected b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.expected rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.ext.yml b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.ext.yml similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.ext.yml rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.ext.yml diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.qlref b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.qlref rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/ExtractorInformation.qlref diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/SomeClass.kt b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/SomeClass.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/SomeClass.kt rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/SomeClass.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/test.py b/java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/test.py rename to java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin2/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/file_classes/A.kt b/java/ql/integration-tests/kotlin/all-platforms/file_classes/A.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/file_classes/A.kt rename to java/ql/integration-tests/kotlin/all-platforms/file_classes/A.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/file_classes/B.kt b/java/ql/integration-tests/kotlin/all-platforms/file_classes/B.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/file_classes/B.kt rename to java/ql/integration-tests/kotlin/all-platforms/file_classes/B.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/file_classes/C.kt b/java/ql/integration-tests/kotlin/all-platforms/file_classes/C.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/file_classes/C.kt rename to java/ql/integration-tests/kotlin/all-platforms/file_classes/C.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/file_classes/classes.expected b/java/ql/integration-tests/kotlin/all-platforms/file_classes/classes.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/file_classes/classes.expected rename to java/ql/integration-tests/kotlin/all-platforms/file_classes/classes.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/file_classes/classes.ql b/java/ql/integration-tests/kotlin/all-platforms/file_classes/classes.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/file_classes/classes.ql rename to java/ql/integration-tests/kotlin/all-platforms/file_classes/classes.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/file_classes/test.py b/java/ql/integration-tests/kotlin/all-platforms/file_classes/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/file_classes/test.py rename to java/ql/integration-tests/kotlin/all-platforms/file_classes/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/app/build.gradle b/java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/app/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/app/build.gradle rename to java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/app/build.gradle diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/app/src/main/kotlin/testProject/App.kt b/java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/app/src/main/kotlin/testProject/App.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/app/src/main/kotlin/testProject/App.kt rename to java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/app/src/main/kotlin/testProject/App.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/compilations.expected b/java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/compilations.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/compilations.expected rename to java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/compilations.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/compilations.ql b/java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/compilations.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/compilations.ql rename to java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/compilations.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/methods.expected b/java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/methods.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/methods.expected rename to java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/methods.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/methods.ql b/java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/methods.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/methods.ql rename to java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/methods.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/settings.gradle b/java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/settings.gradle rename to java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/test.py b/java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_groovy_app/test.py rename to java/ql/integration-tests/kotlin/all-platforms/gradle_groovy_app/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.expected b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.expected rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.qlref b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.qlref rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/ConstantExpAppearsNonConstant.qlref diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/PrintAst.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/PrintAst.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.qlref b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/PrintAst.qlref similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.qlref rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/PrintAst.qlref diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/app/build.gradle b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/app/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/app/build.gradle rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/app/build.gradle diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/app/src/main/kotlin/testProject/App.kt b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/app/src/main/kotlin/testProject/App.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/app/src/main/kotlin/testProject/App.kt rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/app/src/main/kotlin/testProject/App.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/diag.expected b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/diag.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/diag.expected rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/diag.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/diag.ql b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/diag.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/diag.ql rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/diag.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/settings.gradle b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/settings.gradle rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/test.py b/java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/test.py rename to java/ql/integration-tests/kotlin/all-platforms/gradle_kotlinx_serialization/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/Test.java b/java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/Test.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/Test.java rename to java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/Test.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/test.expected b/java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/test.py b/java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/test.py rename to java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/test.ql b/java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/user.kt b/java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/user.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java-interface-redeclares-tostring/user.kt rename to java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/user.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/java_modifiers/libsrc/extlib/A.java b/java/ql/integration-tests/kotlin/all-platforms/java_modifiers/libsrc/extlib/A.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java_modifiers/libsrc/extlib/A.java rename to java/ql/integration-tests/kotlin/all-platforms/java_modifiers/libsrc/extlib/A.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/java_modifiers/test.expected b/java/ql/integration-tests/kotlin/all-platforms/java_modifiers/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java_modifiers/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/java_modifiers/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/java_modifiers/test.kt b/java/ql/integration-tests/kotlin/all-platforms/java_modifiers/test.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java_modifiers/test.kt rename to java/ql/integration-tests/kotlin/all-platforms/java_modifiers/test.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/java_modifiers/test.py b/java/ql/integration-tests/kotlin/all-platforms/java_modifiers/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java_modifiers/test.py rename to java/ql/integration-tests/kotlin/all-platforms/java_modifiers/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/java_modifiers/test.ql b/java/ql/integration-tests/kotlin/all-platforms/java_modifiers/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/java_modifiers/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/java_modifiers/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/User.java b/java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/User.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/User.java rename to java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/User.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.expected b/java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.kt b/java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/test.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.kt rename to java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/test.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.py b/java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.py rename to java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.ql b/java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/user.kt b/java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/user.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/jvmoverloads-external-class/user.kt rename to java/ql/integration-tests/kotlin/all-platforms/jvmoverloads-external-class/user.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/User.java b/java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/User.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/User.java rename to java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/User.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/noforwards.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/noforwards.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/noforwards.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/noforwards.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/test.expected b/java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/test.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/test.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/test.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/test.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/test.py b/java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/test.py rename to java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/test.ql b/java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin-interface-inherited-default/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/kotlin-interface-inherited-default/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/J.java b/java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/J.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/J.java rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/J.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/K.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/K.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/K.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/K.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/K2.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/K2.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/K2.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/K2.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/jlocs.expected b/java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/jlocs.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/jlocs.expected rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/jlocs.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/jlocs.ql b/java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/jlocs.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/jlocs.ql rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/jlocs.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/test.py b/java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_compiler_java_source/test.py rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_compiler_java_source/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/libsrc/longsig.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/libsrc/longsig.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/libsrc/longsig.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/libsrc/longsig.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/test.expected b/java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/test.py b/java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/test.py rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/test.ql b/java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/user.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/user.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_file_import/user.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_file_import/user.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/JavaDefns.java b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/JavaDefns.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/JavaDefns.java rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/JavaDefns.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/JavaDefns2.java b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/JavaDefns2.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/JavaDefns2.java rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/JavaDefns2.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/JavaUser.java b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/JavaUser.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/JavaUser.java rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/JavaUser.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/kotlindefns.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/kotlindefns.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/kotlindefns.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/kotlindefns.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/kotlinuser.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/kotlinuser.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/kotlinuser.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/kotlinuser.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/test.expected b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/test.py b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/test.py rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/test.ql b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_lowering_wildcards/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/ReadsFields.java b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/ReadsFields.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/ReadsFields.java rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/ReadsFields.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/hasFields.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/hasFields.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/hasFields.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/hasFields.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.py b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.py rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.ql b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_java_static_fields/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_java_static_fields/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/app/build.gradle b/java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/app/build.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/app/build.gradle rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/app/build.gradle diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/app/src/main/kotlin/testProject/App.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/app/src/main/kotlin/testProject/App.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/app/src/main/kotlin/testProject/App.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/app/src/main/kotlin/testProject/App.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/diag.expected b/java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/diag.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/diag.expected rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/diag.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/diag.ql b/java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/diag.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/diag.ql rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/diag.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/settings.gradle b/java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/settings.gradle similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/settings.gradle rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/settings.gradle diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/test.py b/java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlin_kfunction/test.py rename to java/ql/integration-tests/kotlin/all-platforms/kotlin_kfunction/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/FileA.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/FileA.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/FileA.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/FileA.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/FileB.kt b/java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/FileB.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/FileB.kt rename to java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/FileB.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/compilations.expected b/java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/compilations.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/compilations.expected rename to java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/compilations.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/compilations.ql b/java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/compilations.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/compilations.ql rename to java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/compilations.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/methods.expected b/java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/methods.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/methods.expected rename to java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/methods.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/methods.ql b/java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/methods.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/methods.ql rename to java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/methods.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/test.py b/java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/kotlinc_multi/test.py rename to java/ql/integration-tests/kotlin/all-platforms/kotlinc_multi/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/logs/logs.expected b/java/ql/integration-tests/kotlin/all-platforms/logs/logs.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/logs/logs.expected rename to java/ql/integration-tests/kotlin/all-platforms/logs/logs.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/logs/test.kt b/java/ql/integration-tests/kotlin/all-platforms/logs/test.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/logs/test.kt rename to java/ql/integration-tests/kotlin/all-platforms/logs/test.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/logs/test.py b/java/ql/integration-tests/kotlin/all-platforms/logs/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/logs/test.py rename to java/ql/integration-tests/kotlin/all-platforms/logs/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/JavaUser.java b/java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/JavaUser.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/JavaUser.java rename to java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/JavaUser.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/KotlinUser.kt b/java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/KotlinUser.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/KotlinUser.kt rename to java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/KotlinUser.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java b/java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/libsrc/extlib/OuterGeneric.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java rename to java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/libsrc/extlib/OuterGeneric.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/libsrc/extlib/OuterManyParams.java b/java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/libsrc/extlib/OuterManyParams.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/libsrc/extlib/OuterManyParams.java rename to java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/libsrc/extlib/OuterManyParams.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java b/java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/libsrc/extlib/OuterNotGeneric.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java rename to java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/libsrc/extlib/OuterNotGeneric.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/libsrc/extlib/TypeParamVisibility.java b/java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/libsrc/extlib/TypeParamVisibility.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/libsrc/extlib/TypeParamVisibility.java rename to java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/libsrc/extlib/TypeParamVisibility.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected b/java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.py b/java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.py rename to java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.ql b/java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/nested_generic_types/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedInterface.java b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/AnnotatedInterface.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedInterface.java rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/AnnotatedInterface.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedMethods.java b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/AnnotatedMethods.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/AnnotatedMethods.java rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/AnnotatedMethods.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/JavaUser.java b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/JavaUser.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/JavaUser.java rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/JavaUser.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/ktUser.kt b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/ktUser.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/ktUser.kt rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/ktUser.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/NotNull.java b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/org/jetbrains/annotations/NotNull.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/NotNull.java rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/org/jetbrains/annotations/NotNull.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/Nullable.java b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/org/jetbrains/annotations/Nullable.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/org/jetbrains/annotations/Nullable.java rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/org/jetbrains/annotations/Nullable.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.expected b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.py b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.py rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.ql b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/zpkg/A.java b/java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/zpkg/A.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/nullability-annotations/zpkg/A.java rename to java/ql/integration-tests/kotlin/all-platforms/nullability-annotations/zpkg/A.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/path_transformer/classes.expected b/java/ql/integration-tests/kotlin/all-platforms/path_transformer/classes.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/path_transformer/classes.expected rename to java/ql/integration-tests/kotlin/all-platforms/path_transformer/classes.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/path_transformer/classes.ql b/java/ql/integration-tests/kotlin/all-platforms/path_transformer/classes.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/path_transformer/classes.ql rename to java/ql/integration-tests/kotlin/all-platforms/path_transformer/classes.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/path_transformer/kotlin_source.kt b/java/ql/integration-tests/kotlin/all-platforms/path_transformer/kotlin_source.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/path_transformer/kotlin_source.kt rename to java/ql/integration-tests/kotlin/all-platforms/path_transformer/kotlin_source.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/path_transformer/test.py b/java/ql/integration-tests/kotlin/all-platforms/path_transformer/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/path_transformer/test.py rename to java/ql/integration-tests/kotlin/all-platforms/path_transformer/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/hasprops.kt b/java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/hasprops.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/hasprops.kt rename to java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/hasprops.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/test.expected b/java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/test.py b/java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/test.py rename to java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/test.ql b/java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/usesprops.kt b/java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/usesprops.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/private_property_accessors/usesprops.kt rename to java/ql/integration-tests/kotlin/all-platforms/private_property_accessors/usesprops.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/JavaUser.java b/java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/JavaUser.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/JavaUser.java rename to java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/JavaUser.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/KotlinUser.kt b/java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/KotlinUser.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/KotlinUser.kt rename to java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/KotlinUser.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/libsrc/extlib/GenericTypeJava.java b/java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/libsrc/extlib/GenericTypeJava.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/libsrc/extlib/GenericTypeJava.java rename to java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/libsrc/extlib/GenericTypeJava.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/libsrc/extlib/GenericTypeKotlin.java b/java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/libsrc/extlib/GenericTypeKotlin.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/libsrc/extlib/GenericTypeKotlin.java rename to java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/libsrc/extlib/GenericTypeKotlin.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/libsrc/extlib/RawTypesInSignatureJava.java b/java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/libsrc/extlib/RawTypesInSignatureJava.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/libsrc/extlib/RawTypesInSignatureJava.java rename to java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/libsrc/extlib/RawTypesInSignatureJava.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/libsrc/extlib/RawTypesInSignatureKotlin.java b/java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/libsrc/extlib/RawTypesInSignatureKotlin.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/libsrc/extlib/RawTypesInSignatureKotlin.java rename to java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/libsrc/extlib/RawTypesInSignatureKotlin.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/test.expected b/java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/test.py b/java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/test.py rename to java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/test.ql b/java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/raw_generic_types/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/raw_generic_types/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedContainer.java b/java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/JavaDefinedContainer.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedContainer.java rename to java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/JavaDefinedContainer.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedRepeatable.java b/java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/JavaDefinedRepeatable.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaDefinedRepeatable.java rename to java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/JavaDefinedRepeatable.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaUser.java b/java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/JavaUser.java similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/JavaUser.java rename to java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/JavaUser.java diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/lib.kt b/java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/lib.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/lib.kt rename to java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/lib.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.expected b/java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/test.expected similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.expected rename to java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/test.expected diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.kt b/java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/test.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.kt rename to java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/test.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.py b/java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.py rename to java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/test.py diff --git a/java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.ql b/java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/test.ql similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/repeatable-annotations/test.ql rename to java/ql/integration-tests/kotlin/all-platforms/repeatable-annotations/test.ql diff --git a/java/ql/integration-tests/all-platforms/kotlin/trap_compression/test.kt b/java/ql/integration-tests/kotlin/all-platforms/trap_compression/test.kt similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/trap_compression/test.kt rename to java/ql/integration-tests/kotlin/all-platforms/trap_compression/test.kt diff --git a/java/ql/integration-tests/all-platforms/kotlin/trap_compression/test.py b/java/ql/integration-tests/kotlin/all-platforms/trap_compression/test.py similarity index 100% rename from java/ql/integration-tests/all-platforms/kotlin/trap_compression/test.py rename to java/ql/integration-tests/kotlin/all-platforms/trap_compression/test.py diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected b/java/ql/integration-tests/kotlin/linux/custom_plugin/PrintAst.expected similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected rename to java/ql/integration-tests/kotlin/linux/custom_plugin/PrintAst.expected diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.qlref b/java/ql/integration-tests/kotlin/linux/custom_plugin/PrintAst.qlref similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.qlref rename to java/ql/integration-tests/kotlin/linux/custom_plugin/PrintAst.qlref diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/a.kt b/java/ql/integration-tests/kotlin/linux/custom_plugin/a.kt similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/a.kt rename to java/ql/integration-tests/kotlin/linux/custom_plugin/a.kt diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/b.kt b/java/ql/integration-tests/kotlin/linux/custom_plugin/b.kt similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/b.kt rename to java/ql/integration-tests/kotlin/linux/custom_plugin/b.kt diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/c.kt b/java/ql/integration-tests/kotlin/linux/custom_plugin/c.kt similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/c.kt rename to java/ql/integration-tests/kotlin/linux/custom_plugin/c.kt diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/d.kt b/java/ql/integration-tests/kotlin/linux/custom_plugin/d.kt similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/d.kt rename to java/ql/integration-tests/kotlin/linux/custom_plugin/d.kt diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/diag.expected b/java/ql/integration-tests/kotlin/linux/custom_plugin/diag.expected similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/diag.expected rename to java/ql/integration-tests/kotlin/linux/custom_plugin/diag.expected diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/diag.ql b/java/ql/integration-tests/kotlin/linux/custom_plugin/diag.ql similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/diag.ql rename to java/ql/integration-tests/kotlin/linux/custom_plugin/diag.ql diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/e.kt b/java/ql/integration-tests/kotlin/linux/custom_plugin/e.kt similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/e.kt rename to java/ql/integration-tests/kotlin/linux/custom_plugin/e.kt diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/methods.expected b/java/ql/integration-tests/kotlin/linux/custom_plugin/methods.expected similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/methods.expected rename to java/ql/integration-tests/kotlin/linux/custom_plugin/methods.expected diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/methods.ql b/java/ql/integration-tests/kotlin/linux/custom_plugin/methods.ql similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/methods.ql rename to java/ql/integration-tests/kotlin/linux/custom_plugin/methods.ql diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/BUILD.bazel b/java/ql/integration-tests/kotlin/linux/custom_plugin/plugin/BUILD.bazel similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/BUILD.bazel rename to java/ql/integration-tests/kotlin/linux/custom_plugin/plugin/BUILD.bazel diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt b/java/ql/integration-tests/kotlin/linux/custom_plugin/plugin/Plugin.kt similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/Plugin.kt rename to java/ql/integration-tests/kotlin/linux/custom_plugin/plugin/Plugin.kt diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/java/ql/integration-tests/kotlin/linux/custom_plugin/plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar rename to java/ql/integration-tests/kotlin/linux/custom_plugin/plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/qlpack.yml b/java/ql/integration-tests/kotlin/linux/custom_plugin/qlpack.yml similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/qlpack.yml rename to java/ql/integration-tests/kotlin/linux/custom_plugin/qlpack.yml diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/rootClasses.expected b/java/ql/integration-tests/kotlin/linux/custom_plugin/rootClasses.expected similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/rootClasses.expected rename to java/ql/integration-tests/kotlin/linux/custom_plugin/rootClasses.expected diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/rootClasses.ql b/java/ql/integration-tests/kotlin/linux/custom_plugin/rootClasses.ql similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/rootClasses.ql rename to java/ql/integration-tests/kotlin/linux/custom_plugin/rootClasses.ql diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected b/java/ql/integration-tests/kotlin/linux/custom_plugin/staticinit.expected similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.expected rename to java/ql/integration-tests/kotlin/linux/custom_plugin/staticinit.expected diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.ql b/java/ql/integration-tests/kotlin/linux/custom_plugin/staticinit.ql similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/staticinit.ql rename to java/ql/integration-tests/kotlin/linux/custom_plugin/staticinit.ql diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/test.py b/java/ql/integration-tests/kotlin/linux/custom_plugin/test.py similarity index 82% rename from java/ql/integration-tests/linux-only/kotlin/custom_plugin/test.py rename to java/ql/integration-tests/kotlin/linux/custom_plugin/test.py index 2ec685ac685..71b6514059f 100644 --- a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/test.py +++ b/java/ql/integration-tests/kotlin/linux/custom_plugin/test.py @@ -13,7 +13,7 @@ def test(codeql, java_full, cwd, semmle_code_dir, test_dir): f"--output_user_root={build_dir}", "--max_idle_secs=1", "build", - "//java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin", + "//java/ql/integration-tests/kotlin/linux/custom_plugin/plugin", "--spawn_strategy=local", "--nouse_action_cache", "--noremote_accept_cached", @@ -23,7 +23,7 @@ def test(codeql, java_full, cwd, semmle_code_dir, test_dir): _cwd=test_dir, ) shutil.copy( - "bazel-bin/java/ql/integration-tests/linux-only/kotlin/custom_plugin/plugin/plugin.jar", + "bazel-bin/java/ql/integration-tests/kotlin/linux/custom_plugin/plugin/plugin.jar", "plugin.jar", ) codeql.database.create( diff --git a/java/ql/integration-tests/linux-only/kotlin/use_java_library/javasrc/extlib/BoundedGenericTest.java b/java/ql/integration-tests/kotlin/linux/use_java_library/javasrc/extlib/BoundedGenericTest.java similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/use_java_library/javasrc/extlib/BoundedGenericTest.java rename to java/ql/integration-tests/kotlin/linux/use_java_library/javasrc/extlib/BoundedGenericTest.java diff --git a/java/ql/integration-tests/linux-only/kotlin/use_java_library/javasrc/extlib/ComplexBoundedGenericTest.java b/java/ql/integration-tests/kotlin/linux/use_java_library/javasrc/extlib/ComplexBoundedGenericTest.java similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/use_java_library/javasrc/extlib/ComplexBoundedGenericTest.java rename to java/ql/integration-tests/kotlin/linux/use_java_library/javasrc/extlib/ComplexBoundedGenericTest.java diff --git a/java/ql/integration-tests/linux-only/kotlin/use_java_library/javasrc/extlib/GenericTest.java b/java/ql/integration-tests/kotlin/linux/use_java_library/javasrc/extlib/GenericTest.java similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/use_java_library/javasrc/extlib/GenericTest.java rename to java/ql/integration-tests/kotlin/linux/use_java_library/javasrc/extlib/GenericTest.java diff --git a/java/ql/integration-tests/linux-only/kotlin/use_java_library/javasrc/extlib/Lib.java b/java/ql/integration-tests/kotlin/linux/use_java_library/javasrc/extlib/Lib.java similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/use_java_library/javasrc/extlib/Lib.java rename to java/ql/integration-tests/kotlin/linux/use_java_library/javasrc/extlib/Lib.java diff --git a/java/ql/integration-tests/linux-only/kotlin/use_java_library/parameterTypes.expected b/java/ql/integration-tests/kotlin/linux/use_java_library/parameterTypes.expected similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/use_java_library/parameterTypes.expected rename to java/ql/integration-tests/kotlin/linux/use_java_library/parameterTypes.expected diff --git a/java/ql/integration-tests/linux-only/kotlin/use_java_library/parameterTypes.ql b/java/ql/integration-tests/kotlin/linux/use_java_library/parameterTypes.ql similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/use_java_library/parameterTypes.ql rename to java/ql/integration-tests/kotlin/linux/use_java_library/parameterTypes.ql diff --git a/java/ql/integration-tests/linux-only/kotlin/use_java_library/test.py b/java/ql/integration-tests/kotlin/linux/use_java_library/test.py similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/use_java_library/test.py rename to java/ql/integration-tests/kotlin/linux/use_java_library/test.py diff --git a/java/ql/integration-tests/linux-only/kotlin/use_java_library/user.kt b/java/ql/integration-tests/kotlin/linux/use_java_library/user.kt similarity index 100% rename from java/ql/integration-tests/linux-only/kotlin/use_java_library/user.kt rename to java/ql/integration-tests/kotlin/linux/use_java_library/user.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/generic-extension-property/User.java b/java/ql/integration-tests/kotlin/posix/generic-extension-property/User.java similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/generic-extension-property/User.java rename to java/ql/integration-tests/kotlin/posix/generic-extension-property/User.java diff --git a/java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.expected b/java/ql/integration-tests/kotlin/posix/generic-extension-property/test.expected similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.expected rename to java/ql/integration-tests/kotlin/posix/generic-extension-property/test.expected diff --git a/java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.kt b/java/ql/integration-tests/kotlin/posix/generic-extension-property/test.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.kt rename to java/ql/integration-tests/kotlin/posix/generic-extension-property/test.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.py b/java/ql/integration-tests/kotlin/posix/generic-extension-property/test.py similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.py rename to java/ql/integration-tests/kotlin/posix/generic-extension-property/test.py diff --git a/java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.ql b/java/ql/integration-tests/kotlin/posix/generic-extension-property/test.ql similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.ql rename to java/ql/integration-tests/kotlin/posix/generic-extension-property/test.ql diff --git a/java/ql/integration-tests/posix-only/kotlin/java_kotlin_extraction_orders/test.expected b/java/ql/integration-tests/kotlin/posix/java_kotlin_extraction_orders/test.expected similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/java_kotlin_extraction_orders/test.expected rename to java/ql/integration-tests/kotlin/posix/java_kotlin_extraction_orders/test.expected diff --git a/java/ql/integration-tests/posix-only/kotlin/java_kotlin_extraction_orders/test.py b/java/ql/integration-tests/kotlin/posix/java_kotlin_extraction_orders/test.py similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/java_kotlin_extraction_orders/test.py rename to java/ql/integration-tests/kotlin/posix/java_kotlin_extraction_orders/test.py diff --git a/java/ql/integration-tests/posix-only/kotlin/java_kotlin_extraction_orders/test.ql b/java/ql/integration-tests/kotlin/posix/java_kotlin_extraction_orders/test.ql similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/java_kotlin_extraction_orders/test.ql rename to java/ql/integration-tests/kotlin/posix/java_kotlin_extraction_orders/test.ql diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/doubleIntercepted.kt b/java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/doubleIntercepted.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/doubleIntercepted.kt rename to java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/doubleIntercepted.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/manual.kt b/java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/manual.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/manual.kt rename to java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/manual.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/manuallyIntercepted.kt b/java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/manuallyIntercepted.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/manuallyIntercepted.kt rename to java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/manuallyIntercepted.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/normal.kt b/java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/normal.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/normal.kt rename to java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/normal.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/notSeen.kt b/java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/notSeen.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/code/notSeen.kt rename to java/ql/integration-tests/kotlin/posix/kotlin_double_interception/code/notSeen.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/files.expected b/java/ql/integration-tests/kotlin/posix/kotlin_double_interception/files.expected similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/files.expected rename to java/ql/integration-tests/kotlin/posix/kotlin_double_interception/files.expected diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/files.ql b/java/ql/integration-tests/kotlin/posix/kotlin_double_interception/files.ql similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/files.ql rename to java/ql/integration-tests/kotlin/posix/kotlin_double_interception/files.ql diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/test.py b/java/ql/integration-tests/kotlin/posix/kotlin_double_interception/test.py similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/kotlin_double_interception/test.py rename to java/ql/integration-tests/kotlin/posix/kotlin_double_interception/test.py diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/User.java b/java/ql/integration-tests/kotlin/posix/module_mangled_names/User.java similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/module_mangled_names/User.java rename to java/ql/integration-tests/kotlin/posix/module_mangled_names/User.java diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.expected b/java/ql/integration-tests/kotlin/posix/module_mangled_names/test.expected similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.expected rename to java/ql/integration-tests/kotlin/posix/module_mangled_names/test.expected diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.py b/java/ql/integration-tests/kotlin/posix/module_mangled_names/test.py similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.py rename to java/ql/integration-tests/kotlin/posix/module_mangled_names/test.py diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.ql b/java/ql/integration-tests/kotlin/posix/module_mangled_names/test.ql similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.ql rename to java/ql/integration-tests/kotlin/posix/module_mangled_names/test.ql diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test1.kt b/java/ql/integration-tests/kotlin/posix/module_mangled_names/test1.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test1.kt rename to java/ql/integration-tests/kotlin/posix/module_mangled_names/test1.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test2.kt b/java/ql/integration-tests/kotlin/posix/module_mangled_names/test2.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test2.kt rename to java/ql/integration-tests/kotlin/posix/module_mangled_names/test2.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test3.kt b/java/ql/integration-tests/kotlin/posix/module_mangled_names/test3.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test3.kt rename to java/ql/integration-tests/kotlin/posix/module_mangled_names/test3.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/Test.java b/java/ql/integration-tests/kotlin/posix/needless-java-wildcards/Test.java similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/Test.java rename to java/ql/integration-tests/kotlin/posix/needless-java-wildcards/Test.java diff --git a/java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/kConsumer.kt b/java/ql/integration-tests/kotlin/posix/needless-java-wildcards/kConsumer.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/kConsumer.kt rename to java/ql/integration-tests/kotlin/posix/needless-java-wildcards/kConsumer.kt diff --git a/java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/test.expected b/java/ql/integration-tests/kotlin/posix/needless-java-wildcards/test.expected similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/test.expected rename to java/ql/integration-tests/kotlin/posix/needless-java-wildcards/test.expected diff --git a/java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/test.py b/java/ql/integration-tests/kotlin/posix/needless-java-wildcards/test.py similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/test.py rename to java/ql/integration-tests/kotlin/posix/needless-java-wildcards/test.py diff --git a/java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/test.ql b/java/ql/integration-tests/kotlin/posix/needless-java-wildcards/test.ql similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/test.ql rename to java/ql/integration-tests/kotlin/posix/needless-java-wildcards/test.ql diff --git a/java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/user.kt b/java/ql/integration-tests/kotlin/posix/needless-java-wildcards/user.kt similarity index 100% rename from java/ql/integration-tests/posix-only/kotlin/needless-java-wildcards/user.kt rename to java/ql/integration-tests/kotlin/posix/needless-java-wildcards/user.kt From 30335ab81ee52abe516d28bf20c9fc615eafd619 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 2 Aug 2024 22:00:31 +0200 Subject: [PATCH 163/404] C++: Add C11 `_Generic` IR tests --- .../library-tests/ir/ir/PrintAST.expected | 61 ++++++++++++++++++- .../library-tests/ir/ir/aliased_ir.expected | 58 +++++++++++++++++- cpp/ql/test/library-tests/ir/ir/generic.c | 29 ++++++++- .../test/library-tests/ir/ir/raw_ir.expected | 55 ++++++++++++++++- 4 files changed, 198 insertions(+), 5 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 4c912a36756..66606ff7056 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -4180,7 +4180,7 @@ destructors_for_temps.cpp: # 103| ValueCategory = prvalue # 104| getStmt(1): [ReturnStmt] return ... generic.c: -# 1| [TopLevelFunction] void c11_generic_test(unsigned int, int) +# 1| [TopLevelFunction] void c11_generic_test_with_load(unsigned int, int) # 1| : # 1| getParameter(0): [Parameter] x # 1| Type = [IntType] unsigned int @@ -4213,6 +4213,65 @@ generic.c: # 3| Value = [CStyleCast] 1 # 3| ValueCategory = prvalue # 4| getStmt(2): [ReturnStmt] return ... +# 12| [TopLevelFunction] char const* c11_generic_test_with_constant_and_macro() +# 12| : +# 13| getEntryPoint(): [BlockStmt] { ... } +# 14| getStmt(0): [DeclStmt] declaration +# 14| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i +# 14| Type = [IntType] int +# 16| getStmt(1): [ReturnStmt] return ... +# 16| getExpr(): int +# 16| Type = [ArrayType] char[4] +# 16| Value = [StringLiteral] "int" +# 16| ValueCategory = lvalue +# 16| getExpr().getFullyConverted(): [CStyleCast] (const char *)... +# 16| Conversion = [PointerConversion] pointer conversion +# 16| Type = [PointerType] const char * +# 16| ValueCategory = prvalue +# 16| getExpr(): [ArrayToPointerConversion] array to pointer conversion +# 16| Type = [CharPointerType] char * +# 16| ValueCategory = prvalue +# 19| [TopLevelFunction] char const* c11_generic_test_with_constant_and_no_macro() +# 19| : +# 20| getEntryPoint(): [BlockStmt] { ... } +# 21| getStmt(0): [DeclStmt] declaration +# 21| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i +# 21| Type = [IntType] int +# 23| getStmt(1): [ReturnStmt] return ... +# 23| getExpr(): int +# 23| Type = [ArrayType] char[4] +# 23| Value = [StringLiteral] "int" +# 23| ValueCategory = lvalue +# 23| getExpr().getFullyConverted(): [CStyleCast] (const char *)... +# 23| Conversion = [PointerConversion] pointer conversion +# 23| Type = [PointerType] const char * +# 23| ValueCategory = prvalue +# 23| getExpr(): [ArrayToPointerConversion] array to pointer conversion +# 23| Type = [CharPointerType] char * +# 23| ValueCategory = prvalue +# 26| [TopLevelFunction] void c11_generic_test_test_with_cast(int) +# 26| : +# 26| getParameter(0): [Parameter] y +# 26| Type = [IntType] int +# 26| getEntryPoint(): [BlockStmt] { ... } +# 27| getStmt(0): [DeclStmt] declaration +# 27| getDeclarationEntry(0): [VariableDeclarationEntry] definition of r +# 27| Type = [IntType] unsigned int +# 28| getStmt(1): [ExprStmt] ExprStmt +# 28| getExpr(): [AssignExpr] ... = ... +# 28| Type = [IntType] unsigned int +# 28| ValueCategory = prvalue +# 28| getLValue(): [VariableAccess] r +# 28| Type = [IntType] unsigned int +# 28| ValueCategory = lvalue +# 28| getRValue(): [VariableAccess] y +# 28| Type = [IntType] int +# 28| ValueCategory = prvalue(load) +# 28| getRValue().getFullyConverted(): [CStyleCast] (unsigned int)... +# 28| Conversion = [IntegralConversion] integral conversion +# 28| Type = [IntType] unsigned int +# 28| ValueCategory = prvalue +# 29| getStmt(2): [ReturnStmt] return ... ir.c: # 5| [TopLevelFunction] int getX(MyCoords*) # 5| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 54ecfba3ffc..ced441595d7 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -2959,7 +2959,7 @@ destructors_for_temps.cpp: # 102| v102_10(void) = ExitFunction : generic.c: -# 1| void c11_generic_test(unsigned int, int) +# 1| void c11_generic_test_with_load(unsigned int, int) # 1| Block 0 # 1| v1_1(void) = EnterFunction : # 1| m1_2(unknown) = AliasedDefinition : @@ -2982,6 +2982,62 @@ generic.c: # 1| v1_10(void) = AliasedUse : m1_3 # 1| v1_11(void) = ExitFunction : +# 12| char const* c11_generic_test_with_constant_and_macro() +# 12| Block 0 +# 12| v12_1(void) = EnterFunction : +# 12| m12_2(unknown) = AliasedDefinition : +# 12| m12_3(unknown) = InitializeNonLocal : +# 12| m12_4(unknown) = Chi : total:m12_2, partial:m12_3 +# 14| r14_1(glval) = VariableAddress[i] : +# 14| m14_2(int) = Uninitialized[i] : &:r14_1 +# 16| r16_1(glval) = VariableAddress[#return] : +# 16| r16_2(glval) = StringConstant[int] : +# 16| r16_3(char *) = Convert : r16_2 +# 16| r16_4(char *) = Convert : r16_3 +# 16| m16_5(char *) = Store[#return] : &:r16_1, r16_4 +# 12| r12_5(glval) = VariableAddress[#return] : +# 12| v12_6(void) = ReturnValue : &:r12_5, m16_5 +# 12| v12_7(void) = AliasedUse : m12_3 +# 12| v12_8(void) = ExitFunction : + +# 19| char const* c11_generic_test_with_constant_and_no_macro() +# 19| Block 0 +# 19| v19_1(void) = EnterFunction : +# 19| m19_2(unknown) = AliasedDefinition : +# 19| m19_3(unknown) = InitializeNonLocal : +# 19| m19_4(unknown) = Chi : total:m19_2, partial:m19_3 +# 21| r21_1(glval) = VariableAddress[i] : +# 21| m21_2(int) = Uninitialized[i] : &:r21_1 +# 23| r23_1(glval) = VariableAddress[#return] : +# 23| r23_2(glval) = StringConstant["int"] : +# 23| r23_3(char *) = Convert : r23_2 +# 23| r23_4(char *) = Convert : r23_3 +# 23| m23_5(char *) = Store[#return] : &:r23_1, r23_4 +# 19| r19_5(glval) = VariableAddress[#return] : +# 19| v19_6(void) = ReturnValue : &:r19_5, m23_5 +# 19| v19_7(void) = AliasedUse : m19_3 +# 19| v19_8(void) = ExitFunction : + +# 26| void c11_generic_test_test_with_cast(int) +# 26| Block 0 +# 26| v26_1(void) = EnterFunction : +# 26| m26_2(unknown) = AliasedDefinition : +# 26| m26_3(unknown) = InitializeNonLocal : +# 26| m26_4(unknown) = Chi : total:m26_2, partial:m26_3 +# 26| r26_5(glval) = VariableAddress[y] : +# 26| m26_6(int) = InitializeParameter[y] : &:r26_5 +# 27| r27_1(glval) = VariableAddress[r] : +# 27| m27_2(unsigned int) = Uninitialized[r] : &:r27_1 +# 28| r28_1(glval) = VariableAddress[y] : +# 28| r28_2(int) = Load[y] : &:r28_1, m26_6 +# 28| r28_3(unsigned int) = Convert : r28_2 +# 28| r28_4(glval) = VariableAddress[r] : +# 28| m28_5(unsigned int) = Store[r] : &:r28_4, r28_3 +# 29| v29_1(void) = NoOp : +# 26| v26_7(void) = ReturnVoid : +# 26| v26_8(void) = AliasedUse : m26_3 +# 26| v26_9(void) = ExitFunction : + ir.c: # 7| void MyCoordsTest(int) # 7| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/generic.c b/cpp/ql/test/library-tests/ir/ir/generic.c index 3d669ba29fb..22c9fb3cd16 100644 --- a/cpp/ql/test/library-tests/ir/ir/generic.c +++ b/cpp/ql/test/library-tests/ir/ir/generic.c @@ -1,6 +1,31 @@ -void c11_generic_test(unsigned int x, int y) { +void c11_generic_test_with_load(unsigned int x, int y) { unsigned int r; r = _Generic(r, unsigned int: x, int: y) + 1; } -// // semmle-extractor-options: -std=c11 +#define describe(val) \ + _Generic((val), \ + int: "int", \ + default: "unknown" \ + ) + +const char *c11_generic_test_with_constant_and_macro() +{ + int i; + + return describe(i); +} + +const char *c11_generic_test_with_constant_and_no_macro() +{ + int i; + + return _Generic(i, int: "int", default: "unknown"); +} + +void c11_generic_test_test_with_cast(int y) { + unsigned int r; + r = _Generic(r, unsigned int: (unsigned int)y, int: y); +} + +// semmle-extractor-options: -std=c11 diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 18f0d99ac67..01ebe0219f9 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -2733,7 +2733,7 @@ destructors_for_temps.cpp: # 102| v102_8(void) = ExitFunction : generic.c: -# 1| void c11_generic_test(unsigned int, int) +# 1| void c11_generic_test_with_load(unsigned int, int) # 1| Block 0 # 1| v1_1(void) = EnterFunction : # 1| mu1_2(unknown) = AliasedDefinition : @@ -2755,6 +2755,59 @@ generic.c: # 1| v1_9(void) = AliasedUse : ~m? # 1| v1_10(void) = ExitFunction : +# 12| char const* c11_generic_test_with_constant_and_macro() +# 12| Block 0 +# 12| v12_1(void) = EnterFunction : +# 12| mu12_2(unknown) = AliasedDefinition : +# 12| mu12_3(unknown) = InitializeNonLocal : +# 14| r14_1(glval) = VariableAddress[i] : +# 14| mu14_2(int) = Uninitialized[i] : &:r14_1 +# 16| r16_1(glval) = VariableAddress[#return] : +# 16| r16_2(glval) = StringConstant[int] : +# 16| r16_3(char *) = Convert : r16_2 +# 16| r16_4(char *) = Convert : r16_3 +# 16| mu16_5(char *) = Store[#return] : &:r16_1, r16_4 +# 12| r12_4(glval) = VariableAddress[#return] : +# 12| v12_5(void) = ReturnValue : &:r12_4, ~m? +# 12| v12_6(void) = AliasedUse : ~m? +# 12| v12_7(void) = ExitFunction : + +# 19| char const* c11_generic_test_with_constant_and_no_macro() +# 19| Block 0 +# 19| v19_1(void) = EnterFunction : +# 19| mu19_2(unknown) = AliasedDefinition : +# 19| mu19_3(unknown) = InitializeNonLocal : +# 21| r21_1(glval) = VariableAddress[i] : +# 21| mu21_2(int) = Uninitialized[i] : &:r21_1 +# 23| r23_1(glval) = VariableAddress[#return] : +# 23| r23_2(glval) = StringConstant["int"] : +# 23| r23_3(char *) = Convert : r23_2 +# 23| r23_4(char *) = Convert : r23_3 +# 23| mu23_5(char *) = Store[#return] : &:r23_1, r23_4 +# 19| r19_4(glval) = VariableAddress[#return] : +# 19| v19_5(void) = ReturnValue : &:r19_4, ~m? +# 19| v19_6(void) = AliasedUse : ~m? +# 19| v19_7(void) = ExitFunction : + +# 26| void c11_generic_test_test_with_cast(int) +# 26| Block 0 +# 26| v26_1(void) = EnterFunction : +# 26| mu26_2(unknown) = AliasedDefinition : +# 26| mu26_3(unknown) = InitializeNonLocal : +# 26| r26_4(glval) = VariableAddress[y] : +# 26| mu26_5(int) = InitializeParameter[y] : &:r26_4 +# 27| r27_1(glval) = VariableAddress[r] : +# 27| mu27_2(unsigned int) = Uninitialized[r] : &:r27_1 +# 28| r28_1(glval) = VariableAddress[y] : +# 28| r28_2(int) = Load[y] : &:r28_1, ~m? +# 28| r28_3(unsigned int) = Convert : r28_2 +# 28| r28_4(glval) = VariableAddress[r] : +# 28| mu28_5(unsigned int) = Store[r] : &:r28_4, r28_3 +# 29| v29_1(void) = NoOp : +# 26| v26_6(void) = ReturnVoid : +# 26| v26_7(void) = AliasedUse : ~m? +# 26| v26_8(void) = ExitFunction : + ir.c: # 7| void MyCoordsTest(int) # 7| Block 0 From a9b5faa6ab4b11364046bc0a95bbf135bf4552ef Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 30 Aug 2024 11:16:59 +0200 Subject: [PATCH 164/404] C#: Add SSA test for enums --- csharp/ql/test/library-tests/dataflow/ssa/Enum.cs | 14 ++++++++++++++ .../dataflow/ssa/ReadAdjacentRead.expected | 1 + .../library-tests/dataflow/ssa/SsaDef.expected | 1 + .../dataflow/ssa/SsaDefElement.expected | 1 + .../dataflow/ssa/SsaDefLastRead.expected | 1 + .../library-tests/dataflow/ssa/SsaRead.expected | 2 ++ .../dataflow/ssa/SsaUltimateDef.expected | 1 + 7 files changed, 21 insertions(+) create mode 100644 csharp/ql/test/library-tests/dataflow/ssa/Enum.cs diff --git a/csharp/ql/test/library-tests/dataflow/ssa/Enum.cs b/csharp/ql/test/library-tests/dataflow/ssa/Enum.cs new file mode 100644 index 00000000000..283b2800098 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/ssa/Enum.cs @@ -0,0 +1,14 @@ +enum E +{ + A +} + +class EnumTest +{ + void M() + { + // enums are modelled as fields; this test checks that we do not compute SSA for them + var e1 = E.A; + var e2 = E.A; + } +} diff --git a/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentRead.expected index 1b416d1b4f2..b1ad39e9793 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentRead.expected @@ -19,6 +19,7 @@ | DefUse.cs:144:22:144:22 | x | DefUse.cs:146:17:146:17 | access to local variable x | DefUse.cs:147:17:147:17 | access to local variable x | | DefUse.cs:152:9:152:14 | Field4 | DefUse.cs:156:13:156:18 | access to field Field4 | DefUse.cs:157:13:157:18 | access to field Field4 | | DefUse.cs:152:9:152:14 | Field4 | DefUse.cs:162:13:162:18 | access to field Field4 | DefUse.cs:163:13:163:18 | access to field Field4 | +| Enum.cs:3:5:3:5 | A | Enum.cs:11:18:11:20 | access to constant A | Enum.cs:12:18:12:20 | access to constant A | | Example.cs:4:9:4:13 | Field | Example.cs:14:13:14:22 | access to field Field | Example.cs:15:13:15:22 | access to field Field | | Example.cs:6:23:6:23 | i | Example.cs:8:22:8:22 | access to parameter i | Example.cs:10:13:10:13 | access to parameter i | | Example.cs:6:23:6:23 | i | Example.cs:10:13:10:13 | access to parameter i | Example.cs:11:26:11:26 | access to parameter i | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected index 8d0e2b8261d..aa119e1e349 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected @@ -94,6 +94,7 @@ | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:184:9:184:18 | SSA def(this.Field5) | | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | | DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | +| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | | Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) | | Example.cs:8:9:8:18 | this.Field | Example.cs:11:13:11:30 | SSA def(this.Field) | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected index 272db29e6f4..473eb6f6b4a 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected @@ -89,6 +89,7 @@ | DefUse.cs:186:9:190:9 | SSA def(a) | DefUse.cs:186:9:190:9 | ... = ... | | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:188:13:188:22 | ... = ... | | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:191:9:191:11 | delegate call | +| Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:8:10:8:10 | M | | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:6:23:6:23 | i | | Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:8:9:8:22 | ... = ... | | Example.cs:11:13:11:30 | SSA def(this.Field) | Example.cs:11:13:11:30 | ... = ... | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected index dd0e7c8d977..6125294cd16 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected @@ -83,6 +83,7 @@ | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:184:9:184:18 | SSA def(this.Field5) | DefUse.cs:185:13:185:18 | access to field Field5 | | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:192:13:192:18 | access to field Field5 | | DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:189:17:189:22 | access to field Field5 | +| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:12:18:12:20 | access to constant A | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:11:26:11:26 | access to parameter i | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:12:18:12:18 | access to parameter i | | Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:9:13:9:22 | access to field Field | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected index 9daa4269711..b5011431b4b 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected @@ -100,6 +100,8 @@ | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:184:9:184:18 | SSA def(this.Field5) | DefUse.cs:185:13:185:18 | access to field Field5 | | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:192:13:192:18 | access to field Field5 | | DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:189:17:189:22 | access to field Field5 | +| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:11:18:11:20 | access to constant A | +| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:12:18:12:20 | access to constant A | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:8:22:8:22 | access to parameter i | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:10:13:10:13 | access to parameter i | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:11:26:11:26 | access to parameter i | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected index d0e6b073f01..63411247676 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected @@ -100,6 +100,7 @@ | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:184:9:184:18 | SSA def(this.Field5) | | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | | DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | +| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:8:10:8:10 | SSA entry def(E.A) | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:6:23:6:23 | SSA param(i) | | Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:8:9:8:22 | SSA def(this.Field) | | Example.cs:8:9:8:18 | this.Field | Example.cs:11:13:11:30 | SSA def(this.Field) | Example.cs:11:13:11:30 | SSA def(this.Field) | From 4ef4ede0b13f23e16d4ff0616e0369a4a32b7641 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 30 Aug 2024 11:17:59 +0200 Subject: [PATCH 165/404] C#: Do not calculate field-based SSA for enums --- .../ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll | 6 +++++- .../library-tests/dataflow/ssa/ReadAdjacentRead.expected | 1 - csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected | 1 - .../test/library-tests/dataflow/ssa/SsaDefElement.expected | 1 - .../test/library-tests/dataflow/ssa/SsaDefLastRead.expected | 1 - csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected | 2 -- .../test/library-tests/dataflow/ssa/SsaUltimateDef.expected | 1 - 7 files changed, 5 insertions(+), 8 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll index 8fd12d90ae7..d4f0625be88 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -108,7 +108,11 @@ private module SourceVariableImpl { */ predicate isPlainFieldOrPropAccess(FieldOrPropAccess fpa, FieldOrProp fp, Callable c) { fieldOrPropAccessInCallable(fpa, fp, c) and - (ownFieldOrPropAccess(fpa) or fp.isStatic()) + ( + ownFieldOrPropAccess(fpa) + or + fp.isStatic() and not fp instanceof EnumConstant + ) } /** diff --git a/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentRead.expected index b1ad39e9793..1b416d1b4f2 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentRead.expected @@ -19,7 +19,6 @@ | DefUse.cs:144:22:144:22 | x | DefUse.cs:146:17:146:17 | access to local variable x | DefUse.cs:147:17:147:17 | access to local variable x | | DefUse.cs:152:9:152:14 | Field4 | DefUse.cs:156:13:156:18 | access to field Field4 | DefUse.cs:157:13:157:18 | access to field Field4 | | DefUse.cs:152:9:152:14 | Field4 | DefUse.cs:162:13:162:18 | access to field Field4 | DefUse.cs:163:13:163:18 | access to field Field4 | -| Enum.cs:3:5:3:5 | A | Enum.cs:11:18:11:20 | access to constant A | Enum.cs:12:18:12:20 | access to constant A | | Example.cs:4:9:4:13 | Field | Example.cs:14:13:14:22 | access to field Field | Example.cs:15:13:15:22 | access to field Field | | Example.cs:6:23:6:23 | i | Example.cs:8:22:8:22 | access to parameter i | Example.cs:10:13:10:13 | access to parameter i | | Example.cs:6:23:6:23 | i | Example.cs:10:13:10:13 | access to parameter i | Example.cs:11:26:11:26 | access to parameter i | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected index aa119e1e349..8d0e2b8261d 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected @@ -94,7 +94,6 @@ | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:184:9:184:18 | SSA def(this.Field5) | | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | | DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | -| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | | Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) | | Example.cs:8:9:8:18 | this.Field | Example.cs:11:13:11:30 | SSA def(this.Field) | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected index 473eb6f6b4a..272db29e6f4 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected @@ -89,7 +89,6 @@ | DefUse.cs:186:9:190:9 | SSA def(a) | DefUse.cs:186:9:190:9 | ... = ... | | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:188:13:188:22 | ... = ... | | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:191:9:191:11 | delegate call | -| Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:8:10:8:10 | M | | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:6:23:6:23 | i | | Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:8:9:8:22 | ... = ... | | Example.cs:11:13:11:30 | SSA def(this.Field) | Example.cs:11:13:11:30 | ... = ... | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected index 6125294cd16..dd0e7c8d977 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected @@ -83,7 +83,6 @@ | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:184:9:184:18 | SSA def(this.Field5) | DefUse.cs:185:13:185:18 | access to field Field5 | | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:192:13:192:18 | access to field Field5 | | DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:189:17:189:22 | access to field Field5 | -| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:12:18:12:20 | access to constant A | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:11:26:11:26 | access to parameter i | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:12:18:12:18 | access to parameter i | | Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:9:13:9:22 | access to field Field | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected index b5011431b4b..9daa4269711 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected @@ -100,8 +100,6 @@ | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:184:9:184:18 | SSA def(this.Field5) | DefUse.cs:185:13:185:18 | access to field Field5 | | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:192:13:192:18 | access to field Field5 | | DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:189:17:189:22 | access to field Field5 | -| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:11:18:11:20 | access to constant A | -| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:12:18:12:20 | access to constant A | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:8:22:8:22 | access to parameter i | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:10:13:10:13 | access to parameter i | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:11:26:11:26 | access to parameter i | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected index 63411247676..d0e6b073f01 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected @@ -100,7 +100,6 @@ | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:184:9:184:18 | SSA def(this.Field5) | | DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | | DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | -| Enum.cs:11:18:11:20 | E.A | Enum.cs:8:10:8:10 | SSA entry def(E.A) | Enum.cs:8:10:8:10 | SSA entry def(E.A) | | Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:6:23:6:23 | SSA param(i) | | Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:8:9:8:22 | SSA def(this.Field) | | Example.cs:8:9:8:18 | this.Field | Example.cs:11:13:11:30 | SSA def(this.Field) | Example.cs:11:13:11:30 | SSA def(this.Field) | From 4f0fe1ce3a6424caa1ca9349e2896501c1e3d748 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 30 Aug 2024 13:05:46 +0200 Subject: [PATCH 166/404] Rust: bazel packaging --- MODULE.bazel | 14 +++++ misc/codegen/generators/rustgen.py | 13 +++-- misc/codegen/lib/rust.py | 10 +++- misc/codegen/templates/rust_classes.mustache | 4 +- rust/.idea/.gitignore | 5 ++ rust/.idea/misc.xml | 6 ++ rust/.idea/modules.xml | 8 +++ rust/.idea/rust.iml | 13 +++++ rust/.idea/vcs.xml | 6 ++ rust/BUILD.bazel | 59 ++++++++++++++++++-- rust/codegen.conf | 2 +- rust/codegen/BUILD.bazel | 6 +- rust/codeql-extractor.yml | 15 +++++ rust/{ => extractor}/.gitignore | 0 rust/extractor/BUILD.bazel | 15 +++++ rust/{ => extractor}/Cargo.lock | 3 +- rust/{ => extractor}/Cargo.toml | 5 ++ rust/{ => extractor}/src/archive.rs | 2 +- rust/{ => extractor}/src/config.rs | 0 rust/{ => extractor}/src/generated/mod.rs | 0 rust/{ => extractor}/src/generated/top.rs | 10 ++-- rust/{ => extractor}/src/main.rs | 2 - rust/{ => extractor}/src/path.rs | 0 rust/{ => extractor}/src/translate.rs | 0 rust/{ => extractor}/src/trap.rs | 7 ++- rust/ql/lib/rust.dbscheme.stats | 4 ++ rust/tools/BUILD.bazel | 9 +++ rust/tools/index.sh | 17 ++++++ 28 files changed, 207 insertions(+), 28 deletions(-) create mode 100644 rust/.idea/.gitignore create mode 100644 rust/.idea/misc.xml create mode 100644 rust/.idea/modules.xml create mode 100644 rust/.idea/rust.iml create mode 100644 rust/.idea/vcs.xml create mode 100644 rust/codeql-extractor.yml rename rust/{ => extractor}/.gitignore (100%) create mode 100644 rust/extractor/BUILD.bazel rename rust/{ => extractor}/Cargo.lock (99%) rename rust/{ => extractor}/Cargo.toml (67%) rename rust/{ => extractor}/src/archive.rs (94%) rename rust/{ => extractor}/src/config.rs (100%) rename rust/{ => extractor}/src/generated/mod.rs (100%) rename rust/{ => extractor}/src/generated/top.rs (82%) rename rust/{ => extractor}/src/main.rs (98%) rename rust/{ => extractor}/src/path.rs (100%) rename rust/{ => extractor}/src/translate.rs (100%) rename rust/{ => extractor}/src/trap.rs (95%) create mode 100644 rust/ql/lib/rust.dbscheme.stats create mode 100644 rust/tools/BUILD.bazel create mode 100755 rust/tools/index.sh diff --git a/MODULE.bazel b/MODULE.bazel index d2add26c88d..783c35dc5fc 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -63,6 +63,20 @@ r.from_cargo( ) use_repo(r, ruby_deps = "rd") +rsp = use_extension( + "@rules_rust//crate_universe:extension.bzl", + "crate", + isolate = True, +) +rsp.from_cargo( + name = "rs_deps", + cargo_lockfile = "//rust/extractor:Cargo.lock", + manifests = [ + "//rust/extractor:Cargo.toml", + ], +) +use_repo(rsp, rust_deps = "rs_deps") + dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet") dotnet.toolchain(dotnet_version = "8.0.101") use_repo(dotnet, "dotnet_toolchains") diff --git a/misc/codegen/generators/rustgen.py b/misc/codegen/generators/rustgen.py index dc5494aa731..04a6538998f 100644 --- a/misc/codegen/generators/rustgen.py +++ b/misc/codegen/generators/rustgen.py @@ -26,7 +26,7 @@ def _get_type(t: str) -> str: def _get_field(cls: schema.Class, p: schema.Property) -> rust.Field: - table_name = None + table_name = inflection.tableize(cls.name) if not p.is_single: table_name = f"{cls.name}_{p.name}" if p.is_predicate: @@ -47,11 +47,12 @@ def _get_field(cls: schema.Class, p: schema.Property) -> rust.Field: def _get_properties( - cls: schema.Class, lookup: dict[str, schema.Class] -) -> typing.Iterable[schema.Property]: + cls: schema.Class, lookup: dict[str, schema.Class], +) -> typing.Iterable[tuple[schema.Class, schema.Property]]: for b in cls.bases: yield from _get_properties(lookup[b], lookup) - yield from cls.properties + for p in cls.properties: + yield cls, p class Processor: @@ -63,8 +64,8 @@ class Processor: return rust.Class( name=name, fields=[ - _get_field(cls, p) - for p in _get_properties(cls, self._classmap) + _get_field(c, p) + for c, p in _get_properties(cls, self._classmap) if "rust_skip" not in p.pragmas and not p.synth ], table_name=inflection.tableize(cls.name), diff --git a/misc/codegen/lib/rust.py b/misc/codegen/lib/rust.py index 0c51d33fbf2..5e6405759b8 100644 --- a/misc/codegen/lib/rust.py +++ b/misc/codegen/lib/rust.py @@ -78,7 +78,7 @@ def get_field_override(field: str): class Field: field_name: str base_type: str - table_name: str = None + table_name: str is_optional: bool = False is_repeated: bool = False is_unordered: bool = False @@ -121,8 +121,12 @@ class Class: fields: list[Field] = dataclasses.field(default_factory=list) @property - def single_fields(self): - return [f for f in self.fields if f.is_single] + def single_field_entries(self): + ret = {self.table_name: []} + for f in self.fields: + if f.is_single: + ret.setdefault(f.table_name, []).append(f) + return [{"table_name": k, "fields": v} for k, v in ret.items()] @dataclasses.dataclass diff --git a/misc/codegen/templates/rust_classes.mustache b/misc/codegen/templates/rust_classes.mustache index 5102b8aea40..a2c0aff6db8 100644 --- a/misc/codegen/templates/rust_classes.mustache +++ b/misc/codegen/templates/rust_classes.mustache @@ -18,7 +18,9 @@ impl TrapEntry for {{name}} { } fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { - write!(out, "{{table_name}}({id}{{#single_fields}}, {}{{/single_fields}})\n"{{#single_fields}}, {{#emitter}}self.{{field_name}}{{/emitter}}{{/single_fields}})?; + {{#single_field_entries}} + write!(out, "{{table_name}}({id}{{#fields}}, {}{{/fields}})\n"{{#fields}}, {{#emitter}}self.{{field_name}}{{/emitter}}{{/fields}})?; + {{/single_field_entries}} {{#fields}} {{#is_predicate}} if self.{{field_name}} { diff --git a/rust/.idea/.gitignore b/rust/.idea/.gitignore new file mode 100644 index 00000000000..b58b603fea7 --- /dev/null +++ b/rust/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/rust/.idea/misc.xml b/rust/.idea/misc.xml new file mode 100644 index 00000000000..73797bfcc85 --- /dev/null +++ b/rust/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/rust/.idea/modules.xml b/rust/.idea/modules.xml new file mode 100644 index 00000000000..9996827f2ba --- /dev/null +++ b/rust/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/rust/.idea/rust.iml b/rust/.idea/rust.iml new file mode 100644 index 00000000000..fd100f63146 --- /dev/null +++ b/rust/.idea/rust.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/rust/.idea/vcs.xml b/rust/.idea/vcs.xml new file mode 100644 index 00000000000..54e4b961ee0 --- /dev/null +++ b/rust/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/rust/BUILD.bazel b/rust/BUILD.bazel index 87aedadba29..606e0e70e9c 100644 --- a/rust/BUILD.bazel +++ b/rust/BUILD.bazel @@ -1,4 +1,55 @@ -exports_files([ - "codegen.conf", - "schema.py", -]) +load("@rules_pkg//pkg:mappings.bzl", "pkg_filegroup") +load( + "//misc/bazel:pkg.bzl", + "codeql_pack", + "codeql_pkg_files", +) + +package(default_visibility = ["//rust:__subpackages__"]) + +filegroup( + name = "schema", + srcs = ["schema.py"], +) + +filegroup( + name = "schema-includes", + srcs = glob(["*.dbscheme"]), +) + +filegroup( + name = "codegen-conf", + srcs = ["codegen.conf"], +) + +codeql_pkg_files( + name = "tools-arch", + exes = ["//rust/extractor"], + prefix = "{CODEQL_PLATFORM}", +) + +pkg_filegroup( + name = "tools", + srcs = [ + ":tools-arch", + "//rust/tools", + ], + prefix = "tools", +) + +codeql_pkg_files( + name = "root-files", + srcs = [ + "codeql-extractor.yml", + "ql/lib/rust.dbscheme", + "ql/lib/rust.dbscheme.stats", + ], +) + +codeql_pack( + name = "rust", + srcs = [ + ":root-files", + ":tools", + ], +) diff --git a/rust/codegen.conf b/rust/codegen.conf index df2f6270a9a..6e8a59de9ae 100644 --- a/rust/codegen.conf +++ b/rust/codegen.conf @@ -4,6 +4,6 @@ --ql-output=ql/lib/codeql/rust/generated --ql-stub-output=ql/lib/codeql/rust/elements --ql-test-output=ql/test/extractor-tests/generated ---rust-output=src/generated +--rust-output=extractor/src/generated --generated-registry=.generated.list --script-name=codegen diff --git a/rust/codegen/BUILD.bazel b/rust/codegen/BUILD.bazel index 82ac81abab0..99f737538a6 100644 --- a/rust/codegen/BUILD.bazel +++ b/rust/codegen/BUILD.bazel @@ -5,11 +5,11 @@ native_binary( src = "//misc/codegen", out = "codegen", args = [ - "--configuration-file=$(location //rust:codegen.conf)", + "--configuration-file=$(location //rust:codegen-conf)", ], data = [ - "//rust:codegen.conf", - "//rust:schema.py", + "//rust:codegen-conf", + "//rust:schema", ], visibility = ["//rust:__subpackages__"], ) diff --git a/rust/codeql-extractor.yml b/rust/codeql-extractor.yml new file mode 100644 index 00000000000..af7d4475867 --- /dev/null +++ b/rust/codeql-extractor.yml @@ -0,0 +1,15 @@ +name: "rust" +display_name: "Rust" +version: 0.1.0 +column_kind: "utf8" +build_modes: + - none +github_api_languages: + - Rust +scc_languages: + - Rust +file_types: + - name: rust + display_name: Rust files + extensions: + - .rs diff --git a/rust/.gitignore b/rust/extractor/.gitignore similarity index 100% rename from rust/.gitignore rename to rust/extractor/.gitignore diff --git a/rust/extractor/BUILD.bazel b/rust/extractor/BUILD.bazel new file mode 100644 index 00000000000..ffe1ee92de9 --- /dev/null +++ b/rust/extractor/BUILD.bazel @@ -0,0 +1,15 @@ +load("@rust_deps//:defs.bzl", "aliases", "all_crate_deps") +load("//misc/bazel:rust.bzl", "codeql_rust_binary") + +codeql_rust_binary( + name = "extractor", + srcs = glob(["src/**/*.rs"]), + aliases = aliases(), + proc_macro_deps = all_crate_deps( + proc_macro = True, + ), + visibility = ["//rust:__subpackages__"], + deps = all_crate_deps( + normal = True, + ), +) diff --git a/rust/Cargo.lock b/rust/extractor/Cargo.lock similarity index 99% rename from rust/Cargo.lock rename to rust/extractor/Cargo.lock index 35f700fa120..98a3f590e2a 100644 --- a/rust/Cargo.lock +++ b/rust/extractor/Cargo.lock @@ -1566,8 +1566,7 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc_apfloat" version = "0.2.1+llvm-462a31f5a5ab" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886d94c63c812a8037c4faca2607453a0fa4cf82f734665266876b022244543f" +source = "git+https://github.com/redsun82/rustc_apfloat.git?rev=096d585100636bc2e9f09d7eefec38c5b334d47b#096d585100636bc2e9f09d7eefec38c5b334d47b" dependencies = [ "bitflags 1.3.2", "smallvec", diff --git a/rust/Cargo.toml b/rust/extractor/Cargo.toml similarity index 67% rename from rust/Cargo.toml rename to rust/extractor/Cargo.toml index 716a506edc6..8c8ef26ef2b 100644 --- a/rust/Cargo.toml +++ b/rust/extractor/Cargo.toml @@ -21,3 +21,8 @@ serde = "1.0.209" serde_with = "3.9.0" stderrlog = "0.6.0" triomphe = "0.1.13" + +[patch.crates-io] +# patch for build script bug preventing bazel build +# see https://github.com/rust-lang/rustc_apfloat/pull/17 +rustc_apfloat = { git = "https://github.com/redsun82/rustc_apfloat.git", rev = "096d585100636bc2e9f09d7eefec38c5b334d47b" } diff --git a/rust/src/archive.rs b/rust/extractor/src/archive.rs similarity index 94% rename from rust/src/archive.rs rename to rust/extractor/src/archive.rs index 09847ac85d6..68a652543c3 100644 --- a/rust/src/archive.rs +++ b/rust/extractor/src/archive.rs @@ -19,7 +19,7 @@ impl Archiver { let mut dest = self.root.clone(); dest.push(path::key(source)); let parent = dest.parent().unwrap(); - if fs::exists(&dest)? { + if fs::metadata(&dest).is_ok() { return Ok(()) } fs::create_dir_all(parent)?; diff --git a/rust/src/config.rs b/rust/extractor/src/config.rs similarity index 100% rename from rust/src/config.rs rename to rust/extractor/src/config.rs diff --git a/rust/src/generated/mod.rs b/rust/extractor/src/generated/mod.rs similarity index 100% rename from rust/src/generated/mod.rs rename to rust/extractor/src/generated/mod.rs diff --git a/rust/src/generated/top.rs b/rust/extractor/src/generated/top.rs similarity index 82% rename from rust/src/generated/top.rs rename to rust/extractor/src/generated/top.rs index d58970b23bc..d337d08c9d4 100644 --- a/rust/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -15,7 +15,8 @@ impl TrapEntry for DbFile { } fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { - write!(out, "db_files({id}, {})\n", quoted(&self.name))?; + write!(out, "db_files({id})\n")?; + write!(out, "files({id}, {})\n", quoted(&self.name))?; Ok(()) } } @@ -36,7 +37,8 @@ impl TrapEntry for DbLocation { } fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { - write!(out, "db_locations({id}, {}, {}, {}, {}, {})\n", self.file, self.start_line, self.start_column, self.end_line, self.end_column)?; + write!(out, "db_locations({id})\n")?; + write!(out, "locations({id}, {}, {}, {}, {}, {})\n", self.file, self.start_line, self.start_column, self.end_line, self.end_column)?; Ok(()) } } @@ -56,7 +58,7 @@ impl TrapEntry for Function { fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { write!(out, "functions({id}, {})\n", quoted(&self.name))?; if let Some(ref v) = &self.location { - write!(out, "function_locations({id}, {})\n", v)?; + write!(out, "locatable_locations({id}, {})\n", v)?; } Ok(()) } @@ -77,7 +79,7 @@ impl TrapEntry for Module { fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { write!(out, "modules({id})\n")?; if let Some(ref v) = &self.location { - write!(out, "module_locations({id}, {})\n", v)?; + write!(out, "locatable_locations({id}, {})\n", v)?; } for (i, &ref v) in self.declarations.iter().enumerate() { write!(out, "module_declarations({id}, {}, {})\n", i, v)?; diff --git a/rust/src/main.rs b/rust/extractor/src/main.rs similarity index 98% rename from rust/src/main.rs rename to rust/extractor/src/main.rs index 016c948739b..cb8d3f2deb2 100644 --- a/rust/src/main.rs +++ b/rust/extractor/src/main.rs @@ -1,5 +1,3 @@ -#![feature(path_add_extension)] - use std::fs; use std::path::{PathBuf, Path}; use ra_ap_project_model::CargoConfig; diff --git a/rust/src/path.rs b/rust/extractor/src/path.rs similarity index 100% rename from rust/src/path.rs rename to rust/extractor/src/path.rs diff --git a/rust/src/translate.rs b/rust/extractor/src/translate.rs similarity index 100% rename from rust/src/translate.rs rename to rust/extractor/src/translate.rs diff --git a/rust/src/trap.rs b/rust/extractor/src/trap.rs similarity index 95% rename from rust/src/trap.rs rename to rust/extractor/src/trap.rs index d74f252577a..ea5be477370 100644 --- a/rust/src/trap.rs +++ b/rust/extractor/src/trap.rs @@ -1,3 +1,4 @@ +use std::ffi::OsString; use std::fmt::{Debug, Display, Formatter}; use std::fs::File; use std::io::Write; @@ -158,7 +159,11 @@ impl TrapFileProvider { pub fn create(&self, category: &str, key: &Path) -> std::io::Result { let mut path = PathBuf::from(category); path.push(path::key(key)); - path.add_extension("trap"); + path.set_extension(path.extension().map(|e| { + let mut o : OsString = e.to_owned(); + o.push(".trap"); + o + }).unwrap_or("trap".into())); let trap_name = String::from(path.to_string_lossy()); debug!("creating trap file {}", trap_name); path = self.trap_dir.join(path); diff --git a/rust/ql/lib/rust.dbscheme.stats b/rust/ql/lib/rust.dbscheme.stats new file mode 100644 index 00000000000..9995467e33e --- /dev/null +++ b/rust/ql/lib/rust.dbscheme.stats @@ -0,0 +1,4 @@ + + + + diff --git a/rust/tools/BUILD.bazel b/rust/tools/BUILD.bazel new file mode 100644 index 00000000000..27bc5bbe600 --- /dev/null +++ b/rust/tools/BUILD.bazel @@ -0,0 +1,9 @@ +load("//misc/bazel:pkg.bzl", "codeql_pkg_files") + +codeql_pkg_files( + name = "tools", + exes = [ + "index.sh", + ], + visibility = ["//rust:__pkg__"], +) diff --git a/rust/tools/index.sh b/rust/tools/index.sh new file mode 100755 index 00000000000..7035f09d0a4 --- /dev/null +++ b/rust/tools/index.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# TODO move this to rust code + +inputs=($(find -name Cargo.toml)) + +if [ "${#inputs}" -eq 0 ]; then + inputs=($(find -name rust-project.json)) + if [ "${#inputs}" -eq 0 ]; then + inputs=($(find -name '*.rs')) + if [ "${#inputs}" -eq 0 ]; then + echo "no source files found" >&2 + exit 1 + fi + fi +fi + +exec "$CODEQL_EXTRACTOR_RUST_ROOT/tools/$CODEQL_PLATFORM/extractor" "${inputs[@]}" From 4945943732dc9f58b57c139bdf720addb44017cf Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 2 Aug 2024 22:41:44 +0200 Subject: [PATCH 167/404] C++: Support C11 `_Generic` expressions --- .../downgrades.ql | 32 + .../old.dbscheme | 2319 +++++++++++++++++ .../semmlecode.cpp.dbscheme | 2317 ++++++++++++++++ .../upgrade.properties | 4 + .../change-notes/2024-08-30-c11-generics.md | 4 + cpp/ql/lib/semmle/code/cpp/PrintAST.qll | 24 + cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll | 100 + .../raw/internal/TranslatedElement.qll | 6 + .../raw/internal/TranslatedExpr.qll | 3 +- cpp/ql/lib/semmlecode.cpp.dbscheme | 2 + cpp/ql/lib/semmlecode.cpp.dbscheme.stats | 2246 ++++++++-------- .../old.dbscheme | 2317 ++++++++++++++++ .../semmlecode.cpp.dbscheme | 2319 +++++++++++++++++ .../upgrade.properties | 2 + .../c11_generic/PrintAST.expected | 458 ++++ .../library-tests/c11_generic/PrintAST.qlref | 1 + .../c11_generic/macro_invocation.expected | 8 + .../c11_generic/macro_invocation.ql | 5 + .../library-tests/ir/ir/PrintAST.expected | 83 +- .../library-tests/ir/ir/aliased_ir.expected | 4 +- .../test/library-tests/ir/ir/raw_ir.expected | 4 +- 21 files changed, 11125 insertions(+), 1133 deletions(-) create mode 100644 cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/downgrades.ql create mode 100644 cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/old.dbscheme create mode 100644 cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/semmlecode.cpp.dbscheme create mode 100644 cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/upgrade.properties create mode 100644 cpp/ql/lib/change-notes/2024-08-30-c11-generics.md create mode 100644 cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme create mode 100644 cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/semmlecode.cpp.dbscheme create mode 100644 cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/upgrade.properties create mode 100644 cpp/ql/test/library-tests/c11_generic/PrintAST.expected create mode 100644 cpp/ql/test/library-tests/c11_generic/PrintAST.qlref create mode 100644 cpp/ql/test/library-tests/c11_generic/macro_invocation.expected create mode 100644 cpp/ql/test/library-tests/c11_generic/macro_invocation.ql diff --git a/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/downgrades.ql b/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/downgrades.ql new file mode 100644 index 00000000000..3425ec2f672 --- /dev/null +++ b/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/downgrades.ql @@ -0,0 +1,32 @@ +/* + * Approach: replace conversion expressions of kind 389 (= @c11_generic) by + * conversion expressions of kind 12 (= @parexpr), i.e., a `ParenthesisExpr`, + * and drop the relation which its child expressions, which are just syntactic + * sugar. Parenthesis expressions are equally benign as C11 _Generic expressions, + * and behave similarly in the context of the IR. + */ + +class Expr extends @expr { + string toString() { none() } +} + +class Location extends @location { + string toString() { none() } +} + +class ExprParent extends @exprparent { + string toString() { none() } +} + +query predicate new_exprs(Expr expr, int new_kind, Location loc) { + exists(int kind | exprs(expr, kind, loc) | if kind = 389 then new_kind = 12 else new_kind = kind) +} + +query predicate new_exprparents(Expr expr, int index, ExprParent expr_parent) { + exprparents(expr, index, expr_parent) and + ( + not expr_parent instanceof @expr + or + exists(int kind | exprs(expr_parent.(Expr), kind, _) | kind != 389) + ) +} diff --git a/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/old.dbscheme b/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/old.dbscheme new file mode 100644 index 00000000000..0fea0ee7026 --- /dev/null +++ b/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/old.dbscheme @@ -0,0 +1,2319 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/semmlecode.cpp.dbscheme b/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..02a123a1a68 --- /dev/null +++ b/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/semmlecode.cpp.dbscheme @@ -0,0 +1,2317 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/upgrade.properties b/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/upgrade.properties new file mode 100644 index 00000000000..1f42059fd60 --- /dev/null +++ b/cpp/downgrades/0fea0ee7026c7c3f7d6faef4df4bf67847b67d71/upgrade.properties @@ -0,0 +1,4 @@ +description: Expose C11 _Generics +compatibility: partial +exprs.rel: run downgrades.ql new_exprs +exprparents.rel: run downgrades.ql new_exprparents diff --git a/cpp/ql/lib/change-notes/2024-08-30-c11-generics.md b/cpp/ql/lib/change-notes/2024-08-30-c11-generics.md new file mode 100644 index 00000000000..29f3579090b --- /dev/null +++ b/cpp/ql/lib/change-notes/2024-08-30-c11-generics.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added a class `C11GenericExpr` to represent C11 generic selection expressions. The generic selection is represented as a `Conversion` on the expression that will be selected. diff --git a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll index b515a346bf3..ac043f47b0f 100644 --- a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll +++ b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll @@ -385,6 +385,21 @@ class CastNode extends ConversionNode { } } +/** + * A node representing a `C11GenericExpr`. + */ +class C11GenericNode extends ConversionNode { + C11GenericExpr generic; + + C11GenericNode() { generic = conv } + + override AstNode getChildInternal(int childIndex) { + result = super.getChildInternal(childIndex - count(generic.getAChild())) + or + result.getAst() = generic.getChild(childIndex) + } +} + /** * A node representing a `StmtExpr`. */ @@ -860,6 +875,15 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred) or expr.(BuiltInVarArgsStart).getLastNamedParameter() = ele and pred = "getLastNamedParameter()" or + expr.(C11GenericExpr).getControllingExpr() = ele and pred = "getControllingExpr()" + or + exists(int n | + expr.(C11GenericExpr).getAssociationType(n) = ele.(TypeName).getType() and + pred = "getAssociationType(" + n + ")" + or + expr.(C11GenericExpr).getAssociationExpr(n) = ele and pred = "getAssociationExpr(" + n + ")" + ) + or expr.(Call).getQualifier() = ele and pred = "getQualifier()" or exists(int n | expr.(Call).getArgument(n) = ele and pred = "getArgument(" + n.toString() + ")") diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll index d85962b9fe7..78c64e22282 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll @@ -632,6 +632,104 @@ class ParenthesisExpr extends Conversion, @parexpr { override string getAPrimaryQlClass() { result = "ParenthesisExpr" } } +/** + * A node representing a C11 `_Generic` selection expression. + * + * For example: + * ``` + * _Generic(e, int: "int", default: "unknown") + * ``` + */ +class C11GenericExpr extends Conversion, @c11_generic { + int associationCount; + + C11GenericExpr() { associationCount = (count(this.getAChild()) - 1) / 2 } + + override string toString() { result = "_Generic" } + + override string getAPrimaryQlClass() { result = "C11GenericExpr" } + + /** + * Gets the controlling expression of the generic selection. + * + * For example, for + * ``` + * _Generic(e, int: "a", default: "b") + * ``` + * the result is `e`. + */ + Expr getControllingExpr() { result = this.getChild(0) } + + /** + * Gets the type of the `n`th element in the association list of the generic selection. + * + * For example, for + * ``` + * _Generic(e, int: "a", default: "b") + * ``` + * the type of the 0th element is `int`. In the case of the default element the + * type will an instance of `VoidType`. + */ + Type getAssociationType(int n) { + n in [0 .. associationCount - 1] and + result = this.getChild(n * 2 + 1).(TypeName).getType() + } + + /** + * Gets the type of an element in the association list of the generic selection. + */ + Type getAnAssociationType() { result = this.getAssociationType(_) } + + /** + * Gets the expression of the `n`th element in the association list of + * the generic selection. + * + * For example, for + * ``` + * _Generic(e, int: "a", default: "b") + * ``` + * the expression for 0th element is `"a"`, and the expression for the + * 1st element is `"b"`. For the selected expression, this predicate + * will yield a `ReuseExpr`, such that + * ``` + * this.getAssociationExpr(n).(ReuseExpr).getReusedExpr() = this.getExpr() + * ``` + */ + Expr getAssociationExpr(int n) { + n in [0 .. associationCount - 1] and + result = this.getChild(n * 2 + 2) + } + + /** + * Gets the expression of an element in the association list of the generic selection. + */ + Expr getAnAssociationExpr() { result = this.getAssociationExpr(_) } + + /** + * Holds if the `n`th element of the association list of the generic selection is the + * default element. + * + * For example, for + * ``` + * _Generic(e, int: "a", default: "b") + * ``` + * this holds for 1. + */ + predicate isDefaultAssociation(int n) { this.getAssociationType(n) instanceof VoidType } + + /** + * Holds if the `n`th element of the association list of the generic selection is the + * one whose expression was selected. + * + * For example, with `e` of type `int` and + * ``` + * _Generic(e, int: "a", default: "b") + * ``` + * this holds for 0. + */ + predicate isSelectedAssociation(int n) { this.getAssociationExpr(n) instanceof ReuseExpr } +} + /** * A C/C++ expression that could not be resolved, or that can no longer be * represented due to a database upgrade or downgrade. @@ -668,6 +766,8 @@ class AssumeExpr extends Expr, @assume { /** * A C/C++ comma expression. + * + * For example: * ``` * int c = compute1(), compute2(), resulting_value; * ``` diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 4d2b1a95d31..2d10b2e32a5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -128,6 +128,9 @@ private predicate ignoreExprAndDescendants(Expr expr) { vaStartExpr.getLastNamedParameter().getFullyConverted() = expr ) or + // The children of C11 _Generic expressions are just surface syntax. + exists(C11GenericExpr generic | generic.getAChild() = expr) + or // Do not translate implicit destructor calls for unnamed temporary variables that are // conditionally constructed (until we have a mechanism for calling these only when the // temporary's constructor was run) @@ -432,6 +435,9 @@ predicate ignoreLoad(Expr expr) { // The load is duplicated from the right operand. isExtractorFrontendVersion65OrHigher() and expr instanceof CommaExpr or + // The load is duplicated from the chosen expression. + expr instanceof C11GenericExpr + or expr.(PointerDereferenceExpr).getOperand().getFullyConverted().getType().getUnspecifiedType() instanceof FunctionPointerType or diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index c2e216cc963..e7ccac24eb9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -893,7 +893,8 @@ class TranslatedTransparentConversion extends TranslatedTransparentExpr { ( expr instanceof ParenthesisExpr or expr instanceof ReferenceDereferenceExpr or - expr instanceof ReferenceToExpr + expr instanceof ReferenceToExpr or + expr instanceof C11GenericExpr ) } diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index 02a123a1a68..0fea0ee7026 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1210,6 +1210,7 @@ conversionkinds( | @reference_to | @ref_indirect | @temp_init + | @c11_generic ; /* @@ -1792,6 +1793,7 @@ case @expr.kind of | 386 = @isscopedenum | 387 = @istriviallyrelocatable | 388 = @datasizeof +| 389 = @c11_generic ; @var_args_expr = @vastartexpr diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index d2d1f3a4e63..73e6d0bf972 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -18,27 +18,27 @@ @location_default - 29768335 + 29765023 @location_stmt 3819884 + + @location_expr + 13187951 + @diagnostic 4996 @file - 123268 + 123252 @folder - 16342 - - - @location_expr - 13187951 + 16340 @macro_expansion @@ -46,23 +46,23 @@ @other_macro_reference - 859141 + 859032 @function - 4179912 + 4179381 @fun_decl - 4544113 + 4543537 @var_decl - 8040448 + 8039427 @type_decl - 3283883 + 3283466 @namespace_decl @@ -70,7 +70,7 @@ @using_declaration - 363267 + 363221 @using_directive @@ -86,7 +86,7 @@ @parameter - 6191425 + 6190639 @membervariable @@ -98,7 +98,7 @@ @localvariable - 576952 + 576947 @enumconstant @@ -330,15 +330,15 @@ @pointer - 568247 + 568175 @type_with_specifiers - 852138 + 852029 @array - 110194 + 110180 @routineptr @@ -346,7 +346,7 @@ @reference - 1276572 + 1276410 @gnu_vector @@ -358,7 +358,7 @@ @rvalue_reference - 333384 + 333342 @block @@ -366,15 +366,15 @@ @decltype - 27081 + 27078 @usertype - 5234696 + 5234031 @mangledname - 6062554 + 6061784 @type_mention @@ -386,19 +386,39 @@ @ptrtomember - 37820 + 37816 @specifier - 24747 + 24743 + + + @gnuattribute + 553702 + + + @stdattribute + 253563 + + + @declspec + 239153 + + + @msattribute + 3 + + + @alignas + 4668 @attribute_arg_token - 25213 + 25210 @attribute_arg_constant_expr - 318442 + 318402 @attribute_arg_empty @@ -416,26 +436,6 @@ @attribute_arg_expr 3 - - @gnuattribute - 553773 - - - @stdattribute - 253563 - - - @declspec - 239153 - - - @msattribute - 3 - - - @alignas - 4669 - @derivation 391568 @@ -450,7 +450,7 @@ @namespace - 12140 + 12138 @specialnamequalifyingelement @@ -470,7 +470,7 @@ @lambdacapture - 28015 + 28011 @address_of @@ -586,11 +586,11 @@ @gtexpr - 104124 + 104111 @ltexpr - 101789 + 101776 @geexpr @@ -638,7 +638,7 @@ @assignorexpr - 23628 + 23627 @assignxorexpr @@ -666,7 +666,7 @@ @subscriptexpr - 364482 + 364478 @callexpr @@ -834,7 +834,7 @@ @sizeof_pack - 5603 + 5602 @hasassignexpr @@ -982,7 +982,7 @@ @lambdaexpr - 21478 + 21475 @param_ref @@ -1026,7 +1026,7 @@ @istriviallycopyableexpr - 3735 + 3734 @isliteraltypeexpr @@ -1356,6 +1356,10 @@ @datasizeof 10 + + @c11_generic + 8 + @stmt_expr 1486025 @@ -1410,7 +1414,7 @@ @stmt_empty - 192685 + 192683 @stmt_continue @@ -1442,7 +1446,7 @@ @stmt_range_based_for - 8404 + 8403 @stmt_handler @@ -1458,31 +1462,31 @@ @ppd_if - 667235 + 667151 @ppd_ifdef - 263345 + 263312 @ppd_ifndef - 266614 + 266580 @ppd_elif - 25213 + 25210 @ppd_else - 209182 + 209155 @ppd_endif - 1197195 + 1197043 @ppd_plain_include - 311438 + 311399 @ppd_define @@ -1490,7 +1494,7 @@ @ppd_undef - 258676 + 258643 @ppd_include_next @@ -1498,7 +1502,7 @@ @ppd_line - 27521 + 27520 @ppd_error @@ -2144,7 +2148,7 @@ seconds - 9628 + 9868 @@ -2233,44 +2237,39 @@ 319 - 5 - 8 + 6 + 7 159 - 8 - 9 - 79 + 7 + 10 + 159 10 11 - 199 + 79 11 - 17 + 14 159 - 17 + 16 18 - 39 - - - 18 - 19 159 - 21 - 53 + 19 + 27 159 - 95 - 96 - 39 + 41 + 88 + 119 @@ -2338,17 +2337,17 @@ 3 4 - 1398 + 1518 4 5 - 359 + 319 5 6 - 279 + 199 6 @@ -2358,23 +2357,23 @@ 7 8 - 79 + 119 8 - 9 - 239 - - - 9 - 20 + 10 279 - 24 - 92 + 10 + 28 279 + + 28 + 86 + 199 + @@ -2424,13 +2423,13 @@ 79 - 135 - 136 + 134 + 135 39 - 138 - 139 + 148 + 149 39 @@ -2447,27 +2446,27 @@ 1 2 - 4794 + 5033 2 3 - 2037 + 2556 3 4 - 1478 + 1438 4 - 5 - 878 + 16 + 759 - 5 - 47 - 439 + 27 + 46 + 79 @@ -2483,32 +2482,32 @@ 1 2 - 4394 + 4314 2 3 - 1717 + 2237 3 4 - 1757 + 1638 4 5 - 719 + 799 5 - 9 - 838 + 11 + 759 - 9 - 77 - 199 + 16 + 76 + 119 @@ -2524,12 +2523,12 @@ 1 2 - 8110 + 8230 2 3 - 1518 + 1638 @@ -2873,7 +2872,7 @@ cpu_seconds - 7100 + 7168 elapsed_seconds @@ -2923,16 +2922,16 @@ 1 2 - 5633 + 5779 2 3 - 925 + 846 3 - 17 + 18 541 @@ -2949,12 +2948,12 @@ 1 2 - 6344 + 6468 2 3 - 756 + 699 @@ -2968,15 +2967,20 @@ 12 - 2 - 3 - 33 + 1 + 2 + 22 4 5 11 + + 5 + 6 + 11 + 9 10 @@ -2985,36 +2989,26 @@ 12 13 + 22 + + + 51 + 52 11 - 17 - 18 + 153 + 154 11 - 47 - 48 - 11 + 177 + 178 + 22 - 165 - 166 - 11 - - - 174 - 175 - 11 - - - 187 - 188 - 11 - - - 242 - 243 + 261 + 262 11 @@ -3029,15 +3023,20 @@ 12 - 2 - 3 - 33 + 1 + 2 + 22 4 5 11 + + 5 + 6 + 11 + 9 10 @@ -3046,36 +3045,31 @@ 12 13 + 22 + + + 49 + 50 11 - 17 - 18 + 106 + 107 11 - 46 - 47 + 127 + 128 11 - 115 - 116 + 135 + 136 11 - 126 - 127 - 11 - - - 142 - 143 - 11 - - - 219 - 220 + 236 + 237 11 @@ -4848,31 +4842,31 @@ locations_default - 29768335 + 29765023 id - 29768335 + 29765023 container - 123268 + 123252 startLine - 2095559 + 2095293 startColumn - 36887 + 36882 endLine - 2099761 + 2099495 endColumn - 48093 + 48087 @@ -4886,7 +4880,7 @@ 1 2 - 29768335 + 29765023 @@ -4902,7 +4896,7 @@ 1 2 - 29768335 + 29765023 @@ -4918,7 +4912,7 @@ 1 2 - 29768335 + 29765023 @@ -4934,7 +4928,7 @@ 1 2 - 29768335 + 29765023 @@ -4950,7 +4944,7 @@ 1 2 - 29768335 + 29765023 @@ -4966,67 +4960,67 @@ 1 11 - 9805 + 9804 11 18 - 10272 + 10271 18 30 - 9338 + 9337 30 42 - 9805 + 9804 43 61 - 9805 + 9804 61 79 - 9338 + 9337 80 106 - 9805 + 9804 108 149 - 9338 + 9337 149 199 - 9338 + 9337 206 291 - 9338 + 9337 304 469 - 9338 + 9337 482 850 - 9338 + 9337 936 2380 - 8404 + 8403 @@ -5042,67 +5036,67 @@ 1 8 - 9338 + 9337 8 13 - 9338 + 9337 13 20 - 9805 + 9804 20 32 - 9338 + 9337 32 43 - 9805 + 9804 44 61 - 9338 + 9337 62 72 - 9338 + 9337 73 93 - 9338 + 9337 97 128 - 9338 + 9337 128 180 - 9338 + 9337 180 267 - 9338 + 9337 277 414 - 9338 + 9337 439 1465 - 9338 + 9337 1557 @@ -5123,67 +5117,67 @@ 1 4 - 8871 + 8870 4 5 - 7937 + 7936 5 6 - 7470 + 7469 6 8 - 11206 + 11204 8 10 - 9338 + 9337 10 15 - 10739 + 10737 15 23 - 9805 + 9804 23 28 - 11206 + 11204 28 34 - 9805 + 9804 34 44 - 9338 + 9337 44 55 - 9338 + 9337 55 66 - 9805 + 9804 66 77 - 8404 + 8403 @@ -5199,67 +5193,67 @@ 1 8 - 9338 + 9337 8 13 - 9338 + 9337 13 20 - 9805 + 9804 20 32 - 9338 + 9337 32 43 - 9805 + 9804 43 60 - 9338 + 9337 61 71 - 9338 + 9337 72 93 - 9338 + 9337 94 127 - 9338 + 9337 128 179 - 9338 + 9337 180 268 - 9338 + 9337 278 413 - 9338 + 9337 437 1465 - 9338 + 9337 1554 @@ -5280,67 +5274,67 @@ 1 9 - 9805 + 9804 9 13 - 9338 + 9337 13 18 - 9338 + 9337 18 26 - 10272 + 10271 27 33 - 9338 + 9337 33 39 - 9338 + 9337 39 47 - 10272 + 10271 47 53 - 9338 + 9337 53 60 - 10272 + 10271 60 66 - 9338 + 9337 66 74 - 9805 + 9804 74 78 - 9805 + 9804 78 90 - 7003 + 7002 @@ -5356,52 +5350,52 @@ 1 2 - 583189 + 583115 2 3 - 314240 + 314200 3 4 - 195641 + 195616 4 6 - 162022 + 162002 6 10 - 183034 + 183011 10 16 - 162956 + 162936 16 25 - 169026 + 169005 25 46 - 161089 + 161068 46 169 - 157353 + 157333 169 265 - 7003 + 7002 @@ -5417,42 +5411,42 @@ 1 2 - 871282 + 871171 2 3 - 273618 + 273583 3 5 - 193773 + 193749 5 8 - 173696 + 173674 8 13 - 188170 + 188146 13 20 - 161089 + 161068 20 51 - 159688 + 159668 51 265 - 74241 + 74231 @@ -5468,47 +5462,47 @@ 1 2 - 612138 + 612060 2 3 - 313306 + 313266 3 4 - 198443 + 198417 4 6 - 183034 + 183011 6 9 - 173229 + 173207 9 13 - 163423 + 163402 13 19 - 174629 + 174607 19 29 - 164824 + 164803 29 52 - 112528 + 112514 @@ -5524,22 +5518,22 @@ 1 2 - 1531980 + 1531786 2 3 - 348792 + 348748 3 5 - 162022 + 162002 5 16 - 52762 + 52755 @@ -5555,47 +5549,47 @@ 1 2 - 587858 + 587783 2 3 - 316108 + 316068 3 4 - 197509 + 197484 4 6 - 168559 + 168538 6 9 - 158287 + 158267 9 14 - 170894 + 170872 14 21 - 175096 + 175074 21 32 - 162489 + 162469 32 63 - 157820 + 157800 64 @@ -6011,52 +6005,52 @@ 1 2 - 593461 + 593386 2 3 - 306302 + 306263 3 4 - 198443 + 198417 4 6 - 159688 + 159668 6 10 - 182567 + 182544 10 16 - 162022 + 162002 16 25 - 171361 + 171339 25 46 - 158754 + 158734 46 161 - 158287 + 158267 162 265 - 8871 + 8870 @@ -6072,47 +6066,47 @@ 1 2 - 886690 + 886577 2 3 - 260077 + 260044 3 4 - 125135 + 125120 4 6 - 141011 + 140993 6 10 - 184902 + 184878 10 15 - 168559 + 168538 15 26 - 163423 + 163402 26 120 - 158287 + 158267 121 265 - 11673 + 11671 @@ -6128,22 +6122,22 @@ 1 2 - 1529646 + 1529452 2 3 - 341789 + 341745 3 5 - 170894 + 170872 5 10 - 57431 + 57424 @@ -6159,47 +6153,47 @@ 1 2 - 623344 + 623265 2 3 - 303501 + 303462 3 4 - 201711 + 201685 4 6 - 183968 + 183945 6 9 - 169960 + 169939 9 13 - 166692 + 166671 13 19 - 175096 + 175074 19 29 - 161089 + 161068 29 52 - 114396 + 114382 @@ -6215,52 +6209,52 @@ 1 2 - 599998 + 599922 2 3 - 306302 + 306263 3 4 - 197042 + 197017 4 6 - 169026 + 169005 6 9 - 156419 + 156400 9 14 - 169026 + 169005 14 21 - 177898 + 177875 21 32 - 162022 + 162002 32 60 - 158287 + 158267 60 65 - 3735 + 3734 @@ -6276,62 +6270,62 @@ 1 2 - 5136 + 5135 2 8 - 3735 + 3734 9 186 - 3735 + 3734 193 288 - 3735 + 3734 294 495 - 3735 + 3734 503 - 554 - 3735 + 555 + 3734 561 633 - 3735 + 3734 640 758 - 3735 + 3734 758 869 - 3735 + 3734 875 1074 - 3735 + 3734 1074 1281 - 3735 + 3734 1289 1590 - 3735 + 3734 1685 @@ -6352,62 +6346,62 @@ 1 2 - 5603 + 5602 2 5 - 3735 + 3734 5 65 - 3735 + 3734 70 100 - 3735 + 3734 100 111 - 3735 + 3734 112 122 - 4202 + 4201 122 140 - 3735 + 3734 143 153 - 3735 + 3734 153 161 - 4202 + 4201 161 173 - 4202 + 4201 173 178 - 3735 + 3734 188 265 - 3735 + 3734 @@ -6423,62 +6417,62 @@ 1 2 - 5603 + 5602 2 8 - 3735 + 3734 9 105 - 3735 + 3734 155 241 - 3735 + 3734 253 336 - 3735 + 3734 340 426 - 3735 + 3734 434 488 - 3735 + 3734 489 572 - 3735 + 3734 573 623 - 3735 + 3734 626 696 - 4202 + 4201 701 813 - 3735 + 3734 818 1095 - 3735 + 3734 1172 @@ -6499,37 +6493,37 @@ 1 2 - 6070 + 6069 2 4 - 3735 + 3734 4 8 - 4202 + 4201 8 15 - 3735 + 3734 15 23 - 3735 + 3734 23 29 - 3735 + 3734 29 35 - 4202 + 4201 35 @@ -6549,12 +6543,12 @@ 44 46 - 3735 + 3734 46 49 - 3735 + 3734 49 @@ -6575,62 +6569,62 @@ 1 2 - 5603 + 5602 2 8 - 3735 + 3734 9 156 - 3735 + 3734 159 240 - 3735 + 3734 251 335 - 3735 + 3734 342 430 - 3735 + 3734 432 490 - 3735 + 3734 490 573 - 3735 + 3734 574 622 - 3735 + 3734 626 698 - 3735 + 3734 700 798 - 3735 + 3734 811 987 - 3735 + 3734 1096 @@ -10559,23 +10553,23 @@ numlines - 1383965 + 1383789 element_id - 1376961 + 1376786 num_lines - 101789 + 101776 num_code - 84980 + 84969 num_comment - 59766 + 59758 @@ -10589,12 +10583,12 @@ 1 2 - 1369957 + 1369783 2 3 - 7003 + 7002 @@ -10610,12 +10604,12 @@ 1 2 - 1370891 + 1370717 2 3 - 6070 + 6069 @@ -10631,7 +10625,7 @@ 1 2 - 1376961 + 1376786 @@ -10647,27 +10641,27 @@ 1 2 - 68171 + 68162 2 3 - 12140 + 12138 3 4 - 7470 + 7469 4 21 - 7937 + 7936 29 921 - 6070 + 6069 @@ -10683,22 +10677,22 @@ 1 2 - 70505 + 70496 2 3 - 12140 + 12138 3 4 - 8404 + 8403 4 6 - 9338 + 9337 6 @@ -10719,17 +10713,17 @@ 1 2 - 69571 + 69562 2 3 - 14941 + 14939 3 4 - 10739 + 10737 4 @@ -10750,12 +10744,12 @@ 1 2 - 52762 + 52755 2 3 - 14474 + 14472 3 @@ -10770,7 +10764,7 @@ 44 922 - 4669 + 4668 @@ -10786,17 +10780,17 @@ 1 2 - 52762 + 52755 2 3 - 16809 + 16807 3 5 - 6070 + 6069 5 @@ -10822,22 +10816,22 @@ 1 2 - 53229 + 53222 2 3 - 15875 + 15873 3 5 - 7470 + 7469 5 7 - 5136 + 5135 7 @@ -10858,27 +10852,27 @@ 1 2 - 34552 + 34548 2 3 - 9338 + 9337 3 4 - 4202 + 4201 4 6 - 4669 + 4668 6 11 - 5136 + 5135 17 @@ -10899,27 +10893,27 @@ 1 2 - 34552 + 34548 2 3 - 9338 + 9337 3 4 - 4202 + 4201 4 6 - 4669 + 4668 6 8 - 4669 + 4668 10 @@ -10940,27 +10934,27 @@ 1 2 - 34552 + 34548 2 3 - 9338 + 9337 3 4 - 4202 + 4201 4 6 - 4669 + 4668 6 10 - 4669 + 4668 10 @@ -11607,15 +11601,15 @@ files - 123268 + 123252 id - 123268 + 123252 name - 123268 + 123252 @@ -11629,7 +11623,7 @@ 1 2 - 123268 + 123252 @@ -11645,7 +11639,7 @@ 1 2 - 123268 + 123252 @@ -11655,15 +11649,15 @@ folders - 16342 + 16340 id - 16342 + 16340 name - 16342 + 16340 @@ -11677,7 +11671,7 @@ 1 2 - 16342 + 16340 @@ -11693,7 +11687,7 @@ 1 2 - 16342 + 16340 @@ -11703,15 +11697,15 @@ containerparent - 138676 + 138659 parent - 16342 + 16340 child - 138676 + 138659 @@ -11725,7 +11719,7 @@ 1 2 - 7470 + 7469 2 @@ -11766,7 +11760,7 @@ 1 2 - 138676 + 138659 @@ -12425,7 +12419,7 @@ 2 3 - 544106 + 544108 3 @@ -12460,7 +12454,7 @@ 11 337 - 224848 + 224847 339 @@ -13567,15 +13561,15 @@ functions - 4179912 + 4179381 id - 4179912 + 4179381 name - 1895715 + 1895474 kind @@ -13593,7 +13587,7 @@ 1 2 - 4179912 + 4179381 @@ -13609,7 +13603,7 @@ 1 2 - 4179912 + 4179381 @@ -13625,22 +13619,22 @@ 1 2 - 1498362 + 1498172 2 3 - 153151 + 153131 3 5 - 142879 + 142860 5 952 - 101322 + 101309 @@ -13656,7 +13650,7 @@ 1 2 - 1895248 + 1895007 2 @@ -13811,15 +13805,15 @@ function_return_type - 4185048 + 4184517 id - 4179912 + 4179381 return_type - 818052 + 817948 @@ -13833,12 +13827,12 @@ 1 2 - 4174776 + 4174246 2 3 - 5136 + 5135 @@ -13854,22 +13848,22 @@ 1 2 - 506146 + 506082 2 3 - 211517 + 211490 3 7 - 66303 + 66294 7 2231 - 34085 + 34081 @@ -14232,33 +14226,33 @@ function_deleted - 96186 + 96174 id - 96186 + 96174 function_defaulted - 73774 + 73764 id - 73774 + 73764 function_prototyped - 4087928 + 4087409 id - 4087928 + 4087409 @@ -14411,27 +14405,27 @@ fun_decls - 4549250 + 4548672 id - 4544113 + 4543537 function - 4036099 + 4035587 type_id - 816651 + 816548 name - 1798128 + 1797899 location - 3371198 + 3370770 @@ -14445,7 +14439,7 @@ 1 2 - 4544113 + 4543537 @@ -14461,12 +14455,12 @@ 1 2 - 4538977 + 4538401 2 3 - 5136 + 5135 @@ -14482,7 +14476,7 @@ 1 2 - 4544113 + 4543537 @@ -14498,7 +14492,7 @@ 1 2 - 4544113 + 4543537 @@ -14514,17 +14508,17 @@ 1 2 - 3606995 + 3606537 2 3 - 356263 + 356218 3 7 - 72840 + 72831 @@ -14540,12 +14534,12 @@ 1 2 - 3996410 + 3995903 2 3 - 39688 + 39683 @@ -14561,7 +14555,7 @@ 1 2 - 4036099 + 4035587 @@ -14577,17 +14571,17 @@ 1 2 - 3663493 + 3663028 2 3 - 311905 + 311866 3 6 - 60700 + 60692 @@ -14603,22 +14597,22 @@ 1 2 - 431438 + 431383 2 3 - 274084 + 274050 3 6 - 63501 + 63493 6 2476 - 47626 + 47620 @@ -14634,22 +14628,22 @@ 1 2 - 515485 + 515419 2 3 - 203112 + 203086 3 7 - 63034 + 63026 7 2192 - 35019 + 35014 @@ -14665,17 +14659,17 @@ 1 2 - 690115 + 690027 2 4 - 67237 + 67228 4 773 - 59299 + 59291 @@ -14691,22 +14685,22 @@ 1 2 - 595329 + 595253 2 3 - 121400 + 121385 3 7 - 63501 + 63493 7 1959 - 36420 + 36415 @@ -14722,27 +14716,27 @@ 1 2 - 1228479 + 1228323 2 3 - 267081 + 267047 3 4 - 77976 + 77966 4 7 - 146147 + 146128 7 986 - 78443 + 78433 @@ -14758,22 +14752,22 @@ 1 2 - 1407778 + 1407600 2 3 - 152217 + 152198 3 5 - 136809 + 136791 5 936 - 101322 + 101309 @@ -14789,17 +14783,17 @@ 1 2 - 1579607 + 1579406 2 4 - 134941 + 134924 4 562 - 83579 + 83568 @@ -14815,27 +14809,27 @@ 1 2 - 1236417 + 1236260 2 3 - 293228 + 293191 3 4 - 78910 + 78900 4 8 - 137275 + 137258 8 542 - 52295 + 52288 @@ -14851,17 +14845,17 @@ 1 2 - 2966841 + 2966464 2 4 - 277820 + 277785 4 55 - 126536 + 126520 @@ -14877,17 +14871,17 @@ 1 2 - 3034078 + 3033693 2 7 - 244201 + 244170 7 55 - 92918 + 92906 @@ -14903,12 +14897,12 @@ 1 2 - 3207774 + 3207367 2 18 - 163423 + 163402 @@ -14924,12 +14918,12 @@ 1 2 - 3232988 + 3232578 2 13 - 138209 + 138192 @@ -14939,22 +14933,22 @@ fun_def - 1889178 + 1888938 id - 1889178 + 1888938 fun_specialized - 26147 + 26144 id - 26147 + 26144 @@ -14972,11 +14966,11 @@ fun_decl_specifiers - 2907074 + 2906705 id - 1689801 + 1689587 name @@ -14994,17 +14988,17 @@ 1 2 - 491205 + 491142 2 3 - 1179919 + 1179769 3 4 - 18676 + 18674 @@ -15176,11 +15170,11 @@ fun_decl_empty_throws - 1472214 + 1472027 fun_decl - 1472214 + 1472027 @@ -15240,11 +15234,11 @@ fun_decl_empty_noexcept - 863344 + 863234 fun_decl - 863344 + 863234 @@ -15349,19 +15343,19 @@ param_decl_bind - 6995937 + 6995048 id - 6995937 + 6995048 index - 7937 + 7936 fun_decl - 3835788 + 3835301 @@ -15375,7 +15369,7 @@ 1 2 - 6995937 + 6995048 @@ -15391,7 +15385,7 @@ 1 2 - 6995937 + 6995048 @@ -15569,27 +15563,27 @@ 1 2 - 1974158 + 1973908 2 3 - 1061787 + 1061652 3 4 - 502878 + 502814 4 8 - 290894 + 290857 8 18 - 6070 + 6069 @@ -15605,27 +15599,27 @@ 1 2 - 1974158 + 1973908 2 3 - 1061787 + 1061652 3 4 - 502878 + 502814 4 8 - 290894 + 290857 8 18 - 6070 + 6069 @@ -15635,27 +15629,27 @@ var_decls - 8111420 + 8110391 id - 8040448 + 8039427 variable - 7028154 + 7027262 type_id - 2043730 + 2043471 name - 667702 + 667617 location - 5312672 + 5311998 @@ -15669,7 +15663,7 @@ 1 2 - 8040448 + 8039427 @@ -15685,12 +15679,12 @@ 1 2 - 7972277 + 7971265 2 3 - 68171 + 68162 @@ -15706,7 +15700,7 @@ 1 2 - 8040448 + 8039427 @@ -15722,7 +15716,7 @@ 1 2 - 8037646 + 8036626 2 @@ -15743,17 +15737,17 @@ 1 2 - 6176016 + 6175232 2 3 - 698519 + 698431 3 7 - 153618 + 153598 @@ -15769,12 +15763,12 @@ 1 2 - 6856793 + 6855922 2 4 - 171361 + 171339 @@ -15790,12 +15784,12 @@ 1 2 - 6912824 + 6911946 2 3 - 115330 + 115315 @@ -15811,12 +15805,12 @@ 1 2 - 6482786 + 6481963 2 3 - 543033 + 542964 3 @@ -15837,27 +15831,27 @@ 1 2 - 1165911 + 1165763 2 3 - 477197 + 477136 3 4 - 94785 + 94773 4 7 - 184902 + 184878 7 762 - 120933 + 120918 @@ -15873,22 +15867,22 @@ 1 2 - 1299452 + 1299287 2 3 - 452450 + 452392 3 6 - 155952 + 155933 6 724 - 135875 + 135857 @@ -15904,17 +15898,17 @@ 1 2 - 1539451 + 1539256 2 3 - 383345 + 383296 3 128 - 120933 + 120918 @@ -15930,22 +15924,22 @@ 1 2 - 1365755 + 1365582 2 3 - 404357 + 404305 3 7 - 173229 + 173207 7 592 - 100388 + 100376 @@ -15961,37 +15955,37 @@ 1 2 - 341322 + 341278 2 3 - 86848 + 86837 3 4 - 48560 + 48554 4 6 - 51828 + 51822 6 12 - 52295 + 52288 12 33 - 50427 + 50421 34 2384 - 36420 + 36415 @@ -16007,37 +16001,37 @@ 1 2 - 368870 + 368823 2 3 - 77976 + 77966 3 4 - 45291 + 45285 4 6 - 49494 + 49487 6 14 - 53229 + 53222 14 56 - 50894 + 50888 56 2301 - 21945 + 21942 @@ -16053,27 +16047,27 @@ 1 2 - 457119 + 457061 2 3 - 93851 + 93840 3 5 - 46692 + 46686 5 19 - 50894 + 50888 19 1182 - 19143 + 19141 @@ -16089,32 +16083,32 @@ 1 2 - 379143 + 379094 2 3 - 90583 + 90571 3 5 - 59766 + 59758 5 9 - 51361 + 51355 9 21 - 50427 + 50421 21 1010 - 36420 + 36415 @@ -16130,17 +16124,17 @@ 1 2 - 4496954 + 4496383 2 3 - 531827 + 531760 3 896 - 283890 + 283854 @@ -16156,17 +16150,17 @@ 1 2 - 4886369 + 4885749 2 17 - 415563 + 415510 17 892 - 10739 + 10737 @@ -16182,12 +16176,12 @@ 1 2 - 4962478 + 4961848 2 759 - 350193 + 350149 @@ -16203,12 +16197,12 @@ 1 2 - 5303334 + 5302660 2 6 - 9338 + 9337 @@ -16218,22 +16212,22 @@ var_def - 3995477 + 3994969 id - 3995477 + 3994969 var_decl_specifiers - 378676 + 378628 id - 378676 + 378628 name @@ -16251,7 +16245,7 @@ 1 2 - 378676 + 378628 @@ -16303,19 +16297,19 @@ type_decls - 3283883 + 3283466 id - 3283883 + 3283466 type_id - 3233455 + 3233045 location - 3166685 + 3166283 @@ -16329,7 +16323,7 @@ 1 2 - 3283883 + 3283466 @@ -16345,7 +16339,7 @@ 1 2 - 3283883 + 3283466 @@ -16361,12 +16355,12 @@ 1 2 - 3191899 + 3191493 2 5 - 41556 + 41551 @@ -16382,12 +16376,12 @@ 1 2 - 3191899 + 3191493 2 5 - 41556 + 41551 @@ -16403,12 +16397,12 @@ 1 2 - 3114389 + 3113994 2 20 - 52295 + 52288 @@ -16424,12 +16418,12 @@ 1 2 - 3114389 + 3113994 2 20 - 52295 + 52288 @@ -16439,22 +16433,22 @@ type_def - 2642328 + 2641993 id - 2642328 + 2641993 type_decl_top - 743811 + 743717 type_decl - 743811 + 743717 @@ -16827,19 +16821,19 @@ usings - 369804 + 369757 id - 369804 + 369757 element_id - 315641 + 315601 location - 247937 + 247905 kind @@ -16857,7 +16851,7 @@ 1 2 - 369804 + 369757 @@ -16873,7 +16867,7 @@ 1 2 - 369804 + 369757 @@ -16889,7 +16883,7 @@ 1 2 - 369804 + 369757 @@ -16905,12 +16899,12 @@ 1 2 - 263345 + 263312 2 3 - 50894 + 50888 3 @@ -16931,12 +16925,12 @@ 1 2 - 263345 + 263312 2 3 - 50894 + 50888 3 @@ -16957,7 +16951,7 @@ 1 2 - 315641 + 315601 @@ -16973,17 +16967,17 @@ 1 2 - 202645 + 202619 2 4 - 10739 + 10737 4 5 - 31283 + 31280 5 @@ -17004,17 +16998,17 @@ 1 2 - 202645 + 202619 2 4 - 10739 + 10737 4 5 - 31283 + 31280 5 @@ -17035,7 +17029,7 @@ 1 2 - 247937 + 247905 @@ -17819,23 +17813,23 @@ params - 6355316 + 6354509 id - 6191425 + 6190639 function - 3492131 + 3491688 index - 7937 + 7936 type_id - 1846688 + 1846453 @@ -17849,7 +17843,7 @@ 1 2 - 6191425 + 6190639 @@ -17865,7 +17859,7 @@ 1 2 - 6191425 + 6190639 @@ -17881,12 +17875,12 @@ 1 2 - 6067690 + 6066919 2 4 - 123735 + 123719 @@ -17902,22 +17896,22 @@ 1 2 - 1867699 + 1867462 2 3 - 952993 + 952872 3 4 - 430037 + 429983 4 18 - 241400 + 241369 @@ -17933,22 +17927,22 @@ 1 2 - 1867699 + 1867462 2 3 - 952993 + 952872 3 4 - 430037 + 429983 4 18 - 241400 + 241369 @@ -17964,22 +17958,22 @@ 1 2 - 2166065 + 2165790 2 3 - 826924 + 826819 3 4 - 346458 + 346414 4 12 - 152684 + 152665 @@ -18233,22 +18227,22 @@ 1 2 - 1184121 + 1183971 2 3 - 406224 + 406173 3 7 - 154085 + 154065 7 518 - 102256 + 102243 @@ -18264,22 +18258,22 @@ 1 2 - 1404977 + 1404798 2 3 - 212450 + 212423 3 7 - 147548 + 147529 7 502 - 81711 + 81701 @@ -18295,17 +18289,17 @@ 1 2 - 1420385 + 1420205 2 3 - 347392 + 347348 3 13 - 78910 + 78900 @@ -18315,11 +18309,11 @@ overrides - 125735 + 125725 new - 122762 + 122753 old @@ -18337,7 +18331,7 @@ 1 2 - 119798 + 119788 2 @@ -18745,11 +18739,11 @@ localvariables - 576952 + 576947 id - 576952 + 576947 type_id @@ -18757,7 +18751,7 @@ name - 90549 + 90548 @@ -18771,7 +18765,7 @@ 1 2 - 576952 + 576947 @@ -18787,7 +18781,7 @@ 1 2 - 576952 + 576947 @@ -18808,7 +18802,7 @@ 2 3 - 5366 + 5362 3 @@ -18818,7 +18812,7 @@ 4 7 - 3376 + 3380 7 @@ -18844,7 +18838,7 @@ 1 2 - 26913 + 26908 2 @@ -18854,7 +18848,7 @@ 3 5 - 2914 + 2918 5 @@ -18880,7 +18874,7 @@ 1 2 - 57032 + 57031 2 @@ -18926,7 +18920,7 @@ 3 1486 - 6645 + 6644 @@ -19954,19 +19948,19 @@ builtintypes - 26147 + 26144 id - 26147 + 26144 name - 26147 + 26144 kind - 26147 + 26144 size @@ -19992,7 +19986,7 @@ 1 2 - 26147 + 26144 @@ -20008,7 +20002,7 @@ 1 2 - 26147 + 26144 @@ -20024,7 +20018,7 @@ 1 2 - 26147 + 26144 @@ -20040,7 +20034,7 @@ 1 2 - 26147 + 26144 @@ -20056,7 +20050,7 @@ 1 2 - 26147 + 26144 @@ -20072,7 +20066,7 @@ 1 2 - 26147 + 26144 @@ -20088,7 +20082,7 @@ 1 2 - 26147 + 26144 @@ -20104,7 +20098,7 @@ 1 2 - 26147 + 26144 @@ -20120,7 +20114,7 @@ 1 2 - 26147 + 26144 @@ -20136,7 +20130,7 @@ 1 2 - 26147 + 26144 @@ -20152,7 +20146,7 @@ 1 2 - 26147 + 26144 @@ -20168,7 +20162,7 @@ 1 2 - 26147 + 26144 @@ -20184,7 +20178,7 @@ 1 2 - 26147 + 26144 @@ -20200,7 +20194,7 @@ 1 2 - 26147 + 26144 @@ -20216,7 +20210,7 @@ 1 2 - 26147 + 26144 @@ -20661,15 +20655,15 @@ derivedtypes - 3670030 + 3669564 id - 3670030 + 3669564 name - 1552992 + 1552795 kind @@ -20677,7 +20671,7 @@ type_id - 2363107 + 2362807 @@ -20691,7 +20685,7 @@ 1 2 - 3670030 + 3669564 @@ -20707,7 +20701,7 @@ 1 2 - 3670030 + 3669564 @@ -20723,7 +20717,7 @@ 1 2 - 3670030 + 3669564 @@ -20739,17 +20733,17 @@ 1 2 - 1324199 + 1324031 2 4 - 120466 + 120451 4 1153 - 108326 + 108312 @@ -20765,7 +20759,7 @@ 1 2 - 1552058 + 1551861 2 @@ -20786,17 +20780,17 @@ 1 2 - 1324199 + 1324031 2 4 - 120466 + 120451 4 1135 - 108326 + 108312 @@ -20935,22 +20929,22 @@ 1 2 - 1515638 + 1515446 2 3 - 546302 + 546232 3 4 - 218520 + 218493 4 72 - 82645 + 82635 @@ -20966,22 +20960,22 @@ 1 2 - 1526844 + 1526650 2 3 - 538831 + 538763 3 4 - 215719 + 215691 4 72 - 81711 + 81701 @@ -20997,22 +20991,22 @@ 1 2 - 1519840 + 1519647 2 3 - 550037 + 549967 3 4 - 217587 + 217559 4 6 - 75641 + 75632 @@ -21022,11 +21016,11 @@ pointerishsize - 2707698 + 2707354 id - 2707698 + 2707354 size @@ -21048,7 +21042,7 @@ 1 2 - 2707698 + 2707354 @@ -21064,7 +21058,7 @@ 1 2 - 2707698 + 2707354 @@ -21138,19 +21132,19 @@ arraysizes - 88248 + 88237 id - 88248 + 88237 num_elements - 31750 + 31746 bytesize - 33151 + 33147 alignment @@ -21168,7 +21162,7 @@ 1 2 - 88248 + 88237 @@ -21184,7 +21178,7 @@ 1 2 - 88248 + 88237 @@ -21200,7 +21194,7 @@ 1 2 - 88248 + 88237 @@ -21221,7 +21215,7 @@ 2 3 - 23813 + 23810 3 @@ -21252,7 +21246,7 @@ 1 2 - 26614 + 26611 2 @@ -21278,7 +21272,7 @@ 1 2 - 26614 + 26611 2 @@ -21309,7 +21303,7 @@ 2 3 - 23813 + 23810 3 @@ -21340,12 +21334,12 @@ 1 2 - 27548 + 27545 2 3 - 3735 + 3734 3 @@ -21366,12 +21360,12 @@ 1 2 - 27548 + 27545 2 3 - 4669 + 4668 4 @@ -21823,19 +21817,19 @@ usertypes - 5234696 + 5234031 id - 5234696 + 5234031 name - 1352681 + 1352509 kind - 5136 + 5135 @@ -21849,7 +21843,7 @@ 1 2 - 5234696 + 5234031 @@ -21865,7 +21859,7 @@ 1 2 - 5234696 + 5234031 @@ -21881,27 +21875,27 @@ 1 2 - 983810 + 983686 2 3 - 153618 + 153598 3 7 - 104591 + 104577 7 61 - 101789 + 101776 65 874 - 8871 + 8870 @@ -21917,17 +21911,17 @@ 1 2 - 1212137 + 1211983 2 3 - 125602 + 125586 3 7 - 14941 + 14939 @@ -22069,15 +22063,15 @@ usertypesize - 1706610 + 1706394 id - 1706610 + 1706394 size - 13540 + 13539 alignment @@ -22095,7 +22089,7 @@ 1 2 - 1706610 + 1706394 @@ -22111,7 +22105,7 @@ 1 2 - 1706610 + 1706394 @@ -22132,7 +22126,7 @@ 2 3 - 4202 + 4201 3 @@ -22183,7 +22177,7 @@ 1 2 - 10272 + 10271 2 @@ -22339,15 +22333,15 @@ mangled_name - 9020523 + 9019378 id - 9020523 + 9019378 mangled_name - 6062554 + 6061784 is_complete @@ -22365,7 +22359,7 @@ 1 2 - 9020523 + 9019378 @@ -22381,7 +22375,7 @@ 1 2 - 9020523 + 9019378 @@ -22397,12 +22391,12 @@ 1 2 - 5789869 + 5789134 2 874 - 272684 + 272649 @@ -22418,7 +22412,7 @@ 1 2 - 6062554 + 6061784 @@ -22471,48 +22465,48 @@ is_standard_layout_class - 1254160 + 1254001 id - 1254160 + 1254001 is_complete - 1645910 + 1645701 id - 1645910 + 1645701 is_class_template - 398287 + 398236 id - 398287 + 398236 class_instantiation - 1089802 + 1089664 to - 1089802 + 1089664 from - 168559 + 168538 @@ -22526,7 +22520,7 @@ 1 2 - 1089802 + 1089664 @@ -22542,42 +22536,42 @@ 1 2 - 59766 + 59758 2 3 - 29416 + 29412 3 4 - 15875 + 15873 4 5 - 13073 + 13072 5 6 - 9805 + 9804 6 10 - 12606 + 12605 10 16 - 13073 + 13072 16 70 - 13540 + 13539 70 @@ -22833,11 +22827,11 @@ class_template_argument_value - 495407 + 495344 type_id - 304902 + 304863 index @@ -22845,7 +22839,7 @@ arg_value - 495407 + 495344 @@ -22859,12 +22853,12 @@ 1 2 - 249804 + 249773 2 3 - 53229 + 53222 3 @@ -22885,22 +22879,22 @@ 1 2 - 189571 + 189547 2 3 - 81244 + 81234 3 4 - 12140 + 12138 4 9 - 21945 + 21942 @@ -22978,7 +22972,7 @@ 1 2 - 495407 + 495344 @@ -22994,7 +22988,7 @@ 1 2 - 495407 + 495344 @@ -23004,15 +22998,15 @@ is_proxy_class_for - 62101 + 62093 id - 62101 + 62093 templ_param_id - 62101 + 62093 @@ -23026,7 +23020,7 @@ 1 2 - 62101 + 62093 @@ -23042,7 +23036,7 @@ 1 2 - 62101 + 62093 @@ -23348,11 +23342,11 @@ is_function_template - 1403109 + 1402931 id - 1403109 + 1402931 @@ -24483,19 +24477,19 @@ routinetypeargs - 983344 + 983219 routine - 423500 + 423447 index - 7937 + 7936 type_id - 226925 + 226896 @@ -24509,27 +24503,27 @@ 1 2 - 152684 + 152665 2 3 - 134007 + 133990 3 4 - 63501 + 63493 4 5 - 45758 + 45752 5 18 - 27548 + 27545 @@ -24545,27 +24539,27 @@ 1 2 - 182567 + 182544 2 3 - 133540 + 133523 3 4 - 58832 + 58825 4 5 - 33618 + 33614 5 11 - 14941 + 14939 @@ -24723,27 +24717,27 @@ 1 2 - 146614 + 146595 2 3 - 30817 + 30813 3 5 - 16809 + 16807 5 12 - 18210 + 18207 12 110 - 14474 + 14472 @@ -24759,22 +24753,22 @@ 1 2 - 172762 + 172740 2 3 - 30817 + 30813 3 6 - 18676 + 18674 6 14 - 4669 + 4668 @@ -24784,19 +24778,19 @@ ptrtomembers - 37820 + 37816 id - 37820 + 37816 type_id - 37820 + 37816 class_id - 15408 + 15406 @@ -24810,7 +24804,7 @@ 1 2 - 37820 + 37816 @@ -24826,7 +24820,7 @@ 1 2 - 37820 + 37816 @@ -24842,7 +24836,7 @@ 1 2 - 37820 + 37816 @@ -24858,7 +24852,7 @@ 1 2 - 37820 + 37816 @@ -24874,7 +24868,7 @@ 1 2 - 13540 + 13539 8 @@ -24900,7 +24894,7 @@ 1 2 - 13540 + 13539 8 @@ -24920,15 +24914,15 @@ specifiers - 24747 + 24743 id - 24747 + 24743 str - 24747 + 24743 @@ -24942,7 +24936,7 @@ 1 2 - 24747 + 24743 @@ -24958,7 +24952,7 @@ 1 2 - 24747 + 24743 @@ -24968,15 +24962,15 @@ typespecifiers - 1132293 + 1132149 type_id - 1114083 + 1113941 spec_id - 3735 + 3734 @@ -24990,12 +24984,12 @@ 1 2 - 1095872 + 1095733 2 3 - 18210 + 18207 @@ -25051,15 +25045,15 @@ funspecifiers - 10305968 + 10305126 func_id - 4068784 + 4068267 spec_id - 8404 + 8403 @@ -25073,27 +25067,27 @@ 1 2 - 1357817 + 1357645 2 3 - 641088 + 640539 3 4 - 985211 + 985553 4 5 - 780231 + 780132 5 8 - 304435 + 304396 @@ -25192,8 +25186,8 @@ 466 - 6434 - 6435 + 6435 + 6436 466 @@ -25204,15 +25198,15 @@ varspecifiers - 2246376 + 2246090 var_id - 1225211 + 1225055 spec_id - 3735 + 3734 @@ -25226,22 +25220,22 @@ 1 2 - 730270 + 730177 2 3 - 202645 + 202619 3 4 - 58365 + 58358 4 5 - 233929 + 233899 @@ -25350,11 +25344,11 @@ attributes - 561710 + 561639 id - 561710 + 561639 kind @@ -25362,7 +25356,7 @@ name - 11206 + 11204 name_space @@ -25370,7 +25364,7 @@ location - 481399 + 481338 @@ -25384,7 +25378,7 @@ 1 2 - 561710 + 561639 @@ -25400,7 +25394,7 @@ 1 2 - 561710 + 561639 @@ -25416,7 +25410,7 @@ 1 2 - 561710 + 561639 @@ -25432,7 +25426,7 @@ 1 2 - 561710 + 561639 @@ -25623,7 +25617,7 @@ 1 2 - 10272 + 10271 2 @@ -25644,7 +25638,7 @@ 1 2 - 11206 + 11204 @@ -25815,17 +25809,17 @@ 1 2 - 431905 + 431850 2 3 - 20077 + 20075 3 7 - 29416 + 29412 @@ -25841,7 +25835,7 @@ 1 2 - 481399 + 481338 @@ -25857,17 +25851,17 @@ 1 2 - 433306 + 433251 2 3 - 19610 + 19608 3 4 - 28482 + 28478 @@ -25883,7 +25877,7 @@ 1 2 - 481399 + 481338 @@ -25893,11 +25887,11 @@ attribute_args - 344123 + 344080 id - 344123 + 344080 kind @@ -25905,7 +25899,7 @@ attribute - 262878 + 262845 index @@ -25913,7 +25907,7 @@ location - 327781 + 327739 @@ -25927,7 +25921,7 @@ 1 2 - 344123 + 344080 @@ -25943,7 +25937,7 @@ 1 2 - 344123 + 344080 @@ -25959,7 +25953,7 @@ 1 2 - 344123 + 344080 @@ -25975,7 +25969,7 @@ 1 2 - 344123 + 344080 @@ -26090,17 +26084,17 @@ 1 2 - 197509 + 197484 2 3 - 49494 + 49487 3 4 - 15875 + 15873 @@ -26116,12 +26110,12 @@ 1 2 - 252606 + 252574 2 3 - 10272 + 10271 @@ -26137,17 +26131,17 @@ 1 2 - 197509 + 197484 2 3 - 49494 + 49487 3 4 - 15875 + 15873 @@ -26163,17 +26157,17 @@ 1 2 - 197509 + 197484 2 3 - 49494 + 49487 3 4 - 15875 + 15873 @@ -26288,12 +26282,12 @@ 1 2 - 313773 + 313733 2 7 - 14007 + 14005 @@ -26309,12 +26303,12 @@ 1 2 - 315174 + 315134 2 3 - 12606 + 12605 @@ -26330,12 +26324,12 @@ 1 2 - 313773 + 313733 2 7 - 14007 + 14005 @@ -26351,7 +26345,7 @@ 1 2 - 327781 + 327739 @@ -26361,15 +26355,15 @@ attribute_arg_value - 25213 + 25210 arg - 25213 + 25210 value - 15875 + 15873 @@ -26383,7 +26377,7 @@ 1 2 - 25213 + 25210 @@ -26399,7 +26393,7 @@ 1 2 - 14474 + 14472 2 @@ -26462,15 +26456,15 @@ attribute_arg_constant - 318442 + 318402 arg - 318442 + 318402 constant - 318442 + 318402 @@ -26484,7 +26478,7 @@ 1 2 - 318442 + 318402 @@ -26500,7 +26494,7 @@ 1 2 - 318442 + 318402 @@ -26674,15 +26668,15 @@ funcattributes - 630348 + 630268 func_id - 443578 + 443522 spec_id - 524823 + 524757 @@ -26696,17 +26690,17 @@ 1 2 - 338520 + 338477 2 3 - 64435 + 64427 3 6 - 39688 + 39683 6 @@ -26727,12 +26721,12 @@ 1 2 - 506146 + 506082 2 17 - 18676 + 18674 @@ -26868,15 +26862,15 @@ unspecifiedtype - 9489316 + 9488111 type_id - 9489316 + 9488111 unspecified_type_id - 6491191 + 6490367 @@ -26890,7 +26884,7 @@ 1 2 - 9489316 + 9488111 @@ -26906,17 +26900,17 @@ 1 2 - 4559522 + 4558943 2 3 - 1715949 + 1715731 3 145 - 215719 + 215691 @@ -26926,19 +26920,19 @@ member - 3881547 + 3881054 parent - 545835 + 545766 index - 92918 + 92906 child - 3810107 + 3809624 @@ -26952,47 +26946,47 @@ 1 2 - 129805 + 129788 2 3 - 64902 + 64894 3 4 - 73307 + 73297 4 5 - 75174 + 75165 5 6 - 40622 + 40617 6 8 - 46692 + 46686 8 14 - 45758 + 45752 14 30 - 41556 + 41551 30 200 - 28015 + 28011 @@ -27008,52 +27002,52 @@ 1 2 - 129805 + 129788 2 3 - 64902 + 64894 3 4 - 73307 + 73297 4 5 - 76108 + 76099 5 6 - 39688 + 39683 6 7 - 24280 + 24277 7 9 - 42023 + 42017 9 17 - 43890 + 43885 17 41 - 41556 + 41551 41 200 - 10272 + 10271 @@ -27069,57 +27063,57 @@ 1 2 - 26147 + 26144 2 3 - 7003 + 7002 3 4 - 3735 + 3734 4 5 - 7937 + 7936 5 6 - 5603 + 5602 6 7 - 5603 + 5602 7 9 - 7470 + 7469 9 16 - 7003 + 7002 16 52 - 7003 + 7002 52 107 - 7003 + 7002 108 577 - 7003 + 7002 737 @@ -27140,57 +27134,57 @@ 1 2 - 26147 + 26144 2 3 - 7003 + 7002 3 4 - 3735 + 3734 4 5 - 7937 + 7936 5 6 - 5603 + 5602 6 7 - 5603 + 5602 7 9 - 7470 + 7469 9 16 - 7003 + 7002 16 52 - 7003 + 7002 52 107 - 7003 + 7002 108 577 - 7003 + 7002 738 @@ -27211,7 +27205,7 @@ 1 2 - 3810107 + 3809624 @@ -27227,12 +27221,12 @@ 1 2 - 3738668 + 3738193 2 3 - 71439 + 71430 @@ -28762,15 +28756,15 @@ commentbinding - 3091510 + 3091117 id - 2445753 + 2445442 element - 3014934 + 3014551 @@ -28784,12 +28778,12 @@ 1 2 - 2368710 + 2368409 2 97 - 77042 + 77032 @@ -28805,12 +28799,12 @@ 1 2 - 2938358 + 2937985 2 3 - 76575 + 76565 @@ -29215,15 +29209,15 @@ namespaces - 12140 + 12138 id - 12140 + 12138 name - 9805 + 9804 @@ -29237,7 +29231,7 @@ 1 2 - 12140 + 12138 @@ -29253,7 +29247,7 @@ 1 2 - 8404 + 8403 2 @@ -29284,15 +29278,15 @@ namespacembrs - 2388321 + 2388018 parentid - 10272 + 10271 memberid - 2388321 + 2388018 @@ -29367,7 +29361,7 @@ 1 2 - 2388321 + 2388018 @@ -30288,7 +30282,7 @@ fun - 511344 + 511325 @@ -30323,12 +30317,12 @@ 1 2 - 315090 + 315052 2 3 - 77893 + 77912 3 @@ -33722,11 +33716,11 @@ lambdas - 21478 + 21475 expr - 21478 + 21475 default_capture @@ -33748,7 +33742,7 @@ 1 2 - 21478 + 21475 @@ -33764,7 +33758,7 @@ 1 2 - 21478 + 21475 @@ -33838,15 +33832,15 @@ lambda_capture - 28015 + 28011 id - 28015 + 28011 lambda - 20544 + 20542 index @@ -33854,7 +33848,7 @@ field - 28015 + 28011 captured_by_reference @@ -33880,7 +33874,7 @@ 1 2 - 28015 + 28011 @@ -33896,7 +33890,7 @@ 1 2 - 28015 + 28011 @@ -33912,7 +33906,7 @@ 1 2 - 28015 + 28011 @@ -33928,7 +33922,7 @@ 1 2 - 28015 + 28011 @@ -33944,7 +33938,7 @@ 1 2 - 28015 + 28011 @@ -33960,7 +33954,7 @@ 1 2 - 28015 + 28011 @@ -33976,12 +33970,12 @@ 1 2 - 13073 + 13072 2 3 - 7470 + 7469 @@ -33997,12 +33991,12 @@ 1 2 - 13073 + 13072 2 3 - 7470 + 7469 @@ -34018,12 +34012,12 @@ 1 2 - 13073 + 13072 2 3 - 7470 + 7469 @@ -34039,7 +34033,7 @@ 1 2 - 20544 + 20542 @@ -34055,7 +34049,7 @@ 1 2 - 20544 + 20542 @@ -34071,12 +34065,12 @@ 1 2 - 13073 + 13072 2 3 - 7470 + 7469 @@ -34208,7 +34202,7 @@ 1 2 - 28015 + 28011 @@ -34224,7 +34218,7 @@ 1 2 - 28015 + 28011 @@ -34240,7 +34234,7 @@ 1 2 - 28015 + 28011 @@ -34256,7 +34250,7 @@ 1 2 - 28015 + 28011 @@ -34272,7 +34266,7 @@ 1 2 - 28015 + 28011 @@ -34288,7 +34282,7 @@ 1 2 - 28015 + 28011 @@ -36334,11 +36328,11 @@ stmt_decl_bind - 580849 + 580844 stmt - 541067 + 541062 num @@ -36346,7 +36340,7 @@ decl - 580745 + 580740 @@ -36360,7 +36354,7 @@ 1 2 - 520378 + 520373 2 @@ -36381,7 +36375,7 @@ 1 2 - 520378 + 520373 2 @@ -36584,7 +36578,7 @@ 1 2 - 580708 + 580703 2 @@ -36605,7 +36599,7 @@ 1 2 - 580745 + 580740 @@ -36615,11 +36609,11 @@ stmt_decl_entry_bind - 580849 + 580844 stmt - 541067 + 541062 num @@ -36627,7 +36621,7 @@ decl_entry - 580791 + 580786 @@ -36641,7 +36635,7 @@ 1 2 - 520378 + 520373 2 @@ -36662,7 +36656,7 @@ 1 2 - 520378 + 520373 2 @@ -36865,7 +36859,7 @@ 1 2 - 580770 + 580765 3 @@ -36886,7 +36880,7 @@ 1 2 - 580791 + 580786 @@ -37135,19 +37129,19 @@ preprocdirects - 4191118 + 4190586 id - 4191118 + 4190586 kind - 5136 + 5135 location - 4150496 + 4149969 @@ -37161,7 +37155,7 @@ 1 2 - 4191118 + 4190586 @@ -37177,7 +37171,7 @@ 1 2 - 4191118 + 4190586 @@ -37325,7 +37319,7 @@ 1 2 - 4150029 + 4149502 88 @@ -37346,7 +37340,7 @@ 1 2 - 4150496 + 4149969 @@ -37356,15 +37350,15 @@ preprocpair - 1431592 + 1431410 begin - 1197195 + 1197043 elseelifend - 1431592 + 1431410 @@ -37378,17 +37372,17 @@ 1 2 - 978674 + 978550 2 3 - 208248 + 208222 3 11 - 10272 + 10271 @@ -37404,7 +37398,7 @@ 1 2 - 1431592 + 1431410 @@ -37414,22 +37408,22 @@ preproctrue - 767157 + 767060 branch - 767157 + 767060 preprocfalse - 331516 + 331474 branch - 331516 + 331474 @@ -37582,15 +37576,15 @@ includes - 313306 + 313266 id - 313306 + 313266 included - 117198 + 117183 @@ -37604,7 +37598,7 @@ 1 2 - 313306 + 313266 @@ -37620,27 +37614,27 @@ 1 2 - 61167 + 61159 2 3 - 21945 + 21942 3 4 - 12606 + 12605 4 6 - 10272 + 10271 6 14 - 8871 + 8870 14 diff --git a/cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme b/cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme new file mode 100644 index 00000000000..02a123a1a68 --- /dev/null +++ b/cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme @@ -0,0 +1,2317 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..0fea0ee7026 --- /dev/null +++ b/cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/semmlecode.cpp.dbscheme @@ -0,0 +1,2319 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +| 7 = @user_defined_literal +| 8 = @deduction_guide +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +function_prototyped(unique int id: @function ref) + +deduction_guide_for_class( + int id: @function ref, + int class_template: @usertype ref +) + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +case @using.kind of + 1 = @using_declaration +| 2 = @using_directive +| 3 = @using_enum_declaration +; + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref, + int kind: int ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname, + boolean is_complete: boolean ref +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +explicit_specifier_exprs( + unique int func_id: @function ref, + int constant: @expr ref +) + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +| 5 = @attribute_arg_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_expr( + unique int arg: @attribute_arg ref, + int expr: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + | @c11_generic + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + ; + +@assign_pointer_expr = @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr + | @assign_bitwise_expr + | @assign_pointer_expr + ; + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + Binary encoding of the allocator form. + + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + Binary encoding of the deallocator form. + + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 4 = destroying_delete + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +expr_reuse( + int reuse: @expr ref, + int original: @expr ref, + int value_category: int ref +) + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +| 363 = @reuseexpr +| 364 = @istriviallycopyassignable +| 365 = @isassignablenopreconditioncheck +| 366 = @referencebindstotemporary +| 367 = @issameas +| 368 = @builtinhasattribute +| 369 = @ispointerinterconvertiblewithclass +| 370 = @builtinispointerinterconvertiblewithclass +| 371 = @iscorrespondingmember +| 372 = @builtiniscorrespondingmember +| 373 = @isboundedarray +| 374 = @isunboundedarray +| 375 = @isreferenceable +| 378 = @isnothrowconvertible +| 379 = @referenceconstructsfromtemporary +| 380 = @referenceconvertsfromtemporary +| 381 = @isconvertible +| 382 = @isvalidwinrttype +| 383 = @iswinclass +| 384 = @iswininterface +| 385 = @istriviallyequalitycomparable +| 386 = @isscopedenum +| 387 = @istriviallyrelocatable +| 388 = @datasizeof +| 389 = @c11_generic +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + | @istriviallycopyassignable + | @isassignablenopreconditioncheck + | @referencebindstotemporary + | @issameas + | @builtinhasattribute + | @ispointerinterconvertiblewithclass + | @builtinispointerinterconvertiblewithclass + | @iscorrespondingmember + | @builtiniscorrespondingmember + | @isboundedarray + | @isunboundedarray + | @isreferenceable + | @isnothrowconvertible + | @referenceconstructsfromtemporary + | @referenceconvertsfromtemporary + | @isconvertible + | @isvalidwinrttype + | @iswinclass + | @iswininterface + | @istriviallyequalitycomparable + | @isscopedenum + | @istriviallyrelocatable + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +@stmt_for_or_range_based_for = @stmt_for + | @stmt_range_based_for; + +for_initialization( + unique int for_stmt: @stmt_for_or_range_based_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/upgrade.properties b/cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/upgrade.properties new file mode 100644 index 00000000000..477f78902ed --- /dev/null +++ b/cpp/ql/lib/upgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/upgrade.properties @@ -0,0 +1,2 @@ +description: Expose C11 _Generics +compatibility: backwards diff --git a/cpp/ql/test/library-tests/c11_generic/PrintAST.expected b/cpp/ql/test/library-tests/c11_generic/PrintAST.expected new file mode 100644 index 00000000000..67583c896c6 --- /dev/null +++ b/cpp/ql/test/library-tests/c11_generic/PrintAST.expected @@ -0,0 +1,458 @@ +#-----| [CopyAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag const&) +#-----| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [LValueReferenceType] const __va_list_tag & +#-----| [MoveAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag&&) +#-----| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [RValueReferenceType] __va_list_tag && +generic.c: +# 3| [FormattingFunction,TopLevelFunction] int printf(char const*) +# 3| : +# 3| getParameter(0): [Parameter] format +# 3| Type = [PointerType] const char * +# 14| [TopLevelFunction] int main() +# 14| : +# 15| getEntryPoint(): [BlockStmt] { ... } +# 16| getStmt(0): [DeclStmt] declaration +# 16| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i +# 16| Type = [IntType] int +# 17| getStmt(1): [DeclStmt] declaration +# 17| getDeclarationEntry(0): [VariableDeclarationEntry] definition of m +# 17| Type = [CTypedefType] MYINT +# 18| getStmt(2): [DeclStmt] declaration +# 18| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 18| Type = [PointerType] const char * +# 19| getStmt(3): [DeclStmt] declaration +# 19| getDeclarationEntry(0): [VariableDeclarationEntry] definition of f +# 19| Type = [PointerType] float *** +# 21| getStmt(4): [ExprStmt] ExprStmt +# 21| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf +# 21| Type = [IntType] int +# 21| ValueCategory = prvalue +# 21| getArgument(0): i is %s\n +# 21| Type = [ArrayType] char[9] +# 21| Value = [StringLiteral] "i is %s\n" +# 21| ValueCategory = lvalue +# 21| getArgument(1): int +# 21| Type = [ArrayType] char[4] +# 21| Value = [StringLiteral] "int" +# 21| ValueCategory = lvalue +# 21| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)... +# 21| Conversion = [PointerConversion] pointer conversion +# 21| Type = [PointerType] const char * +# 21| ValueCategory = prvalue +# 21| getExpr(): [ArrayToPointerConversion] array to pointer conversion +# 21| Type = [CharPointerType] char * +# 21| ValueCategory = prvalue +# 21| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 21| Type = [CharPointerType] char * +# 21| ValueCategory = prvalue +# 21| getExpr(): [C11GenericExpr] _Generic +# 21| Type = [ArrayType] char[4] +# 21| Value = [C11GenericExpr] int +# 21| ValueCategory = lvalue +# 21| getControllingExpr(): [VariableAccess] i +# 21| Type = [IntType] int +# 21| ValueCategory = prvalue(load) +# 21| getAssociationType(0): [TypeName] int +# 21| Type = [IntType] int +# 21| ValueCategory = prvalue +# 21| getAssociationExpr(0): [ReuseExpr] reuse of int +# 21| Type = [ArrayType] char[4] +# 21| ValueCategory = lvalue +# 21| getAssociationType(1): [TypeName] const char * +# 21| Type = [PointerType] const char * +# 21| ValueCategory = prvalue +# 21| getAssociationExpr(1): string +# 21| Type = [ArrayType] char[7] +# 21| Value = [StringLiteral] "string" +# 21| ValueCategory = lvalue +# 21| getAssociationType(2): [TypeName] void +# 21| Type = [VoidType] void +# 21| ValueCategory = prvalue +# 21| getAssociationExpr(2): unknown +# 21| Type = [ArrayType] char[8] +# 21| Value = [StringLiteral] "unknown" +# 21| ValueCategory = lvalue +# 21| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 21| Type = [IntType] int +# 21| ValueCategory = prvalue(load) +# 22| getStmt(5): [ExprStmt] ExprStmt +# 22| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf +# 22| Type = [IntType] int +# 22| ValueCategory = prvalue +# 22| getArgument(0): c is %s\n +# 22| Type = [ArrayType] char[9] +# 22| Value = [StringLiteral] "c is %s\n" +# 22| ValueCategory = lvalue +# 22| getArgument(1): int +# 22| Type = [ArrayType] char[4] +# 22| Value = [StringLiteral] "int" +# 22| ValueCategory = lvalue +# 22| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)... +# 22| Conversion = [PointerConversion] pointer conversion +# 22| Type = [PointerType] const char * +# 22| ValueCategory = prvalue +# 22| getExpr(): [ArrayToPointerConversion] array to pointer conversion +# 22| Type = [CharPointerType] char * +# 22| ValueCategory = prvalue +# 22| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 22| Type = [CharPointerType] char * +# 22| ValueCategory = prvalue +# 22| getExpr(): [C11GenericExpr] _Generic +# 22| Type = [ArrayType] char[4] +# 22| Value = [C11GenericExpr] int +# 22| ValueCategory = lvalue +# 22| getControllingExpr(): [VariableAccess] m +# 22| Type = [CTypedefType] MYINT +# 22| ValueCategory = prvalue(load) +# 22| getAssociationType(0): [TypeName] int +# 22| Type = [IntType] int +# 22| ValueCategory = prvalue +# 22| getAssociationExpr(0): [ReuseExpr] reuse of int +# 22| Type = [ArrayType] char[4] +# 22| ValueCategory = lvalue +# 22| getAssociationType(1): [TypeName] const char * +# 22| Type = [PointerType] const char * +# 22| ValueCategory = prvalue +# 22| getAssociationExpr(1): string +# 22| Type = [ArrayType] char[7] +# 22| Value = [StringLiteral] "string" +# 22| ValueCategory = lvalue +# 22| getAssociationType(2): [TypeName] void +# 22| Type = [VoidType] void +# 22| ValueCategory = prvalue +# 22| getAssociationExpr(2): unknown +# 22| Type = [ArrayType] char[8] +# 22| Value = [StringLiteral] "unknown" +# 22| ValueCategory = lvalue +# 22| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 22| Type = [CTypedefType] MYINT +# 22| ValueCategory = prvalue(load) +# 23| getStmt(6): [ExprStmt] ExprStmt +# 23| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf +# 23| Type = [IntType] int +# 23| ValueCategory = prvalue +# 23| getArgument(0): s is %s\n +# 23| Type = [ArrayType] char[9] +# 23| Value = [StringLiteral] "s is %s\n" +# 23| ValueCategory = lvalue +# 23| getArgument(1): string +# 23| Type = [ArrayType] char[7] +# 23| Value = [StringLiteral] "string" +# 23| ValueCategory = lvalue +# 23| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)... +# 23| Conversion = [PointerConversion] pointer conversion +# 23| Type = [PointerType] const char * +# 23| ValueCategory = prvalue +# 23| getExpr(): [ArrayToPointerConversion] array to pointer conversion +# 23| Type = [CharPointerType] char * +# 23| ValueCategory = prvalue +# 23| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 23| Type = [CharPointerType] char * +# 23| ValueCategory = prvalue +# 23| getExpr(): [C11GenericExpr] _Generic +# 23| Type = [ArrayType] char[7] +# 23| Value = [C11GenericExpr] string +# 23| ValueCategory = lvalue +# 23| getControllingExpr(): [VariableAccess] s +# 23| Type = [PointerType] const char * +# 23| ValueCategory = prvalue(load) +# 23| getAssociationType(0): [TypeName] int +# 23| Type = [IntType] int +# 23| ValueCategory = prvalue +# 23| getAssociationExpr(0): int +# 23| Type = [ArrayType] char[4] +# 23| Value = [StringLiteral] "int" +# 23| ValueCategory = lvalue +# 23| getAssociationType(1): [TypeName] const char * +# 23| Type = [PointerType] const char * +# 23| ValueCategory = prvalue +# 23| getAssociationExpr(1): [ReuseExpr] reuse of string +# 23| Type = [ArrayType] char[7] +# 23| ValueCategory = lvalue +# 23| getAssociationType(2): [TypeName] void +# 23| Type = [VoidType] void +# 23| ValueCategory = prvalue +# 23| getAssociationExpr(2): unknown +# 23| Type = [ArrayType] char[8] +# 23| Value = [StringLiteral] "unknown" +# 23| ValueCategory = lvalue +# 23| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 23| Type = [PointerType] const char * +# 23| ValueCategory = prvalue(load) +# 24| getStmt(7): [ExprStmt] ExprStmt +# 24| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf +# 24| Type = [IntType] int +# 24| ValueCategory = prvalue +# 24| getArgument(0): f is %s\n +# 24| Type = [ArrayType] char[9] +# 24| Value = [StringLiteral] "f is %s\n" +# 24| ValueCategory = lvalue +# 24| getArgument(1): unknown +# 24| Type = [ArrayType] char[8] +# 24| Value = [StringLiteral] "unknown" +# 24| ValueCategory = lvalue +# 24| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)... +# 24| Conversion = [PointerConversion] pointer conversion +# 24| Type = [PointerType] const char * +# 24| ValueCategory = prvalue +# 24| getExpr(): [ArrayToPointerConversion] array to pointer conversion +# 24| Type = [CharPointerType] char * +# 24| ValueCategory = prvalue +# 24| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 24| Type = [CharPointerType] char * +# 24| ValueCategory = prvalue +# 24| getExpr(): [C11GenericExpr] _Generic +# 24| Type = [ArrayType] char[8] +# 24| Value = [C11GenericExpr] unknown +# 24| ValueCategory = lvalue +# 24| getControllingExpr(): [VariableAccess] f +# 24| Type = [PointerType] float *** +# 24| ValueCategory = prvalue(load) +# 24| getAssociationType(0): [TypeName] int +# 24| Type = [IntType] int +# 24| ValueCategory = prvalue +# 24| getAssociationExpr(0): int +# 24| Type = [ArrayType] char[4] +# 24| Value = [StringLiteral] "int" +# 24| ValueCategory = lvalue +# 24| getAssociationType(1): [TypeName] const char * +# 24| Type = [PointerType] const char * +# 24| ValueCategory = prvalue +# 24| getAssociationExpr(1): string +# 24| Type = [ArrayType] char[7] +# 24| Value = [StringLiteral] "string" +# 24| ValueCategory = lvalue +# 24| getAssociationType(2): [TypeName] void +# 24| Type = [VoidType] void +# 24| ValueCategory = prvalue +# 24| getAssociationExpr(2): [ReuseExpr] reuse of unknown +# 24| Type = [ArrayType] char[8] +# 24| ValueCategory = lvalue +# 24| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 24| Type = [PointerType] float *** +# 24| ValueCategory = prvalue(load) +# 25| getStmt(8): [ReturnStmt] return ... +#-----| getExpr(): [Literal] 0 +#-----| Type = [IntType] int +#-----| Value = [Literal] 0 +#-----| ValueCategory = prvalue +generic.cpp: +# 4| [FormattingFunction,TopLevelFunction] int printf(char const*) +# 4| : +# 4| getParameter(0): [Parameter] format +# 4| Type = [PointerType] const char * +# 15| [TopLevelFunction] int main() +# 15| : +# 16| getEntryPoint(): [BlockStmt] { ... } +# 17| getStmt(0): [DeclStmt] declaration +# 17| getDeclarationEntry(0): [VariableDeclarationEntry] definition of i +# 17| Type = [IntType] int +# 18| getStmt(1): [DeclStmt] declaration +# 18| getDeclarationEntry(0): [VariableDeclarationEntry] definition of m +# 18| Type = [CTypedefType] MYINT +# 19| getStmt(2): [DeclStmt] declaration +# 19| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s +# 19| Type = [PointerType] const char * +# 20| getStmt(3): [DeclStmt] declaration +# 20| getDeclarationEntry(0): [VariableDeclarationEntry] definition of f +# 20| Type = [PointerType] float *** +# 22| getStmt(4): [ExprStmt] ExprStmt +# 22| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf +# 22| Type = [IntType] int +# 22| ValueCategory = prvalue +# 22| getArgument(0): i is %s\n +# 22| Type = [ArrayType] const char[9] +# 22| Value = [StringLiteral] "i is %s\n" +# 22| ValueCategory = lvalue +# 22| getArgument(1): int +# 22| Type = [ArrayType] const char[4] +# 22| Value = [StringLiteral] "int" +# 22| ValueCategory = lvalue +# 22| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 22| Type = [PointerType] const char * +# 22| ValueCategory = prvalue +# 22| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 22| Type = [PointerType] const char * +# 22| ValueCategory = prvalue +# 22| getExpr(): [C11GenericExpr] _Generic +# 22| Type = [ArrayType] const char[4] +# 22| Value = [C11GenericExpr] int +# 22| ValueCategory = lvalue +# 22| getControllingExpr(): [VariableAccess] i +# 22| Type = [IntType] int +# 22| ValueCategory = lvalue +# 22| getAssociationType(0): [TypeName] int +# 22| Type = [IntType] int +# 22| ValueCategory = prvalue +# 22| getAssociationExpr(0): [ReuseExpr] reuse of int +# 22| Type = [ArrayType] const char[4] +# 22| ValueCategory = lvalue +# 22| getAssociationType(1): [TypeName] const char * +# 22| Type = [PointerType] const char * +# 22| ValueCategory = prvalue +# 22| getAssociationExpr(1): string +# 22| Type = [ArrayType] const char[7] +# 22| Value = [StringLiteral] "string" +# 22| ValueCategory = lvalue +# 22| getAssociationType(2): [TypeName] void +# 22| Type = [VoidType] void +# 22| ValueCategory = prvalue +# 22| getAssociationExpr(2): unknown +# 22| Type = [ArrayType] const char[8] +# 22| Value = [StringLiteral] "unknown" +# 22| ValueCategory = lvalue +# 22| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 22| Type = [IntType] int +# 22| ValueCategory = lvalue +# 23| getStmt(5): [ExprStmt] ExprStmt +# 23| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf +# 23| Type = [IntType] int +# 23| ValueCategory = prvalue +# 23| getArgument(0): c is %s\n +# 23| Type = [ArrayType] const char[9] +# 23| Value = [StringLiteral] "c is %s\n" +# 23| ValueCategory = lvalue +# 23| getArgument(1): int +# 23| Type = [ArrayType] const char[4] +# 23| Value = [StringLiteral] "int" +# 23| ValueCategory = lvalue +# 23| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 23| Type = [PointerType] const char * +# 23| ValueCategory = prvalue +# 23| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 23| Type = [PointerType] const char * +# 23| ValueCategory = prvalue +# 23| getExpr(): [C11GenericExpr] _Generic +# 23| Type = [ArrayType] const char[4] +# 23| Value = [C11GenericExpr] int +# 23| ValueCategory = lvalue +# 23| getControllingExpr(): [VariableAccess] m +# 23| Type = [CTypedefType] MYINT +# 23| ValueCategory = lvalue +# 23| getAssociationType(0): [TypeName] int +# 23| Type = [IntType] int +# 23| ValueCategory = prvalue +# 23| getAssociationExpr(0): [ReuseExpr] reuse of int +# 23| Type = [ArrayType] const char[4] +# 23| ValueCategory = lvalue +# 23| getAssociationType(1): [TypeName] const char * +# 23| Type = [PointerType] const char * +# 23| ValueCategory = prvalue +# 23| getAssociationExpr(1): string +# 23| Type = [ArrayType] const char[7] +# 23| Value = [StringLiteral] "string" +# 23| ValueCategory = lvalue +# 23| getAssociationType(2): [TypeName] void +# 23| Type = [VoidType] void +# 23| ValueCategory = prvalue +# 23| getAssociationExpr(2): unknown +# 23| Type = [ArrayType] const char[8] +# 23| Value = [StringLiteral] "unknown" +# 23| ValueCategory = lvalue +# 23| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 23| Type = [CTypedefType] MYINT +# 23| ValueCategory = lvalue +# 24| getStmt(6): [ExprStmt] ExprStmt +# 24| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf +# 24| Type = [IntType] int +# 24| ValueCategory = prvalue +# 24| getArgument(0): s is %s\n +# 24| Type = [ArrayType] const char[9] +# 24| Value = [StringLiteral] "s is %s\n" +# 24| ValueCategory = lvalue +# 24| getArgument(1): string +# 24| Type = [ArrayType] const char[7] +# 24| Value = [StringLiteral] "string" +# 24| ValueCategory = lvalue +# 24| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 24| Type = [PointerType] const char * +# 24| ValueCategory = prvalue +# 24| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 24| Type = [PointerType] const char * +# 24| ValueCategory = prvalue +# 24| getExpr(): [C11GenericExpr] _Generic +# 24| Type = [ArrayType] const char[7] +# 24| Value = [C11GenericExpr] string +# 24| ValueCategory = lvalue +# 24| getControllingExpr(): [VariableAccess] s +# 24| Type = [PointerType] const char * +# 24| ValueCategory = lvalue +# 24| getAssociationType(0): [TypeName] int +# 24| Type = [IntType] int +# 24| ValueCategory = prvalue +# 24| getAssociationExpr(0): int +# 24| Type = [ArrayType] const char[4] +# 24| Value = [StringLiteral] "int" +# 24| ValueCategory = lvalue +# 24| getAssociationType(1): [TypeName] const char * +# 24| Type = [PointerType] const char * +# 24| ValueCategory = prvalue +# 24| getAssociationExpr(1): [ReuseExpr] reuse of string +# 24| Type = [ArrayType] const char[7] +# 24| ValueCategory = lvalue +# 24| getAssociationType(2): [TypeName] void +# 24| Type = [VoidType] void +# 24| ValueCategory = prvalue +# 24| getAssociationExpr(2): unknown +# 24| Type = [ArrayType] const char[8] +# 24| Value = [StringLiteral] "unknown" +# 24| ValueCategory = lvalue +# 24| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 24| Type = [PointerType] const char * +# 24| ValueCategory = lvalue +# 25| getStmt(7): [ExprStmt] ExprStmt +# 25| getExpr(): [FormattingFunctionCall,FunctionCall] call to printf +# 25| Type = [IntType] int +# 25| ValueCategory = prvalue +# 25| getArgument(0): f is %s\n +# 25| Type = [ArrayType] const char[9] +# 25| Value = [StringLiteral] "f is %s\n" +# 25| ValueCategory = lvalue +# 25| getArgument(1): unknown +# 25| Type = [ArrayType] const char[8] +# 25| Value = [StringLiteral] "unknown" +# 25| ValueCategory = lvalue +# 25| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 25| Type = [PointerType] const char * +# 25| ValueCategory = prvalue +# 25| getArgument(1).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion +# 25| Type = [PointerType] const char * +# 25| ValueCategory = prvalue +# 25| getExpr(): [C11GenericExpr] _Generic +# 25| Type = [ArrayType] const char[8] +# 25| Value = [C11GenericExpr] unknown +# 25| ValueCategory = lvalue +# 25| getControllingExpr(): [VariableAccess] f +# 25| Type = [PointerType] float *** +# 25| ValueCategory = lvalue +# 25| getAssociationType(0): [TypeName] int +# 25| Type = [IntType] int +# 25| ValueCategory = prvalue +# 25| getAssociationExpr(0): int +# 25| Type = [ArrayType] const char[4] +# 25| Value = [StringLiteral] "int" +# 25| ValueCategory = lvalue +# 25| getAssociationType(1): [TypeName] const char * +# 25| Type = [PointerType] const char * +# 25| ValueCategory = prvalue +# 25| getAssociationExpr(1): string +# 25| Type = [ArrayType] const char[7] +# 25| Value = [StringLiteral] "string" +# 25| ValueCategory = lvalue +# 25| getAssociationType(2): [TypeName] void +# 25| Type = [VoidType] void +# 25| ValueCategory = prvalue +# 25| getAssociationExpr(2): [ReuseExpr] reuse of unknown +# 25| Type = [ArrayType] const char[8] +# 25| ValueCategory = lvalue +# 25| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 25| Type = [PointerType] float *** +# 25| ValueCategory = lvalue +# 26| getStmt(8): [ReturnStmt] return ... +#-----| getExpr(): [Literal] 0 +#-----| Type = [IntType] int +#-----| Value = [Literal] 0 +#-----| ValueCategory = prvalue diff --git a/cpp/ql/test/library-tests/c11_generic/PrintAST.qlref b/cpp/ql/test/library-tests/c11_generic/PrintAST.qlref new file mode 100644 index 00000000000..6f85a6dbe69 --- /dev/null +++ b/cpp/ql/test/library-tests/c11_generic/PrintAST.qlref @@ -0,0 +1 @@ +semmle/code/cpp/PrintAST.ql diff --git a/cpp/ql/test/library-tests/c11_generic/macro_invocation.expected b/cpp/ql/test/library-tests/c11_generic/macro_invocation.expected new file mode 100644 index 00000000000..a022878b4ea --- /dev/null +++ b/cpp/ql/test/library-tests/c11_generic/macro_invocation.expected @@ -0,0 +1,8 @@ +| generic.c:21:22:21:32 | _Generic | generic.c:21:22:21:32 | describe(val) | +| generic.c:22:22:22:32 | _Generic | generic.c:22:22:22:32 | describe(val) | +| generic.c:23:22:23:32 | _Generic | generic.c:23:22:23:32 | describe(val) | +| generic.c:24:22:24:32 | _Generic | generic.c:24:22:24:32 | describe(val) | +| generic.cpp:22:22:22:32 | _Generic | generic.cpp:22:22:22:32 | describe(val) | +| generic.cpp:23:22:23:32 | _Generic | generic.cpp:23:22:23:32 | describe(val) | +| generic.cpp:24:22:24:32 | _Generic | generic.cpp:24:22:24:32 | describe(val) | +| generic.cpp:25:22:25:32 | _Generic | generic.cpp:25:22:25:32 | describe(val) | diff --git a/cpp/ql/test/library-tests/c11_generic/macro_invocation.ql b/cpp/ql/test/library-tests/c11_generic/macro_invocation.ql new file mode 100644 index 00000000000..c63e4c8114e --- /dev/null +++ b/cpp/ql/test/library-tests/c11_generic/macro_invocation.ql @@ -0,0 +1,5 @@ +import cpp + +from C11GenericExpr g, MacroInvocation m +where m.getAnExpandedElement() = g +select g, m diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 66606ff7056..f17680ebe2d 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -4207,6 +4207,24 @@ generic.c: # 3| Type = [IntType] int # 3| Value = [Literal] 1 # 3| ValueCategory = prvalue +# 3| getLeftOperand().getFullyConverted(): [C11GenericExpr] _Generic +# 3| Type = [IntType] unsigned int +# 3| ValueCategory = prvalue(load) +# 3| getControllingExpr(): [VariableAccess] r +# 3| Type = [IntType] unsigned int +# 3| ValueCategory = prvalue(load) +# 3| getAssociationType(0): [TypeName] unsigned int +# 3| Type = [IntType] unsigned int +# 3| ValueCategory = prvalue +# 3| getAssociationExpr(0): [ReuseExpr] reuse of x +# 3| Type = [IntType] unsigned int +# 3| ValueCategory = lvalue +# 3| getAssociationType(1): [TypeName] int +# 3| Type = [IntType] int +# 3| ValueCategory = prvalue +# 3| getAssociationExpr(1): [VariableAccess] y +# 3| Type = [IntType] int +# 3| ValueCategory = lvalue # 3| getRightOperand().getFullyConverted(): [CStyleCast] (unsigned int)... # 3| Conversion = [IntegralConversion] integral conversion # 3| Type = [IntType] unsigned int @@ -4231,6 +4249,29 @@ generic.c: # 16| getExpr(): [ArrayToPointerConversion] array to pointer conversion # 16| Type = [CharPointerType] char * # 16| ValueCategory = prvalue +# 16| getExpr(): [C11GenericExpr] _Generic +# 16| Type = [ArrayType] char[4] +# 16| Value = [C11GenericExpr] int +# 16| ValueCategory = lvalue +# 16| getControllingExpr(): [VariableAccess] i +# 16| Type = [IntType] int +# 16| ValueCategory = prvalue(load) +# 16| getAssociationType(0): [TypeName] int +# 16| Type = [IntType] int +# 16| ValueCategory = prvalue +# 16| getAssociationExpr(0): [ReuseExpr] reuse of int +# 16| Type = [ArrayType] char[4] +# 16| ValueCategory = lvalue +# 16| getAssociationType(1): [TypeName] void +# 16| Type = [VoidType] void +# 16| ValueCategory = prvalue +# 16| getAssociationExpr(1): unknown +# 16| Type = [ArrayType] char[8] +# 16| Value = [StringLiteral] "unknown" +# 16| ValueCategory = lvalue +# 16| getControllingExpr().getFullyConverted(): [ParenthesisExpr] (...) +# 16| Type = [IntType] int +# 16| ValueCategory = prvalue(load) # 19| [TopLevelFunction] char const* c11_generic_test_with_constant_and_no_macro() # 19| : # 20| getEntryPoint(): [BlockStmt] { ... } @@ -4249,6 +4290,26 @@ generic.c: # 23| getExpr(): [ArrayToPointerConversion] array to pointer conversion # 23| Type = [CharPointerType] char * # 23| ValueCategory = prvalue +# 23| getExpr(): [C11GenericExpr] _Generic +# 23| Type = [ArrayType] char[4] +# 23| Value = [C11GenericExpr] int +# 23| ValueCategory = lvalue +# 23| getControllingExpr(): [VariableAccess] i +# 23| Type = [IntType] int +# 23| ValueCategory = prvalue(load) +# 23| getAssociationType(0): [TypeName] int +# 23| Type = [IntType] int +# 23| ValueCategory = prvalue +# 23| getAssociationExpr(0): [ReuseExpr] reuse of int +# 23| Type = [ArrayType] char[4] +# 23| ValueCategory = lvalue +# 23| getAssociationType(1): [TypeName] void +# 23| Type = [VoidType] void +# 23| ValueCategory = prvalue +# 23| getAssociationExpr(1): unknown +# 23| Type = [ArrayType] char[8] +# 23| Value = [StringLiteral] "unknown" +# 23| ValueCategory = lvalue # 26| [TopLevelFunction] void c11_generic_test_test_with_cast(int) # 26| : # 26| getParameter(0): [Parameter] y @@ -4267,10 +4328,28 @@ generic.c: # 28| getRValue(): [VariableAccess] y # 28| Type = [IntType] int # 28| ValueCategory = prvalue(load) -# 28| getRValue().getFullyConverted(): [CStyleCast] (unsigned int)... -# 28| Conversion = [IntegralConversion] integral conversion +# 28| getRValue().getFullyConverted(): [C11GenericExpr] _Generic # 28| Type = [IntType] unsigned int # 28| ValueCategory = prvalue +# 28| getControllingExpr(): [VariableAccess] r +# 28| Type = [IntType] unsigned int +# 28| ValueCategory = prvalue(load) +# 28| getAssociationType(0): [TypeName] unsigned int +# 28| Type = [IntType] unsigned int +# 28| ValueCategory = prvalue +# 28| getAssociationExpr(0): [ReuseExpr] reuse of y +# 28| Type = [IntType] int +# 28| ValueCategory = prvalue +# 28| getAssociationType(1): [TypeName] int +# 28| Type = [IntType] int +# 28| ValueCategory = prvalue +# 28| getAssociationExpr(1): [VariableAccess] y +# 28| Type = [IntType] int +# 28| ValueCategory = lvalue +# 28| getExpr(): [CStyleCast] (unsigned int)... +# 28| Conversion = [IntegralConversion] integral conversion +# 28| Type = [IntType] unsigned int +# 28| ValueCategory = prvalue # 29| getStmt(2): [ReturnStmt] return ... ir.c: # 5| [TopLevelFunction] int getX(MyCoords*) diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index ced441595d7..51d5c943c4c 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -2991,7 +2991,7 @@ generic.c: # 14| r14_1(glval) = VariableAddress[i] : # 14| m14_2(int) = Uninitialized[i] : &:r14_1 # 16| r16_1(glval) = VariableAddress[#return] : -# 16| r16_2(glval) = StringConstant[int] : +# 16| r16_2(glval) = Constant[int] : # 16| r16_3(char *) = Convert : r16_2 # 16| r16_4(char *) = Convert : r16_3 # 16| m16_5(char *) = Store[#return] : &:r16_1, r16_4 @@ -3009,7 +3009,7 @@ generic.c: # 21| r21_1(glval) = VariableAddress[i] : # 21| m21_2(int) = Uninitialized[i] : &:r21_1 # 23| r23_1(glval) = VariableAddress[#return] : -# 23| r23_2(glval) = StringConstant["int"] : +# 23| r23_2(glval) = Constant[int] : # 23| r23_3(char *) = Convert : r23_2 # 23| r23_4(char *) = Convert : r23_3 # 23| m23_5(char *) = Store[#return] : &:r23_1, r23_4 diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 01ebe0219f9..ab1336a268a 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -2763,7 +2763,7 @@ generic.c: # 14| r14_1(glval) = VariableAddress[i] : # 14| mu14_2(int) = Uninitialized[i] : &:r14_1 # 16| r16_1(glval) = VariableAddress[#return] : -# 16| r16_2(glval) = StringConstant[int] : +# 16| r16_2(glval) = Constant[int] : # 16| r16_3(char *) = Convert : r16_2 # 16| r16_4(char *) = Convert : r16_3 # 16| mu16_5(char *) = Store[#return] : &:r16_1, r16_4 @@ -2780,7 +2780,7 @@ generic.c: # 21| r21_1(glval) = VariableAddress[i] : # 21| mu21_2(int) = Uninitialized[i] : &:r21_1 # 23| r23_1(glval) = VariableAddress[#return] : -# 23| r23_2(glval) = StringConstant["int"] : +# 23| r23_2(glval) = Constant[int] : # 23| r23_3(char *) = Convert : r23_2 # 23| r23_4(char *) = Convert : r23_3 # 23| mu23_5(char *) = Store[#return] : &:r23_1, r23_4 From 5360192a581d056e5a17f775917fc711bd1aadb1 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 30 Aug 2024 13:25:59 +0100 Subject: [PATCH 168/404] Apply review suggestions - change = to in Co-authored-by: Rasmus Wriedt Larsen --- .../python/security/dataflow/CleartextLoggingCustomizations.qll | 2 +- .../python/security/dataflow/CleartextStorageCustomizations.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll index d794b024996..857cd81a330 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll @@ -41,7 +41,7 @@ module CleartextLogging { */ class SensitiveDataSourceAsSource extends Source, SensitiveDataSource { SensitiveDataSourceAsSource() { - not SensitiveDataSource.super.getClassification() = + not SensitiveDataSource.super.getClassification() in [SensitiveDataClassification::id(), SensitiveDataClassification::certificate()] } diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll index ebe70bc1b59..e3a698bfd82 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll @@ -40,7 +40,7 @@ module CleartextStorage { */ class SensitiveDataSourceAsSource extends Source, SensitiveDataSource { SensitiveDataSourceAsSource() { - not SensitiveDataSource.super.getClassification() = + not SensitiveDataSource.super.getClassification() in [SensitiveDataClassification::id(), SensitiveDataClassification::certificate()] } From ec7ad84cd14ee604a529e1ccf53fea90fab4a2b5 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 30 Aug 2024 13:51:33 +0100 Subject: [PATCH 169/404] Update formatting --- .../security/dataflow/CleartextLoggingCustomizations.qll | 5 +++-- .../security/dataflow/CleartextStorageCustomizations.qll | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll index 857cd81a330..c00106a1260 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextLoggingCustomizations.qll @@ -41,8 +41,9 @@ module CleartextLogging { */ class SensitiveDataSourceAsSource extends Source, SensitiveDataSource { SensitiveDataSourceAsSource() { - not SensitiveDataSource.super.getClassification() in - [SensitiveDataClassification::id(), SensitiveDataClassification::certificate()] + not SensitiveDataSource.super.getClassification() in [ + SensitiveDataClassification::id(), SensitiveDataClassification::certificate() + ] } override SensitiveDataClassification getClassification() { diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll index e3a698bfd82..70a17acbe9a 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll @@ -40,8 +40,9 @@ module CleartextStorage { */ class SensitiveDataSourceAsSource extends Source, SensitiveDataSource { SensitiveDataSourceAsSource() { - not SensitiveDataSource.super.getClassification() in - [SensitiveDataClassification::id(), SensitiveDataClassification::certificate()] + not SensitiveDataSource.super.getClassification() in [ + SensitiveDataClassification::id(), SensitiveDataClassification::certificate() + ] } override SensitiveDataClassification getClassification() { From 7e1290aa7493ad1fbeea1178ffe93a8802621429 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 30 Aug 2024 16:08:37 +0200 Subject: [PATCH 170/404] Rust: reuse shared rust trap library --- .pre-commit-config.yaml | 2 +- config/identical-files.json | 3 +- misc/codegen/generators/rustgen.py | 8 +- misc/codegen/lib/rust.py | 13 +- misc/codegen/templates/rust_classes.mustache | 23 +- rust/extractor/.cargo/config.toml | 1 + rust/extractor/BUILD.bazel | 4 +- rust/extractor/Cargo.lock | 418 +++++++++++++++++- rust/extractor/Cargo.toml | 6 + .../codeql-extractor-fake-crate/BUILD.bazel | 0 .../codeql-extractor-fake-crate/Cargo.toml | 28 ++ .../codeql-extractor-fake-crate/README.md | 7 + .../codeql-extractor-fake-crate/src/lib.rs | 0 rust/extractor/src/config.rs | 26 +- rust/extractor/src/generated/top.rs | 56 ++- rust/extractor/src/main.rs | 13 +- rust/extractor/src/translate.rs | 78 ++-- rust/extractor/src/trap.rs | 175 ++++---- shared/tree-sitter-extractor/src/trap.rs | 32 +- 19 files changed, 677 insertions(+), 216 deletions(-) create mode 100644 rust/extractor/.cargo/config.toml create mode 100644 rust/extractor/codeql-extractor-fake-crate/BUILD.bazel create mode 100644 rust/extractor/codeql-extractor-fake-crate/Cargo.toml create mode 100644 rust/extractor/codeql-extractor-fake-crate/README.md create mode 100644 rust/extractor/codeql-extractor-fake-crate/src/lib.rs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 15682841dd2..bb8924ea8a4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: - id: sync-files name: Fix files required to be identical - files: \.(qll?|qhelp|swift)$|^config/identical-files\.json$ + files: \.(qll?|qhelp|swift|toml)$|^config/identical-files\.json$ language: system entry: python3 config/sync-files.py --latest pass_filenames: false diff --git a/config/identical-files.json b/config/identical-files.json index 891ddd8b631..44835401e51 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -358,6 +358,7 @@ ], "shared tree-sitter extractor cargo.toml": [ "shared/tree-sitter-extractor/Cargo.toml", - "ruby/extractor/codeql-extractor-fake-crate/Cargo.toml" + "ruby/extractor/codeql-extractor-fake-crate/Cargo.toml", + "rust/extractor/codeql-extractor-fake-crate/Cargo.toml" ] } diff --git a/misc/codegen/generators/rustgen.py b/misc/codegen/generators/rustgen.py index 04a6538998f..8e0bf4c087b 100644 --- a/misc/codegen/generators/rustgen.py +++ b/misc/codegen/generators/rustgen.py @@ -13,14 +13,16 @@ from misc.codegen.loaders import schemaloader def _get_type(t: str) -> str: match t: - case None | "boolean": # None means a predicate + case None: # None means a predicate return "bool" case "string": return "String" case "int": - return "i32" + return "usize" case _ if t[0].isupper(): - return "TrapLabel" + return "trap::Label" + case "boolean": + assert False, "boolean unsupported" case _: return t diff --git a/misc/codegen/lib/rust.py b/misc/codegen/lib/rust.py index 5e6405759b8..d28a5f55a24 100644 --- a/misc/codegen/lib/rust.py +++ b/misc/codegen/lib/rust.py @@ -58,10 +58,6 @@ keywords = { } _field_overrides = [ - ( - re.compile(r"(start|end)_(line|column)|(.*_)?index|width|num_.*"), - {"base_type": "u32"}, - ), (re.compile(r"(.*)_"), lambda m: {"field_name": m[1]}), ] @@ -98,20 +94,13 @@ class Field: type = f"Vec<{type}>" return type - # using @property breaks pystache internals here - def emitter(self): - if self.type == "String": - return lambda x: f"quoted(&{x})" - else: - return lambda x: x - @property def is_single(self): return not (self.is_optional or self.is_repeated or self.is_predicate) @property def is_label(self): - return self.base_type == "TrapLabel" + return self.base_type == "trap::Label" @dataclasses.dataclass diff --git a/misc/codegen/templates/rust_classes.mustache b/misc/codegen/templates/rust_classes.mustache index a2c0aff6db8..946fb512a37 100644 --- a/misc/codegen/templates/rust_classes.mustache +++ b/misc/codegen/templates/rust_classes.mustache @@ -1,7 +1,7 @@ // generated by {{generator}} -use crate::trap::{TrapLabel, TrapId, TrapEntry, quoted}; -use std::io::Write; +use crate::trap::{TrapId, TrapEntry}; +use codeql_extractor::trap; {{#classes}} #[derive(Debug)] @@ -17,37 +17,36 @@ impl TrapEntry for {{name}} { std::mem::replace(&mut self.id, TrapId::Star) } - fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { + fn emit(self, id: trap::Label, out: &mut trap::Writer) { {{#single_field_entries}} - write!(out, "{{table_name}}({id}{{#fields}}, {}{{/fields}})\n"{{#fields}}, {{#emitter}}self.{{field_name}}{{/emitter}}{{/fields}})?; + out.add_tuple("{{table_name}}", vec![trap::Arg::Label(id){{#fields}}, self.{{field_name}}.into(){{/fields}}]); {{/single_field_entries}} {{#fields}} {{#is_predicate}} if self.{{field_name}} { - write!(out, "{{table_name}}({id})\n")?; + out.add_tuple("{{table_name}}", vec![trap::Arg::Label(id)]); } {{/is_predicate}} {{#is_optional}} {{^is_repeated}} - if let Some(ref v) = &self.{{field_name}} { - write!(out, "{{table_name}}({id}, {})\n", {{#emitter}}v{{/emitter}})?; + if let Some(v) = self.{{field_name}} { + out.add_tuple("{{table_name}}", vec![trap::Arg::Label(id), v.into()]); } {{/is_repeated}} {{/is_optional}} {{#is_repeated}} - for (i, &ref v) in self.{{field_name}}.iter().enumerate() { + for (i, &v) in self.{{field_name}}.iter().enumerate() { {{^is_optional}} - write!(out, "{{table_name}}({id}, {{^is_unordered}}{}, {{/is_unordered}}{})\n", {{^is_unordered}}i, {{/is_unordered}}{{#emitter}}v{{/emitter}})?; + out.add_tuple("{{table_name}}", vec![trap::Arg::Label(id){{^is_unordered}}, i.into(){{/is_unordered}}, v.into()]); {{/is_optional}} {{#is_optional}} - if let Some(ref vv) = &v { - write!(out, "{{table_name}}({id}, {{^is_unordered}}{}, {{/is_unordered}}{})\n", {{^is_unordered}}i, {{/is_unordered}}{{#emitter}}vv{{/emitter}})?; + if let Some(vv) = v { + out.add_tuple("{{table_name}}", vec![trap::Arg::Label(id){{^is_unordered}}, i.into(){{/is_unordered}}, v.into()]); } {{/is_optional}} } {{/is_repeated}} {{/fields}} - Ok(()) } } {{/classes}} diff --git a/rust/extractor/.cargo/config.toml b/rust/extractor/.cargo/config.toml new file mode 100644 index 00000000000..3e8c45cb78b --- /dev/null +++ b/rust/extractor/.cargo/config.toml @@ -0,0 +1 @@ +paths = ["../../shared/tree-sitter-extractor"] diff --git a/rust/extractor/BUILD.bazel b/rust/extractor/BUILD.bazel index ffe1ee92de9..ffda10101d0 100644 --- a/rust/extractor/BUILD.bazel +++ b/rust/extractor/BUILD.bazel @@ -11,5 +11,7 @@ codeql_rust_binary( visibility = ["//rust:__subpackages__"], deps = all_crate_deps( normal = True, - ), + ) + [ + "//shared/tree-sitter-extractor:codeql-extractor", + ], ) diff --git a/rust/extractor/Cargo.lock b/rust/extractor/Cargo.lock index 98a3f590e2a..40bf5c1903d 100644 --- a/rust/extractor/Cargo.lock +++ b/rust/extractor/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "always-assert" version = "0.2.0" @@ -120,6 +135,16 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bstr" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -132,6 +157,12 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "camino" version = "1.1.9" @@ -285,12 +316,35 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +[[package]] +name = "codeql-extractor" +version = "0.2.0" +dependencies = [ + "chrono", + "encoding", + "flate2", + "globset", + "lazy_static", + "num_cpus", + "rand", + "rayon", + "regex", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", + "tree-sitter", + "tree-sitter-json", + "tree-sitter-ql", +] + [[package]] name = "codeql-rust" version = "0.1.0" dependencies = [ "anyhow", "clap", + "codeql-extractor", "figment", "log", "num-traits", @@ -332,6 +386,15 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0570650661aa447e7335f1d5e4f499d8e58796e617bedc9267d971e51c8b49d4" +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" version = "0.5.13" @@ -445,6 +508,70 @@ dependencies = [ "log", ] +[[package]] +name = "encoding" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" +dependencies = [ + "encoding-index-japanese", + "encoding-index-korean", + "encoding-index-simpchinese", + "encoding-index-singlebyte", + "encoding-index-tradchinese", +] + +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" + [[package]] name = "equivalent" version = "1.0.1" @@ -482,6 +609,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -503,6 +640,30 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -527,6 +688,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hermit-abi" version = "0.4.0" @@ -631,7 +798,7 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi", + "hermit-abi 0.4.0", "libc", "windows-sys 0.52.0", ] @@ -698,6 +865,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3752f229dcc5a481d60f385fa479ff46818033d881d2d801aa27dffcfb5e8306" +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.158" @@ -747,6 +920,15 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.7.4" @@ -762,6 +944,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "mio" version = "0.8.11" @@ -808,6 +999,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -823,6 +1024,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -835,6 +1046,12 @@ version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.3" @@ -922,6 +1139,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -1515,6 +1741,36 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.10.0" @@ -1544,6 +1800,50 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + [[package]] name = "rowan" version = "0.15.15" @@ -1670,6 +1970,15 @@ dependencies = [ "syn", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1849,6 +2158,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tree-sitter" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df7cc499ceadd4dcdf7ec6d4cbc34ece92c3fa07821e287aedecd4416c516dca" +dependencies = [ + "cc", + "regex", +] + +[[package]] +name = "tree-sitter-json" +version = "0.21.0" +source = "git+https://github.com/tree-sitter/tree-sitter-json#bdd69eb8c8a58a9f54df03de0488d9990179be46" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-ql" +version = "0.22.5" +source = "git+https://github.com/tree-sitter/tree-sitter-ql#42becd6f8f7bae82c818fa3abb1b6ff34b552310" +dependencies = [ + "cc", + "tree-sitter", ] [[package]] @@ -1900,6 +2267,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.5" @@ -1977,6 +2350,22 @@ version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.9" @@ -1986,6 +2375,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" @@ -2148,3 +2543,24 @@ name = "yansi" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/rust/extractor/Cargo.toml b/rust/extractor/Cargo.toml index 8c8ef26ef2b..bb3178956d3 100644 --- a/rust/extractor/Cargo.toml +++ b/rust/extractor/Cargo.toml @@ -1,3 +1,5 @@ +[workspace] + [package] name = "codeql-rust" version = "0.1.0" @@ -21,6 +23,10 @@ serde = "1.0.209" serde_with = "3.9.0" stderrlog = "0.6.0" triomphe = "0.1.13" +# Ideally, we'd like to pull this in via a relative path. +# However, our bazel/rust tooling chokes on this, c.f. https://github.com/bazelbuild/rules_rust/issues/1525 +# Therefore, we have a pretty bad hack in place instead, see README.md in the codeql-extractor-fake-crate directory. +codeql-extractor = { path = "codeql-extractor-fake-crate" } [patch.crates-io] # patch for build script bug preventing bazel build diff --git a/rust/extractor/codeql-extractor-fake-crate/BUILD.bazel b/rust/extractor/codeql-extractor-fake-crate/BUILD.bazel new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rust/extractor/codeql-extractor-fake-crate/Cargo.toml b/rust/extractor/codeql-extractor-fake-crate/Cargo.toml new file mode 100644 index 00000000000..d51d64a3349 --- /dev/null +++ b/rust/extractor/codeql-extractor-fake-crate/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "codeql-extractor" +version = "0.2.0" +edition = "2021" +authors = ["GitHub"] + +[dependencies] +flate2 = "1.0" +globset = "0.4" +tree-sitter = ">= 0.22.6" +tracing = "0.1" +tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } +rayon = "1.5.0" +regex = "1.7.1" +encoding = "0.2" +lazy_static = "1.4.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +chrono = { version = "0.4.19", features = ["serde"] } +num_cpus = "1.14.0" + +[dev-dependencies] +tree-sitter-ql = { git = "https://github.com/tree-sitter/tree-sitter-ql" } +tree-sitter-json = {git = "https://github.com/tree-sitter/tree-sitter-json" } +rand = "0.8.5" + +[patch.crates-io] +tree-sitter = {git = "https://github.com/redsun82/tree-sitter.git", rev = "1f5c1112ceaa8fc6aff61d1852690407670d2a96"} diff --git a/rust/extractor/codeql-extractor-fake-crate/README.md b/rust/extractor/codeql-extractor-fake-crate/README.md new file mode 100644 index 00000000000..71f7ec8974b --- /dev/null +++ b/rust/extractor/codeql-extractor-fake-crate/README.md @@ -0,0 +1,7 @@ +We're presenting a fake crate in this workspace that ensures that the correct crate dependencies from the shared tree sitter +extractor can be parsed by Bazel (which doesn't resolve path dependencies outside of the cargo workspace unfortunately). + +The sync-identical-files script keeps this up-to-date. +For local development and IDEs, we override the path to `codeql-extractor` using the `.cargo/config.toml` mechanism. +Bazel doesn't actually do anything with path dependencies except to pull in their dependency tree, so we manually +specify the dependency from the ruby extractor to the shared extractor in `BUILD.bazel`. diff --git a/rust/extractor/codeql-extractor-fake-crate/src/lib.rs b/rust/extractor/codeql-extractor-fake-crate/src/lib.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rust/extractor/src/config.rs b/rust/extractor/src/config.rs index c37ed508620..521718c831a 100644 --- a/rust/extractor/src/config.rs +++ b/rust/extractor/src/config.rs @@ -1,9 +1,28 @@ use std::path::PathBuf; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize, Serializer, Deserializer}; use serde_with; use figment::{Figment, providers::{Env, Serialized}}; -use clap::{Parser, ArgAction}; +use clap::{Parser, ArgAction, ValueEnum}; +use clap::builder::PossibleValue; +use codeql_extractor::trap; +#[derive(Debug, PartialEq, Eq, Default, Serialize, Deserialize, Clone, Copy, ValueEnum)] +#[serde(rename_all = "lowercase")] +#[clap(rename_all = "lowercase")] +pub enum Compression { + #[default] // TODO make gzip default + None, + Gzip, +} + +impl Into for Compression { + fn into(self) -> trap::Compression { + match self { + Compression::None => trap::Compression::None, + Compression::Gzip => trap::Compression::Gzip, + } + } +} #[serde_with::apply(_ => #[serde(default)])] #[derive(Debug, Deserialize, Default)] @@ -12,6 +31,7 @@ pub struct Config { pub trap_dir: PathBuf, pub source_archive_dir: PathBuf, pub verbose: u8, + pub compression: Compression, pub inputs: Vec, } @@ -25,6 +45,8 @@ struct CliArgs { trap_dir: Option, #[arg(long)] source_archive_dir: Option, + #[arg(long)] + compression: Option, #[arg(short, long, action = ArgAction::Count)] pub verbose: u8, diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index d337d08c9d4..c0c7f9ddee8 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -1,7 +1,7 @@ // generated by codegen -use crate::trap::{TrapLabel, TrapId, TrapEntry, quoted}; -use std::io::Write; +use crate::trap::{TrapId, TrapEntry}; +use codeql_extractor::trap; #[derive(Debug)] pub struct DbFile { @@ -14,21 +14,20 @@ impl TrapEntry for DbFile { std::mem::replace(&mut self.id, TrapId::Star) } - fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { - write!(out, "db_files({id})\n")?; - write!(out, "files({id}, {})\n", quoted(&self.name))?; - Ok(()) + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("db_files", vec![trap::Arg::Label(id)]); + out.add_tuple("files", vec![trap::Arg::Label(id), self.name.into()]); } } #[derive(Debug)] pub struct DbLocation { pub id: TrapId, - pub file: TrapLabel, - pub start_line: u32, - pub start_column: u32, - pub end_line: u32, - pub end_column: u32, + pub file: trap::Label, + pub start_line: usize, + pub start_column: usize, + pub end_line: usize, + pub end_column: usize, } impl TrapEntry for DbLocation { @@ -36,17 +35,16 @@ impl TrapEntry for DbLocation { std::mem::replace(&mut self.id, TrapId::Star) } - fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { - write!(out, "db_locations({id})\n")?; - write!(out, "locations({id}, {}, {}, {}, {}, {})\n", self.file, self.start_line, self.start_column, self.end_line, self.end_column)?; - Ok(()) + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("db_locations", vec![trap::Arg::Label(id)]); + out.add_tuple("locations", vec![trap::Arg::Label(id), self.file.into(), self.start_line.into(), self.start_column.into(), self.end_line.into(), self.end_column.into()]); } } #[derive(Debug)] pub struct Function { pub id: TrapId, - pub location: Option, + pub location: Option, pub name: String, } @@ -55,20 +53,19 @@ impl TrapEntry for Function { std::mem::replace(&mut self.id, TrapId::Star) } - fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { - write!(out, "functions({id}, {})\n", quoted(&self.name))?; - if let Some(ref v) = &self.location { - write!(out, "locatable_locations({id}, {})\n", v)?; + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("functions", vec![trap::Arg::Label(id), self.name.into()]); + if let Some(v) = self.location { + out.add_tuple("locatable_locations", vec![trap::Arg::Label(id), v.into()]); } - Ok(()) } } #[derive(Debug)] pub struct Module { pub id: TrapId, - pub location: Option, - pub declarations: Vec, + pub location: Option, + pub declarations: Vec, } impl TrapEntry for Module { @@ -76,14 +73,13 @@ impl TrapEntry for Module { std::mem::replace(&mut self.id, TrapId::Star) } - fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()> { - write!(out, "modules({id})\n")?; - if let Some(ref v) = &self.location { - write!(out, "locatable_locations({id}, {})\n", v)?; + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("modules", vec![trap::Arg::Label(id)]); + if let Some(v) = self.location { + out.add_tuple("locatable_locations", vec![trap::Arg::Label(id), v.into()]); } - for (i, &ref v) in self.declarations.iter().enumerate() { - write!(out, "module_declarations({id}, {}, {})\n", i, v)?; + for (i, &v) in self.declarations.iter().enumerate() { + out.add_tuple("module_declarations", vec![trap::Arg::Label(id), i.into(), v.into()]); } - Ok(()) } } diff --git a/rust/extractor/src/main.rs b/rust/extractor/src/main.rs index cb8d3f2deb2..ff98d58c314 100644 --- a/rust/extractor/src/main.rs +++ b/rust/extractor/src/main.rs @@ -35,21 +35,14 @@ fn main() -> anyhow::Result<()> { prefill_caches: false, }; for input in cfg.inputs { - let path = fs::canonicalize(input)?; - { - let mut trap = traps.create("input", &path)?; - let name = String::from(path.to_string_lossy()); - trap.emit(generated::DbFile { id: name.clone().into(), name })?; - archiver.archive(&path); - } - load_workspace_at(&path, &config, &load_config, &no_progress)?; - let (db, vfs, _macro_server) = load_workspace_at(&path, &config, &load_config, &no_progress)?; + load_workspace_at(&input, &config, &load_config, &no_progress)?; + let (db, vfs, _macro_server) = load_workspace_at(&input, &config, &load_config, &no_progress)?; let crates = ::crate_graph(&db); for crate_id in crates.iter().take(1) { let krate = Crate::from(crate_id); let name = krate.display_name(&db); let crate_name = name.as_ref().map(|n| n.canonical_name().as_str()).unwrap_or(""); - let trap = traps.create("crates", &PathBuf::from(format!("/{}_{}", crate_name, crate_id.into_raw().into_u32())))?; + let trap = traps.create("crates", &PathBuf::from(format!("/{}_{}", crate_name, crate_id.into_raw().into_u32()))); translate::CrateTranslator::new( &db, trap, diff --git a/rust/extractor/src/translate.rs b/rust/extractor/src/translate.rs index b30ff5f8acc..505abf1044b 100644 --- a/rust/extractor/src/translate.rs +++ b/rust/extractor/src/translate.rs @@ -1,11 +1,10 @@ use std::collections::HashMap; use std::fs; use std::path::{PathBuf}; -use crate::trap::{TrapFile, TrapId, TrapLabel}; +use crate::trap::{TrapFile, TrapId, AsTrapKeyPart}; use crate::{generated, trap_key}; use ra_ap_hir::{Crate, Module, ModuleDef}; use anyhow; -use ra_ap_base_db::{CrateId}; use ra_ap_hir::{HasSource}; use ra_ap_vfs::{AbsPath, FileId, Vfs}; use ra_ap_syntax::ast::HasName; @@ -15,10 +14,11 @@ use triomphe::Arc; use ra_ap_ide_db::{LineIndexDatabase, RootDatabase}; use ra_ap_ide_db::line_index::LineIndex; use ra_ap_syntax::AstNode; +use codeql_extractor::trap; #[derive(Clone)] struct FileData { - label: TrapLabel, + label: trap::Label, line_index: Arc, } pub struct CrateTranslator<'a> { @@ -49,55 +49,47 @@ impl CrateTranslator<'_> { } } - fn emit_file(&mut self, file_id: FileId) -> Result> { - if let Some(abs_path) = self.vfs.file_path(file_id).as_path() { + fn emit_file(&mut self, file_id: FileId) -> Option { + self.vfs.file_path(file_id).as_path().and_then(|abs_path| { let mut canonical = PathBuf::from(abs_path.as_str()); if !self.file_labels.contains_key(&canonical) { self.archiver.archive(&canonical); canonical = fs::canonicalize(&canonical).unwrap_or(canonical); let name = canonical.to_string_lossy(); - let label = self.trap.emit(generated::DbFile { id: trap_key!["DbFile@", name.as_ref()], name: String::from(name) })?; + let label = self.trap.emit(generated::DbFile { id: trap_key!["file;", name.as_ref()], name: String::from(name) }); let line_index = ::line_index(self.db, file_id); self.file_labels.insert(canonical.clone(), FileData { label, line_index }); } - Ok(self.file_labels.get(&canonical).cloned()) - } else { - Ok(None) - } + self.file_labels.get(&canonical).cloned() + }) } - fn emit_location(&mut self, entity: T) -> Result> where T::Ast: AstNode { - if let Some(source) = entity.source(self.db) { - if let Some(file_id) = source.file_id.file_id().map(|f| f.file_id()) { - if let Some(data) = self.emit_file(file_id)? { - let range = source.value.syntax().text_range(); - let start = data.line_index.line_col(range.start()); - let end = data.line_index.line_col(range.end()); - return Ok(Some(self.trap.emit(generated::DbLocation { - id: trap_key![data.label, ":", start.line, ":", start.col, ":", end.line, ":", end.col], - file: data.label, - start_line: start.line, - start_column: start.col, - end_line: end.line, - end_column: end.col, - })?)); - } - } - } - Ok(None) + fn emit_location(&mut self, entity: T) -> Option + where + T::Ast: AstNode, + { + entity.source(self.db) + .and_then(|source| source.file_id.file_id().map(|f| (f.file_id(), source))) + .and_then(|(file_id, source)| self.emit_file(file_id).map(|data| (data, source))) + .and_then(|(data, source)| { + let range = source.value.syntax().text_range(); + let start = data.line_index.line_col(range.start()); + let end = data.line_index.line_col(range.end()); + Some(self.trap.emit_location(data.label, start, end)) + }) } - fn emit_definition(&mut self, module_label: TrapLabel, id: ModuleDef, labels: &mut Vec) -> Result<()> { + fn emit_definition(&mut self, module_label: trap::Label, id: ModuleDef, labels: &mut Vec) { match id { ModuleDef::Module(_) => {} ModuleDef::Function(function) => { let name = function.name(self.db); - let location = self.emit_location(function)?; + let location = self.emit_location(function); labels.push(self.trap.emit(generated::Function { id: trap_key![module_label, name.as_str()], location, name: name.as_str().into(), - })?); + })); } ModuleDef::Adt(_) => {} ModuleDef::Variant(_) => {} @@ -109,25 +101,23 @@ impl CrateTranslator<'_> { ModuleDef::BuiltinType(_) => {} ModuleDef::Macro(_) => {} } - Ok(()) } - fn emit_module(&mut self, label: TrapLabel, module: Module) -> Result<()> { + fn emit_module(&mut self, label: trap::Label, module: Module) { let mut children = Vec::new(); for id in module.declarations(self.db) { - self.emit_definition(label, id, &mut children)?; + self.emit_definition(label, id, &mut children); } self.trap.emit(generated::Module { id: label.into(), location: None, declarations: children, - })?; - Ok(()) + }); } - pub fn emit_crate(&mut self) -> Result<()> { - self.emit_file(self.krate.root_file(self.db))?; - let mut map = HashMap::::new(); + pub fn emit_crate(&mut self) -> std::io::Result<()> { + self.emit_file(self.krate.root_file(self.db)); + let mut map = HashMap::::new(); for module in self.krate.modules(self.db) { let mut key = String::new(); if let Some(parent) = module.parent(self.db) { @@ -137,17 +127,17 @@ impl CrateTranslator<'_> { } let def = module.definition_source(self.db); if let Some(file) = def.file_id.file_id() { - if let Some(data) = self.emit_file(file.file_id())? { + if let Some(data) = self.emit_file(file.file_id()) { key.push_str(&data.label.as_key_part()); } } if let Some(name) = module.name(self.db) { key.push_str(name.as_str()); } - let label = self.trap.label(TrapId::Key(key))?; + let label = self.trap.label(TrapId::Key(key)); map.insert(module, label); - self.emit_module(label, module)?; + self.emit_module(label, module); } - Ok(()) + self.trap.commit() } } diff --git a/rust/extractor/src/trap.rs b/rust/extractor/src/trap.rs index ea5be477370..f79be500d67 100644 --- a/rust/extractor/src/trap.rs +++ b/rust/extractor/src/trap.rs @@ -5,35 +5,39 @@ use std::io::Write; use std::path::{Path, PathBuf}; use log::{debug, trace}; use crate::{config, path}; - -#[derive(Clone, Copy)] -pub struct TrapLabel(u64); - -impl Debug for TrapLabel { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "TrapLabel({:x})", self.0) - } -} - -impl Display for TrapLabel { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "#{:x}", self.0) - } -} +use codeql_extractor::trap; +use ra_ap_ide_db::line_index::LineCol; +use crate::config::Compression; +use crate::generated; //TODO: typed labels +pub trait AsTrapKeyPart { + fn as_key_part(&self) -> String; +} -impl TrapLabel { - pub fn as_key_part(&self) -> String { +impl AsTrapKeyPart for trap::Label { + fn as_key_part(&self) -> String { format!("{{{}}}", self) } } +impl AsTrapKeyPart for String { + fn as_key_part(&self) -> String { + self.clone() + } +} + +impl AsTrapKeyPart for &str { + fn as_key_part(&self) -> String { + String::from(*self) + } +} + #[derive(Debug, Clone)] pub enum TrapId { Star, Key(String), - Label(TrapLabel), + Label(trap::Label), } impl From for TrapId { @@ -48,8 +52,8 @@ impl From<&str> for TrapId { } } -impl From for TrapId { - fn from(value: TrapLabel) -> Self { +impl From for TrapId { + fn from(value: trap::Label) -> Self { TrapId::Label(value) } } @@ -57,12 +61,6 @@ impl From for TrapId { #[macro_export] macro_rules! trap_key { ($($x:expr),+ $(,)?) => {{ - trait BlanketKeyPart: std::fmt::Display { - fn as_key_part(&self) -> String { - format!("{}", self) - } - } - impl BlanketKeyPart for T {} let mut key = String::new(); $( key.push_str(&$x.as_key_part()); @@ -71,80 +69,63 @@ macro_rules! trap_key { }}; } -impl Display for TrapId { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - TrapId::Star => write!(f, "*"), - TrapId::Key(k) => write!(f, "@{}", quoted(k)), - TrapId::Label(l) => Display::fmt(&l, f) - } - } -} - -pub fn escaped(s: &str) -> String { - s.replace("\"", "\"\"") -} - -pub fn quoted(s: &str) -> String { - format!("\"{}\"", escaped(s)) -} - - pub trait TrapEntry: std::fmt::Debug { fn extract_id(&mut self) -> TrapId; - fn emit(self, id: TrapLabel, out: &mut W) -> std::io::Result<()>; + fn emit(self, id: trap::Label, out: &mut trap::Writer); } -#[derive(Debug)] pub struct TrapFile { - label_index: u64, - file: File, - trap_name: String, + path: PathBuf, + writer: trap::Writer, + compression: Compression, } impl TrapFile { - pub fn comment(&mut self, message: &str) -> std::io::Result<()> { - for part in message.split("\n") { - trace!("emit -> {}: // {part}", self.trap_name); - write!(self.file, "// {part}\n")?; - } - Ok(()) - } - - pub fn label(&mut self, mut id: TrapId) -> std::io::Result { - match id { - TrapId::Star => {} - TrapId::Key(ref s) => { - if s.is_empty() { - id = TrapId::Star; - } - } - TrapId::Label(l) => { - return Ok(l); - } - } - let ret = self.create_label(); - trace!("emit -> {}: {ret:?} = {id:?}", self.trap_name); - write!(self.file, "{ret}={id}\n")?; - Ok(ret) - } - - pub fn emit(&mut self, mut entry: T) -> std::io::Result { - trace!("emit -> {}: {entry:?}", self.trap_name); - let id = self.label(entry.extract_id())?; - entry.emit(id, &mut self.file)?; - Ok(id) - } - - fn create_label(&mut self) -> TrapLabel { - let ret = TrapLabel(self.label_index); - self.label_index += 1; + pub fn emit_location(&mut self, file_label: trap::Label, start: LineCol, end: LineCol) -> trap::Label { + let start_line = start.line as usize; + let start_column = start.col as usize; + let end_line = end.line as usize; + let end_column = end.col as usize; + let (ret, _) = self.writer.location_label(trap::Location { + start_line, + start_column, + end_line, + end_column, + }); + self.emit(generated::DbLocation { + id: ret.into(), + file: file_label, + start_line, + start_column, + end_line, + end_column, + }); ret } + + pub fn label(&mut self, id: TrapId) -> trap::Label { + match id { + TrapId::Star => self.writer.fresh_id(), + TrapId::Key(s) => self.writer.global_id(&s).0, + TrapId::Label(l) => l, + } + } + + pub fn emit(&mut self, mut e: T) -> trap::Label { + let label = self.label(e.extract_id()); + e.emit(label, &mut self.writer); + label + } + + pub fn commit(&self) -> std::io::Result<()> { + std::fs::create_dir_all(self.path.parent().unwrap())?; + self.writer.write_to_file(&self.path, self.compression.into()) + } } pub struct TrapFileProvider { trap_dir: PathBuf, + compression: Compression, } impl TrapFileProvider { @@ -152,27 +133,25 @@ impl TrapFileProvider { let trap_dir = cfg.trap_dir.clone(); std::fs::create_dir_all(&trap_dir)?; Ok(TrapFileProvider { - trap_dir + trap_dir, + compression: cfg.compression, }) } - pub fn create(&self, category: &str, key: &Path) -> std::io::Result { + pub fn create(&self, category: &str, key: &Path) -> TrapFile { let mut path = PathBuf::from(category); path.push(path::key(key)); path.set_extension(path.extension().map(|e| { - let mut o : OsString = e.to_owned(); + let mut o: OsString = e.to_owned(); o.push(".trap"); o }).unwrap_or("trap".into())); - let trap_name = String::from(path.to_string_lossy()); - debug!("creating trap file {}", trap_name); + debug!("creating trap file {}", path.display()); path = self.trap_dir.join(path); - std::fs::create_dir_all(path.parent().unwrap())?; - let file = File::create(path)?; - Ok(TrapFile { - label_index: 0, - file, - trap_name, - }) + TrapFile { + path, + writer: trap::Writer::new(), + compression: self.compression, + } } } diff --git a/shared/tree-sitter-extractor/src/trap.rs b/shared/tree-sitter-extractor/src/trap.rs index 64c06539ecb..5e0c80615e1 100644 --- a/shared/tree-sitter-extractor/src/trap.rs +++ b/shared/tree-sitter-extractor/src/trap.rs @@ -136,10 +136,16 @@ impl fmt::Display for Entry { } } -#[derive(Debug, Copy, Clone)] +#[derive(Copy, Clone)] // Identifiers of the form #0, #1... pub struct Label(u32); +impl fmt::Debug for Label { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Label({:#x})", self.0) + } +} + impl fmt::Display for Label { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "#{:x}", self.0) @@ -170,6 +176,30 @@ impl fmt::Display for Arg { } } +impl From for Arg { + fn from(value: String) -> Self { + Arg::String(value) + } +} + +impl From<&str> for Arg { + fn from(value: &str) -> Self { + Arg::String(value.into()) + } +} + +impl From