diff --git a/Directory.Build.props b/Directory.Build.props
index defc4645..63b1b942 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -30,6 +30,6 @@
$(WarningsAsErrors);RS0016;RS0017;RS0026;RS0027;RS0022;RS0023;RS0024;RS0025
- 6.1.16
+ 6.1.17
diff --git a/docs/0_de/versioning/002_HISTORY_VERSIONS.MD b/docs/0_de/versioning/002_HISTORY_VERSIONS.MD
index f60fc9d8..25bfe419 100644
--- a/docs/0_de/versioning/002_HISTORY_VERSIONS.MD
+++ b/docs/0_de/versioning/002_HISTORY_VERSIONS.MD
@@ -12,7 +12,7 @@ Heuristik für die Rückwirkungs-Zuordnung:
- `docs|test|ci|chore|tooling|refactor|fix` => Patch
Aktueller Entwicklungsstand:
-- Aktuelle Entwicklungslinie enthält `6.x` (aktueller Arbeitsstand: `v6.1.16`; Details in `docs/versioning/003_CHANGELOG_RELEASES.MD`).
+- Aktuelle Entwicklungslinie enthält `6.x` (aktueller Arbeitsstand: `v6.1.17`; Details in `docs/versioning/003_CHANGELOG_RELEASES.MD`).
Hinweis:
- Die Spalte `Keyword` verwendet den technischen Klassifizierungswert aus der Historie.
@@ -20,6 +20,7 @@ Hinweis:
| Version | Kurzbeschreibung | Commit | Keyword |
|---|---|---|---|
+| `6.1.17` | Bridge-/In-Code-Härtung abgeschlossen: `CsCoreRuntimeBridge` strukturell entdoppelt (Tuple-/Assembly-Helper), XML-Dokumentation mit konsistenter deutscher Umlautschreibweise vereinheitlicht und Randfalltests für Delegation/Fallback ergänzt | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.16` | API-Auditierbarkeit fail-closed aktiviert: `Microsoft.CodeAnalysis.PublicApiAnalyzers` zentral eingebunden, Public-API-Baseline (`PublicAPI.Shipped.txt`/`PublicAPI.Unshipped.txt`) für `FileTypeDetectionLib` eingeführt und Governance-/Versioning-Dokumentation um den verbindlichen API-Änderungsprozess erweitert | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.15` | Governance-Drift geschlossen: Branch-Protection-Review-Policy und Scorecard-Governance-Mappings auf den verifizierten Ist-Stand `required_approving_review_count = 0` konsolidiert, inklusive aktualisierter Prozesskontrollen für verpflichtende Required-Checks und Review-Thread-Evidence gemäß `AGENTS.md` | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.14` | 6.1.14 Pipeline-Konvergenz geschlossen: Release-Workflow erzwingt NuGet-Online-Konvergenz jetzt fail-closed auch für `workflow_dispatch`, Release-Metadaten werden artefaktbasiert deterministisch aufgelöst und Fuzzing-Blocker-/Governance-Evidence-Dokumentation entsprechend nachgezogen | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
diff --git a/docs/0_de/versioning/003_CHANGELOG_RELEASES.MD b/docs/0_de/versioning/003_CHANGELOG_RELEASES.MD
index 7dc5399b..f98ef029 100644
--- a/docs/0_de/versioning/003_CHANGELOG_RELEASES.MD
+++ b/docs/0_de/versioning/003_CHANGELOG_RELEASES.MD
@@ -7,6 +7,16 @@
Alle Änderungen werden hier technisch dokumentiert. Die Release-Version selbst ist
der Git-Tag `vX.Y.Z` (optional `-prerelease`) als SSOT.
+## [6.1.17]
+- Added:
+ - Zwei neue Bridge-Randfalltests für fail-closed Delegation/Fallback (`NormalizeArchiveRelativePath`, `ResolveHmacKeyFromEnvironment`) ergänzt.
+- Changed:
+ - `CsCoreRuntimeBridge` redundanzreduziert: Tuple-Auswertung in dedizierte Helper zentralisiert und Assembly-Pfadauflösung über eine gemeinsame Directory-Probe-Funktion vereinheitlicht.
+ - In-Code-XML-Dokumentation in Bridge-Kommentaren mit konsistenter deutscher Umlautschreibweise harmonisiert (`Brücke`, `Rückgabe`, `Prüfung`, `Länge`).
+- Docs/CI/Tooling:
+ - Phase-C-Gates lokal erfolgreich ausgeführt: `preflight`, `tests-bdd-coverage`, `api-contract`.
+ - Versionskonvergenz aktiv auf `6.1.17` gesetzt (`RepoVersion`, `Version`, `PackageVersion`, Versionshistorie DE/EN).
+
## [6.1.16]
- Added:
- `Microsoft.CodeAnalysis.PublicApiAnalyzers` als zentrales Analyzer-Paket aufgenommen und für `FileTypeDetectionLib` aktiviert.
diff --git a/docs/1_en/versioning/002_HISTORY_VERSIONS.MD b/docs/1_en/versioning/002_HISTORY_VERSIONS.MD
index b2ecdcd4..e27b0480 100644
--- a/docs/1_en/versioning/002_HISTORY_VERSIONS.MD
+++ b/docs/1_en/versioning/002_HISTORY_VERSIONS.MD
@@ -12,13 +12,14 @@ Heuristics for retroactive classification:
- `docs|test|ci|chore|tooling|refactor|fix` => patch
Current state:
-- Current release line contains `6.x` (current working state: `v6.1.16`; details in `docs/versioning/103_CHANGELOG_RELEASES.MD`).
+- Current release line contains `6.x` (current working state: `v6.1.17`; details in `docs/versioning/103_CHANGELOG_RELEASES.MD`).
Note:
- The \"short description\" column follows the original commit/PR intent text for deterministic traceability and is not normalized to a single language.
| Version | Short description | Commit | Keyword |
|---|---|---|---|
+| `6.1.17` | Bridge and in-code hardening completed: `CsCoreRuntimeBridge` was structurally de-duplicated (tuple/assembly helpers), XML docs were aligned for German-language consistency, and edge-case delegation/fallback tests were added | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.16` | API auditability fail-closed enabled: `Microsoft.CodeAnalysis.PublicApiAnalyzers` was added centrally, a public API baseline (`PublicAPI.Shipped.txt`/`PublicAPI.Unshipped.txt`) was introduced for `FileTypeDetectionLib`, and governance/versioning docs now define the mandatory API-change process | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.15` | Governance drift closed: branch-protection review policy and Scorecard governance mappings were aligned to the verified state `required_approving_review_count = 0`, including updated process controls for mandatory required checks and review-thread evidence per `AGENTS.md` | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.14` | 6.1.14 pipeline convergence closed: release workflow now enforces NuGet online convergence fail-closed for `workflow_dispatch` too, resolves release metadata deterministically via artifact, and aligns fuzzing-blocker/governance evidence documentation | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
diff --git a/docs/1_en/versioning/003_CHANGELOG_RELEASES.MD b/docs/1_en/versioning/003_CHANGELOG_RELEASES.MD
index e7715517..7944a44a 100644
--- a/docs/1_en/versioning/003_CHANGELOG_RELEASES.MD
+++ b/docs/1_en/versioning/003_CHANGELOG_RELEASES.MD
@@ -6,6 +6,16 @@
All changes are documented here in technical terms. The release version itself is the Git tag `vX.Y.Z` (optional `-prerelease`) as SSOT.
+## [6.1.17]
+- Added:
+ - Added two bridge edge-case tests for fail-closed delegation/fallback (`NormalizeArchiveRelativePath`, `ResolveHmacKeyFromEnvironment`).
+- Changed:
+ - Reduced redundancy in `CsCoreRuntimeBridge`: tuple mapping is centralized in dedicated helpers and assembly path probing now uses one shared directory-probe function.
+ - Harmonized in-code XML documentation in bridge comments with consistent German umlaut spelling (`Brücke`, `Rückgabe`, `Prüfung`, `Länge`).
+- Docs/CI/Tooling:
+ - Executed phase-C local gates successfully: `preflight`, `tests-bdd-coverage`, `api-contract`.
+ - Version convergence set to `6.1.17` (`RepoVersion`, `Version`, `PackageVersion`, DE/EN version history).
+
## [6.1.16]
- Added:
- Added `Microsoft.CodeAnalysis.PublicApiAnalyzers` as a centrally managed analyzer package and enabled it for `FileTypeDetectionLib`.
diff --git a/docs/versioning/002_HISTORY_VERSIONS.MD b/docs/versioning/002_HISTORY_VERSIONS.MD
index 8f121b7a..544a9385 100644
--- a/docs/versioning/002_HISTORY_VERSIONS.MD
+++ b/docs/versioning/002_HISTORY_VERSIONS.MD
@@ -12,7 +12,7 @@ Heuristik für die Rückwirkungs-Zuordnung:
- `docs|test|ci|chore|tooling|refactor|fix` => Patch
Aktueller Entwicklungsstand:
-- Aktuelle Entwicklungslinie enthält `6.x` (aktueller Arbeitsstand: `v6.1.16`; Details in `docs/versioning/003_CHANGELOG_RELEASES.MD`).
+- Aktuelle Entwicklungslinie enthält `6.x` (aktueller Arbeitsstand: `v6.1.17`; Details in `docs/versioning/003_CHANGELOG_RELEASES.MD`).
Hinweis:
- Die Spalte `Keyword` verwendet den technischen Klassifizierungswert aus der Historie.
@@ -20,6 +20,7 @@ Hinweis:
| Version | Kurzbeschreibung | Commit | Keyword |
|---|---|---|---|
+| `6.1.17` | Bridge-/In-Code-Härtung abgeschlossen: `CsCoreRuntimeBridge` strukturell entdoppelt (Tuple-/Assembly-Helper), XML-Dokumentation mit konsistenter deutscher Umlautschreibweise vereinheitlicht und Randfalltests für Delegation/Fallback ergänzt | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.16` | API-Auditierbarkeit fail-closed aktiviert: `Microsoft.CodeAnalysis.PublicApiAnalyzers` zentral eingebunden, Public-API-Baseline (`PublicAPI.Shipped.txt`/`PublicAPI.Unshipped.txt`) für `FileTypeDetectionLib` eingeführt und Governance-/Versioning-Dokumentation um den verbindlichen API-Änderungsprozess erweitert | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.15` | Governance-Drift geschlossen: Branch-Protection-Review-Policy und Scorecard-Governance-Mappings auf den verifizierten Ist-Stand `required_approving_review_count = 0` konsolidiert, inklusive aktualisierter Prozesskontrollen für verpflichtende Required-Checks und Review-Thread-Evidence gemäß `AGENTS.md` | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.14` | 6.1.14 Pipeline-Konvergenz geschlossen: Release-Workflow erzwingt NuGet-Online-Konvergenz jetzt fail-closed auch für `workflow_dispatch`, Release-Metadaten werden artefaktbasiert deterministisch aufgelöst und Fuzzing-Blocker-/Governance-Evidence-Dokumentation entsprechend nachgezogen | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
diff --git a/docs/versioning/003_CHANGELOG_RELEASES.MD b/docs/versioning/003_CHANGELOG_RELEASES.MD
index 333ad8ce..0e34ac9a 100644
--- a/docs/versioning/003_CHANGELOG_RELEASES.MD
+++ b/docs/versioning/003_CHANGELOG_RELEASES.MD
@@ -7,6 +7,16 @@
Alle Änderungen werden hier technisch dokumentiert. Die Release-Version selbst ist
der Git-Tag `vX.Y.Z` (optional `-prerelease`) als SSOT.
+## [6.1.17]
+- Added:
+ - Zwei neue Bridge-Randfalltests für fail-closed Delegation/Fallback (`NormalizeArchiveRelativePath`, `ResolveHmacKeyFromEnvironment`) ergänzt.
+- Changed:
+ - `CsCoreRuntimeBridge` redundanzreduziert: Tuple-Auswertung in dedizierte Helper zentralisiert und Assembly-Pfadauflösung über eine gemeinsame Directory-Probe-Funktion vereinheitlicht.
+ - In-Code-XML-Dokumentation in Bridge-Kommentaren mit konsistenter deutscher Umlautschreibweise harmonisiert (`Brücke`, `Rückgabe`, `Prüfung`, `Länge`).
+- Docs/CI/Tooling:
+ - Phase-C-Gates lokal erfolgreich ausgeführt: `preflight`, `tests-bdd-coverage`, `api-contract`.
+ - Versionskonvergenz aktiv auf `6.1.17` gesetzt (`RepoVersion`, `Version`, `PackageVersion`, Versionshistorie DE/EN).
+
## [6.1.16]
- Added:
- `Microsoft.CodeAnalysis.PublicApiAnalyzers` als zentrales Analyzer-Paket aufgenommen und für `FileTypeDetectionLib` aktiviert.
diff --git a/docs/versioning/102_HISTORY_VERSIONS.MD b/docs/versioning/102_HISTORY_VERSIONS.MD
index 1775318f..a18d220c 100644
--- a/docs/versioning/102_HISTORY_VERSIONS.MD
+++ b/docs/versioning/102_HISTORY_VERSIONS.MD
@@ -12,13 +12,14 @@ Heuristics for retroactive classification:
- `docs|test|ci|chore|tooling|refactor|fix` => patch
Current state:
-- Current release line contains `6.x` (current working state: `v6.1.16`; details in `docs/versioning/103_CHANGELOG_RELEASES.MD`).
+- Current release line contains `6.x` (current working state: `v6.1.17`; details in `docs/versioning/103_CHANGELOG_RELEASES.MD`).
Note:
- The \"short description\" column follows the original commit/PR intent text for deterministic traceability and is not normalized to a single language.
| Version | Short description | Commit | Keyword |
|---|---|---|---|
+| `6.1.17` | Bridge and in-code hardening completed: `CsCoreRuntimeBridge` was structurally de-duplicated (tuple/assembly helpers), XML docs were aligned for German-language consistency, and edge-case delegation/fallback tests were added | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.16` | API auditability fail-closed enabled: `Microsoft.CodeAnalysis.PublicApiAnalyzers` was added centrally, a public API baseline (`PublicAPI.Shipped.txt`/`PublicAPI.Unshipped.txt`) was introduced for `FileTypeDetectionLib`, and governance/versioning docs now define the mandatory API-change process | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.15` | Governance drift closed: branch-protection review policy and Scorecard governance mappings were aligned to the verified state `required_approving_review_count = 0`, including updated process controls for mandatory required checks and review-thread evidence per `AGENTS.md` | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
| `6.1.14` | 6.1.14 pipeline convergence closed: release workflow now enforces NuGet online convergence fail-closed for `workflow_dispatch` too, resolves release metadata deterministically via artifact, and aligns fuzzing-blocker/governance evidence documentation | [unreleased](https://github.com/tomtastisch/FileClassifier/compare/main...HEAD) | patch |
diff --git a/docs/versioning/103_CHANGELOG_RELEASES.MD b/docs/versioning/103_CHANGELOG_RELEASES.MD
index feeb4fd2..5114544b 100644
--- a/docs/versioning/103_CHANGELOG_RELEASES.MD
+++ b/docs/versioning/103_CHANGELOG_RELEASES.MD
@@ -6,6 +6,16 @@
All changes are documented here in technical terms. The release version itself is the Git tag `vX.Y.Z` (optional `-prerelease`) as SSOT.
+## [6.1.17]
+- Added:
+ - Added two bridge edge-case tests for fail-closed delegation/fallback (`NormalizeArchiveRelativePath`, `ResolveHmacKeyFromEnvironment`).
+- Changed:
+ - Reduced redundancy in `CsCoreRuntimeBridge`: tuple mapping is centralized in dedicated helpers and assembly path probing now uses one shared directory-probe function.
+ - Harmonized in-code XML documentation in bridge comments with consistent German umlaut spelling (`Brücke`, `Rückgabe`, `Prüfung`, `Länge`).
+- Docs/CI/Tooling:
+ - Executed phase-C local gates successfully: `preflight`, `tests-bdd-coverage`, `api-contract`.
+ - Version convergence set to `6.1.17` (`RepoVersion`, `Version`, `PackageVersion`, DE/EN version history).
+
## [6.1.16]
- Added:
- Added `Microsoft.CodeAnalysis.PublicApiAnalyzers` as a centrally managed analyzer package and enabled it for `FileTypeDetectionLib`.
diff --git a/src/FileTypeDetection/FileTypeDetectionLib.vbproj b/src/FileTypeDetection/FileTypeDetectionLib.vbproj
index 018af9ef..d3d31b8a 100644
--- a/src/FileTypeDetection/FileTypeDetectionLib.vbproj
+++ b/src/FileTypeDetection/FileTypeDetectionLib.vbproj
@@ -7,8 +7,8 @@
true
false
Tomtastisch.FileClassifier
- 6.1.16
- 6.1.16
+ 6.1.17
+ 6.1.17
tomtastisch
Deterministic file type and MIME detection with fail-closed archive safety checks, secure extraction primitives, and reproducible hashing evidence for .NET.
filetype;mime;detection;magic-bytes;sniffing;archive;zip;tar;7z;rar;zipslip;security;hashing;sha256;deterministic;dotnet;netstandard2.0;net8;net10
diff --git a/src/FileTypeDetection/Infrastructure/Utils/CsCoreRuntimeBridge.vb b/src/FileTypeDetection/Infrastructure/Utils/CsCoreRuntimeBridge.vb
index 6bf59990..ce0d1ddf 100644
--- a/src/FileTypeDetection/Infrastructure/Utils/CsCoreRuntimeBridge.vb
+++ b/src/FileTypeDetection/Infrastructure/Utils/CsCoreRuntimeBridge.vb
@@ -7,8 +7,8 @@
' - Variablen im Deklarationsblock, spaltenartig ausgerichtet
'
' Kontext:
-' - Runtime-Bruecke fuer optionale Delegation auf C#-CSCore Utilities.
-' - Fail-closed: Falls CSCore nicht aufloesbar ist, bleibt VB-Fallback aktiv.
+' - Runtime-Brücke für optionale Delegation auf C#-CSCore Utilities.
+' - Fail-closed: Falls CSCore nicht auflösbar ist, bleibt VB-Fallback aktiv.
' ============================================================================
Option Strict On
@@ -24,12 +24,12 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
'''
''' Zweck:
- ''' Runtime-Bruecke zwischen VB-Core und optionalem CSCore-Utility-Layer.
+ ''' Runtime-Brücke zwischen VB-Core und optionalem CSCore-Utility-Layer.
'''
'''
''' Fail-Closed:
- ''' - Ist die CSCore-Assembly oder ein erwarteter Typ/Member nicht verfuegbar,
- ''' liefert die Bruecke deterministisch False und der VB-Fallback bleibt aktiv.
+ ''' - Ist die CSCore-Assembly oder ein erwarteter Typ/Member nicht verfügbar,
+ ''' liefert die Brücke deterministisch False und der VB-Fallback bleibt aktiv.
'''
Friend NotInheritable Class CsCoreRuntimeBridge
@@ -127,8 +127,8 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
End Sub
'''
- ''' Rueckgabe:
- ''' Laufzeitindikator fuer Unit-Tests und Diagnostik.
+ ''' Rückgabe:
+ ''' Laufzeitindikator für Unit-Tests und Diagnostik.
'''
Friend Shared ReadOnly Property IsCsCoreAvailable As Boolean
Get
@@ -139,7 +139,7 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
'''
''' Aktion:
- ''' Setzt die Telemetry-Zaehler zurueck (nur fuer Tests/Diagnostik).
+ ''' Setzt die Telemetry-Zähler zurück (nur für Tests/Diagnostik).
'''
Friend Shared Sub ResetTelemetry()
@@ -148,8 +148,8 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
End Sub
'''
- ''' Rueckgabe:
- ''' Liefert eine unveraenderliche Telemetry-Sicht fuer Audit/Tests.
+ ''' Rückgabe:
+ ''' Liefert eine unveränderliche Telemetry-Sicht für Audit/Tests.
'''
Friend Shared Function GetTelemetrySnapshot() As CsCoreRuntimeBridgeTelemetrySnapshot
@@ -823,22 +823,21 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
Return False
End If
- Try
- ' Striktes Tuple-Shape: [Boolean, Byte(), String]
- isResolved = CBool(values(0))
- key = If(CType(values(1), Byte()), Array.Empty(Of Byte)())
- note = If(CStr(values(2)), String.Empty)
- Return True
- Catch ex As Exception When _
- TypeOf ex Is InvalidCastException OrElse
- TypeOf ex Is NullReferenceException OrElse
- TypeOf ex Is IndexOutOfRangeException
+ ' Striktes Tuple-Shape: [Boolean, Byte(), String]
+ If Not TryReadHmacResolutionTuple(
+ OperationResolveHmacKeyFromEnvironment,
+ values,
+ isResolved,
+ key,
+ note
+ ) Then
isResolved = False
key = Array.Empty(Of Byte)()
note = String.Empty
- RecordFallback(OperationResolveHmacKeyFromEnvironment)
Return False
- End Try
+ End If
+
+ Return True
End Function
Friend Shared Function TryNormalizeArchiveRelativePath _
@@ -873,22 +872,21 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
Return False
End If
- Try
- ' Striktes Tuple-Shape: [Boolean, String, Boolean]
- isValid = CBool(values(0))
- normalizedPath = If(CStr(values(1)), String.Empty)
- isDirectory = CBool(values(2))
- Return True
- Catch ex As Exception When _
- TypeOf ex Is InvalidCastException OrElse
- TypeOf ex Is NullReferenceException OrElse
- TypeOf ex Is IndexOutOfRangeException
+ ' Striktes Tuple-Shape: [Boolean, String, Boolean]
+ If Not TryReadArchivePathTuple(
+ OperationNormalizeArchiveRelativePath,
+ values,
+ isValid,
+ normalizedPath,
+ isDirectory
+ ) Then
isValid = False
normalizedPath = String.Empty
isDirectory = False
- RecordFallback(OperationNormalizeArchiveRelativePath)
Return False
- End Try
+ End If
+
+ Return True
End Function
Friend Shared Function TryIsRootPath _
@@ -1200,6 +1198,11 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
End SyncLock
End Sub
+ '''
+ ''' Auflösung:
+ ''' Ermittelt die CSCore-Assembly deterministisch über geladene Domäne, Assembly-Name
+ ''' und vertrauenswürdige Basisverzeichnisse.
+ '''
Private Shared Function ResolveCsCoreAssembly() As Assembly
Dim loadedAssemblies() As Assembly
@@ -1207,7 +1210,6 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
Dim loadedName As String
Dim resolvedAssembly As Assembly
Dim assemblyDirectory As String
- Dim assemblyPath As String
Dim baseDirectoryPath As String
resolvedAssembly = Nothing
@@ -1229,24 +1231,41 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
End Try
assemblyDirectory = IO.Path.GetDirectoryName(GetType(CsCoreRuntimeBridge).Assembly.Location)
- If Not String.IsNullOrWhiteSpace(assemblyDirectory) Then
- assemblyPath = IO.Path.Combine(assemblyDirectory, CsCoreAssemblyFileName)
- If TryLoadAssemblyFromPath(assemblyPath, resolvedAssembly) Then
- Return resolvedAssembly
- End If
+ If TryResolveAssemblyFromDirectory(assemblyDirectory, resolvedAssembly) Then
+ Return resolvedAssembly
End If
baseDirectoryPath = AppContext.BaseDirectory
- If Not String.IsNullOrWhiteSpace(baseDirectoryPath) Then
- assemblyPath = IO.Path.Combine(baseDirectoryPath, CsCoreAssemblyFileName)
- If TryLoadAssemblyFromPath(assemblyPath, resolvedAssembly) Then
- Return resolvedAssembly
- End If
+ If TryResolveAssemblyFromDirectory(baseDirectoryPath, resolvedAssembly) Then
+ Return resolvedAssembly
End If
Return Nothing
End Function
+ '''
+ ''' Auflösung:
+ ''' Versucht eine Assembly-Datei aus einem angegebenen Verzeichnis zu laden.
+ '''
+ Private Shared Function TryResolveAssemblyFromDirectory _
+ (
+ directoryPath As String,
+ ByRef resolvedAssembly As Assembly
+ ) As Boolean
+
+ Dim assemblyPath As String
+
+ resolvedAssembly = Nothing
+ If String.IsNullOrWhiteSpace(directoryPath) Then Return False
+
+ assemblyPath = IO.Path.Combine(directoryPath, CsCoreAssemblyFileName)
+ Return TryLoadAssemblyFromPath(assemblyPath, resolvedAssembly)
+ End Function
+
+ '''
+ ''' Ladevorgang:
+ ''' Lädt eine Assembly defensiv über Rohbytes und liefert bei Fehlern deterministisch False.
+ '''
Private Shared Function TryLoadAssemblyFromPath _
(
assemblyPath As String,
@@ -1319,8 +1338,8 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
End Function
'''
- ''' Pruefung:
- ''' Stellt sicher, dass CSCore initialisiert und als verfuegbar markiert ist.
+ ''' Prüfung:
+ ''' Stellt sicher, dass CSCore initialisiert und als verfügbar markiert ist.
'''
Private Shared Function TryEnsureCsCoreAvailable _
(
@@ -1337,8 +1356,8 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
End Function
'''
- ''' Pruefung:
- ''' Fuehrt Verfuegbarkeits- und Methodenguard zusammen und zaehlt Delegation.
+ ''' Prüfung:
+ ''' Führt Verfügbarkeits- und Methodenguard zusammen und zählt Delegation.
'''
Private Shared Function TryPrepareInvocation _
(
@@ -1360,7 +1379,7 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
End Function
'''
- ''' Typisierte Rueckgabe:
+ ''' Typisierte Rückgabe:
''' Invoked Ergebnis muss String sein; sonst fail-closed Fallback.
'''
Private Shared Function TryInvokeStringForFallback _
@@ -1388,7 +1407,7 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
End Function
'''
- ''' Typisierte Rueckgabe:
+ ''' Typisierte Rückgabe:
''' Invoked Ergebnis muss Integer sein; sonst fail-closed Fallback.
'''
Private Shared Function TryInvokeIntegerForFallback _
@@ -1417,7 +1436,7 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
'''
''' Shape-Guard:
- ''' Invoked Ergebnis muss Object() mit exakt erwarteter Laenge liefern.
+ ''' Invoked Ergebnis muss Object() mit exakt erwarteter Länge liefern.
'''
Private Shared Function TryInvokeObjectArrayForFallback _
(
@@ -1452,7 +1471,7 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
'''
''' Shape-Guard:
- ''' Invoked Ergebnis muss String() mit exakt erwarteter Laenge liefern.
+ ''' Invoked Ergebnis muss String() mit exakt erwarteter Länge liefern.
'''
Private Shared Function TryInvokeStringArrayForFallback _
(
@@ -1485,6 +1504,72 @@ Namespace Global.Tomtastisch.FileClassifier.Infrastructure.Utils
Return True
End Function
+ '''
+ ''' Tuple-Guard:
+ ''' Liest das HMAC-Tuple im festen Format
+ ''' [isResolved(Boolean), key(Byte()), note(String)].
+ '''
+ Private Shared Function TryReadHmacResolutionTuple _
+ (
+ operationName As String,
+ values() As Object,
+ ByRef isResolved As Boolean,
+ ByRef key As Byte(),
+ ByRef note As String
+ ) As Boolean
+
+ If values Is Nothing OrElse values.Length <> ExpectedHmacResolutionValuesCount Then
+ RecordFallback(operationName)
+ Return False
+ End If
+
+ Try
+ isResolved = CBool(values(0))
+ key = If(CType(values(1), Byte()), Array.Empty(Of Byte)())
+ note = If(CStr(values(2)), String.Empty)
+ Return True
+ Catch ex As Exception When _
+ TypeOf ex Is InvalidCastException OrElse
+ TypeOf ex Is NullReferenceException OrElse
+ TypeOf ex Is IndexOutOfRangeException
+ RecordFallback(operationName)
+ Return False
+ End Try
+ End Function
+
+ '''
+ ''' Tuple-Guard:
+ ''' Liest das Archivpfad-Tuple im festen Format
+ ''' [isValid(Boolean), normalizedPath(String), isDirectory(Boolean)].
+ '''
+ Private Shared Function TryReadArchivePathTuple _
+ (
+ operationName As String,
+ values() As Object,
+ ByRef isValid As Boolean,
+ ByRef normalizedPath As String,
+ ByRef isDirectory As Boolean
+ ) As Boolean
+
+ If values Is Nothing OrElse values.Length <> ExpectedArchivePathValuesCount Then
+ RecordFallback(operationName)
+ Return False
+ End If
+
+ Try
+ isValid = CBool(values(0))
+ normalizedPath = If(CStr(values(1)), String.Empty)
+ isDirectory = CBool(values(2))
+ Return True
+ Catch ex As Exception When _
+ TypeOf ex Is InvalidCastException OrElse
+ TypeOf ex Is NullReferenceException OrElse
+ TypeOf ex Is IndexOutOfRangeException
+ RecordFallback(operationName)
+ Return False
+ End Try
+ End Function
+
Private Shared Function TryGetClosedGenericMethod _
(
genericMethodDefinition As MethodInfo,
diff --git a/tests/FileTypeDetectionLib.Tests/Unit/CsCoreUtilityBridgeUnitTests.cs b/tests/FileTypeDetectionLib.Tests/Unit/CsCoreUtilityBridgeUnitTests.cs
index 1179e5b2..fa2900ec 100644
--- a/tests/FileTypeDetectionLib.Tests/Unit/CsCoreUtilityBridgeUnitTests.cs
+++ b/tests/FileTypeDetectionLib.Tests/Unit/CsCoreUtilityBridgeUnitTests.cs
@@ -203,6 +203,84 @@ public void BridgeTelemetry_TracksDelegationOrFallback_ForHashAndMaterialization
}
}
+ [Fact]
+ public void Bridge_NormalizeArchiveRelativePath_InvalidTraversal_RemainsFailClosed()
+ {
+ CsCoreRuntimeBridge.ResetTelemetry();
+
+ var isValid = true;
+ var normalizedPath = "seed";
+ var isDirectory = true;
+
+ var bridgeCall = CsCoreRuntimeBridge.TryNormalizeArchiveRelativePath(
+ "../escape.txt",
+ allowDirectoryMarker: false,
+ ref isValid,
+ ref normalizedPath,
+ ref isDirectory);
+
+ var snapshot = CsCoreRuntimeBridge.GetTelemetrySnapshot();
+ if (snapshot.IsCsCoreAvailable)
+ {
+ Assert.True(bridgeCall);
+ Assert.False(isValid);
+ Assert.Equal(string.Empty, normalizedPath);
+ Assert.False(isDirectory);
+ Assert.True(snapshot.GetDelegatedCount("NormalizeArchiveRelativePath") > 0);
+ return;
+ }
+
+ Assert.False(bridgeCall);
+ Assert.False(isValid);
+ Assert.Equal(string.Empty, normalizedPath);
+ Assert.False(isDirectory);
+ Assert.True(snapshot.GetFallbackCount("NormalizeArchiveRelativePath") > 0);
+ }
+
+ [Fact]
+ public void Bridge_ResolveHmacKeyFromEnvironment_InvalidBase64_RemainsDeterministic()
+ {
+ CsCoreRuntimeBridge.ResetTelemetry();
+
+ const string environmentVariableName = "FILECLASSIFIER_BRIDGE_TEST_HMAC_B64";
+ var original = Environment.GetEnvironmentVariable(environmentVariableName);
+ try
+ {
+ Environment.SetEnvironmentVariable(environmentVariableName, "invalid-base64");
+
+ var isResolved = false;
+ var key = Array.Empty();
+ var note = string.Empty;
+
+ var bridgeCall = CsCoreRuntimeBridge.TryResolveHmacKeyFromEnvironment(
+ environmentVariableName,
+ ref isResolved,
+ ref key,
+ ref note);
+
+ var snapshot = CsCoreRuntimeBridge.GetTelemetrySnapshot();
+ if (snapshot.IsCsCoreAvailable)
+ {
+ Assert.True(bridgeCall);
+ Assert.False(isResolved);
+ Assert.Empty(key);
+ Assert.Contains("invalid Base64", note, StringComparison.Ordinal);
+ Assert.True(snapshot.GetDelegatedCount("ResolveHmacKeyFromEnvironment") > 0);
+ return;
+ }
+
+ Assert.False(bridgeCall);
+ Assert.False(isResolved);
+ Assert.Empty(key);
+ Assert.Equal(string.Empty, note);
+ Assert.True(snapshot.GetFallbackCount("ResolveHmacKeyFromEnvironment") > 0);
+ }
+ finally
+ {
+ Environment.SetEnvironmentVariable(environmentVariableName, original);
+ }
+ }
+
private static byte[] CreateOpenDocumentPackage(string mimeType)
{
using var ms = new MemoryStream();