mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Merge branch 'main' into redsun82/bzlmod
This commit is contained in:
@@ -75,7 +75,7 @@ namespace Semmle.Autobuild.Shared
|
||||
return defaultValue;
|
||||
|
||||
return value.
|
||||
Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).
|
||||
Split(FileUtils.NewLineCharacters, StringSplitOptions.RemoveEmptyEntries).
|
||||
Select(s => AsStringWithExpandedEnvVars(s, actions)).ToArray();
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
try
|
||||
{
|
||||
this.dotnet = DotNet.Make(options, logger, tempWorkingDirectory);
|
||||
runtimeLazy = new Lazy<Runtime>(() => new Runtime(dotnet));
|
||||
runtimeLazy = new Lazy<Runtime>(() => new Runtime(dotnet, logger));
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -112,7 +112,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
logger.LogInfo($"Unresolved reference {r.Key} in project {r.Value}");
|
||||
}
|
||||
|
||||
var webViewExtractionOption = Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_STANDALONE_EXTRACT_WEB_VIEWS");
|
||||
var webViewExtractionOption = Environment.GetEnvironmentVariable(EnvironmentVariableNames.WebViewGeneration);
|
||||
if (webViewExtractionOption == null ||
|
||||
bool.TryParse(webViewExtractionOption, out var shouldExtractWebViews) &&
|
||||
shouldExtractWebViews)
|
||||
@@ -159,6 +159,53 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
var frameworkLocations = new HashSet<string>();
|
||||
|
||||
var frameworkReferences = Environment.GetEnvironmentVariable(EnvironmentVariableNames.DotnetFrameworkReferences);
|
||||
var frameworkReferencesUseSubfolders = Environment.GetEnvironmentVariable(EnvironmentVariableNames.DotnetFrameworkReferencesUseSubfolders);
|
||||
_ = bool.TryParse(frameworkReferencesUseSubfolders, out var useSubfolders);
|
||||
if (!string.IsNullOrWhiteSpace(frameworkReferences))
|
||||
{
|
||||
RemoveFrameworkNugetPackages(dllPaths);
|
||||
RemoveNugetPackageReference(FrameworkPackageNames.AspNetCoreFramework, dllPaths);
|
||||
RemoveNugetPackageReference(FrameworkPackageNames.WindowsDesktopFramework, dllPaths);
|
||||
|
||||
var frameworkPaths = frameworkReferences.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach (var path in frameworkPaths)
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
logger.LogError($"Specified framework reference path '{path}' does not exist.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (useSubfolders)
|
||||
{
|
||||
dllPaths.Add(path);
|
||||
frameworkLocations.Add(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var dlls = Directory.GetFiles(path, "*.dll", new EnumerationOptions { RecurseSubdirectories = false, MatchCasing = MatchCasing.CaseInsensitive });
|
||||
if (dlls.Length == 0)
|
||||
{
|
||||
logger.LogError($"No DLLs found in specified framework reference path '{path}'.");
|
||||
continue;
|
||||
}
|
||||
|
||||
dllPaths.UnionWith(dlls);
|
||||
frameworkLocations.UnionWith(dlls);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError($"Error while searching for DLLs in '{path}': {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return frameworkLocations;
|
||||
}
|
||||
|
||||
AddNetFrameworkDlls(dllPaths, frameworkLocations);
|
||||
AddAspNetCoreFrameworkDlls(dllPaths, frameworkLocations);
|
||||
AddMicrosoftWindowsDesktopDlls(dllPaths, frameworkLocations);
|
||||
@@ -204,9 +251,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
nugetPackageDllPaths.ExceptWith(excludedPaths);
|
||||
dllPaths.UnionWith(nugetPackageDllPaths);
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogError("Failed to restore Nuget packages with nuget.exe");
|
||||
logger.LogError($"Failed to restore Nuget packages with nuget.exe: {exc.Message}");
|
||||
}
|
||||
|
||||
var restoredProjects = RestoreSolutions(allSolutions, out var assets1);
|
||||
@@ -297,6 +344,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private void RemoveFrameworkNugetPackages(ISet<string> dllPaths, int fromIndex = 0)
|
||||
{
|
||||
var packagesInPrioOrder = FrameworkPackageNames.NetFrameworks;
|
||||
for (var i = fromIndex; i < packagesInPrioOrder.Length; i++)
|
||||
{
|
||||
RemoveNugetPackageReference(packagesInPrioOrder[i], dllPaths);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddNetFrameworkDlls(ISet<string> dllPaths, ISet<string> frameworkLocations)
|
||||
{
|
||||
// Multiple dotnet framework packages could be present.
|
||||
@@ -304,7 +360,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
var packagesInPrioOrder = FrameworkPackageNames.NetFrameworks;
|
||||
|
||||
var frameworkPaths = packagesInPrioOrder
|
||||
.Select((s, index) => (Index: index, Path: GetPackageDirectory(s)))
|
||||
.Select((s, index) => (Index: index, Path: GetPackageDirectory(s, packageDirectory)))
|
||||
.Where(pair => pair.Path is not null)
|
||||
.ToArray();
|
||||
|
||||
@@ -318,12 +374,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
|
||||
SelectNewestFrameworkPath(frameworkPath.Path, ".NET Framework", dllPaths, frameworkLocations);
|
||||
|
||||
for (var i = frameworkPath.Index + 1; i < packagesInPrioOrder.Length; i++)
|
||||
{
|
||||
RemoveNugetPackageReference(packagesInPrioOrder[i], dllPaths);
|
||||
}
|
||||
|
||||
RemoveFrameworkNugetPackages(dllPaths, frameworkPath.Index + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -336,6 +387,16 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
else if (fileContent.IsLegacyProjectStructureUsed)
|
||||
{
|
||||
runtimeLocation = Runtime.DesktopRuntime;
|
||||
|
||||
if (runtimeLocation is null)
|
||||
{
|
||||
logger.LogInfo("No .NET Desktop Runtime location found. Attempting to restore the .NET Framework reference assemblies manually.");
|
||||
|
||||
if (TryRestorePackageManually(FrameworkPackageNames.LatestNetFrameworkReferenceAssemblies, null))
|
||||
{
|
||||
runtimeLocation = GetPackageDirectory(FrameworkPackageNames.LatestNetFrameworkReferenceAssemblies, missingPackageDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runtimeLocation ??= Runtime.ExecutingRuntime;
|
||||
@@ -375,7 +436,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
|
||||
// First try to find ASP.NET Core assemblies in the NuGet packages
|
||||
if (GetPackageDirectory(FrameworkPackageNames.AspNetCoreFramework) is string aspNetCorePackage)
|
||||
if (GetPackageDirectory(FrameworkPackageNames.AspNetCoreFramework, packageDirectory) is string aspNetCorePackage)
|
||||
{
|
||||
SelectNewestFrameworkPath(aspNetCorePackage, "ASP.NET Core", dllPaths, frameworkLocations);
|
||||
return;
|
||||
@@ -391,15 +452,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
private void AddMicrosoftWindowsDesktopDlls(ISet<string> dllPaths, ISet<string> frameworkLocations)
|
||||
{
|
||||
if (GetPackageDirectory(FrameworkPackageNames.WindowsDesktopFramework) is string windowsDesktopApp)
|
||||
if (GetPackageDirectory(FrameworkPackageNames.WindowsDesktopFramework, packageDirectory) is string windowsDesktopApp)
|
||||
{
|
||||
SelectNewestFrameworkPath(windowsDesktopApp, "Windows Desktop App", dllPaths, frameworkLocations);
|
||||
}
|
||||
}
|
||||
|
||||
private string? GetPackageDirectory(string packagePrefix)
|
||||
private string? GetPackageDirectory(string packagePrefix, TemporaryDirectory root)
|
||||
{
|
||||
return new DirectoryInfo(packageDirectory.DirInfo.FullName)
|
||||
return new DirectoryInfo(root.DirInfo.FullName)
|
||||
.EnumerateDirectories(packagePrefix + "*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
|
||||
.FirstOrDefault()?
|
||||
.FullName;
|
||||
@@ -435,19 +496,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
|
||||
// Hardcoded values from https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#implicit-using-directives
|
||||
usings.UnionWith(new[] { "System", "System.Collections.Generic", "System.IO", "System.Linq", "System.Net.Http", "System.Threading",
|
||||
"System.Threading.Tasks" });
|
||||
usings.UnionWith([ "System", "System.Collections.Generic", "System.IO", "System.Linq", "System.Net.Http", "System.Threading",
|
||||
"System.Threading.Tasks" ]);
|
||||
|
||||
if (fileContent.UseAspNetCoreDlls)
|
||||
{
|
||||
usings.UnionWith(new[] { "System.Net.Http.Json", "Microsoft.AspNetCore.Builder", "Microsoft.AspNetCore.Hosting",
|
||||
usings.UnionWith([ "System.Net.Http.Json", "Microsoft.AspNetCore.Builder", "Microsoft.AspNetCore.Hosting",
|
||||
"Microsoft.AspNetCore.Http", "Microsoft.AspNetCore.Routing", "Microsoft.Extensions.Configuration",
|
||||
"Microsoft.Extensions.DependencyInjection", "Microsoft.Extensions.Hosting", "Microsoft.Extensions.Logging" });
|
||||
"Microsoft.Extensions.DependencyInjection", "Microsoft.Extensions.Hosting", "Microsoft.Extensions.Logging" ]);
|
||||
}
|
||||
|
||||
if (fileContent.UseWindowsForms)
|
||||
{
|
||||
usings.UnionWith(new[] { "System.Drawing", "System.Windows.Forms" });
|
||||
usings.UnionWith(["System.Drawing", "System.Windows.Forms"]);
|
||||
}
|
||||
|
||||
usings.UnionWith(fileContent.CustomImplicitUsings);
|
||||
@@ -869,38 +930,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
Parallel.ForEach(notYetDownloadedPackages, new ParallelOptions { MaxDegreeOfParallelism = options.Threads }, package =>
|
||||
{
|
||||
logger.LogInfo($"Restoring package {package}...");
|
||||
using var tempDir = new TemporaryDirectory(ComputeTempDirectory(package, "missingpackages_workingdir"));
|
||||
var success = dotnet.New(tempDir.DirInfo.FullName);
|
||||
var success = TryRestorePackageManually(package, nugetConfig);
|
||||
if (!success)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
success = dotnet.AddPackage(tempDir.DirInfo.FullName, package);
|
||||
if (!success)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var res = dotnet.Restore(new(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: false, PathToNugetConfig: nugetConfig));
|
||||
if (!res.Success)
|
||||
{
|
||||
if (res.HasNugetPackageSourceError)
|
||||
{
|
||||
// Restore could not be completed because the listed source is unavailable. Try without the nuget.config:
|
||||
res = dotnet.Restore(new(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: false, PathToNugetConfig: null, ForceReevaluation: true));
|
||||
}
|
||||
|
||||
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
|
||||
|
||||
if (!res.Success)
|
||||
{
|
||||
logger.LogInfo($"Failed to restore nuget package {package}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lock (sync)
|
||||
{
|
||||
successCount++;
|
||||
@@ -912,6 +947,43 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
dllPaths.Add(missingPackageDirectory.DirInfo.FullName);
|
||||
}
|
||||
|
||||
private bool TryRestorePackageManually(string package, string? nugetConfig)
|
||||
{
|
||||
logger.LogInfo($"Restoring package {package}...");
|
||||
using var tempDir = new TemporaryDirectory(ComputeTempDirectory(package, "missingpackages_workingdir"));
|
||||
var success = dotnet.New(tempDir.DirInfo.FullName);
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
success = dotnet.AddPackage(tempDir.DirInfo.FullName, package);
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var res = dotnet.Restore(new(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: false, PathToNugetConfig: nugetConfig));
|
||||
if (!res.Success)
|
||||
{
|
||||
if (res.HasNugetPackageSourceError && nugetConfig is not null)
|
||||
{
|
||||
// Restore could not be completed because the listed source is unavailable. Try without the nuget.config:
|
||||
res = dotnet.Restore(new(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: false, PathToNugetConfig: null, ForceReevaluation: true));
|
||||
}
|
||||
|
||||
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
|
||||
|
||||
if (!res.Success)
|
||||
{
|
||||
logger.LogInfo($"Failed to restore nuget package {package}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Dispose(TemporaryDirectory? dir, string name)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal class EnvironmentVariableNames
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls whether to generate source files from Asp.Net Core views (`.cshtml`, `.razor`).
|
||||
/// </summary>
|
||||
public const string WebViewGeneration = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_EXTRACT_WEB_VIEWS";
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the location of .Net framework references added to the compilation.
|
||||
/// </summary>
|
||||
public const string DotnetFrameworkReferences = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_DOTNET_FRAMEWORK_REFERENCES";
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether to use framework dependencies from subfolders.
|
||||
/// </summary>
|
||||
public const string DotnetFrameworkReferencesUseSubfolders = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_DOTNET_FRAMEWORK_REFERENCES_USE_SUBFOLDERS";
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
public IEnumerable<FileInfo> Filter(IEnumerable<FileInfo> files)
|
||||
{
|
||||
var filters = (Environment.GetEnvironmentVariable("LGTM_INDEX_FILTERS") ?? string.Empty).Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var filters = (Environment.GetEnvironmentVariable("LGTM_INDEX_FILTERS") ?? string.Empty).Split(FileUtils.NewLineCharacters, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (filters.Length == 0)
|
||||
{
|
||||
return files;
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal static class FrameworkPackageNames
|
||||
{
|
||||
public static string LatestNetFrameworkReferenceAssemblies { get; } = "microsoft.netframework.referenceassemblies.net481";
|
||||
|
||||
public static string AspNetCoreFramework { get; } = "microsoft.aspnetcore.app.ref";
|
||||
|
||||
public static string WindowsDesktopFramework { get; } = "microsoft.windowsdesktop.app.ref";
|
||||
|
||||
// The order of the packages is important.
|
||||
public static string[] NetFrameworks { get; } = new string[]
|
||||
{
|
||||
public static string[] NetFrameworks { get; } =
|
||||
[
|
||||
"microsoft.netcore.app.ref", // net7.0, ... net5.0, netcoreapp3.1, netcoreapp3.0
|
||||
"microsoft.netframework.referenceassemblies.", // net48, ..., net20
|
||||
"netstandard.library.ref", // netstandard2.1
|
||||
"netstandard.library" // netstandard2.0
|
||||
};
|
||||
];
|
||||
|
||||
public static IEnumerable<string> AllFrameworks { get; } =
|
||||
NetFrameworks
|
||||
.Union(new string[] { AspNetCoreFramework, WindowsDesktopFramework });
|
||||
[.. NetFrameworks, AspNetCoreFramework, WindowsDesktopFramework];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
var args = new StringBuilder();
|
||||
args.Append($"/target:exe /generatedfilesout:\"{outputFolder}\" /out:\"{dllPath}\" /analyzerconfig:\"{analyzerConfig}\" ");
|
||||
|
||||
foreach (var f in Directory.GetFiles(sourceGeneratorFolder, "*.dll"))
|
||||
foreach (var f in Directory.GetFiles(sourceGeneratorFolder, "*.dll", new EnumerationOptions { RecurseSubdirectories = false, MatchCasing = MatchCasing.CaseInsensitive }))
|
||||
{
|
||||
args.Append($"/analyzer:\"{f}\" ");
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
@@ -17,12 +18,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private const string aspNetCoreApp = "Microsoft.AspNetCore.App";
|
||||
|
||||
private readonly IDotNet dotNet;
|
||||
private readonly ILogger logger;
|
||||
private readonly Lazy<Dictionary<string, DotNetVersion>> newestRuntimes;
|
||||
private Dictionary<string, DotNetVersion> NewestRuntimes => newestRuntimes.Value;
|
||||
|
||||
public Runtime(IDotNet dotNet)
|
||||
public Runtime(IDotNet dotNet, ILogger logger)
|
||||
{
|
||||
this.dotNet = dotNet;
|
||||
this.logger = logger;
|
||||
this.newestRuntimes = new(GetNewestRuntimes);
|
||||
}
|
||||
|
||||
@@ -65,7 +68,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// Locates .NET Desktop Runtimes.
|
||||
/// This includes Mono and Microsoft.NET.
|
||||
/// </summary>
|
||||
private static IEnumerable<string> DesktopRuntimes
|
||||
private IEnumerable<string> DesktopRuntimes
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -76,20 +79,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
|
||||
var monoPath = FileUtils.FindProgramOnPath(Win32.IsWindows() ? "mono.exe" : "mono");
|
||||
var monoDirs = monoPath is not null
|
||||
? new[] { Path.GetFullPath(Path.Combine(monoPath, "..", "lib", "mono")), monoPath }
|
||||
: new[] { "/usr/lib/mono", "/usr/local/mono", "/usr/local/bin/mono", @"C:\Program Files\Mono\lib\mono" };
|
||||
string[] monoDirs = monoPath is not null
|
||||
? [Path.GetFullPath(Path.Combine(monoPath, "..", "lib", "mono")), monoPath]
|
||||
: ["/usr/lib/mono", "/usr/local/mono", "/usr/local/bin/mono", @"C:\Program Files\Mono\lib\mono"];
|
||||
|
||||
var dir = monoDirs.FirstOrDefault(Directory.Exists);
|
||||
|
||||
if (dir is not null)
|
||||
var monoDir = monoDirs.FirstOrDefault(Directory.Exists);
|
||||
if (monoDir is not null)
|
||||
{
|
||||
return Directory.EnumerateDirectories(dir)
|
||||
.Where(d => Char.IsDigit(Path.GetFileName(d)[0]))
|
||||
return Directory.EnumerateDirectories(monoDir)
|
||||
.Where(d => char.IsDigit(Path.GetFileName(d)[0]))
|
||||
.OrderByDescending(Path.GetFileName);
|
||||
}
|
||||
|
||||
return Enumerable.Empty<string>();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -386,7 +386,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
if (compilerArguments.GeneratedFilesOutputDirectory is not null)
|
||||
{
|
||||
paths.AddRange(Directory.GetFiles(compilerArguments.GeneratedFilesOutputDirectory, "*.cs", SearchOption.AllDirectories));
|
||||
paths.AddRange(Directory.GetFiles(compilerArguments.GeneratedFilesOutputDirectory, "*.cs", new EnumerationOptions { RecurseSubdirectories = true, MatchCasing = MatchCasing.CaseInsensitive }));
|
||||
}
|
||||
|
||||
return ReadSyntaxTrees(
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Semmle.Extraction.Tests
|
||||
"Microsoft.NETCore.App 7.0.2 [/path/dotnet/shared/Microsoft.NETCore.App]"
|
||||
};
|
||||
var dotnet = new DotNetStub(listedRuntimes, null!);
|
||||
var runtime = new Runtime(dotnet);
|
||||
var runtime = new Runtime(dotnet, new LoggerStub());
|
||||
|
||||
// Execute
|
||||
var runtimes = runtime.GetNewestRuntimes();
|
||||
@@ -73,7 +73,7 @@ namespace Semmle.Extraction.Tests
|
||||
"Microsoft.NETCore.App 8.0.0-preview.5.23280.8 [/path/dotnet/shared/Microsoft.NETCore.App]"
|
||||
};
|
||||
var dotnet = new DotNetStub(listedRuntimes, null!);
|
||||
var runtime = new Runtime(dotnet);
|
||||
var runtime = new Runtime(dotnet, new LoggerStub());
|
||||
|
||||
// Execute
|
||||
var runtimes = runtime.GetNewestRuntimes();
|
||||
@@ -96,7 +96,7 @@ namespace Semmle.Extraction.Tests
|
||||
"Microsoft.NETCore.App 8.0.0-preview.5.23280.8 [/path/dotnet/shared/Microsoft.NETCore.App]"
|
||||
};
|
||||
var dotnet = new DotNetStub(listedRuntimes, null!);
|
||||
var runtime = new Runtime(dotnet);
|
||||
var runtime = new Runtime(dotnet, new LoggerStub());
|
||||
|
||||
// Execute
|
||||
var runtimes = runtime.GetNewestRuntimes();
|
||||
@@ -125,7 +125,7 @@ namespace Semmle.Extraction.Tests
|
||||
@"Microsoft.WindowsDesktop.App 7.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]"
|
||||
};
|
||||
var dotnet = new DotNetStub(listedRuntimes, null!);
|
||||
var runtime = new Runtime(dotnet);
|
||||
var runtime = new Runtime(dotnet, new LoggerStub());
|
||||
|
||||
// Execute
|
||||
var runtimes = runtime.GetNewestRuntimes();
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Semmle.Extraction
|
||||
.Where(s => s is not null)
|
||||
?? Enumerable.Empty<string>();
|
||||
|
||||
var additionalCsFiles = System.IO.Directory.GetFiles(directoryName, "*.cs", SearchOption.AllDirectories);
|
||||
var additionalCsFiles = System.IO.Directory.GetFiles(directoryName, "*.cs", new EnumerationOptions { RecurseSubdirectories = true, MatchCasing = MatchCasing.CaseInsensitive });
|
||||
|
||||
var projectReferences = root
|
||||
.SelectNodes("/Project/ItemGroup/ProjectReference/@Include", mgr)
|
||||
|
||||
@@ -13,6 +13,8 @@ namespace Semmle.Util
|
||||
{
|
||||
public const string NugetExeUrl = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe";
|
||||
|
||||
public static readonly char[] NewLineCharacters = ['\r', '\n'];
|
||||
|
||||
public static string ConvertToWindows(string path)
|
||||
{
|
||||
return path.Replace('/', '\\');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import os
|
||||
from create_database_utils import *
|
||||
|
||||
os.environ['CODEQL_EXTRACTOR_CSHARP_STANDALONE_EXTRACT_WEB_VIEWS'] = 'false'
|
||||
os.environ['CODEQL_EXTRACTOR_CSHARP_BUILDLESS_EXTRACT_WEB_VIEWS'] = 'false'
|
||||
run_codeql_database_create(lang="csharp", extra_args=["--extractor-option=buildless=true"])
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| /packages/newtonsoft.json/6.0.4/lib/net45/Newtonsoft.Json.dll |
|
||||
@@ -0,0 +1,15 @@
|
||||
import csharp
|
||||
|
||||
private string getPath(Assembly a) {
|
||||
not a.getCompilation().getOutputAssembly() = a and
|
||||
exists(string s | s = a.getFile().getAbsolutePath() |
|
||||
result =
|
||||
s.substring(s.indexOf("test-db/working/") + "test-db/working/".length() + 16, s.length())
|
||||
or
|
||||
result = s and
|
||||
not exists(s.indexOf("test-db/working/"))
|
||||
)
|
||||
}
|
||||
|
||||
from Assembly a
|
||||
select getPath(a)
|
||||
@@ -0,0 +1,6 @@
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.101"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net461" />
|
||||
<package id="NUnit.ConsoleRunner" version="3.12.0" />
|
||||
</packages>
|
||||
@@ -0,0 +1 @@
|
||||
Skipping the test on the ARM runners, as we're running into trouble with Mono and nuget.
|
||||
@@ -0,0 +1,5 @@
|
||||
from create_database_utils import *
|
||||
import os
|
||||
|
||||
os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_DOTNET_FRAMEWORK_REFERENCES"] = "/non-existent-path"
|
||||
run_codeql_database_create([], lang="csharp", extra_args=["--extractor-option=buildless=true"])
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
|
||||
<RemoveDir Directories=".\bin" />
|
||||
<RemoveDir Directories=".\obj" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="6.0.4" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* C#: Data flow via get only properties like `public object Obj { get; }` is now captured by the data flow library.
|
||||
@@ -127,6 +127,13 @@ class Property extends DotNet::Property, DeclarationWithGetSetAccessors, @proper
|
||||
properties(this, _, _, getTypeRef(result), _)
|
||||
}
|
||||
|
||||
private predicate isAutoPartial() {
|
||||
this.fromSource() and
|
||||
not this.isExtern() and
|
||||
not this.isAbstract() and
|
||||
not this.getAnAccessor().hasBody()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this property is automatically implemented. For example, `P1`
|
||||
* on line 2 is automatically implemented, while `P2` on line 5 is not in
|
||||
@@ -147,11 +154,22 @@ class Property extends DotNet::Property, DeclarationWithGetSetAccessors, @proper
|
||||
* code.
|
||||
*/
|
||||
predicate isAutoImplemented() {
|
||||
this.fromSource() and
|
||||
this.isReadWrite() and
|
||||
not this.isExtern() and
|
||||
not this.isAbstract() and
|
||||
not this.getAnAccessor().hasBody()
|
||||
this.isAutoPartial() and
|
||||
this.isReadWrite()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this property is automatically implemented and read-only. For
|
||||
* example, `P1` on line 2 is automatically implemented and read-only
|
||||
* ```csharp
|
||||
* class C {
|
||||
* public int P1 { get; }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
predicate isAutoImplementedReadOnly() {
|
||||
this.isAutoPartial() and
|
||||
this.isReadOnly()
|
||||
}
|
||||
|
||||
override Property getUnboundDeclaration() { properties(this, _, _, _, result) }
|
||||
|
||||
@@ -1899,6 +1899,8 @@ class FieldOrProperty extends Assignable, Modifiable {
|
||||
(
|
||||
p.isAutoImplemented()
|
||||
or
|
||||
p.isAutoImplementedReadOnly()
|
||||
or
|
||||
p.matchesHandle(any(CIL::TrivialProperty tp))
|
||||
or
|
||||
p.getDeclaringType() instanceof AnonymousClass
|
||||
|
||||
@@ -64,6 +64,20 @@ edges
|
||||
| Constructors.cs:112:25:112:27 | access to local variable o31 : Object | Constructors.cs:112:18:112:28 | object creation of type C3 : C3 [parameter o31param] : Object | provenance | |
|
||||
| Constructors.cs:113:14:113:15 | access to local variable c3 : C3 [parameter o31param] : Object | Constructors.cs:106:32:106:39 | this : C3 [parameter o31param] : Object | provenance | |
|
||||
| Constructors.cs:113:14:113:15 | access to local variable c3 : C3 [parameter o31param] : Object | Constructors.cs:113:14:113:21 | access to property Obj31 | provenance | |
|
||||
| Constructors.cs:121:26:121:28 | oc1 : Object | Constructors.cs:123:20:123:22 | access to parameter oc1 : Object | provenance | |
|
||||
| Constructors.cs:121:38:121:40 | oc2 : Object | Constructors.cs:124:20:124:22 | access to parameter oc2 : Object | provenance | |
|
||||
| Constructors.cs:123:20:123:22 | access to parameter oc1 : Object | Constructors.cs:123:13:123:16 | [post] this access : C4 [property Obj1] : Object | provenance | |
|
||||
| Constructors.cs:124:20:124:22 | access to parameter oc2 : Object | Constructors.cs:124:13:124:16 | [post] this access : C4 [property Obj2] : Object | provenance | |
|
||||
| Constructors.cs:130:18:130:34 | call to method Source<Object> : Object | Constructors.cs:132:25:132:26 | access to local variable o1 : Object | provenance | |
|
||||
| Constructors.cs:131:18:131:34 | call to method Source<Object> : Object | Constructors.cs:132:29:132:30 | access to local variable o2 : Object | provenance | |
|
||||
| Constructors.cs:132:18:132:31 | object creation of type C4 : C4 [property Obj1] : Object | Constructors.cs:133:14:133:15 | access to local variable c4 : C4 [property Obj1] : Object | provenance | |
|
||||
| Constructors.cs:132:18:132:31 | object creation of type C4 : C4 [property Obj2] : Object | Constructors.cs:134:14:134:15 | access to local variable c4 : C4 [property Obj2] : Object | provenance | |
|
||||
| Constructors.cs:132:25:132:26 | access to local variable o1 : Object | Constructors.cs:121:26:121:28 | oc1 : Object | provenance | |
|
||||
| Constructors.cs:132:25:132:26 | access to local variable o1 : Object | Constructors.cs:132:18:132:31 | object creation of type C4 : C4 [property Obj1] : Object | provenance | |
|
||||
| Constructors.cs:132:29:132:30 | access to local variable o2 : Object | Constructors.cs:121:38:121:40 | oc2 : Object | provenance | |
|
||||
| Constructors.cs:132:29:132:30 | access to local variable o2 : Object | Constructors.cs:132:18:132:31 | object creation of type C4 : C4 [property Obj2] : Object | provenance | |
|
||||
| Constructors.cs:133:14:133:15 | access to local variable c4 : C4 [property Obj1] : Object | Constructors.cs:133:14:133:20 | access to property Obj1 | provenance | |
|
||||
| Constructors.cs:134:14:134:15 | access to local variable c4 : C4 [property Obj2] : Object | Constructors.cs:134:14:134:20 | access to property Obj2 | provenance | |
|
||||
nodes
|
||||
| Constructors.cs:5:24:5:25 | [post] this access : C_no_ctor [field s1] : Object | semmle.label | [post] this access : C_no_ctor [field s1] : Object |
|
||||
| Constructors.cs:5:29:5:45 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object |
|
||||
@@ -134,6 +148,22 @@ nodes
|
||||
| Constructors.cs:112:25:112:27 | access to local variable o31 : Object | semmle.label | access to local variable o31 : Object |
|
||||
| Constructors.cs:113:14:113:15 | access to local variable c3 : C3 [parameter o31param] : Object | semmle.label | access to local variable c3 : C3 [parameter o31param] : Object |
|
||||
| Constructors.cs:113:14:113:21 | access to property Obj31 | semmle.label | access to property Obj31 |
|
||||
| Constructors.cs:121:26:121:28 | oc1 : Object | semmle.label | oc1 : Object |
|
||||
| Constructors.cs:121:38:121:40 | oc2 : Object | semmle.label | oc2 : Object |
|
||||
| Constructors.cs:123:13:123:16 | [post] this access : C4 [property Obj1] : Object | semmle.label | [post] this access : C4 [property Obj1] : Object |
|
||||
| Constructors.cs:123:20:123:22 | access to parameter oc1 : Object | semmle.label | access to parameter oc1 : Object |
|
||||
| Constructors.cs:124:13:124:16 | [post] this access : C4 [property Obj2] : Object | semmle.label | [post] this access : C4 [property Obj2] : Object |
|
||||
| Constructors.cs:124:20:124:22 | access to parameter oc2 : Object | semmle.label | access to parameter oc2 : Object |
|
||||
| Constructors.cs:130:18:130:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object |
|
||||
| Constructors.cs:131:18:131:34 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object |
|
||||
| Constructors.cs:132:18:132:31 | object creation of type C4 : C4 [property Obj1] : Object | semmle.label | object creation of type C4 : C4 [property Obj1] : Object |
|
||||
| Constructors.cs:132:18:132:31 | object creation of type C4 : C4 [property Obj2] : Object | semmle.label | object creation of type C4 : C4 [property Obj2] : Object |
|
||||
| Constructors.cs:132:25:132:26 | access to local variable o1 : Object | semmle.label | access to local variable o1 : Object |
|
||||
| Constructors.cs:132:29:132:30 | access to local variable o2 : Object | semmle.label | access to local variable o2 : Object |
|
||||
| Constructors.cs:133:14:133:15 | access to local variable c4 : C4 [property Obj1] : Object | semmle.label | access to local variable c4 : C4 [property Obj1] : Object |
|
||||
| Constructors.cs:133:14:133:20 | access to property Obj1 | semmle.label | access to property Obj1 |
|
||||
| Constructors.cs:134:14:134:15 | access to local variable c4 : C4 [property Obj2] : Object | semmle.label | access to local variable c4 : C4 [property Obj2] : Object |
|
||||
| Constructors.cs:134:14:134:20 | access to property Obj2 | semmle.label | access to property Obj2 |
|
||||
subpaths
|
||||
| Constructors.cs:64:37:64:37 | access to parameter o : Object | Constructors.cs:57:54:57:55 | o2 : Object | Constructors.cs:59:13:59:19 | SSA def(o1) : Object | Constructors.cs:64:27:64:34 | SSA def(o22param) : Object |
|
||||
| Constructors.cs:71:25:71:25 | access to local variable o : Object | Constructors.cs:41:26:41:26 | o : Object | Constructors.cs:41:32:41:34 | [post] this access : C1 [field Obj] : Object | Constructors.cs:71:18:71:26 | object creation of type C1 : C1 [field Obj] : Object |
|
||||
@@ -147,6 +177,8 @@ subpaths
|
||||
| Constructors.cs:101:14:101:15 | access to local variable c2 : C2 [parameter o22param] : Object | Constructors.cs:48:32:48:39 | this : C2 [parameter o22param] : Object | Constructors.cs:48:32:48:39 | access to parameter o22param : Object | Constructors.cs:101:14:101:21 | access to property Obj22 |
|
||||
| Constructors.cs:112:25:112:27 | access to local variable o31 : Object | Constructors.cs:104:28:104:35 | o31param : Object | Constructors.cs:104:28:104:35 | o31param : Object | Constructors.cs:112:18:112:28 | object creation of type C3 : C3 [parameter o31param] : Object |
|
||||
| Constructors.cs:113:14:113:15 | access to local variable c3 : C3 [parameter o31param] : Object | Constructors.cs:106:32:106:39 | this : C3 [parameter o31param] : Object | Constructors.cs:106:32:106:39 | access to parameter o31param : Object | Constructors.cs:113:14:113:21 | access to property Obj31 |
|
||||
| Constructors.cs:132:25:132:26 | access to local variable o1 : Object | Constructors.cs:121:26:121:28 | oc1 : Object | Constructors.cs:123:13:123:16 | [post] this access : C4 [property Obj1] : Object | Constructors.cs:132:18:132:31 | object creation of type C4 : C4 [property Obj1] : Object |
|
||||
| Constructors.cs:132:29:132:30 | access to local variable o2 : Object | Constructors.cs:121:38:121:40 | oc2 : Object | Constructors.cs:124:13:124:16 | [post] this access : C4 [property Obj2] : Object | Constructors.cs:132:18:132:31 | object creation of type C4 : C4 [property Obj2] : Object |
|
||||
#select
|
||||
| Constructors.cs:15:18:15:19 | access to field s1 | Constructors.cs:5:29:5:45 | call to method Source<Object> : Object | Constructors.cs:15:18:15:19 | access to field s1 | $@ | Constructors.cs:5:29:5:45 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
| Constructors.cs:33:18:33:19 | access to field s1 | Constructors.cs:21:29:21:45 | call to method Source<Object> : Object | Constructors.cs:33:18:33:19 | access to field s1 | $@ | Constructors.cs:21:29:21:45 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
@@ -157,3 +189,5 @@ subpaths
|
||||
| Constructors.cs:93:14:93:21 | access to property Obj22 | Constructors.cs:91:21:91:37 | call to method Source<Object> : Object | Constructors.cs:93:14:93:21 | access to property Obj22 | $@ | Constructors.cs:91:21:91:37 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
| Constructors.cs:101:14:101:21 | access to property Obj22 | Constructors.cs:99:21:99:37 | call to method Source<Object> : Object | Constructors.cs:101:14:101:21 | access to property Obj22 | $@ | Constructors.cs:99:21:99:37 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
| Constructors.cs:113:14:113:21 | access to property Obj31 | Constructors.cs:111:19:111:35 | call to method Source<Object> : Object | Constructors.cs:113:14:113:21 | access to property Obj31 | $@ | Constructors.cs:111:19:111:35 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
| Constructors.cs:133:14:133:20 | access to property Obj1 | Constructors.cs:130:18:130:34 | call to method Source<Object> : Object | Constructors.cs:133:14:133:20 | access to property Obj1 | $@ | Constructors.cs:130:18:130:34 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
| Constructors.cs:134:14:134:20 | access to property Obj2 | Constructors.cs:131:18:131:34 | call to method Source<Object> : Object | Constructors.cs:134:14:134:20 | access to property Obj2 | $@ | Constructors.cs:131:18:131:34 | call to method Source<Object> : Object | call to method Source<Object> : Object |
|
||||
|
||||
@@ -113,6 +113,27 @@ public class Constructors
|
||||
Sink(c3.Obj31); // $ hasValueFlow=6
|
||||
}
|
||||
|
||||
public class C4
|
||||
{
|
||||
public object Obj1 { get; init; }
|
||||
public object Obj2 { get; }
|
||||
|
||||
public C4(object oc1, object oc2)
|
||||
{
|
||||
Obj1 = oc1;
|
||||
Obj2 = oc2;
|
||||
}
|
||||
}
|
||||
|
||||
public void M6()
|
||||
{
|
||||
var o1 = Source<object>(7);
|
||||
var o2 = Source<object>(8);
|
||||
var c4 = new C4(o1, o2);
|
||||
Sink(c4.Obj1); // $ hasValueFlow=7
|
||||
Sink(c4.Obj2); // $ hasValueFlow=8
|
||||
}
|
||||
|
||||
public static void Sink(object o) { }
|
||||
|
||||
public static T Source<T>(object source) => throw null;
|
||||
|
||||
@@ -80,18 +80,21 @@ private class ArrayUpdate extends Expr {
|
||||
Expr getArray() { result = array }
|
||||
}
|
||||
|
||||
/**
|
||||
* A config that tracks dataflow from creating an array to an operation that updates it.
|
||||
*/
|
||||
private module ArrayUpdateConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof StaticByteArrayCreation }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(ArrayUpdate upd).getArray() }
|
||||
|
||||
predicate isBarrierOut(DataFlow::Node node) { isSink(node) }
|
||||
private predicate arrayUpdateSrc(DataFlow::Node source) {
|
||||
source.asExpr() instanceof StaticByteArrayCreation
|
||||
}
|
||||
|
||||
private module ArrayUpdateFlow = DataFlow::Global<ArrayUpdateConfig>;
|
||||
private predicate arrayUpdateSink(DataFlow::Node sink) {
|
||||
sink.asExpr() = any(ArrayUpdate upd).getArray()
|
||||
}
|
||||
|
||||
private module ArrayUpdateFlowFwd = DataFlow::SimpleGlobal<arrayUpdateSrc/1>;
|
||||
|
||||
private module ArrayUpdateFlow = ArrayUpdateFlowFwd::Graph<arrayUpdateSink/1>;
|
||||
|
||||
private predicate arrayReachesUpdate(StaticByteArrayCreation array) {
|
||||
exists(ArrayUpdateFlow::PathNode src | src.isSource() and src.getNode().asExpr() = array)
|
||||
}
|
||||
|
||||
/**
|
||||
* A source that defines an array that doesn't get updated.
|
||||
@@ -99,7 +102,7 @@ private module ArrayUpdateFlow = DataFlow::Global<ArrayUpdateConfig>;
|
||||
private class StaticInitializationVectorSource extends DataFlow::Node {
|
||||
StaticInitializationVectorSource() {
|
||||
exists(StaticByteArrayCreation array | array = this.asExpr() |
|
||||
not ArrayUpdateFlow::flow(DataFlow::exprNode(array), _) and
|
||||
not arrayReachesUpdate(array) and
|
||||
// Reduce FPs from utility methods that return an empty array in an exceptional case
|
||||
not exists(ReturnStmt ret |
|
||||
array.getADimension().(CompileTimeConstantExpr).getIntValue() = 0 and
|
||||
|
||||
@@ -785,24 +785,26 @@ module TypeTracking<TypeTrackingInput I> {
|
||||
)
|
||||
}
|
||||
|
||||
private Node getNodeMid(PathNodeFwd n) { n = TPathNodeMid(result, _) }
|
||||
|
||||
private Node getNodeSink(PathNodeFwd n) { n = TPathNodeSink(result) }
|
||||
|
||||
private predicate edgeCand(PathNodeFwd n1, PathNodeFwd n2) {
|
||||
exists(PathNodeFwd tgt |
|
||||
edgeCand(n1.getNode(), n1.getTypeTracker(), tgt.getNode(), tgt.getTypeTracker())
|
||||
edgeCand(getNodeMid(n1), n1.getTypeTracker(), getNodeMid(tgt), tgt.getTypeTracker())
|
||||
|
|
||||
n2 = tgt
|
||||
or
|
||||
n2 = TPathNodeSink(tgt.getNode()) and tgt.getTypeTracker().end()
|
||||
n2 = TPathNodeSink(getNodeMid(tgt)) and tgt.getTypeTracker().end()
|
||||
)
|
||||
or
|
||||
n1.getTypeTracker().end() and
|
||||
flowsTo(n1.getNode(), n2.getNode()) and
|
||||
n1.getNode() != n2.getNode() and
|
||||
n2 instanceof TPathNodeSink
|
||||
flowsTo(getNodeMid(n1), getNodeSink(n2)) and
|
||||
getNodeMid(n1) != getNodeSink(n2)
|
||||
or
|
||||
sourceSimpleLocalSmallSteps(n1.getNode(), n2.getNode()) and
|
||||
n1.getNode() != n2.getNode() and
|
||||
n1.isSource() and
|
||||
n2.isSink()
|
||||
sourceSimpleLocalSmallSteps(n1.getNode(), getNodeSink(n2)) and
|
||||
n1.getNode() != getNodeSink(n2) and
|
||||
n1.isSource()
|
||||
}
|
||||
|
||||
private predicate reachRev(PathNodeFwd n) {
|
||||
|
||||
Reference in New Issue
Block a user