Skip to content

Commit 239776b

Browse files
authored
Merge pull request #16124 from tamasvajk/buildless/nuget-feed-precheck
C#: Validate all nuget feeds to respond in reasonable time
2 parents 5f8eb7b + 80995ec commit 239776b

File tree

18 files changed

+726
-362
lines changed

18 files changed

+726
-362
lines changed

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.Nuget.cs

Lines changed: 514 additions & 0 deletions
Large diffs are not rendered by default.

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs

Lines changed: 23 additions & 353 deletions
Large diffs are not rendered by default.

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
1616
public partial class DotNet : IDotNet
1717
{
1818
private readonly IDotNetCliInvoker dotnetCliInvoker;
19+
private readonly ILogger logger;
1920
private readonly TemporaryDirectory? tempWorkingDirectory;
2021

2122
private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, TemporaryDirectory? tempWorkingDirectory = null)
2223
{
2324
this.tempWorkingDirectory = tempWorkingDirectory;
2425
this.dotnetCliInvoker = dotnetCliInvoker;
26+
this.logger = logger;
2527
Info();
2628
}
2729

@@ -89,17 +91,18 @@ public bool AddPackage(string folder, string package)
8991
return dotnetCliInvoker.RunCommand(args);
9092
}
9193

92-
public IList<string> GetListedRuntimes() => GetListed("--list-runtimes");
94+
public IList<string> GetListedRuntimes() => GetResultList("--list-runtimes");
9395

94-
public IList<string> GetListedSdks() => GetListed("--list-sdks");
96+
public IList<string> GetListedSdks() => GetResultList("--list-sdks");
9597

96-
private IList<string> GetListed(string args)
98+
private IList<string> GetResultList(string args)
9799
{
98-
if (dotnetCliInvoker.RunCommand(args, out var artifacts))
100+
if (dotnetCliInvoker.RunCommand(args, out var results))
99101
{
100-
return artifacts;
102+
return results;
101103
}
102-
return new List<string>();
104+
logger.LogWarning($"Running 'dotnet {args}' failed.");
105+
return [];
103106
}
104107

105108
public bool Exec(string execArgs)
@@ -108,6 +111,8 @@ public bool Exec(string execArgs)
108111
return dotnetCliInvoker.RunCommand(args);
109112
}
110113

114+
public IList<string> GetNugetFeeds(string nugetConfig) => GetResultList($"nuget list source --format Short --configfile \"{nugetConfig}\"");
115+
111116
// The version number should be kept in sync with the version .NET version used for building the application.
112117
public const string LatestDotNetSdkVersion = "8.0.101";
113118

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,30 @@ internal class EnvironmentVariableNames
1616
/// Controls whether to use framework dependencies from subfolders.
1717
/// </summary>
1818
public const string DotnetFrameworkReferencesUseSubfolders = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_DOTNET_FRAMEWORK_REFERENCES_USE_SUBFOLDERS";
19+
20+
/// <summary>
21+
/// Controls whether to check the responsiveness of NuGet feeds.
22+
/// </summary>
23+
public const string CheckNugetFeedResponsiveness = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK";
24+
25+
/// <summary>
26+
/// Specifies the NuGet feeds to exclude from the responsiveness check. The value is a space-separated list of feed URLs.
27+
/// </summary>
28+
public const string ExcludedNugetFeedsFromResponsivenessCheck = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_EXCLUDED";
29+
30+
/// <summary>
31+
/// Specifies the timeout (as an integer) in milliseconds for the initial check of NuGet feeds responsiveness. The value is then doubled for each subsequent check.
32+
/// </summary>
33+
public const string NugetFeedResponsivenessInitialTimeout = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_TIMEOUT";
34+
35+
/// <summary>
36+
/// Specifies how many requests to make to the NuGet feed to check its responsiveness.
37+
/// </summary>
38+
public const string NugetFeedResponsivenessRequestCount = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_LIMIT";
39+
40+
/// <summary>
41+
/// Specifies the location of the diagnostic directory.
42+
/// </summary>
43+
public const string DiagnosticDir = "CODEQL_EXTRACTOR_CSHARP_DIAGNOSTIC_DIR";
1944
}
2045
}

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNet.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public interface IDotNet
1313
IList<string> GetListedRuntimes();
1414
IList<string> GetListedSdks();
1515
bool Exec(string execArgs);
16+
IList<string> GetNugetFeeds(string nugetConfig);
1617
}
1718

1819
public record class RestoreSettings(string File, string PackageDirectory, bool ForceDotnetRefAssemblyFetching, string? PathToNugetConfig = null, bool ForceReevaluation = false);

csharp/extractor/Semmle.Extraction.Tests/Runtime.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public DotNetStub(IList<string> runtimes, IList<string> sdks)
2626
public IList<string> GetListedSdks() => sdks;
2727

2828
public bool Exec(string execArgs) => true;
29+
30+
public IList<string> GetNugetFeeds(string nugetConfig) => [];
2931
}
3032

3133
public class RuntimeTests

csharp/extractor/Semmle.Util/EnvironmentVariables.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,12 @@ public static int GetDefaultNumberOfThreads()
2727
}
2828
return threads;
2929
}
30+
31+
public static bool GetBoolean(string name)
32+
{
33+
var env = Environment.GetEnvironmentVariable(name);
34+
var _ = bool.TryParse(env, out var value);
35+
return value;
36+
}
3037
}
3138
}

csharp/extractor/Semmle.Util/FileUtils.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ public static string ComputeFileHash(string filePath)
102102
private static async Task DownloadFileAsync(string address, string filename)
103103
{
104104
using var httpClient = new HttpClient();
105-
using var request = new HttpRequestMessage(HttpMethod.Get, address);
106-
using var contentStream = await (await httpClient.SendAsync(request)).Content.ReadAsStreamAsync();
105+
using var contentStream = await httpClient.GetStreamAsync(address);
107106
using var stream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true);
108107
await contentStream.CopyToAsync(stream);
109108
}
@@ -112,7 +111,7 @@ private static async Task DownloadFileAsync(string address, string filename)
112111
/// Downloads the file at <paramref name="address"/> to <paramref name="fileName"/>.
113112
/// </summary>
114113
public static void DownloadFile(string address, string fileName) =>
115-
DownloadFileAsync(address, fileName).Wait();
114+
DownloadFileAsync(address, fileName).GetAwaiter().GetResult();
116115

117116
public static string NestPaths(ILogger logger, string? outerpath, string innerpath)
118117
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| [...]/newtonsoft.json/13.0.3/lib/net6.0/Newtonsoft.Json.dll |
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import csharp
2+
3+
private string getPath(Assembly a) {
4+
not a.getCompilation().getOutputAssembly() = a and
5+
exists(string s | s = a.getFile().getAbsolutePath() |
6+
result = "[...]/" + s.substring(s.indexOf("newtonsoft.json"), s.length())
7+
)
8+
}
9+
10+
from Assembly a
11+
select getPath(a)

0 commit comments

Comments
 (0)