From c22504b51987a24528eac1a2c6af354260d626fe Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Tue, 17 Feb 2026 09:19:19 +0100 Subject: [PATCH 1/4] =?UTF-8?q?fix(filetypedetection):=20policy-045=20doku?= =?UTF-8?q?-=20und=20sprachverst=C3=B6sse=20bereinigen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/FileTypeDetection/ArchiveProcessing.vb | 7 - src/FileTypeDetection/FileMaterializer.vb | 22 +-- src/FileTypeDetection/FileTypeDetector.vb | 179 ++++++++---------- src/FileTypeDetection/FileTypeOptions.vb | 39 ++-- .../Infrastructure/ArchiveInternals.vb | 2 +- .../Infrastructure/CoreInternals.vb | 2 +- .../Net8_0Plus/HashPrimitivesProvider.vb | 29 +++ .../NetStandard2_0/HashPrimitivesProvider.vb | 29 +++ 8 files changed, 161 insertions(+), 148 deletions(-) diff --git a/src/FileTypeDetection/ArchiveProcessing.vb b/src/FileTypeDetection/ArchiveProcessing.vb index e12a2ca..1c400ce 100644 --- a/src/FileTypeDetection/ArchiveProcessing.vb +++ b/src/FileTypeDetection/ArchiveProcessing.vb @@ -40,9 +40,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' ''' Pfad zur zu prüfenden Datei. ''' True, wenn das Archiv die Sicherheitsregeln erfüllt; andernfalls False. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. Public Shared Function TryValidate _ ( path As String @@ -78,10 +75,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' True aktiviert eine vorgelagerte Typprüfung; False extrahiert direkt unter Sicherheitsregeln. ''' ''' Read-only Liste der extrahierten Einträge oder eine leere Liste bei Fehlern. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Archivstrukturen intern auftreten und wird fail-closed behandelt. Public Shared Function ExtractToMemory _ ( path As String, diff --git a/src/FileTypeDetection/FileMaterializer.vb b/src/FileTypeDetection/FileMaterializer.vb index 51daf36..97637e1 100644 --- a/src/FileTypeDetection/FileMaterializer.vb +++ b/src/FileTypeDetection/FileMaterializer.vb @@ -51,12 +51,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' Zu persistierende Nutzdaten. ''' Dateisystemziel für die Materialisierung. ''' True bei erfolgreicher Persistierung; andernfalls False. - ''' Kann aus I/O-Operationen intern auftreten und wird fail-closed behandelt. - ''' Kann bei Zugriff auf geschützte Pfade intern auftreten und wird fail-closed behandelt. - ''' Kann bei Datei- oder Verzeichniszugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Datenzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumenten intern auftreten und wird fail-closed behandelt. ''' ''' ''' Dim payload As Byte() = File.ReadAllBytes("input.bin") @@ -83,12 +77,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' Dateisystemziel für die Materialisierung. ''' True, um ein bestehendes Ziel gemäß Zielpfad-Policy zu ersetzen; sonst False. ''' True bei erfolgreicher Persistierung; andernfalls False. - ''' Kann aus I/O-Operationen intern auftreten und wird fail-closed behandelt. - ''' Kann bei Zugriff auf geschützte Pfade intern auftreten und wird fail-closed behandelt. - ''' Kann bei Datei- oder Verzeichniszugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Datenzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumenten intern auftreten und wird fail-closed behandelt. Public Shared Function Persist _ ( data As Byte(), @@ -119,12 +107,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' True, um ein vorhandenes Ziel gemäß Zielpfad-Policy zu ersetzen. ''' True, um Archivpayloads sicher zu validieren und zu extrahieren; sonst Rohpersistenz. ''' True bei erfolgreicher Materialisierung; andernfalls False. - ''' Kann bei Pfad- und I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevanten Dateisystemoperationen intern auftreten und wird fail-closed behandelt. - ''' Kann bei Dateisystemzugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Archiv- oder Payloaddaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfad-/I/O-Konstellationen intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumenten intern auftreten und wird fail-closed behandelt. Public Shared Function Persist _ ( data As Byte(), @@ -139,7 +121,7 @@ Namespace Global.Tomtastisch.FileClassifier If data Is Nothing Then Return False If CLng(data.Length) > opt.MaxBytes Then - LogGuard.Warn(opt.Logger, $"[Materialize] Daten zu gross ({data.Length} > {opt.MaxBytes}).") + LogGuard.Warn(opt.Logger, $"[Materialize] Daten zu groß ({data.Length} > {opt.MaxBytes}).") Return False End If @@ -159,7 +141,7 @@ Namespace Global.Tomtastisch.FileClassifier TypeOf ex Is PathTooLongException OrElse TypeOf ex Is IOException - LogGuard.Warn(opt.Logger, $"[Materialize] Ungueltiger Zielpfad: {ex.Message}") + LogGuard.Warn(opt.Logger, $"[Materialize] Ungültiger Zielpfad: {ex.Message}") Return False End Try diff --git a/src/FileTypeDetection/FileTypeDetector.vb b/src/FileTypeDetection/FileTypeDetector.vb index 8d014ae..9de73f1 100644 --- a/src/FileTypeDetection/FileTypeDetector.vb +++ b/src/FileTypeDetection/FileTypeDetector.vb @@ -96,12 +96,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' ''' Dateipfad der Quelldatei. ''' Gelesene Bytes oder ein leeres Array bei Fehlern bzw. Regelverletzungen. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Datenzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. Public Shared Function ReadFileSafe _ ( path As String @@ -119,7 +113,7 @@ Namespace Global.Tomtastisch.FileClassifier ' Größenprüfung: Datei muss innerhalb der konfigurierten Grenzen liegen. Dim fi As New FileInfo(path) If fi.Length < 0 OrElse fi.Length > opt.MaxBytes Then - LogGuard.Warn(opt.Logger, $"[Detect] Datei zu gross ({fi.Length} > {opt.MaxBytes}).") + LogGuard.Warn(opt.Logger, $"[Detect] Datei zu groß ({fi.Length} > {opt.MaxBytes}).") Return Array.Empty(Of Byte)() End If @@ -153,12 +147,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' ''' Dateipfad der zu klassifizierenden Datei. ''' Erkannter Typ oder bei Fehlern. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Datenzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. Public Function Detect _ ( path As String @@ -184,12 +172,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' Dateipfad der zu klassifizierenden Datei. ''' True erzwingt die fail-closed Endungsprüfung nach Inhaltsdetektion. ''' Erkannter Typ oder bei Mismatch oder Fehlern. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Datenzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. Public Function Detect _ ( @@ -209,12 +191,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' ''' Dateipfad der zu klassifizierenden Datei. ''' Detailliertes Detektionsergebnis inklusive Reason-Code und Trace-Flags. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Datenzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. Public Function DetectDetailed _ ( path As String @@ -240,12 +216,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' Dateipfad der zu klassifizierenden Datei. ''' True aktiviert die Endungsprüfung nach Inhaltsdetektion. ''' Detailliertes Detektionsergebnis mit typisiertem Trace-Kontext. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Datenzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. ''' ''' ''' Dim detector As New FileTypeDetector() @@ -296,7 +266,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' ''' Dateipfad der zu klassifizierenden Datei. ''' True bei passender oder fehlender Endung; sonst False. - ''' Kann bei ungültigen Pfad-/Typzuständen intern auftreten und wird fail-closed behandelt. Public Function DetectAndVerifyExtension _ ( path As String @@ -322,12 +291,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' ''' Dateipfad der zu validierenden Archivdatei. ''' True, wenn der Container valide und sicher ist; andernfalls False. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Archivdaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. Public Shared Function TryValidateArchive _ ( path As String @@ -363,15 +326,20 @@ Namespace Global.Tomtastisch.FileClassifier End Try End Function - Private Shared Function DetectPathCore(path As String) As FileType + Private Shared Function DetectPathCore( + path As String + ) As FileType Dim opt = GetDefaultOptions() Dim trace As DetectionTrace = DetectionTrace.Empty Return DetectPathCoreWithTrace(path, opt, trace) End Function - Private Shared Function DetectPathCoreWithTrace(path As String, opt As FileTypeProjectOptions, - ByRef trace As DetectionTrace) As FileType + Private Shared Function DetectPathCoreWithTrace( + path As String, + opt As FileTypeProjectOptions, + ByRef trace As DetectionTrace + ) As FileType If String.IsNullOrWhiteSpace(path) OrElse Not File.Exists(path) Then LogGuard.Warn(opt.Logger, "[Detect] Datei nicht gefunden.") @@ -385,19 +353,26 @@ Namespace Global.Tomtastisch.FileClassifier trace.ReasonCode = ReasonInvalidLength Return UnknownType() End If + If fi.Length > opt.MaxBytes Then - LogGuard.Warn(opt.Logger, $"[Detect] Datei zu gross ({fi.Length} > {opt.MaxBytes}).") + LogGuard.Warn(opt.Logger, $"[Detect] Datei zu groß ({fi.Length} > {opt.MaxBytes}).") trace.ReasonCode = ReasonFileTooLarge Return UnknownType() End If - Using _ - fs As _ - New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, - InternalIoDefaults.FileStreamBufferSize, FileOptions.SequentialScan) + Using fs As New FileStream( + path, FileMode.Open, + FileAccess.Read, + FileShare.Read, + InternalIoDefaults.FileStreamBufferSize, + FileOptions.SequentialScan + ) + Dim header = ReadHeader(fs, opt.SniffBytes, opt.MaxBytes) Return ResolveByHeaderForPath(header, opt, trace, fs) + End Using + Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse TypeOf ex Is Security.SecurityException OrElse @@ -417,12 +392,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' ''' Zu prüfende Nutzdaten. ''' Erkannter Typ oder bei Fehlern. - ''' Kann bei Datenzugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-nahen Operationen intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Datenzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Konstellationen intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. ' ReSharper disable once MemberCanBeMadeStatic.Global Public Function Detect _ @@ -443,12 +412,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' Zu prüfende Nutzdaten. ''' Erwarteter Dateityp. ''' True bei Typgleichheit, sonst False. - ''' Kann bei Datenzugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-nahen Operationen intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Datenzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Konstellationen intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. Public Function IsOfType _ ( data As Byte(), @@ -477,12 +440,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' Leeres, noch nicht existierendes Zielverzeichnis. ''' True aktiviert eine vorgelagerte Typprüfung über Detect(path). ''' True bei erfolgreichem, atomarem Entpacken; sonst False. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Archivdaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. Public Function ExtractArchiveSafe _ ( path As String, @@ -495,9 +452,16 @@ Namespace Global.Tomtastisch.FileClassifier Try Dim payload = ReadFileSafe(path) + If payload.Length = 0 Then Return False - Return _ - FileMaterializer.Persist(payload, destinationDirectory, overwrite:=False, secureExtract:=True) + + Return FileMaterializer.Persist( + payload, + destinationDirectory, + overwrite:=False, + secureExtract:=True + ) + Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse TypeOf ex Is Security.SecurityException OrElse @@ -527,12 +491,6 @@ Namespace Global.Tomtastisch.FileClassifier ''' Pfad zur Archivdatei. ''' True aktiviert eine vorgelagerte Typprüfung über Detect(path). ''' Read-only Liste extrahierter Einträge oder leer bei Fehler. - ''' Kann bei Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei sicherheitsrelevantem Dateizugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei I/O-Zugriff intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Archivdaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützten Pfadformaten intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. Public Function ExtractArchiveSafeToMemory _ ( path As String, @@ -546,12 +504,18 @@ Namespace Global.Tomtastisch.FileClassifier If Not CanExtractArchivePath(path, verifyBeforeExtract, opt) Then Return emptyResult Try - Using _ - fs As _ - New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, - InternalIoDefaults.FileStreamBufferSize, FileOptions.SequentialScan) + Using fs As New FileStream( + path, + FileMode.Open, + FileAccess.Read, + FileShare.Read, + InternalIoDefaults.FileStreamBufferSize, + FileOptions.SequentialScan + ) Return ArchiveExtractor.TryExtractArchiveStreamToMemory(fs, opt) + End Using + Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse TypeOf ex Is Security.SecurityException OrElse @@ -563,17 +527,22 @@ Namespace Global.Tomtastisch.FileClassifier End Try End Function - Private Shared Function DetectInternalBytes(data As Byte(), opt As FileTypeProjectOptions) As FileType + Private Shared Function DetectInternalBytes( + data As Byte(), + opt As FileTypeProjectOptions + ) As FileType If data Is Nothing OrElse data.Length = 0 Then Return UnknownType() + If CLng(data.Length) > opt.MaxBytes Then - LogGuard.Warn(opt.Logger, $"[Detect] Daten zu gross ({data.Length} > {opt.MaxBytes}).") + LogGuard.Warn(opt.Logger, $"[Detect] Daten zu groß ({data.Length} > {opt.MaxBytes}).") Return UnknownType() End If Try Dim trace As DetectionTrace = DetectionTrace.Empty Return ResolveByHeaderForBytes(data, opt, trace, data) + Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse TypeOf ex Is Security.SecurityException OrElse @@ -589,11 +558,11 @@ Namespace Global.Tomtastisch.FileClassifier ''' Entscheidungslogik für die Pfad-Variante. ''' Private Shared Function ResolveByHeaderForPath( - header As Byte(), - opt As FileTypeProjectOptions, - ByRef trace As DetectionTrace, - fs As FileStream - ) As FileType + header As Byte(), + opt As FileTypeProjectOptions, + ByRef trace As DetectionTrace, + fs As FileStream + ) As FileType Return ResolveByHeaderCommon( header, @@ -683,10 +652,10 @@ Namespace Global.Tomtastisch.FileClassifier End Function Private Shared Function ValidateArchiveStreamRaw( - fs As FileStream, - opt As FileTypeProjectOptions, - descriptor As ArchiveDescriptor - ) As Boolean + fs As FileStream, + opt As FileTypeProjectOptions, + descriptor As ArchiveDescriptor + ) As Boolean If fs Is Nothing OrElse Not fs.CanRead Then Return False If fs.CanSeek Then fs.Position = 0 @@ -694,20 +663,20 @@ Namespace Global.Tomtastisch.FileClassifier End Function Private Shared Function ValidateArchiveBytesRaw( - data As Byte(), - opt As FileTypeProjectOptions, - descriptor As ArchiveDescriptor - ) As Boolean + data As Byte(), + opt As FileTypeProjectOptions, + descriptor As ArchiveDescriptor + ) As Boolean Return ArchiveSafetyGate.IsArchiveSafeBytes(data, opt, descriptor) End Function Private Shared Function ResolveAfterArchiveGate( - magicKind As FileKind, - opt As FileTypeProjectOptions, - ByRef trace As DetectionTrace, - tryRefine As Func(Of FileType) - ) As FileType + magicKind As FileKind, + opt As FileTypeProjectOptions, + ByRef trace As DetectionTrace, + tryRefine As Func(Of FileType) + ) As FileType If magicKind <> FileKind.Zip Then trace.ReasonCode = ReasonArchiveGeneric @@ -718,8 +687,11 @@ Namespace Global.Tomtastisch.FileClassifier Return FinalizeArchiveDetection(refined, opt, trace) End Function - Private Shared Function FinalizeArchiveDetection(refined As FileType, opt As FileTypeProjectOptions, - ByRef trace As DetectionTrace) As FileType + Private Shared Function FinalizeArchiveDetection( + refined As FileType, + opt As FileTypeProjectOptions, + ByRef trace As DetectionTrace + ) As FileType If refined.Kind <> FileKind.Unknown Then WarnIfNoDirectContentDetection(refined.Kind, opt) @@ -735,8 +707,11 @@ Namespace Global.Tomtastisch.FileClassifier Return FileTypeRegistry.Resolve(FileKind.Zip) End Function - Private Function CanExtractArchivePath(path As String, verifyBeforeExtract As Boolean, - opt As FileTypeProjectOptions) As Boolean + Private Function CanExtractArchivePath( + path As String, + verifyBeforeExtract As Boolean, + opt As FileTypeProjectOptions + ) As Boolean If String.IsNullOrWhiteSpace(path) OrElse Not File.Exists(path) Then LogGuard.Warn(opt.Logger, "[ArchiveExtract] Quelldatei fehlt.") @@ -746,7 +721,7 @@ Namespace Global.Tomtastisch.FileClassifier If verifyBeforeExtract Then Dim detected = Detect(path) If Not IsArchiveContainerKind(detected.Kind) Then - LogGuard.Warn(opt.Logger, $"[ArchiveExtract] Vorpruefung fehlgeschlagen ({detected.Kind}).") + LogGuard.Warn(opt.Logger, $"[ArchiveExtract] Vorprüfung fehlgeschlagen ({detected.Kind}).") Return False End If End If @@ -775,7 +750,7 @@ Namespace Global.Tomtastisch.FileClassifier If kind = FileKind.Unknown Then Return If FileTypeRegistry.HasDirectContentDetection(kind) Then Return LogGuard.Warn(opt.Logger, - $"[Detect] Keine direkte Content-Erkennung fuer Typ '{kind _ + $"[Detect] Keine direkte Content-Erkennung für Typ '{kind _ }'. Ergebnis stammt aus Fallback/Refinement.") End Sub diff --git a/src/FileTypeDetection/FileTypeOptions.vb b/src/FileTypeDetection/FileTypeOptions.vb index 4de864d..08d2da9 100644 --- a/src/FileTypeDetection/FileTypeOptions.vb +++ b/src/FileTypeDetection/FileTypeOptions.vb @@ -49,13 +49,11 @@ Namespace Global.Tomtastisch.FileClassifier ''' ''' JSON-Konfiguration mit unterstützten Optionsfeldern. ''' True, wenn ein gültiger Snapshot gesetzt wurde; andernfalls False. - ''' Kann bei ungültiger JSON-Struktur intern auftreten und wird fail-closed behandelt. - ''' Kann bei ungültigen Argumentzuständen intern auftreten und wird fail-closed behandelt. - ''' Kann bei nicht unterstützter JSON-Konstellation intern auftreten und wird fail-closed behandelt. Public Shared Function LoadOptions _ ( json As String ) As Boolean + If String.IsNullOrWhiteSpace(json) Then Return False Dim defaults = FileTypeProjectOptions.DefaultOptions() @@ -131,7 +129,7 @@ Namespace Global.Tomtastisch.FileClassifier Case "deterministichashmaterializedfilename" hashMaterializedFileName = ParseString(p.Value, hashMaterializedFileName, p.Name, logger) Case Else - LogGuard.Warn(logger, $"[Config] Unbekannter Schluessel '{p.Name}' ignoriert.") + LogGuard.Warn(logger, $"[Config] Unbekannter Schlüssel '{p.Name}' ignoriert.") End Select Next End Using @@ -160,6 +158,7 @@ Namespace Global.Tomtastisch.FileClassifier nextOptions.NormalizeInPlace() SetSnapshot(nextOptions) Return True + Catch ex As Exception When _ TypeOf ex Is ArgumentException OrElse TypeOf ex Is Text.Json.JsonException OrElse @@ -179,6 +178,7 @@ Namespace Global.Tomtastisch.FileClassifier ''' ''' JSON-Serialisierung der normierten Optionen. Public Shared Function GetOptions() As String + Dim opt = GetSnapshot() Dim dto As New Dictionary(Of String, Object) From { {"headerOnlyNonZip", opt.HeaderOnlyNonZip}, @@ -249,7 +249,7 @@ Namespace Global.Tomtastisch.FileClassifier logger As Microsoft.Extensions.Logging.ILogger) As Integer Dim v = SafeInt(el, fallback) If v > 0 Then Return v - LogGuard.Warn(logger, $"[Config] Ungueltiger Wert fuer '{name}', fallback={fallback}.") + LogGuard.Warn(logger, $"[Config] Ungültiger Wert für '{name}', fallback={fallback}.") Return fallback End Function @@ -258,7 +258,7 @@ Namespace Global.Tomtastisch.FileClassifier logger As Microsoft.Extensions.Logging.ILogger) As Integer Dim v = SafeInt(el, fallback) If v >= 0 Then Return v - LogGuard.Warn(logger, $"[Config] Ungueltiger Wert fuer '{name}', fallback={fallback}.") + LogGuard.Warn(logger, $"[Config] Ungültiger Wert für '{name}', fallback={fallback}.") Return fallback End Function @@ -268,7 +268,7 @@ Namespace Global.Tomtastisch.FileClassifier As Long Dim v = SafeLong(el, fallback) If v > 0 Then Return v - LogGuard.Warn(logger, $"[Config] Ungueltiger Wert fuer '{name}', fallback={fallback}.") + LogGuard.Warn(logger, $"[Config] Ungültiger Wert für '{name}', fallback={fallback}.") Return fallback End Function @@ -278,7 +278,7 @@ Namespace Global.Tomtastisch.FileClassifier As Boolean If el.ValueKind = Text.Json.JsonValueKind.True Then Return True If el.ValueKind = Text.Json.JsonValueKind.False Then Return False - LogGuard.Warn(logger, $"[Config] Ungueltiger Wert fuer '{name}', fallback={fallback}.") + LogGuard.Warn(logger, $"[Config] Ungültiger Wert für '{name}', fallback={fallback}.") Return fallback End Function @@ -290,17 +290,18 @@ Namespace Global.Tomtastisch.FileClassifier Dim value = el.GetString() If value IsNot Nothing Then Return value End If - LogGuard.Warn(logger, $"[Config] Ungueltiger Wert fuer '{name}', fallback={fallback}.") + LogGuard.Warn(logger, $"[Config] Ungültiger Wert für '{name}', fallback={fallback}.") Return fallback End Function Private Shared Sub TryParseHashOptions( - el As Text.Json.JsonElement, - ByRef includePayloadCopies As Boolean, - ByRef includeFastHash As Boolean, - ByRef includeSecureHash As Boolean, - ByRef materializedFileName As String, - logger As Microsoft.Extensions.Logging.ILogger) + el As Text.Json.JsonElement, + ByRef includePayloadCopies As Boolean, + ByRef includeFastHash As Boolean, + ByRef includeSecureHash As Boolean, + ByRef materializedFileName As String, + logger As Microsoft.Extensions.Logging.ILogger + ) If el.ValueKind <> Text.Json.JsonValueKind.Object Then LogGuard.Warn(logger, "[Config] 'deterministicHash' muss ein JSON-Objekt sein.") @@ -339,16 +340,20 @@ Namespace Global.Tomtastisch.FileClassifier ) Case Else - LogGuard.Warn(logger, $"[Config] Unbekannter Schluessel 'deterministicHash.{p.Name}' ignoriert.") + LogGuard.Warn(logger, $"[Config] Unbekannter Schlüssel 'deterministicHash.{p.Name}' ignoriert.") End Select Next End Sub - Private Shared Function Snapshot(opt As FileTypeProjectOptions) As FileTypeProjectOptions + Private Shared Function Snapshot( + opt As FileTypeProjectOptions + ) As FileTypeProjectOptions + If opt Is Nothing Then Return FileTypeProjectOptions.DefaultOptions() Dim snap = opt.Clone() snap.NormalizeInPlace() Return snap + End Function End Class End Namespace diff --git a/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb b/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb index 99ac0a2..06d4708 100644 --- a/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb +++ b/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb @@ -286,7 +286,7 @@ Namespace Global.Tomtastisch.FileClassifier Try destinationFull = Path.GetFullPath(destinationDirectory) Catch ex As Exception - LogGuard.Debug(opt.Logger, $"[ArchiveExtract] Ungueltiger Zielpfad: {ex.Message}") + LogGuard.Debug(opt.Logger, $"[ArchiveExtract] Ungültiger Zielpfad: {ex.Message}") Return False End Try diff --git a/src/FileTypeDetection/Infrastructure/CoreInternals.vb b/src/FileTypeDetection/Infrastructure/CoreInternals.vb index 2c52423..292b4f1 100644 --- a/src/FileTypeDetection/Infrastructure/CoreInternals.vb +++ b/src/FileTypeDetection/Infrastructure/CoreInternals.vb @@ -169,7 +169,7 @@ Namespace Global.Tomtastisch.FileClassifier Dim parent = Path.GetDirectoryName(destinationFull) If String.IsNullOrWhiteSpace(parent) Then - LogGuard.Warn(opt.Logger, "[PathGuard] Ziel ohne gueltigen Parent.") + LogGuard.Warn(opt.Logger, "[PathGuard] Ziel ohne gültigen Parent.") Return False End If diff --git a/src/FileTypeDetection/Providers/Net8_0Plus/HashPrimitivesProvider.vb b/src/FileTypeDetection/Providers/Net8_0Plus/HashPrimitivesProvider.vb index 86051ea..bec15d0 100644 --- a/src/FileTypeDetection/Providers/Net8_0Plus/HashPrimitivesProvider.vb +++ b/src/FileTypeDetection/Providers/Net8_0Plus/HashPrimitivesProvider.vb @@ -58,6 +58,11 @@ Namespace Global.Tomtastisch.FileClassifier Private NotInheritable Class LowerHexCodec Implements IHexCodec + ''' + ''' Kodiert Byte-Daten deterministisch als Hex-String in Kleinbuchstaben. + ''' + ''' Zu kodierende Eingabedaten; Nothing wird als leeres Array behandelt. + ''' Hex-String in Kleinbuchstaben ohne Trennzeichen. Public Function EncodeLowerHex(data As Byte()) As String Implements IHexCodec.EncodeLowerHex Dim safeData = If(data, Array.Empty(Of Byte)()) Return Convert.ToHexString(safeData).ToLowerInvariant() @@ -75,15 +80,29 @@ Namespace Global.Tomtastisch.FileClassifier Private ReadOnly _codec As IHexCodec + ''' + ''' Initialisiert die SHA256-Primitive mit dem bereitgestellten Hex-Codec. + ''' + ''' Hex-Codec zur Ausgabe von Hashwerten als Kleinbuchstaben-Hex. Public Sub New(codec As IHexCodec) _codec = codec End Sub + ''' + ''' Berechnet den SHA256-Hash für die übergebenen Daten. + ''' + ''' Eingabedaten; Nothing wird als leeres Array behandelt. + ''' SHA256-Digest als Byte-Array. Public Function ComputeHash(data As Byte()) As Byte() Implements ISha256Primitives.ComputeHash Dim safeData = If(data, Array.Empty(Of Byte)()) Return Security.Cryptography.SHA256.HashData(safeData) End Function + ''' + ''' Berechnet den SHA256-Hash und liefert ihn als Kleinbuchstaben-Hex. + ''' + ''' Eingabedaten; Nothing wird als leeres Array behandelt. + ''' SHA256-Digest als Hex-String in Kleinbuchstaben. Public Function ComputeHashHex(data As Byte()) As String Implements ISha256Primitives.ComputeHashHex Return _codec.EncodeLowerHex(ComputeHash(data)) End Function @@ -98,11 +117,21 @@ Namespace Global.Tomtastisch.FileClassifier Private NotInheritable Class FastHash64Primitives Implements IFastHash64 + ''' + ''' Berechnet einen deterministischen 64-Bit-Fasthash (XxHash3). + ''' + ''' Eingabedaten; Nothing wird als leeres Array behandelt. + ''' Fasthash als . Public Function ComputeHashUInt64(data As Byte()) As ULong Implements IFastHash64.ComputeHashUInt64 Dim safeData = If(data, Array.Empty(Of Byte)()) Return IO.Hashing.XxHash3.HashToUInt64(safeData) End Function + ''' + ''' Berechnet den 64-Bit-Fasthash und liefert ihn als festen Hex-String. + ''' + ''' Eingabedaten; Nothing wird als leeres Array behandelt. + ''' 16-stelliger Hex-String in Kleinbuchstaben. Public Function ComputeHashHex(data As Byte()) As String Implements IFastHash64.ComputeHashHex Return ComputeHashUInt64(data).ToString("x16", CultureInfo.InvariantCulture) End Function diff --git a/src/FileTypeDetection/Providers/NetStandard2_0/HashPrimitivesProvider.vb b/src/FileTypeDetection/Providers/NetStandard2_0/HashPrimitivesProvider.vb index 81c9350..0991dd2 100644 --- a/src/FileTypeDetection/Providers/NetStandard2_0/HashPrimitivesProvider.vb +++ b/src/FileTypeDetection/Providers/NetStandard2_0/HashPrimitivesProvider.vb @@ -60,6 +60,11 @@ Namespace Global.Tomtastisch.FileClassifier Private Shared ReadOnly HexDigits As Char() = "0123456789abcdef".ToCharArray() + ''' + ''' Kodiert Byte-Daten deterministisch als Hex-String in Kleinbuchstaben. + ''' + ''' Zu kodierende Eingabedaten; Nothing wird als leeres Array behandelt. + ''' Hex-String in Kleinbuchstaben ohne Trennzeichen. Public Function EncodeLowerHex(data As Byte()) As String Implements IHexCodec.EncodeLowerHex Dim safeData = If(data, Array.Empty(Of Byte)()) Dim chars As Char() = Nothing @@ -89,10 +94,19 @@ Namespace Global.Tomtastisch.FileClassifier Private ReadOnly _codec As IHexCodec + ''' + ''' Initialisiert die SHA256-Primitive mit dem bereitgestellten Hex-Codec. + ''' + ''' Hex-Codec zur Ausgabe von Hashwerten als Kleinbuchstaben-Hex. Public Sub New(codec As IHexCodec) _codec = codec End Sub + ''' + ''' Berechnet den SHA256-Hash für die übergebenen Daten. + ''' + ''' Eingabedaten; Nothing wird als leeres Array behandelt. + ''' SHA256-Digest als Byte-Array. Public Function ComputeHash(data As Byte()) As Byte() Implements ISha256Primitives.ComputeHash Dim safeData = If(data, Array.Empty(Of Byte)()) Using sha As Security.Cryptography.SHA256 = Security.Cryptography.SHA256.Create() @@ -100,6 +114,11 @@ Namespace Global.Tomtastisch.FileClassifier End Using End Function + ''' + ''' Berechnet den SHA256-Hash und liefert ihn als Kleinbuchstaben-Hex. + ''' + ''' Eingabedaten; Nothing wird als leeres Array behandelt. + ''' SHA256-Digest als Hex-String in Kleinbuchstaben. Public Function ComputeHashHex(data As Byte()) As String Implements ISha256Primitives.ComputeHashHex Return _codec.EncodeLowerHex(ComputeHash(data)) End Function @@ -114,11 +133,21 @@ Namespace Global.Tomtastisch.FileClassifier Private NotInheritable Class FastHash64Primitives Implements IFastHash64 + ''' + ''' Berechnet einen deterministischen 64-Bit-Fasthash (XxHash3). + ''' + ''' Eingabedaten; Nothing wird als leeres Array behandelt. + ''' Fasthash als . Public Function ComputeHashUInt64(data As Byte()) As ULong Implements IFastHash64.ComputeHashUInt64 Dim safeData = If(data, Array.Empty(Of Byte)()) Return IO.Hashing.XxHash3.HashToUInt64(safeData) End Function + ''' + ''' Berechnet den 64-Bit-Fasthash und liefert ihn als festen Hex-String. + ''' + ''' Eingabedaten; Nothing wird als leeres Array behandelt. + ''' 16-stelliger Hex-String in Kleinbuchstaben. Public Function ComputeHashHex(data As Byte()) As String Implements IFastHash64.ComputeHashHex Return ComputeHashUInt64(data).ToString("x16", CultureInfo.InvariantCulture) End Function From 03239b0beed89f18948322ddf4d3d93d685af5e1 Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Tue, 17 Feb 2026 09:19:25 +0100 Subject: [PATCH 2/4] fix(release): prerelease-gate4 robust machen und ssot-doku aktualisieren --- README.md | 2 +- .../003_NETSTANDARD2_COMPAT_EVIDENCE.MD | 64 +++++++++++-------- docs/ci/002_NUGET_TRUSTED_PUBLISHING.MD | 10 +-- docs/ci/102_NUGET_TRUSTED_PUBLISHING.MD | 10 +-- docs/versioning/002_HISTORY_VERSIONS.MD | 4 +- docs/versioning/003_CHANGELOG_RELEASES.MD | 14 ++-- docs/versioning/102_HISTORY_VERSIONS.MD | 4 +- docs/versioning/103_CHANGELOG_RELEASES.MD | 14 ++-- tools/ci/release/gate4_verify_postpublish.sh | 31 ++++++++- 9 files changed, 101 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index afe5b61..bf6b1b2 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ dotnet add package Tomtastisch.FileClassifier --version X.Y.Z ```bash EXPECTED_VERSION=X.Y.Z bash tools/ci/verify_nuget_release.sh ``` -- Release-Ablauf: `Release Publish` blockiert post-publish auf `registration + flatcontainer`; die vollständige Online-Konvergenz inkl. `search` läuft asynchron über `NuGet Online Convergence` (Details: `docs/ci/002_NUGET_TRUSTED_PUBLISHING.MD`). +- Release-Ablauf: `Release Publish` blockiert post-publish immer auf `flatcontainer`; `registration` ist für stabile Tags blocker und für Pre-Release-Tags standardmäßig entkoppelt. Die vollständige Online-Konvergenz inkl. `search + registration` läuft asynchron über `NuGet Online Convergence` (Details: `docs/ci/002_NUGET_TRUSTED_PUBLISHING.MD`). - Details: [NuGet Usage Guide](https://github.com/tomtastisch/FileClassifier/blob/main/docs/021_USAGE_NUGET.MD) - Portable-Integration: [Portable Adoption Guide](https://github.com/tomtastisch/FileClassifier/blob/main/docs/guides/003_GUIDE_PORTABLE.MD) - Maintainer-Hinweis: Das Publish-Helper-Skript nutzt `NUGET_API_KEY` aus dem Keychain und gibt den Token nicht aus. diff --git a/docs/audit/compat/003_NETSTANDARD2_COMPAT_EVIDENCE.MD b/docs/audit/compat/003_NETSTANDARD2_COMPAT_EVIDENCE.MD index 5c3bdd5..3bf63de 100644 --- a/docs/audit/compat/003_NETSTANDARD2_COMPAT_EVIDENCE.MD +++ b/docs/audit/compat/003_NETSTANDARD2_COMPAT_EVIDENCE.MD @@ -45,19 +45,20 @@ MSBuild-Conditionen in `src/FileTypeDetection/FileTypeDetectionLib.vbproj`: ### 4.1 Befehle und Exit-Codes 1. `dotnet --info` -> `0` 2. `dotnet restore FileClassifier.sln -v minimal` -> `0` -3. `dotnet restore --locked-mode FileClassifier.sln -v minimal` -> `0` -4. `dotnet build FileClassifier.sln -c Release --no-restore -warnaserror -v minimal` -> `0` -5. `dotnet test tests/FileTypeDetectionLib.Tests/FileTypeDetectionLib.Tests.csproj -c Release --no-build -v minimal` -> `0` (`414` Tests gruen) -6. `dotnet test tests/FileTypeDetectionLib.Tests/FileTypeDetectionLib.Tests.csproj -c Release --no-build --filter "Category=ApiContract" -v minimal` -> `0` (`3` Tests gruen) -7. `dotnet pack src/FileTypeDetection/FileTypeDetectionLib.vbproj -c Release --no-build -o artifacts/ci/netstandard2-compat/nuget -v minimal` -> `0` -8. `dotnet build src/FileTypeDetection/FileTypeDetectionLib.vbproj -c Release -f netstandard2.0 -v diag > artifacts/ci/netstandard2-compat/build-netstandard2.0.log` -> `0` -9. `dotnet build src/FileTypeDetection/FileTypeDetectionLib.vbproj -c Release -f net8.0 -v diag > artifacts/ci/netstandard2-compat/build-net8.0.log` -> `0` -10. `dotnet build src/FileTypeDetection/FileTypeDetectionLib.vbproj -c Release -f net10.0 -v diag > artifacts/ci/netstandard2-compat/build-net10.0.log` -> `0` -11. `python3 tools/check-doc-consistency.py` -> `0` -12. `python3 tools/check-docs.py` -> `0` -13. `bash tools/ci/bin/run.sh versioning-svt` -> `0` -14. `bash tools/ci/bin/run.sh version-convergence` -> `0` -15. `bash tools/ci/bin/run.sh security-nuget` -> `0` +3. `dotnet build FileClassifier.sln -c Release --no-restore -warnaserror -v minimal` -> `0` +4. `dotnet test tests/FileTypeDetectionLib.Tests/FileTypeDetectionLib.Tests.csproj -c Release --no-build -v minimal` -> `0` (`414` Tests gruen) +5. `dotnet pack src/FileTypeDetection/FileTypeDetectionLib.vbproj -c Release --no-build -o artifacts/ci/netstandard2-compat/nuget -v minimal` -> `0` +6. `dotnet build src/FileTypeDetection/FileTypeDetectionLib.vbproj -c Release -f netstandard2.0 -v diag > artifacts/ci/netstandard2-compat/build-netstandard2.0.log` -> `0` +7. `dotnet build src/FileTypeDetection/FileTypeDetectionLib.vbproj -c Release -f net8.0 -v diag > artifacts/ci/netstandard2-compat/build-net8.0.log` -> `0` +8. `dotnet build src/FileTypeDetection/FileTypeDetectionLib.vbproj -c Release -f net10.0 -v diag > artifacts/ci/netstandard2-compat/build-net10.0.log` -> `0` +9. `python3 tools/check-doc-consistency.py` -> `0` +10. `python3 tools/check-docs.py` -> `0` +11. `bash tools/versioning/verify-version-convergence.sh` -> `0` +12. `bash tools/ci/bin/run.sh security-nuget` -> `0` +13. `EXPECTED_RELEASE_TAG=v5.2.0-rc.3 REQUIRE_RELEASE_TAG=1 bash tools/ci/check-versioning-svt.sh --repo-root . --out artifacts/ci/versioning-svt/versioning-svt-summary.json` -> `0` +14. `bash tools/ci/release/gate2_version_policy.sh release v5.2.0-rc.3 artifacts/nuget/Tomtastisch.FileClassifier.5.2.0-rc.3.nupkg` -> `0` +15. `VERIFY_ONLINE=0 bash tools/ci/release/gate4_verify_postpublish.sh 5.2.0-rc.3 artifacts/nuget/Tomtastisch.FileClassifier.5.2.0-rc.3.nupkg` -> `0` +16. `VERIFY_ONLINE=0 bash tools/ci/release/gate4_verify_postpublish.sh 5.2.0 artifacts/ci/netstandard2-compat/nuget/Tomtastisch.FileClassifier.5.2.0.nupkg` -> `0` ### 4.2 Build-/Pack-Proof - Build-Matrix erfolgreich: @@ -70,18 +71,22 @@ MSBuild-Conditionen in `src/FileTypeDetection/FileTypeDetectionLib.vbproj`: - `lib/net10.0/Tomtastisch.FileClassifier.dll` ### 4.3 Provider-Compile-Proof -- `netstandard2.0`: - - `artifacts/ci/netstandard2-compat/build-netstandard2.0.log:48497` - - Treffer: `Providers/NetStandard2_0/HashPrimitivesProvider.vb (Aufgaben-ID: 7)` -- `net8.0`: - - `artifacts/ci/netstandard2-compat/build-net8.0.log:48421` - - Treffer: `Providers/Net8_0Plus/HashPrimitivesProvider.vb (Aufgaben-ID: 12)` -- `net10.0`: - - `artifacts/ci/netstandard2-compat/build-net10.0.log:48416` - - Treffer: `Providers/Net8_0Plus/HashPrimitivesProvider.vb (Aufgaben-ID: 12)` -- Negativ-Proof: - - kein Treffer fuer `Providers/Net8_0Plus/HashPrimitivesProvider.vb (Aufgaben-ID: 7)` in `build-netstandard2.0.log` - - kein Treffer fuer `Providers/NetStandard2_0/HashPrimitivesProvider.vb (Aufgaben-ID: 12)` in `build-net8.0.log` und `build-net10.0.log` +- Build-Logs enthalten die erwarteten Providerpfade je TFM: + - `artifacts/ci/netstandard2-compat/build-netstandard2.0.log` mit `Providers/NetStandard2_0/HashPrimitivesProvider.vb` + - `artifacts/ci/netstandard2-compat/build-net8.0.log` mit `Providers/Net8_0Plus/HashPrimitivesProvider.vb` + - `artifacts/ci/netstandard2-compat/build-net10.0.log` mit `Providers/Net8_0Plus/HashPrimitivesProvider.vb` +- Runtime-nahe Marker-Probe aus den drei Build-Artefakten: + - `netstandard2.0:NetStandard2_0` + - `net8.0:Net8_0Plus` + - `net10.0:Net8_0Plus` +- Probe-Kommando: +```bash +tmpdir=$(mktemp -d) +cd "$tmpdir" +dotnet new console -n Probe -f net10.0 +# Program.cs laedt jede TFM-DLL in eigenem AssemblyLoadContext und liest ProviderMarker via Reflection. +dotnet run -c Release --no-restore +``` ### 4.4 Forbidden-API Grep-Proof (Core) Befehl: @@ -89,20 +94,23 @@ Befehl: rg -n "Convert\.ToHexString|SHA256\.HashData|System\.IO\.Hashing|Microsoft\.AspNetCore\.App" src/FileTypeDetection/Core ``` Ergebnis: -- keine Treffer, Exit-Code `1` (expected for no-match) +- keine Treffer (`forbidden_core_refs=none`) ### 4.5 CI-Teilchecks -- `artifacts/ci/versioning-svt/versioning-svt-summary.json` -> `status: pass` +- `artifacts/ci/versioning-svt/versioning-svt-summary.json` -> `status: pass` (pre-release `v5.2.0-rc.3`, core-match `5.2.0`) - `artifacts/ci/version-convergence/summary.json` -> `status: pass`, `repo_version=5.2.0`, `vbproj_version=5.2.0`, `docs_latest_version=5.2.0` - `artifacts/ci/security-nuget/result.json` -> `status: pass` +- Gate-4-PreRelease-Probe (`VERIFY_ONLINE=0`) zeigt `require_registration=0`. +- Gate-4-Stable-Probe (`VERIFY_ONLINE=0`) zeigt `require_registration=1`. -### 4.6 Policy Ambiguity +### 4.6 Policy/Konvergenz-Notiz Ambiguitaet zwischen: - `docs/versioning/001_POLICY_VERSIONING.MD:43` (in PR/CI keine statischen Versionfelder), und - existierendem SVT/Convergence-Setup (`verify-version-convergence.sh`, `check-versioning-svt.sh`), das `RepoVersion` und `Version`/`PackageVersion` in `FileTypeDetectionLib.vbproj` erwartet. Entscheidung fuer diesen Scope: - fail-closed nach bestehendem CI/Repo-Vertrag: Versionen auf `5.2.0` synchron gehalten und durch `versioning-svt` + `version-convergence` verifiziert. +- Pre-Releases werden ueber Tag `v5.2.0-rc.N` abgebildet; die Projektfelder bleiben semantisch auf Kernversion `5.2.0`. ## 5. Grenzen/Nicht-Ziele - Keine oeffentliche API-Signatur geaendert. diff --git a/docs/ci/002_NUGET_TRUSTED_PUBLISHING.MD b/docs/ci/002_NUGET_TRUSTED_PUBLISHING.MD index 327059a..087011e 100644 --- a/docs/ci/002_NUGET_TRUSTED_PUBLISHING.MD +++ b/docs/ci/002_NUGET_TRUSTED_PUBLISHING.MD @@ -21,13 +21,15 @@ Die aktive Trusted-Publishing-Policy ist an folgende Identität gebunden: - Nach erfolgreichem `dotnet nuget push` kann die NuGet-Indexierung (Search/Registration/Flatcontainer) zeitverzögert sichtbar sein. - Gate 4 im Release-Workflow bleibt **fail-closed** für publish-kritische Endpunkte: - `REQUIRE_FLATCONTAINER=1` - - `REQUIRE_REGISTRATION=1` + - `REQUIRE_REGISTRATION=1` fuer stabile Tags `vX.Y.Z` + - `REQUIRE_REGISTRATION=0` fuer Pre-Release-Tags `vX.Y.Z-