up
Some checks failed
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-12-13 09:37:15 +02:00
parent e00f6365da
commit 6e45066e37
349 changed files with 17160 additions and 1867 deletions

View File

@@ -1,3 +1,4 @@
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
@@ -125,6 +126,137 @@ public sealed class PythonLanguageAnalyzerTests
}
}
[Fact]
public async Task EditableRequirementsUseExplicitKeyWithoutHostPathLeakAsync()
{
var cancellationToken = TestContext.Current.CancellationToken;
var fixturePath = CreateTemporaryWorkspace();
try
{
var editableDir = Path.Combine(fixturePath, "editable-src");
Directory.CreateDirectory(editableDir);
var requirementsPath = Path.Combine(fixturePath, "requirements.txt");
await File.WriteAllTextAsync(requirementsPath, $"--editable {editableDir}{Environment.NewLine}", cancellationToken);
var analyzers = new ILanguageAnalyzer[]
{
new PythonLanguageAnalyzer()
};
var json = await LanguageAnalyzerTestHarness.RunToJsonAsync(
fixturePath,
analyzers,
cancellationToken);
using var document = JsonDocument.Parse(json);
var root = document.RootElement;
foreach (var component in root.EnumerateArray())
{
if (component.TryGetProperty("purl", out var purlElement) && purlElement.ValueKind == JsonValueKind.String)
{
Assert.DoesNotContain("@editable", purlElement.GetString(), StringComparison.OrdinalIgnoreCase);
}
}
var editableComponent = root.EnumerateArray().Single(static component =>
component.TryGetProperty("name", out var nameElement)
&& string.Equals("editable-src", nameElement.GetString(), StringComparison.OrdinalIgnoreCase));
Assert.True(!editableComponent.TryGetProperty("purl", out var purlValue) || purlValue.ValueKind == JsonValueKind.Null);
var componentKey = editableComponent.GetProperty("componentKey").GetString();
Assert.StartsWith("explicit::python::pypi::editable-src::sha256:", componentKey, StringComparison.Ordinal);
var metadata = editableComponent.GetProperty("metadata");
Assert.Equal("true", metadata.GetProperty("declaredOnly").GetString());
Assert.Equal("editable", metadata.GetProperty("declared.sourceType").GetString());
Assert.Equal("requirements.txt", metadata.GetProperty("declared.source").GetString());
Assert.Equal("requirements.txt", metadata.GetProperty("declared.locator").GetString());
var editableSpec = metadata.GetProperty("lockEditablePath").GetString();
Assert.Equal("editable-src", editableSpec);
Assert.DoesNotContain(fixturePath, editableSpec, StringComparison.OrdinalIgnoreCase);
Assert.DoesNotContain(":", editableSpec, StringComparison.Ordinal);
}
finally
{
Directory.Delete(fixturePath, recursive: true);
}
}
[Fact]
public async Task WheelArchiveDistInfo_IsVerifiedFromRecordAsync()
{
var cancellationToken = TestContext.Current.CancellationToken;
var fixturePath = CreateTemporaryWorkspace();
try
{
var distDir = Path.Combine(fixturePath, "dist");
Directory.CreateDirectory(distDir);
var wheelPath = Path.Combine(distDir, "archivepkg-1.0.0-py3-none-any.whl");
var initBytes = Encoding.UTF8.GetBytes("__version__ = \"1.0.0\"\n");
var metadataBytes = Encoding.UTF8.GetBytes(
$"Metadata-Version: 2.1\nName: archivepkg\nVersion: 1.0.0\n{Environment.NewLine}");
var wheelBytes = Encoding.UTF8.GetBytes(
"Wheel-Version: 1.0\nGenerator: test\nRoot-Is-Purelib: true\nTag: py3-none-any\n");
var recordContent = new StringBuilder()
.AppendLine($"archivepkg/__init__.py,sha256={ComputeSha256Base64(initBytes)},{initBytes.Length}")
.AppendLine($"archivepkg-1.0.0.dist-info/METADATA,sha256={ComputeSha256Base64(metadataBytes)},{metadataBytes.Length}")
.AppendLine($"archivepkg-1.0.0.dist-info/WHEEL,sha256={ComputeSha256Base64(wheelBytes)},{wheelBytes.Length}")
.AppendLine("archivepkg-1.0.0.dist-info/RECORD,,")
.ToString();
var recordBytes = Encoding.UTF8.GetBytes(recordContent);
using (var stream = File.Create(wheelPath))
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: false))
{
WriteEntry(archive, "archivepkg/__init__.py", initBytes);
WriteEntry(archive, "archivepkg-1.0.0.dist-info/METADATA", metadataBytes);
WriteEntry(archive, "archivepkg-1.0.0.dist-info/WHEEL", wheelBytes);
WriteEntry(archive, "archivepkg-1.0.0.dist-info/RECORD", recordBytes);
}
var analyzers = new ILanguageAnalyzer[]
{
new PythonLanguageAnalyzer()
};
var json = await LanguageAnalyzerTestHarness.RunToJsonAsync(
fixturePath,
analyzers,
cancellationToken);
using var document = JsonDocument.Parse(json);
var root = document.RootElement;
Assert.True(ComponentHasMetadata(root, "archivepkg", "record.totalEntries", "4"));
Assert.True(ComponentHasMetadata(root, "archivepkg", "record.hashedEntries", "3"));
Assert.True(ComponentHasMetadata(root, "archivepkg", "record.missingFiles", "0"));
Assert.True(ComponentHasMetadata(root, "archivepkg", "record.hashMismatches", "0"));
Assert.True(ComponentHasMetadata(root, "archivepkg", "record.ioErrors", "0"));
}
finally
{
Directory.Delete(fixturePath, recursive: true);
}
static void WriteEntry(ZipArchive archive, string entryName, byte[] content)
{
var entry = archive.CreateEntry(entryName);
using var entryStream = entry.Open();
entryStream.Write(content, 0, content.Length);
}
static string ComputeSha256Base64(byte[] content)
=> Convert.ToBase64String(SHA256.HashData(content));
}
private static async Task CreatePythonPackageAsync(string root, string name, string version, CancellationToken cancellationToken)
{
var sitePackages = Path.Combine(root, "lib", "python3.11", "site-packages");