diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index 0a6602b0b67..e1687c97dc9 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -23,13 +23,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching private readonly IDictionary unresolvedReferences = new ConcurrentDictionary(); private int failedProjects; private int succeededProjects; - private readonly string[] allSources; + private readonly List allSources; private int conflictedReferences = 0; private readonly IDependencyOptions options; private readonly DirectoryInfo sourceDir; private readonly DotNet dotnet; private readonly FileContent fileContent; private readonly TemporaryDirectory packageDirectory; + private readonly TemporaryDirectory? razorWorkingDirectory; /// @@ -60,7 +61,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching packageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName)); this.fileContent = new FileContent(packageDirectory, progressMonitor, () => GetFiles("*.*")); - this.allSources = GetFiles("*.cs").ToArray(); + this.allSources = GetFiles("*.cs").ToList(); var allProjects = GetFiles("*.csproj"); var solutions = options.SolutionFile is not null ? new[] { options.SolutionFile } @@ -131,6 +132,32 @@ namespace Semmle.Extraction.CSharp.DependencyFetching progressMonitor.UnresolvedReference(r.Key, r.Value); } + var views = GetFiles("*.cshtml") + .Concat(GetFiles("*.razor")) + .ToArray(); + + if (views.Length > 0) + { + // TODO: use SDK specified in global.json + // TODO: add feature flag to control razor generation + var sdk = new Sdk(dotnet).GetNewestSdk(); + if (sdk != null) + { + try + { + var razor = new Razor(sdk, dotnet, progressMonitor); + razorWorkingDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName, "razor")); + var generatedFiles = razor.GenerateFiles(views, usedReferences.Keys, razorWorkingDirectory.ToString()); + this.allSources.AddRange(generatedFiles); + } + catch (Exception ex) + { + // It's okay, we tried our best to generate source files from cshtml files. + progressMonitor.LogInfo($"Failed to generate source files from cshtml files: {ex.Message}"); + } + } + } + progressMonitor.Summary( AllSourceFiles.Count(), ProjectSourceFiles.Count(), @@ -156,9 +183,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// Computes a unique temp directory for the packages associated /// with this source tree. Use a SHA1 of the directory name. /// - /// /// The full path of the temp directory. - private static string ComputeTempDirectory(string srcDir) + private static string ComputeTempDirectory(string srcDir, string subfolderName = "packages") { var bytes = Encoding.Unicode.GetBytes(srcDir); var sha = SHA1.HashData(bytes); @@ -166,7 +192,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching foreach (var b in sha.Take(8)) sb.AppendFormat("{0:x2}", b); - return Path.Combine(Path.GetTempPath(), "GitHub", "packages", sb.ToString()); + return Path.Combine(Path.GetTempPath(), "GitHub", subfolderName, sb.ToString()); } /// @@ -392,6 +418,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching }); } - public void Dispose() => packageDirectory?.Dispose(); + public void Dispose() + { + packageDirectory?.Dispose(); + razorWorkingDirectory?.Dispose(); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index 0507dcd52a0..c3fb87ab57b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -5,14 +5,6 @@ using Semmle.Util; namespace Semmle.Extraction.CSharp.DependencyFetching { - internal interface IDotNet - { - bool RestoreToDirectory(string project, string directory, string? pathToNugetConfig = null); - bool New(string folder); - bool AddPackage(string folder, string package); - IList GetListedRuntimes(); - } - /// /// Utilities to run the "dotnet" command. /// @@ -76,23 +68,33 @@ namespace Semmle.Extraction.CSharp.DependencyFetching return RunCommand(args); } - public IList GetListedRuntimes() + public IList GetListedRuntimes() => GetListed("--list-runtimes", "runtime"); + + public IList GetListedSdks() => GetListed("--list-sdks", "SDK"); + + private IList GetListed(string args, string artifact) { - const string args = "--list-runtimes"; progressMonitor.RunningProcess($"{dotnet} {args}"); var pi = new ProcessStartInfo(dotnet, args) { RedirectStandardOutput = true, UseShellExecute = false }; - var exitCode = pi.ReadOutput(out var runtimes); + var exitCode = pi.ReadOutput(out var artifacts); if (exitCode != 0) { progressMonitor.CommandFailed(dotnet, args, exitCode); return new List(); } - progressMonitor.LogInfo($"Found runtimes: {string.Join("\n", runtimes)}"); - return runtimes; + progressMonitor.LogInfo($"Found {artifact}s: {string.Join("\n", artifacts)}"); + return artifacts; + } + + public bool Exec(string execArgs) + { + // TODO: we might need to swallow the stdout of the started process to not pollute the logs of the extraction. + var args = $"exec {execArgs}"; + return RunCommand(args); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/ProgressMonitor.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/ProgressMonitor.cs index 94410c7286b..37c1b3c97fd 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/ProgressMonitor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/ProgressMonitor.cs @@ -108,5 +108,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching internal void NoTopLevelNugetConfig() => LogInfo("Could not find a top-level nuget.config file."); + + internal void RazorSourceGeneratorMissing(string fullPath) => + LogInfo($"Razor source generator folder {fullPath} does not exist."); + + internal void CscMissing(string cscPath) => + LogInfo($"Csc.exe not found at {cscPath}."); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs index bcfee79db8f..cc7f77f5aac 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs @@ -17,8 +17,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching private const string aspNetCoreApp = "Microsoft.AspNetCore.App"; private readonly IDotNet dotNet; - private readonly Lazy> newestRuntimes; - private Dictionary NewestRuntimes => newestRuntimes.Value; + private readonly Lazy> newestRuntimes; + private Dictionary NewestRuntimes => newestRuntimes.Value; private static string ExecutingRuntime => RuntimeEnvironment.GetRuntimeDirectory(); public Runtime(IDotNet dotNet) @@ -27,58 +27,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching this.newestRuntimes = new(GetNewestRuntimes); } - internal record RuntimeVersion : IComparable - { - private readonly string dir; - private readonly Version version; - private readonly Version? preReleaseVersion; - private readonly string? preReleaseVersionType; - private bool IsPreRelease => preReleaseVersionType is not null && preReleaseVersion is not null; - public string FullPath - { - get - { - var preRelease = IsPreRelease ? $"-{preReleaseVersionType}.{preReleaseVersion}" : ""; - var version = this.version + preRelease; - return Path.Combine(dir, version); - } - } - - public RuntimeVersion(string dir, string version, string preReleaseVersionType, string preReleaseVersion) - { - this.dir = dir; - this.version = Version.Parse(version); - if (!string.IsNullOrEmpty(preReleaseVersion) && !string.IsNullOrEmpty(preReleaseVersionType)) - { - this.preReleaseVersionType = preReleaseVersionType; - this.preReleaseVersion = Version.Parse(preReleaseVersion); - } - } - - public int CompareTo(RuntimeVersion? other) - { - var c = version.CompareTo(other?.version); - if (c == 0 && IsPreRelease) - { - if (!other!.IsPreRelease) - { - return -1; - } - - // Both are pre-release like runtime versions. - // The pre-release version types are sorted alphabetically (e.g. alpha, beta, preview, rc) - // and the pre-release version types are more important that the pre-release version numbers. - return preReleaseVersionType != other!.preReleaseVersionType - ? preReleaseVersionType!.CompareTo(other!.preReleaseVersionType) - : preReleaseVersion!.CompareTo(other!.preReleaseVersion); - } - - return c; - } - - public override string ToString() => FullPath; - } - [GeneratedRegex(@"^(\S+)\s(\d+\.\d+\.\d+)(-([a-z]+)\.(\d+\.\d+\.\d+))?\s\[(.+)\]$")] private static partial Regex RuntimeRegex(); @@ -88,16 +36,17 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// It is assume that the format of a listed runtime is something like: /// Microsoft.NETCore.App 7.0.2 [/usr/share/dotnet/shared/Microsoft.NETCore.App] /// - private static Dictionary ParseRuntimes(IList listed) + private static Dictionary ParseRuntimes(IList listed) { // Parse listed runtimes. - var runtimes = new Dictionary(); + var runtimes = new Dictionary(); + var regex = RuntimeRegex(); listed.ForEach(r => { - var match = RuntimeRegex().Match(r); + var match = regex.Match(r); if (match.Success) { - runtimes.AddOrUpdateToLatest(match.Groups[1].Value, new RuntimeVersion(match.Groups[6].Value, match.Groups[2].Value, match.Groups[4].Value, match.Groups[5].Value)); + runtimes.AddOrUpdateToLatest(match.Groups[1].Value, new DotnetVersion(match.Groups[6].Value, match.Groups[2].Value, match.Groups[4].Value, match.Groups[5].Value)); } }); @@ -107,7 +56,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// /// Returns a dictionary mapping runtimes to their newest version. /// - internal Dictionary GetNewestRuntimes() + internal Dictionary GetNewestRuntimes() { var listed = dotNet.GetListedRuntimes(); return ParseRuntimes(listed); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/DotnetVersion.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/DotnetVersion.cs new file mode 100644 index 00000000000..ae91a429120 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/DotnetVersion.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; + +namespace Semmle.Extraction.CSharp.Standalone +{ + internal record DotnetVersion : IComparable + { + private readonly string dir; + private readonly Version version; + private readonly Version? preReleaseVersion; + private readonly string? preReleaseVersionType; + private bool IsPreRelease => preReleaseVersionType is not null && preReleaseVersion is not null; + public string FullPath + { + get + { + var preRelease = IsPreRelease ? $"-{preReleaseVersionType}.{preReleaseVersion}" : ""; + var version = this.version + preRelease; + return Path.Combine(dir, version); + } + } + + public DotnetVersion(string dir, string version, string preReleaseVersionType, string preReleaseVersion) + { + this.dir = dir; + this.version = Version.Parse(version); + if (!string.IsNullOrEmpty(preReleaseVersion) && !string.IsNullOrEmpty(preReleaseVersionType)) + { + this.preReleaseVersionType = preReleaseVersionType; + this.preReleaseVersion = Version.Parse(preReleaseVersion); + } + } + + public int CompareTo(DotnetVersion? other) + { + var c = version.CompareTo(other?.version); + if (c == 0 && IsPreRelease) + { + if (!other!.IsPreRelease) + { + return -1; + } + + // Both are pre-release like runtime versions. + // The pre-release version types are sorted alphabetically (e.g. alpha, beta, preview, rc) + // and the pre-release version types are more important that the pre-release version numbers. + return preReleaseVersionType != other!.preReleaseVersionType + ? preReleaseVersionType!.CompareTo(other!.preReleaseVersionType) + : preReleaseVersion!.CompareTo(other!.preReleaseVersion); + } + + return c; + } + + public override string ToString() => FullPath; + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/IDotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/IDotNet.cs new file mode 100644 index 00000000000..63296599cba --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/IDotNet.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Semmle.BuildAnalyser +{ + internal interface IDotNet + { + bool RestoreToDirectory(string project, string directory, string? pathToNugetConfig = null); + bool New(string folder); + bool AddPackage(string folder, string package); + IList GetListedRuntimes(); + IList GetListedSdks(); + bool Exec(string execArgs); + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Razor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Razor.cs new file mode 100644 index 00000000000..14c7c406abc --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Razor.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Semmle.BuildAnalyser; +using Semmle.Util; +using System.Text; + +namespace Semmle.Extraction.CSharp.Standalone +{ + internal class Razor + { + private readonly DotnetVersion sdk; + private readonly ProgressMonitor progressMonitor; + private readonly DotNet dotNet; + private readonly string sourceGeneratorFolder; + private readonly string cscPath; + + public Razor(DotnetVersion sdk, DotNet dotNet, ProgressMonitor progressMonitor) + { + this.sdk = sdk; + this.progressMonitor = progressMonitor; + this.dotNet = dotNet; + + sourceGeneratorFolder = Path.Combine(this.sdk.FullPath, "Sdks/Microsoft.NET.Sdk.Razor/source-generators"); + if (!Directory.Exists(sourceGeneratorFolder)) + { + this.progressMonitor.RazorSourceGeneratorMissing(sourceGeneratorFolder); + throw new Exception($"Razor source generator folder {sourceGeneratorFolder} does not exist."); + } + + cscPath = Path.Combine(this.sdk.FullPath, "Roslyn/bincore/csc.dll"); + if (!File.Exists(cscPath)) + { + this.progressMonitor.CscMissing(cscPath); + throw new Exception($"csc.dll {cscPath} does not exist."); + } + } + + private static void GenerateAnalyzerConfig(IEnumerable cshtmls, string analyzerConfigPath) + { + using var sw = new StreamWriter(analyzerConfigPath); + sw.WriteLine("is_global = true"); + + foreach (var f in cshtmls) + { + sw.WriteLine($"\n[{f}]"); + var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(f)); // TODO: this should be the relative path of the file. + sw.WriteLine($"build_metadata.AdditionalFiles.TargetPath = {base64}"); + } + } + + public IEnumerable GenerateFiles(IEnumerable cshtmls, IEnumerable references, string workingDirectory) + { + // TODO: the below command might be too long. It should be written to a temp file and passed to csc via @. + + var name = Guid.NewGuid().ToString("N").ToUpper(); + var analyzerConfig = Path.Combine(Path.GetTempPath(), name + ".txt"); + var dllPath = Path.Combine(Path.GetTempPath(), name + ".dll"); + var outputFolder = Path.Combine(workingDirectory, name); + Directory.CreateDirectory(outputFolder); + + try + { + GenerateAnalyzerConfig(cshtmls, Path.Combine(sourceGeneratorFolder, analyzerConfig)); + + var args = new StringBuilder(); + args.Append($"\"{cscPath}\" /target:exe /generatedfilesout:\"{outputFolder}\" /out:\"{dllPath}\" /analyzerconfig:\"{analyzerConfig}\" "); + + // TODO: quote paths: + foreach (var f in Directory.GetFiles(sourceGeneratorFolder, "*.dll")) + { + args.Append($"/analyzer:\"{f}\" "); + } + + foreach (var f in cshtmls) + { + args.Append($"/additionalfile:\"{f}\" "); + } + + foreach (var f in references) + { + args.Append($"/reference:\"{f}\" "); + } + + dotNet.Exec(args.ToString()); + + return Directory.GetFiles(outputFolder, "*.*", new EnumerationOptions { RecurseSubdirectories = true }); + } + finally + { + DeleteFile(analyzerConfig); + DeleteFile(dllPath); + } + } + + private static void DeleteFile(string path) + { + try + { + File.Delete(path); + } + catch + { + // Ignore + } + } + } +} \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Sdk.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Sdk.cs new file mode 100644 index 00000000000..074160faab9 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Sdk.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using Semmle.BuildAnalyser; +using Semmle.Util; +using System.Text.RegularExpressions; +using System.Linq; + +namespace Semmle.Extraction.CSharp.Standalone +{ + internal partial class Sdk + { + private readonly IDotNet dotNet; + + public Sdk(IDotNet dotNet) => this.dotNet = dotNet; + + [GeneratedRegex(@"^(\d+\.\d+\.\d+)(-([a-z]+)\.(\d+\.\d+\.\d+))?\s\[(.+)\]$")] + private static partial Regex SdkRegex(); + + private static HashSet ParseSdks(IList listed) + { + var sdks = new HashSet(); + var regex = SdkRegex(); + listed.ForEach(r => + { + var match = regex.Match(r); + if (match.Success) + { + sdks.Add(new DotnetVersion(match.Groups[5].Value, match.Groups[1].Value, match.Groups[3].Value, match.Groups[4].Value)); + } + }); + + return sdks; + } + + public DotnetVersion? GetNewestSdk() + { + var listed = dotNet.GetListedSdks(); + var sdks = ParseSdks(listed); + return sdks.OrderByDescending(s => s).FirstOrDefault(); + } + } +} \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.Tests/Runtime.cs b/csharp/extractor/Semmle.Extraction.Tests/Runtime.cs index 79b286f7334..78e2270a883 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/Runtime.cs +++ b/csharp/extractor/Semmle.Extraction.Tests/Runtime.cs @@ -7,9 +7,13 @@ namespace Semmle.Extraction.Tests internal class DotNetStub : IDotNet { private readonly IList runtimes; + private readonly IList sdks; - public DotNetStub(IList runtimes) => this.runtimes = runtimes; - + public DotNetStub(IList runtimes, IList sdks) + { + this.runtimes = runtimes; + this.sdks = sdks; + } public bool AddPackage(string folder, string package) => true; public bool New(string folder) => true; @@ -17,6 +21,10 @@ namespace Semmle.Extraction.Tests public bool RestoreToDirectory(string project, string directory, string? pathToNugetConfig = null) => true; public IList GetListedRuntimes() => runtimes; + + public IList GetListedSdks() => sdks; + + public bool Exec(string execArgs) => true; } public class RuntimeTests @@ -37,7 +45,7 @@ namespace Semmle.Extraction.Tests "Microsoft.NETCore.App 7.0.0 [/path/dotnet/shared/Microsoft.NETCore.App]", "Microsoft.NETCore.App 7.0.2 [/path/dotnet/shared/Microsoft.NETCore.App]" }; - var dotnet = new DotNetStub(listedRuntimes); + var dotnet = new DotNetStub(listedRuntimes, null!); var runtime = new Runtime(dotnet); // Execute @@ -63,7 +71,7 @@ namespace Semmle.Extraction.Tests "Microsoft.NETCore.App 8.0.0-preview.5.43280.8 [/path/dotnet/shared/Microsoft.NETCore.App]", "Microsoft.NETCore.App 8.0.0-preview.5.23280.8 [/path/dotnet/shared/Microsoft.NETCore.App]" }; - var dotnet = new DotNetStub(listedRuntimes); + var dotnet = new DotNetStub(listedRuntimes, null!); var runtime = new Runtime(dotnet); // Execute @@ -86,7 +94,7 @@ namespace Semmle.Extraction.Tests "Microsoft.NETCore.App 8.0.0-rc.4.43280.8 [/path/dotnet/shared/Microsoft.NETCore.App]", "Microsoft.NETCore.App 8.0.0-preview.5.23280.8 [/path/dotnet/shared/Microsoft.NETCore.App]" }; - var dotnet = new DotNetStub(listedRuntimes); + var dotnet = new DotNetStub(listedRuntimes, null!); var runtime = new Runtime(dotnet); // Execute @@ -115,7 +123,7 @@ namespace Semmle.Extraction.Tests @"Microsoft.WindowsDesktop.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]", @"Microsoft.WindowsDesktop.App 7.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]" }; - var dotnet = new DotNetStub(listedRuntimes); + var dotnet = new DotNetStub(listedRuntimes, null!); var runtime = new Runtime(dotnet); // Execute @@ -131,4 +139,56 @@ namespace Semmle.Extraction.Tests Assert.Equal(@"C:/Program Files/dotnet/shared/Microsoft.NETCore.App/7.0.2", FixExpectedPathOnWindows(netCoreApp.FullPath)); } } + + public class SdkTests + { + private static string FixExpectedPathOnWindows(string path) => path.Replace('\\', '/'); + + [Fact] + public void TestSdk1() + { + // Setup + var listedSdks = new List + { + "6.0.413 [/usr/local/share/dotnet/sdk1]", + "7.0.102 [/usr/local/share/dotnet/sdk2]", + "7.0.302 [/usr/local/share/dotnet/sdk3]", + "7.0.400 [/usr/local/share/dotnet/sdk4]", + "5.0.402 [/usr/local/share/dotnet/sdk5]", + "6.0.102 [/usr/local/share/dotnet/sdk6]", + "6.0.301 [/usr/local/share/dotnet/sdk7]", + }; + var dotnet = new DotNetStub(null!, listedSdks); + var sdk = new Sdk(dotnet); + + // Execute + var version = sdk.GetNewestSdk(); + + // Verify + Assert.NotNull(version); + Assert.Equal("/usr/local/share/dotnet/sdk4/7.0.400", FixExpectedPathOnWindows(version.FullPath)); + } + + [Fact] + public void TestSdk2() + { + // Setup + var listedSdks = new List + { + "6.0.413 [/usr/local/share/dotnet/sdk1]", + "7.0.102 [/usr/local/share/dotnet/sdk2]", + "8.0.100-preview.7.23376.3 [/usr/local/share/dotnet/sdk3]", + "7.0.400 [/usr/local/share/dotnet/sdk4]", + }; + var dotnet = new DotNetStub(null!, listedSdks); + var sdk = new Sdk(dotnet); + + // Execute + var version = sdk.GetNewestSdk(); + + // Verify + Assert.NotNull(version); + Assert.Equal("/usr/local/share/dotnet/sdk3/8.0.100-preview.7.23376.3", FixExpectedPathOnWindows(version.FullPath)); + } + } } diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua index 68b7b816ffe..716a6f42cee 100644 --- a/csharp/tools/tracing-config.lua +++ b/csharp/tools/tracing-config.lua @@ -150,6 +150,8 @@ function RegisterExtractorPack(id) end local windowsMatchers = { + CreatePatternMatcher({ '^semmle%.extraction%.csharp%.standalone%.exe$' }, + MatchCompilerName, nil, { trace = false }), DotnetMatcherBuild, MsBuildMatcher, CreatePatternMatcher({ '^csc.*%.exe$' }, MatchCompilerName, extractor, { @@ -191,6 +193,9 @@ function RegisterExtractorPack(id) end } local posixMatchers = { + -- The compiler name is case sensitive on Linux and lower cased on MacOS + CreatePatternMatcher({ '^semmle%.extraction%.csharp%.standalone$', '^Semmle%.Extraction%.CSharp%.Standalone$' }, + MatchCompilerName, nil, { trace = false }), DotnetMatcherBuild, CreatePatternMatcher({ '^mcs%.exe$', '^csc%.exe$' }, MatchCompilerName, extractor, {