Skip to content

C#: Change random temp folder names to hash values #17257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ public NugetPackageRestorer(
this.logger = logger;
this.compilationInfoContainer = compilationInfoContainer;

PackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath(fileProvider.SourceDir.FullName, "packages"), "package", logger);
legacyPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath(fileProvider.SourceDir.FullName, "legacypackages"), "legacy package", logger);
missingPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath(fileProvider.SourceDir.FullName, "missingpackages"), "missing package", logger);
PackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("packages"), "package", logger);
legacyPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("legacypackages"), "legacy package", logger);
missingPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("missingpackages"), "missing package", logger);
}

public string? TryRestore(string package)
Expand Down Expand Up @@ -338,7 +338,7 @@ private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<Dep
}

logger.LogInfo($"Found {notYetDownloadedPackages.Count} packages that are not yet restored");
using var tempDir = new TemporaryDirectory(ComputeTempDirectoryPath(fileProvider.SourceDir.FullName, "nugetconfig"), "generated nuget config", logger);
using var tempDir = new TemporaryDirectory(ComputeTempDirectoryPath("nugetconfig"), "generated nuget config", logger);
var nugetConfig = fallbackNugetFeeds is null
? GetNugetConfig()
: CreateFallbackNugetConfig(fallbackNugetFeeds, tempDir.DirInfo.FullName);
Expand Down Expand Up @@ -771,19 +771,19 @@ public void Dispose()
}

/// <summary>
/// Computes a unique temp directory for the packages associated
/// with this source tree. Use a SHA1 of the directory name.
/// Returns the full path to a temporary directory with the given subfolder name.
/// </summary>
/// <returns>The full path of the temp directory.</returns>
private static string ComputeTempDirectoryPath(string srcDir, string subfolderName)
private static string ComputeTempDirectoryPath(string subfolderName)
{
var bytes = Encoding.Unicode.GetBytes(srcDir);
var sha = SHA1.HashData(bytes);
var sb = new StringBuilder();
foreach (var b in sha.Take(8))
sb.AppendFormat("{0:x2}", b);
return Path.Combine(FileUtils.GetTemporaryWorkingDirectory(out _), subfolderName);
}

return Path.Combine(FileUtils.GetTemporaryWorkingDirectory(out _), sb.ToString(), subfolderName);
/// <summary>
/// Computes a unique temporary directory path based on the source directory and the subfolder name.
/// </summary>
private static string ComputeTempDirectoryPath(string srcDir, string subfolderName)
{
return Path.Combine(FileUtils.GetTemporaryWorkingDirectory(out _), FileUtils.ComputeHash(srcDir), subfolderName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ protected override IEnumerable<string> Run()
var targetDir = GetTemporaryWorkingDirectory(FileType.ToLowerInvariant());

return groupedFiles
.SelectMany(group => sourceGenerator.RunSourceGenerator(group.Value, group.Key, references, targetDir));
.SelectMany(group => sourceGenerator.RunSourceGenerator(group.Value, group.Key, references, targetDir, fileProvider.SourceDir.FullName));
}
catch (Exception ex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ public DotnetSourceGeneratorWrapper(

protected abstract void GenerateAnalyzerConfig(IEnumerable<string> additionalFiles, string csprojFile, string analyzerConfigPath);

public IEnumerable<string> RunSourceGenerator(IEnumerable<string> additionalFiles, string csprojFile, IEnumerable<string> references, string targetDir)
public IEnumerable<string> RunSourceGenerator(IEnumerable<string> additionalFiles, string csprojFile, IEnumerable<string> references, string targetDir, string sourceDir)
{
try
{
var name = Guid.NewGuid().ToString("N").ToUpper();
var relativePathToCsProj = Path.GetRelativePath(sourceDir, csprojFile);
var name = FileUtils.ComputeHash($"{relativePathToCsProj}\n{this.GetType().Name}");
using var tempDir = new TemporaryDirectory(Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), "source-generator"), "source generator temporary", logger);
var analyzerConfigPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.txt");
var dllPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.dll");
Expand Down
22 changes: 19 additions & 3 deletions csharp/extractor/Semmle.Util/FileUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,32 @@ public static void TryDelete(string file)
}

/// <summary>
/// Computes the hash of <paramref name="filePath"/>.
/// Computes the hash of the file at <paramref name="filePath"/>.
/// </summary>
public static string ComputeFileHash(string filePath)
{
using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
using var shaAlg = SHA256.Create();
var sha = shaAlg.ComputeHash(fileStream);
var sha = SHA256.HashData(fileStream);
return GetHashString(sha);
}

/// <summary>
/// Computes the hash of <paramref name="input"/>.
/// </summary>
public static string ComputeHash(string input)
{
var bytes = Encoding.Unicode.GetBytes(input);
var sha = MD5.HashData(bytes); // MD5 to keep it shorter than SHA256
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried calculating the propability of collision for 1k elements on a 128bit hash - the calculator rounded it to 0 😂

return GetHashString(sha).ToUpper();
}

private static string GetHashString(byte[] sha)
{
var hex = new StringBuilder(sha.Length * 2);
foreach (var b in sha)
{
hex.AppendFormat("{0:x2}", b);
}
return hex.ToString();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
| Program.cs |
| Views/Home/Index.cshtml |
| _ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_test_test_Views_Home_Index_cshtml.g.cs |
| test-db/working/implicitUsings/GlobalUsings.g.cs |
| test-db/working/razor/EC52D77FE9BF67AD10C5C3F248392316/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/[...]_ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_test_test_Views_Home_Index_cshtml.g.cs |
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ private string getPath(File f) {
result = f.getRelativePath() and
not exists(result.indexOf("_ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_"))
or
exists(int index |
index =
exists(int index1, int index2, string pattern |
pattern = "Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator" and
index1 = f.getRelativePath().indexOf(pattern) and
index2 =
f.getRelativePath()
.indexOf("_ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_") and
result = f.getRelativePath().substring(index, f.getRelativePath().length())
result =
f.getRelativePath().substring(0, index1 + pattern.length()) + "/[...]" +
f.getRelativePath().substring(index2, f.getRelativePath().length())
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
| Program.cs |
| test-db/working/implicitUsings/GlobalUsings.g.cs |
| Program.cs:0:0:0:0 | Program.cs |
| test-db/working/implicitUsings/GlobalUsings.g.cs:0:0:0:0 | test-db/working/implicitUsings/GlobalUsings.g.cs |
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
import csharp

private string getPath(File f) {
result = f.getRelativePath() and
not exists(
result
.indexOf("_semmle_code_target_codeql_csharp_integration_tests_ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_")
)
or
exists(int index |
index =
f.getRelativePath()
.indexOf("_semmle_code_target_codeql_csharp_integration_tests_ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_") and
result = f.getRelativePath().substring(index, f.getRelativePath().length())
)
}

from File f
where f.fromSource() or f.getExtension() = "cshtml"
select getPath(f)
select f
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
| Program.cs |
| Views/Home/Index.cshtml |
| _ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_net6_test_test_Views_Home_Index_cshtml.g.cs |
| test-db/working/implicitUsings/GlobalUsings.g.cs |
| test-db/working/razor/EC52D77FE9BF67AD10C5C3F248392316/[...]/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/[...]_ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_net6_test_test_Views_Home_Index_cshtml.g.cs |
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@ private string getPath(File f) {
result = f.getRelativePath() and
not exists(result.indexOf("_ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_"))
or
exists(int index |
index =
exists(int index0, int index1, int index2, string pattern0, string pattern1 |
// TODO: Remove index0 and pattern0. Currently there's some instability in the path depending on which dotnet SDK is being used. (See issue #448)
pattern0 = "EC52D77FE9BF67AD10C5C3F248392316" and
index0 = f.getRelativePath().indexOf(pattern0) and
pattern1 = "Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator" and
index1 = f.getRelativePath().indexOf(pattern1) and
index2 =
f.getRelativePath()
.indexOf("_ql_csharp_ql_integration_tests_all_platforms_cshtml_standalone_") and
result = f.getRelativePath().substring(index, f.getRelativePath().length())
result =
f.getRelativePath().substring(0, index0 + pattern0.length()) + "/[...]/" +
f.getRelativePath().substring(index1, index1 + pattern1.length()) + "/[...]" +
f.getRelativePath().substring(index2, f.getRelativePath().length())
)
}

Expand Down
Loading
Loading