From a5f6e9bd5adc40621ca920507c7133735f57d2de Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 13 Aug 2026 11:49:49 +0200 Subject: [PATCH 1/7] C#: Remove the explicit feed timeout fallback. --- .../NugetPackageRestorer.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index aeedbc176867..9ff4760ed396 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -129,17 +129,6 @@ public HashSet Restore() var allExplicitReachable = explicitFeeds.Count == feedManager.ReachableExplicitFeeds.Count; EmitUnreachableFeedsDiagnostics(allExplicitReachable); - - if (feedManager.ExplicitFeedTimeout) - { - // If we experience a timeout, we use this fallback. - // 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 = DownloadMissingPackages([]); - return unresponsiveMissingPackageLocation is null - ? [] - : [unresponsiveMissingPackageLocation]; - } - } try From 87af0b06fe1b79958ef58490a00d2b2fe36d17ec Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 13 Aug 2026 12:44:27 +0200 Subject: [PATCH 2/7] C#: Remove the timeout bool logic in the feed manager. --- .../FeedManager.cs | 52 +++++-------------- 1 file changed, 13 insertions(+), 39 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FeedManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FeedManager.cs index 1d5523a983cb..0cbf106df38a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FeedManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FeedManager.cs @@ -60,17 +60,12 @@ internal sealed partial class FeedManager : IDisposable /// public ImmutableHashSet InheritedFeeds => AllFeeds.Except(ExplicitFeeds).ToImmutableHashSet(); - private readonly Lazy<(bool, ImmutableHashSet)> lazyReachableExplicitFeeds; - - /// - /// Gets whether there was a timeout when checking the reachability of the explicitly configured NuGet feeds. - /// - public bool ExplicitFeedTimeout => lazyReachableExplicitFeeds.Value.Item1; + private readonly Lazy> lazyReachableExplicitFeeds; /// /// Gets the list of reachable NuGet feeds that are explicitly configured. /// - public ImmutableHashSet ReachableExplicitFeeds => lazyReachableExplicitFeeds.Value.Item2; + public ImmutableHashSet ReachableExplicitFeeds => lazyReachableExplicitFeeds.Value; private readonly Lazy> lazyReachableFeeds; /// @@ -96,15 +91,11 @@ public FeedManager(ILogger logger, IDotNet dotnet, DependabotProxy? dependabotPr lazyExplicitFeeds = new Lazy>(GetExplicitFeeds); lazyAllFeeds = new Lazy>(GetAllFeeds); - lazyReachableExplicitFeeds = new Lazy<(bool, ImmutableHashSet)>(() => - { - var timeout = CheckSpecifiedFeeds(ExplicitFeeds, out var reachableFeeds); - return (timeout, reachableFeeds); - }); + lazyReachableExplicitFeeds = new Lazy>(() => CheckSpecifiedFeeds(ExplicitFeeds)); lazyReachableFeeds = new Lazy>(() => { // Inherited feeds should only be used, if they are indeed reachable (as they may be environment specific). - CheckSpecifiedFeeds(InheritedFeeds, out var reachableInheritedFeeds); + var reachableInheritedFeeds = CheckSpecifiedFeeds(InheritedFeeds); return ReachableExplicitFeeds.Union(reachableInheritedFeeds).ToImmutableHashSet(); }); lazyReachableFallbackFeeds = new Lazy>(() => @@ -271,7 +262,7 @@ private static async Task ExecuteGetRequest(string address, return await httpClient.GetAsync(address, HttpCompletionOption.ResponseHeadersRead, cancellationToken); } - private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, out bool isTimeout) + private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount) { logger.LogInfo($"Checking if NuGet feed '{feed}' is reachable..."); @@ -304,8 +295,6 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, using HttpClient client = new(httpClientHandler); - isTimeout = false; - for (var i = 0; i < tryCount; i++) { using var cts = new CancellationTokenSource(); @@ -335,7 +324,6 @@ private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, } logger.LogWarning($"Didn't receive answer from NuGet feed '{feed}'. Tried it {tryCount} times."); - isTimeout = true; return false; } @@ -359,12 +347,8 @@ private HashSet GetExcludedFeeds() /// Checks that we can connect to the specified NuGet feeds. /// /// The set of package feeds to check. - /// The list of feeds that were reachable. - /// - /// True if there is a timeout when trying to reach the feeds (excluding any feeds that are configured - /// to be excluded from the check) or false otherwise. - /// - private bool CheckSpecifiedFeeds(ImmutableHashSet feeds, out ImmutableHashSet reachableFeeds) + /// The list of feeds that were reachable. + private ImmutableHashSet CheckSpecifiedFeeds(ImmutableHashSet feeds) { // Exclude any feeds from the feed check that are configured by the corresponding environment variable. // These feeds are always assumed to be reachable. @@ -380,12 +364,10 @@ private bool CheckSpecifiedFeeds(ImmutableHashSet feeds, out ImmutableHa return true; }).ToHashSet(); - var reachable = GetReachableNuGetFeeds(feedsToCheck, isFallback: false, out var isTimeout); + var reachable = GetReachableNuGetFeeds(feedsToCheck, isFallback: false); // Always consider feeds excluded for the reachability check as reachable. - reachableFeeds = reachable.Union(feeds.Where(feed => excludedFeeds.Contains(feed))).ToImmutableHashSet(); - - return isTimeout; + return reachable.Union(feeds.Where(feed => excludedFeeds.Contains(feed))).ToImmutableHashSet(); } /// @@ -398,7 +380,7 @@ public bool IsDefaultFeedReachable() if (CheckNugetFeedResponsiveness) { var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false); - return IsFeedReachable(PublicNugetOrgFeed, initialTimeout, tryCount, out var _); + return IsFeedReachable(PublicNugetOrgFeed, initialTimeout, tryCount); } return true; @@ -409,22 +391,15 @@ public bool IsDefaultFeedReachable() /// /// The feeds to check. /// Whether the feeds are fallback feeds or not. - /// Whether a timeout occurred while checking the feeds. /// The list of feeds that could be reached. - private List GetReachableNuGetFeeds(HashSet feedsToCheck, bool isFallback, out bool isTimeout) + private List GetReachableNuGetFeeds(HashSet feedsToCheck, bool isFallback) { var fallbackStr = isFallback ? "fallback " : ""; logger.LogInfo($"Checking {fallbackStr}NuGet feed reachability on feeds: {string.Join(", ", feedsToCheck.OrderBy(f => f))}"); var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback); - var timeout = false; var reachableFeeds = feedsToCheck - .Where(feed => - { - var reachable = IsFeedReachable(feed, initialTimeout, tryCount, out var feedTimeout); - timeout |= feedTimeout; - return reachable; - }) + .Where(feed => IsFeedReachable(feed, initialTimeout, tryCount)) .ToList(); if (reachableFeeds.Count == 0) @@ -436,7 +411,6 @@ private List GetReachableNuGetFeeds(HashSet feedsToCheck, bool i logger.LogInfo($"Reachable {fallbackStr}NuGet feeds: {string.Join(", ", reachableFeeds.OrderBy(f => f))}"); } - isTimeout = timeout; return reachableFeeds; } @@ -460,7 +434,7 @@ private List GetReachableFallbackNugetFeeds() } } - return GetReachableNuGetFeeds(fallbackFeeds, isFallback: true, out var _); + return GetReachableNuGetFeeds(fallbackFeeds, isFallback: true); } private ImmutableHashSet GetExplicitFeeds() From 394274cd84b97f00bb0135cdd5dfad9dbec271fa Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Thu, 13 Aug 2026 15:25:16 +0200 Subject: [PATCH 3/7] C#: Update integration tests. --- .../CompilationInfo.expected | 7 +++++++ .../CompilationInfo.expected | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected index 5a7abcf543c8..4acd4f54e8a6 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected @@ -1,4 +1,8 @@ | All NuGet feeds reachable | 0.0 | +| Failed project restore with missing package error | 1.0 | +| Failed project restore with package source error | 0.0 | +| Failed solution restore with missing package error | 0.0 | +| Failed solution restore with package source error | 0.0 | | Fallback nuget restore | 1.0 | | Inherited NuGet feed count | 1.0 | | NuGet feed responsiveness checked | 1.0 | @@ -7,10 +11,13 @@ | Resolved assembly conflicts | 7.0 | | Resource extraction enabled | 0.0 | | Restored .NET framework variants | 0.0 | +| Restored projects through solution files | 0.0 | | Solution files on filesystem | 1.0 | | Source files generated | 0.0 | | Source files on filesystem | 1.0 | | Successfully ran fallback nuget restore | 1.0 | +| Successfully restored project files | 0.0 | +| Successfully restored solution files | 1.0 | | Unresolved references | 0.0 | | UseWPF set | 0.0 | | UseWindowsForms set | 0.0 | diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected index 9cc03f2f5372..d421cfc42e1a 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected @@ -1,4 +1,8 @@ | All NuGet feeds reachable | 0.0 | +| Failed project restore with missing package error | 1.0 | +| Failed project restore with package source error | 0.0 | +| Failed solution restore with missing package error | 0.0 | +| Failed solution restore with package source error | 0.0 | | Fallback nuget restore | 1.0 | | Inherited NuGet feed count | 1.0 | | NuGet feed responsiveness checked | 1.0 | @@ -7,10 +11,13 @@ | Resolved assembly conflicts | 7.0 | | Resource extraction enabled | 0.0 | | Restored .NET framework variants | 0.0 | +| Restored projects through solution files | 0.0 | | Solution files on filesystem | 1.0 | | Source files generated | 0.0 | | Source files on filesystem | 1.0 | | Successfully ran fallback nuget restore | 1.0 | +| Successfully restored project files | 0.0 | +| Successfully restored solution files | 1.0 | | Unresolved references | 0.0 | | UseWPF set | 0.0 | | UseWindowsForms set | 0.0 | From 00816ca4ea8bbb0b4bc8f3901209fa4bfb158927 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 19 Aug 2026 15:09:39 +0200 Subject: [PATCH 4/7] C#: Remove some dead code. --- .../NugetPackageRestorer.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 9ff4760ed396..38924e2f876e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -614,14 +614,6 @@ public void Dispose() feedManager.Dispose(); } - /// - /// Returns the full path to a temporary directory with the given subfolder name. - /// - private static string ComputeTempDirectoryPath(string subfolderName) - { - return Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), subfolderName); - } - /// /// Computes a unique temporary directory path based on the source directory and the subfolder name. /// From 983ac7e5798155c754895d4e0aa59d78f220b97c Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 17 Aug 2026 15:43:35 +0200 Subject: [PATCH 5/7] C#: Add tool status page information and compilation info for unreachable explicit feeds. --- .../NugetPackageRestorer.cs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs index 38924e2f876e..109d050f8786 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs @@ -127,8 +127,8 @@ public HashSet Restore() compilationInfoContainer.CompilationInfos.Add(("Inherited NuGet feed count", inheritedFeeds.Count.ToString())); } - var allExplicitReachable = explicitFeeds.Count == feedManager.ReachableExplicitFeeds.Count; - EmitUnreachableFeedsDiagnostics(allExplicitReachable); + var unreachableExplicitFeeds = explicitFeeds.Except(feedManager.ReachableExplicitFeeds).ToImmutableHashSet(); + EmitFeedReachabilityDiagnostics(unreachableExplicitFeeds); } try @@ -536,25 +536,31 @@ private void TryChangeProjectFile(DirectoryInfo projectDir, Regex pattern, strin } /// - /// If is `false`, logs this and emits a diagnostic. + /// If is not empty, logs this and emits a diagnostic. /// Adds a `CompilationInfos` entry either way. /// - /// Whether all feeds were reachable or not. - private void EmitUnreachableFeedsDiagnostics(bool allFeedsReachable) + /// The feeds that were not reachable. + private void EmitFeedReachabilityDiagnostics(ImmutableHashSet unreachableFeeds) { - if (!allFeedsReachable) + if (unreachableFeeds.Count > 0) { - logger.LogWarning("Found unreachable NuGet feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis."); + var orderedUnreachableFeeds = unreachableFeeds.OrderBy(feed => feed).ToList(); + var unreachableFeedList = string.Join(", ", orderedUnreachableFeeds); + logger.LogWarning($"Found unreachable NuGet feeds in C# analysis with build-mode 'none': {unreachableFeedList}. This may cause missing dependencies in the analysis."); + compilationInfoContainer.CompilationInfos.Add(("Unreachable NuGet feeds", unreachableFeedList)); diagnosticsWriter.AddEntry(new DiagnosticMessage( Language.CSharp, "buildless/unreachable-feed", - "Found unreachable NuGet feed in C# analysis with build-mode 'none'", + "Found unreachable NuGet feeds in C# analysis with build-mode 'none'", visibility: new DiagnosticMessage.TspVisibility(statusPage: true, cliSummaryTable: true, telemetry: true), - markdownMessage: "Found unreachable NuGet feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis.", + markdownMessage: string.Format( + "Found unreachable NuGet feeds in C# analysis with build-mode 'none':\n\n{0}\n\nThis may cause missing dependencies in the analysis.", + string.Join("\n", orderedUnreachableFeeds.Select(feed => $"- `{feed}`")) + ), severity: DiagnosticMessage.TspSeverity.Note )); } - compilationInfoContainer.CompilationInfos.Add(("All NuGet feeds reachable", allFeedsReachable ? "1" : "0")); + compilationInfoContainer.CompilationInfos.Add(("All NuGet feeds reachable", unreachableFeeds.Count == 0 ? "1" : "0")); } private void EmitNugetConfigDiagnostics() From 0990408d537a38f2f96dca70ba25043b8834bbaf Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Mon, 17 Aug 2026 16:16:56 +0200 Subject: [PATCH 6/7] C#: Update integration test expected output. --- .../standalone_resx/CompilationInfo.expected | 42 ++++++++-------- .../standalone_resx/CompilationInfo.ql | 11 +---- .../standalone_slnx/CompilationInfo.expected | 42 ++++++++-------- .../standalone_slnx/CompilationInfo.ql | 11 +---- .../CompilationInfo.expected | 42 ++++++++-------- .../standalone_winforms/CompilationInfo.ql | 11 +---- .../CompilationInfo.expected | 44 ++++++++--------- .../CompilationInfo.ql | 11 +---- .../CompilationInfo.expected | 49 ++++++++++--------- .../CompilationInfo.ql | 11 +---- .../CompilationInfo.expected | 49 ++++++++++--------- .../CompilationInfo.ql | 11 +---- .../diagnostics.expected | 4 +- .../CompilationInfo.expected | 49 ++++++++++--------- .../CompilationInfo.ql | 11 +---- .../diagnostics.expected | 4 +- 16 files changed, 178 insertions(+), 224 deletions(-) diff --git a/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected b/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected index 6d91b2700226..d0b09f83622c 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected +++ b/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.expected @@ -1,21 +1,21 @@ -| All NuGet feeds reachable | 1.0 | -| Failed project restore with missing package error | 0.0 | -| Failed project restore with package source error | 0.0 | -| Failed solution restore with missing package 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 | -| Resource extraction enabled | 1.0 | -| Restored .NET framework variants | 1.0 | -| Restored projects through solution files | 0.0 | -| Solution files on filesystem | 0.0 | -| Source files generated | 2.0 | -| Source files on filesystem | 1.0 | -| Successfully restored project files | 1.0 | -| Successfully restored solution files | 0.0 | -| Unresolved references | 0.0 | -| UseWPF set | 0.0 | -| UseWindowsForms set | 0.0 | -| WebView extraction enabled | 1.0 | +| All NuGet feeds reachable | 1 | +| Failed project restore with missing package error | 0 | +| Failed project restore with package source error | 0 | +| Failed solution restore with missing package error | 0 | +| Failed solution restore with package source error | 0 | +| Inherited NuGet feed count | 1 | +| NuGet feed responsiveness checked | 1 | +| Project files on filesystem | 1 | +| Reachable fallback NuGet feed count | 1 | +| Resource extraction enabled | 1 | +| Restored .NET framework variants | 1 | +| Restored projects through solution files | 0 | +| Solution files on filesystem | 0 | +| Source files generated | 2 | +| Source files on filesystem | 1 | +| Successfully restored project files | 1 | +| Successfully restored solution files | 0 | +| Unresolved references | 0 | +| UseWPF set | 0 | +| UseWindowsForms set | 0 | +| WebView extraction enabled | 1 | diff --git a/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.ql b/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.ql index a96c2fd99a69..28898f02fd24 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.ql +++ b/csharp/ql/integration-tests/all-platforms/standalone_resx/CompilationInfo.ql @@ -1,16 +1,9 @@ import csharp import semmle.code.csharp.commons.Diagnostics -query predicate compilationInfo(string key, float value) { +query predicate compilationInfo(string key, string value) { key != "Resolved references" and key != "Resolved assembly conflicts" and not key.matches("Compiler diagnostic count for%") and - exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | - key = infoKey and - value = infoValue.toFloat() - or - not exists(infoValue.toFloat()) and - key = infoKey + ": " + infoValue and - value = 1 - ) + value = any(Compilation c).getInfo(key) } diff --git a/csharp/ql/integration-tests/all-platforms/standalone_slnx/CompilationInfo.expected b/csharp/ql/integration-tests/all-platforms/standalone_slnx/CompilationInfo.expected index 82cf0509d345..94716c3255ae 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone_slnx/CompilationInfo.expected +++ b/csharp/ql/integration-tests/all-platforms/standalone_slnx/CompilationInfo.expected @@ -1,21 +1,21 @@ -| All NuGet feeds reachable | 1.0 | -| Failed project restore with missing package error | 0.0 | -| Failed project restore with package source error | 0.0 | -| Failed solution restore with missing package 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 | 2.0 | -| Reachable fallback NuGet feed count | 1.0 | -| Resource extraction enabled | 0.0 | -| Restored .NET framework variants | 1.0 | -| Restored projects through solution files | 2.0 | -| Solution files on filesystem | 1.0 | -| Source files generated | 1.0 | -| Source files on filesystem | 2.0 | -| Successfully restored project files | 0.0 | -| Successfully restored solution files | 1.0 | -| Unresolved references | 0.0 | -| UseWPF set | 0.0 | -| UseWindowsForms set | 0.0 | -| WebView extraction enabled | 1.0 | +| All NuGet feeds reachable | 1 | +| Failed project restore with missing package error | 0 | +| Failed project restore with package source error | 0 | +| Failed solution restore with missing package error | 0 | +| Failed solution restore with package source error | 0 | +| Inherited NuGet feed count | 1 | +| NuGet feed responsiveness checked | 1 | +| Project files on filesystem | 2 | +| Reachable fallback NuGet feed count | 1 | +| Resource extraction enabled | 0 | +| Restored .NET framework variants | 1 | +| Restored projects through solution files | 2 | +| Solution files on filesystem | 1 | +| Source files generated | 1 | +| Source files on filesystem | 2 | +| Successfully restored project files | 0 | +| Successfully restored solution files | 1 | +| Unresolved references | 0 | +| UseWPF set | 0 | +| UseWindowsForms set | 0 | +| WebView extraction enabled | 1 | diff --git a/csharp/ql/integration-tests/all-platforms/standalone_slnx/CompilationInfo.ql b/csharp/ql/integration-tests/all-platforms/standalone_slnx/CompilationInfo.ql index 078e352be4d9..e6dc52674f37 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone_slnx/CompilationInfo.ql +++ b/csharp/ql/integration-tests/all-platforms/standalone_slnx/CompilationInfo.ql @@ -1,16 +1,9 @@ import csharp import semmle.code.csharp.commons.Diagnostics -query predicate compilationInfo(string key, float value) { +query predicate compilationInfo(string key, string value) { key != "Resolved references" and key != "Resolved assembly conflicts" and not key.matches(["Compiler diagnostic count for%", "Extractor message count for group%"]) and - exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | - key = infoKey and - value = infoValue.toFloat() - or - not exists(infoValue.toFloat()) and - key = infoKey + ": " + infoValue and - value = 1 - ) + value = any(Compilation c).getInfo(key) } diff --git a/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.expected b/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.expected index 63ddd4903f3e..ee79179d4fae 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.expected +++ b/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.expected @@ -1,21 +1,21 @@ -| All NuGet feeds reachable | 1.0 | -| Failed project restore with missing package error | 0.0 | -| Failed project restore with package source error | 0.0 | -| Failed solution restore with missing package 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 | -| Resource extraction enabled | 0.0 | -| Restored .NET framework variants | 1.0 | -| Restored projects through solution files | 0.0 | -| Solution files on filesystem | 0.0 | -| Source files generated | 1.0 | -| Source files on filesystem | 3.0 | -| Successfully restored project files | 1.0 | -| Successfully restored solution files | 0.0 | -| Unresolved references | 0.0 | -| UseWPF set | 0.0 | -| UseWindowsForms set | 1.0 | -| WebView extraction enabled | 1.0 | +| All NuGet feeds reachable | 1 | +| Failed project restore with missing package error | 0 | +| Failed project restore with package source error | 0 | +| Failed solution restore with missing package error | 0 | +| Failed solution restore with package source error | 0 | +| Inherited NuGet feed count | 1 | +| NuGet feed responsiveness checked | 1 | +| Project files on filesystem | 1 | +| Reachable fallback NuGet feed count | 1 | +| Resource extraction enabled | 0 | +| Restored .NET framework variants | 1 | +| Restored projects through solution files | 0 | +| Solution files on filesystem | 0 | +| Source files generated | 1 | +| Source files on filesystem | 3 | +| Successfully restored project files | 1 | +| Successfully restored solution files | 0 | +| Unresolved references | 0 | +| UseWPF set | 0 | +| UseWindowsForms set | 1 | +| WebView extraction enabled | 1 | diff --git a/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.ql b/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.ql index 078e352be4d9..e6dc52674f37 100644 --- a/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.ql +++ b/csharp/ql/integration-tests/all-platforms/standalone_winforms/CompilationInfo.ql @@ -1,16 +1,9 @@ import csharp import semmle.code.csharp.commons.Diagnostics -query predicate compilationInfo(string key, float value) { +query predicate compilationInfo(string key, string value) { key != "Resolved references" and key != "Resolved assembly conflicts" and not key.matches(["Compiler diagnostic count for%", "Extractor message count for group%"]) and - exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | - key = infoKey and - value = infoValue.toFloat() - or - not exists(infoValue.toFloat()) and - key = infoKey + ": " + infoValue and - value = 1 - ) + value = any(Compilation c).getInfo(key) } diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_clear/CompilationInfo.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_clear/CompilationInfo.expected index ff0b29da33fa..e8a0b5897082 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_clear/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_clear/CompilationInfo.expected @@ -1,22 +1,22 @@ -| All NuGet feeds reachable | 1.0 | -| Failed project restore with missing package error | 0.0 | -| Failed project restore with package source error | 0.0 | -| Failed solution restore with missing package 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 | -| Resolved assembly conflicts | 0.0 | -| Resource extraction enabled | 0.0 | -| Restored .NET framework variants | 1.0 | -| Restored projects through solution files | 0.0 | -| Solution files on filesystem | 0.0 | -| Source files generated | 0.0 | -| Source files on filesystem | 1.0 | -| Successfully restored project files | 1.0 | -| Successfully restored solution files | 0.0 | -| Unresolved references | 0.0 | -| UseWPF set | 0.0 | -| UseWindowsForms set | 0.0 | -| WebView extraction enabled | 1.0 | +| All NuGet feeds reachable | 1 | +| Failed project restore with missing package error | 0 | +| Failed project restore with package source error | 0 | +| Failed solution restore with missing package error | 0 | +| Failed solution restore with package source error | 0 | +| Inherited NuGet feed count | 1 | +| NuGet feed responsiveness checked | 1 | +| Project files on filesystem | 1 | +| Reachable fallback NuGet feed count | 1 | +| Resolved assembly conflicts | 0 | +| Resource extraction enabled | 0 | +| Restored .NET framework variants | 1 | +| Restored projects through solution files | 0 | +| Solution files on filesystem | 0 | +| Source files generated | 0 | +| Source files on filesystem | 1 | +| Successfully restored project files | 1 | +| Successfully restored solution files | 0 | +| Unresolved references | 0 | +| UseWPF set | 0 | +| UseWindowsForms set | 0 | +| WebView extraction enabled | 1 | diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_clear/CompilationInfo.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_clear/CompilationInfo.ql index 073ffe3b224d..ae7505a8b0be 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_clear/CompilationInfo.ql +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_clear/CompilationInfo.ql @@ -1,15 +1,8 @@ import csharp import semmle.code.csharp.commons.Diagnostics -query predicate compilationInfo(string key, float value) { +query predicate compilationInfo(string key, string value) { key != "Resolved references" and not key.matches("Compiler diagnostic count for%") and - exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | - key = infoKey and - value = infoValue.toFloat() - or - not exists(infoValue.toFloat()) and - key = infoKey + ": " + infoValue and - value = 1 - ) + value = any(Compilation c).getInfo(key) } diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.expected index 4acd4f54e8a6..c5cb911d3731 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.expected @@ -1,24 +1,25 @@ -| All NuGet feeds reachable | 0.0 | -| Failed project restore with missing package error | 1.0 | -| Failed project restore with package source error | 0.0 | -| Failed solution restore with missing package error | 0.0 | -| Failed solution restore with package source error | 0.0 | -| Fallback nuget restore | 1.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 | -| Resolved assembly conflicts | 7.0 | -| Resource extraction enabled | 0.0 | -| Restored .NET framework variants | 0.0 | -| Restored projects through solution files | 0.0 | -| Solution files on filesystem | 1.0 | -| Source files generated | 0.0 | -| Source files on filesystem | 1.0 | -| Successfully ran fallback nuget restore | 1.0 | -| Successfully restored project files | 0.0 | -| Successfully restored solution files | 1.0 | -| Unresolved references | 0.0 | -| UseWPF set | 0.0 | -| UseWindowsForms set | 0.0 | -| WebView extraction enabled | 1.0 | +| All NuGet feeds reachable | 0 | +| Failed project restore with missing package error | 1 | +| Failed project restore with package source error | 0 | +| Failed solution restore with missing package error | 0 | +| Failed solution restore with package source error | 0 | +| Fallback nuget restore | 1 | +| Inherited NuGet feed count | 1 | +| NuGet feed responsiveness checked | 1 | +| Project files on filesystem | 1 | +| Reachable fallback NuGet feed count | 1 | +| Resolved assembly conflicts | 7 | +| Resource extraction enabled | 0 | +| Restored .NET framework variants | 0 | +| Restored projects through solution files | 0 | +| Solution files on filesystem | 1 | +| Source files generated | 0 | +| Source files on filesystem | 1 | +| Successfully ran fallback nuget restore | 1 | +| Successfully restored project files | 0 | +| Successfully restored solution files | 1 | +| Unreachable NuGet feeds | https://abc.abc/packages/ | +| Unresolved references | 0 | +| UseWPF set | 0 | +| UseWindowsForms set | 0 | +| WebView extraction enabled | 1 | diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.ql index 073ffe3b224d..ae7505a8b0be 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.ql +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error/CompilationInfo.ql @@ -1,15 +1,8 @@ import csharp import semmle.code.csharp.commons.Diagnostics -query predicate compilationInfo(string key, float value) { +query predicate compilationInfo(string key, string value) { key != "Resolved references" and not key.matches("Compiler diagnostic count for%") and - exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | - key = infoKey and - value = infoValue.toFloat() - or - not exists(infoValue.toFloat()) and - key = infoKey + ": " + infoValue and - value = 1 - ) + value = any(Compilation c).getInfo(key) } diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected index 4acd4f54e8a6..680a7960a06c 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.expected @@ -1,24 +1,25 @@ -| All NuGet feeds reachable | 0.0 | -| Failed project restore with missing package error | 1.0 | -| Failed project restore with package source error | 0.0 | -| Failed solution restore with missing package error | 0.0 | -| Failed solution restore with package source error | 0.0 | -| Fallback nuget restore | 1.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 | -| Resolved assembly conflicts | 7.0 | -| Resource extraction enabled | 0.0 | -| Restored .NET framework variants | 0.0 | -| Restored projects through solution files | 0.0 | -| Solution files on filesystem | 1.0 | -| Source files generated | 0.0 | -| Source files on filesystem | 1.0 | -| Successfully ran fallback nuget restore | 1.0 | -| Successfully restored project files | 0.0 | -| Successfully restored solution files | 1.0 | -| Unresolved references | 0.0 | -| UseWPF set | 0.0 | -| UseWindowsForms set | 0.0 | -| WebView extraction enabled | 1.0 | +| All NuGet feeds reachable | 0 | +| Failed project restore with missing package error | 1 | +| Failed project restore with package source error | 0 | +| Failed solution restore with missing package error | 0 | +| Failed solution restore with package source error | 0 | +| Fallback nuget restore | 1 | +| Inherited NuGet feed count | 1 | +| NuGet feed responsiveness checked | 1 | +| Project files on filesystem | 1 | +| Reachable fallback NuGet feed count | 1 | +| Resolved assembly conflicts | 7 | +| Resource extraction enabled | 0 | +| Restored .NET framework variants | 0 | +| Restored projects through solution files | 0 | +| Solution files on filesystem | 1 | +| Source files generated | 0 | +| Source files on filesystem | 1 | +| Successfully ran fallback nuget restore | 1 | +| Successfully restored project files | 0 | +| Successfully restored solution files | 1 | +| Unreachable NuGet feeds | https://localhost:53/packages/, https://localhost:80/packages/ | +| Unresolved references | 0 | +| UseWPF set | 0 | +| UseWindowsForms set | 0 | +| WebView extraction enabled | 1 | diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.ql index 073ffe3b224d..ae7505a8b0be 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.ql +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/CompilationInfo.ql @@ -1,15 +1,8 @@ import csharp import semmle.code.csharp.commons.Diagnostics -query predicate compilationInfo(string key, float value) { +query predicate compilationInfo(string key, string value) { key != "Resolved references" and not key.matches("Compiler diagnostic count for%") and - exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | - key = infoKey and - value = infoValue.toFloat() - or - not exists(infoValue.toFloat()) and - key = infoKey + ": " + infoValue and - value = 1 - ) + value = any(Compilation c).getInfo(key) } diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/diagnostics.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/diagnostics.expected index bbd2081f4554..074e4bd48ae9 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/diagnostics.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_error_timeout/diagnostics.expected @@ -27,12 +27,12 @@ } } { - "markdownMessage": "Found unreachable NuGet feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis.", + "markdownMessage": "Found unreachable NuGet feeds in C# analysis with build-mode 'none':\n\n- `https://localhost:53/packages/`\n- `https://localhost:80/packages/`\n\nThis may cause missing dependencies in the analysis.", "severity": "note", "source": { "extractorName": "csharp", "id": "csharp/autobuilder/buildless/unreachable-feed", - "name": "Found unreachable NuGet feed in C# analysis with build-mode 'none'" + "name": "Found unreachable NuGet feeds in C# analysis with build-mode 'none'" }, "visibility": { "cliSummaryTable": true, diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected index d421cfc42e1a..384d64a59855 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.expected @@ -1,24 +1,25 @@ -| All NuGet feeds reachable | 0.0 | -| Failed project restore with missing package error | 1.0 | -| Failed project restore with package source error | 0.0 | -| Failed solution restore with missing package error | 0.0 | -| Failed solution restore with package source error | 0.0 | -| Fallback nuget restore | 1.0 | -| Inherited NuGet feed count | 1.0 | -| NuGet feed responsiveness checked | 1.0 | -| Project files on filesystem | 1.0 | -| Reachable fallback NuGet feed count | 2.0 | -| Resolved assembly conflicts | 7.0 | -| Resource extraction enabled | 0.0 | -| Restored .NET framework variants | 0.0 | -| Restored projects through solution files | 0.0 | -| Solution files on filesystem | 1.0 | -| Source files generated | 0.0 | -| Source files on filesystem | 1.0 | -| Successfully ran fallback nuget restore | 1.0 | -| Successfully restored project files | 0.0 | -| Successfully restored solution files | 1.0 | -| Unresolved references | 0.0 | -| UseWPF set | 0.0 | -| UseWindowsForms set | 0.0 | -| WebView extraction enabled | 1.0 | +| All NuGet feeds reachable | 0 | +| Failed project restore with missing package error | 1 | +| Failed project restore with package source error | 0 | +| Failed solution restore with missing package error | 0 | +| Failed solution restore with package source error | 0 | +| Fallback nuget restore | 1 | +| Inherited NuGet feed count | 1 | +| NuGet feed responsiveness checked | 1 | +| Project files on filesystem | 1 | +| Reachable fallback NuGet feed count | 2 | +| Resolved assembly conflicts | 7 | +| Resource extraction enabled | 0 | +| Restored .NET framework variants | 0 | +| Restored projects through solution files | 0 | +| Solution files on filesystem | 1 | +| Source files generated | 0 | +| Source files on filesystem | 1 | +| Successfully ran fallback nuget restore | 1 | +| Successfully restored project files | 0 | +| Successfully restored solution files | 1 | +| Unreachable NuGet feeds | https://www.nuget.org/api/v2/ | +| Unresolved references | 0 | +| UseWPF set | 0 | +| UseWindowsForms set | 0 | +| WebView extraction enabled | 1 | diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.ql b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.ql index 073ffe3b224d..ae7505a8b0be 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.ql +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/CompilationInfo.ql @@ -1,15 +1,8 @@ import csharp import semmle.code.csharp.commons.Diagnostics -query predicate compilationInfo(string key, float value) { +query predicate compilationInfo(string key, string value) { key != "Resolved references" and not key.matches("Compiler diagnostic count for%") and - exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | - key = infoKey and - value = infoValue.toFloat() - or - not exists(infoValue.toFloat()) and - key = infoKey + ": " + infoValue and - value = 1 - ) + value = any(Compilation c).getInfo(key) } diff --git a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/diagnostics.expected b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/diagnostics.expected index bbd2081f4554..66867fd38eeb 100644 --- a/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/diagnostics.expected +++ b/csharp/ql/integration-tests/posix/standalone_dependencies_nuget_config_fallback/diagnostics.expected @@ -27,12 +27,12 @@ } } { - "markdownMessage": "Found unreachable NuGet feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis.", + "markdownMessage": "Found unreachable NuGet feeds in C# analysis with build-mode 'none':\n\n- `https://www.nuget.org/api/v2/`\n\nThis may cause missing dependencies in the analysis.", "severity": "note", "source": { "extractorName": "csharp", "id": "csharp/autobuilder/buildless/unreachable-feed", - "name": "Found unreachable NuGet feed in C# analysis with build-mode 'none'" + "name": "Found unreachable NuGet feeds in C# analysis with build-mode 'none'" }, "visibility": { "cliSummaryTable": true, From a7acd5cfe6ccccd40b222202cb273e7f043329fc Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 18 Aug 2026 08:28:47 +0200 Subject: [PATCH 7/7] C#: Add change-note. --- .../change-notes/2026-08-18-tsp-nuget-feed-reachability.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2026-08-18-tsp-nuget-feed-reachability.md diff --git a/csharp/ql/lib/change-notes/2026-08-18-tsp-nuget-feed-reachability.md b/csharp/ql/lib/change-notes/2026-08-18-tsp-nuget-feed-reachability.md new file mode 100644 index 000000000000..fc391ad6f804 --- /dev/null +++ b/csharp/ql/lib/change-notes/2026-08-18-tsp-nuget-feed-reachability.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* C# analysis with build mode `none` now lists unreachable explicitly configured NuGet feeds in both the extraction warning and the tool status page note. This makes it easier to identify feeds that may cause dependencies to be missing from the analysis.