mirror of
https://github.com/github/codeql.git
synced 2026-04-24 16:25:15 +02:00
C#: Add framework detection to the assets.json parser.
This commit is contained in:
@@ -68,19 +68,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// Returns dependencies
|
||||
/// RequiredPaths = {
|
||||
/// Adds the following dependencies
|
||||
/// Paths: {
|
||||
/// "castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll",
|
||||
/// "json.net/1.0.33/lib/netstandard2.0/Json.Net.dll"
|
||||
/// }
|
||||
/// UsedPackages = {
|
||||
/// Packages: {
|
||||
/// "castle.core",
|
||||
/// "json.net"
|
||||
/// }
|
||||
/// </summary>
|
||||
private DependencyContainer AddPackageDependencies(JObject json, DependencyContainer dependencies)
|
||||
private void AddPackageDependencies(JObject json, DependencyContainer dependencies)
|
||||
{
|
||||
// If there are more than one framework we need to pick just one.
|
||||
// If there is more than one framework we need to pick just one.
|
||||
// To ensure stability we pick one based on the lexicographic order of
|
||||
// the framework names.
|
||||
var references = json
|
||||
@@ -93,7 +93,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
if (references is null)
|
||||
{
|
||||
progressMonitor.LogDebug("No references found in the targets section in the assets file.");
|
||||
return dependencies;
|
||||
return;
|
||||
}
|
||||
|
||||
// Find all the compile dependencies for each reference and
|
||||
@@ -111,7 +111,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
// If this is a .NET framework reference then include everything.
|
||||
if (netFrameworks.Any(framework => name.StartsWith(framework)))
|
||||
{
|
||||
dependencies.Add(name);
|
||||
dependencies.AddFramework(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -120,7 +120,69 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
});
|
||||
|
||||
return dependencies;
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the framework dependencies from the assets file to dependencies.
|
||||
///
|
||||
/// Example:
|
||||
/// "project": {
|
||||
// "version": "1.0.0",
|
||||
// "frameworks": {
|
||||
// "net7.0": {
|
||||
// "frameworkReferences": {
|
||||
// "Microsoft.AspNetCore.App": {
|
||||
// "privateAssets": "none"
|
||||
// },
|
||||
// "Microsoft.NETCore.App": {
|
||||
// "privateAssets": "all"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
/// Adds the following dependencies
|
||||
/// Paths: {
|
||||
/// "microsoft.aspnetcore.app.ref",
|
||||
/// "microsoft.netcore.app.ref"
|
||||
/// }
|
||||
/// Packages: {
|
||||
/// "microsoft.aspnetcore.app.ref",
|
||||
/// "microsoft.netcore.app.ref"
|
||||
/// }
|
||||
/// </summary>
|
||||
private void AddFrameworkDependencies(JObject json, DependencyContainer dependencies)
|
||||
{
|
||||
|
||||
var frameworks = json
|
||||
.GetProperty("project")?
|
||||
.GetProperty("frameworks");
|
||||
|
||||
if (frameworks is null)
|
||||
{
|
||||
progressMonitor.LogDebug("No framework section in assets.json.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is more than one framework we need to pick just one.
|
||||
// To ensure stability we pick one based on the lexicographic order of
|
||||
// the framework names.
|
||||
var references = frameworks
|
||||
.Properties()?
|
||||
.MaxBy(p => p.Name)?
|
||||
.Value["frameworkReferences"] as JObject;
|
||||
|
||||
if (references is null)
|
||||
{
|
||||
progressMonitor.LogDebug("No framework references in assets.json.");
|
||||
return;
|
||||
}
|
||||
|
||||
references
|
||||
.Properties()
|
||||
.ForEach(f => dependencies.AddFramework($"{f.Name}.Ref".ToLowerInvariant()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -134,6 +196,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
var obj = JObject.Parse(json);
|
||||
AddPackageDependencies(obj, dependencies);
|
||||
AddFrameworkDependencies(obj, dependencies);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -9,8 +9,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// </summary>
|
||||
internal class DependencyContainer
|
||||
{
|
||||
private readonly List<string> requiredPaths = new();
|
||||
private readonly HashSet<string> usedPackages = new();
|
||||
/// <summary>
|
||||
/// Paths to dependencies required for compilation.
|
||||
/// </summary>
|
||||
public List<string> Paths { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Packages that are used as a part of the required dependencies.
|
||||
/// </summary>
|
||||
public HashSet<string> Packages { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// In most cases paths in asset files point to dll's or the empty _._ file, which
|
||||
@@ -32,16 +39,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
.Split(Path.DirectorySeparatorChar)
|
||||
.First();
|
||||
|
||||
/// <summary>
|
||||
/// Paths to dependencies required for compilation.
|
||||
/// </summary>
|
||||
public IEnumerable<string> RequiredPaths => requiredPaths;
|
||||
|
||||
/// <summary>
|
||||
/// Packages that are used as a part of the required dependencies.
|
||||
/// </summary>
|
||||
public HashSet<string> UsedPackages => usedPackages;
|
||||
|
||||
/// <summary>
|
||||
/// Add a dependency inside a package.
|
||||
/// </summary>
|
||||
@@ -51,19 +48,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
var d = dependency.Replace('/', Path.DirectorySeparatorChar);
|
||||
|
||||
var path = Path.Combine(p, ParseFilePath(d));
|
||||
requiredPaths.Add(path);
|
||||
usedPackages.Add(GetPackageName(p));
|
||||
Paths.Add(path);
|
||||
Packages.Add(GetPackageName(p));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a dependency to an entire package
|
||||
/// Add a dependency to an entire framework package.
|
||||
/// </summary>
|
||||
public void Add(string package)
|
||||
public void AddFramework(string framework)
|
||||
{
|
||||
var p = package.Replace('/', Path.DirectorySeparatorChar);
|
||||
var p = framework.Replace('/', Path.DirectorySeparatorChar);
|
||||
|
||||
requiredPaths.Add(p);
|
||||
usedPackages.Add(GetPackageName(p));
|
||||
Paths.Add(p);
|
||||
Packages.Add(GetPackageName(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
var dependencies = Assets.GetCompilationDependencies(progressMonitor, assets1.Union(assets2));
|
||||
|
||||
var paths = dependencies
|
||||
.RequiredPaths
|
||||
.Paths
|
||||
.Select(d => Path.Combine(packageDirectory.DirInfo.FullName, d))
|
||||
.ToList();
|
||||
dllPaths.UnionWith(paths);
|
||||
@@ -356,7 +356,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
private void LogAllUnusedPackages(DependencyContainer dependencies) =>
|
||||
GetAllPackageDirectories()
|
||||
.Where(package => !dependencies.UsedPackages.Contains(package))
|
||||
.Where(package => !dependencies.Packages.Contains(package))
|
||||
.ForEach(package => progressMonitor.LogInfo($"Unused package: {package}"));
|
||||
|
||||
private void GenerateSourceFileFromImplicitUsings()
|
||||
|
||||
Reference in New Issue
Block a user