From 4bd7f74a3733bd13af7cf9f72aacbbeeb948c76f Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Thu, 19 Feb 2026 20:41:12 +0100 Subject: [PATCH 1/6] fix(archive): sharpcompress-1.0 api-kompatibilitaet absichern --- .../Infrastructure/ArchiveInternals.vb | 45 ++++++++++++++- .../Support/ArchivePayloadFactory.cs | 6 +- .../Support/SharpCompressApiCompat.cs | 56 +++++++++++++++++++ .../ArchiveInternalsNestedBranchUnitTests.cs | 5 +- ...eAndArchiveInternalsFailClosedUnitTests.cs | 4 +- .../SharpCompressArchiveBackendUnitTests.cs | 2 +- ...SharpCompressEntryModelNonNullUnitTests.cs | 6 +- 7 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs diff --git a/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb b/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb index 7468e69..1e56304 100644 --- a/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb +++ b/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb @@ -126,8 +126,10 @@ Namespace Global.Tomtastisch.FileClassifier Friend Shared Function OpenArchive(stream As Stream) As SharpCompress.Archives.IArchive Try Dim options = New SharpCompress.Readers.ReaderOptions() With {.LeaveStreamOpen = True} - Return SharpCompress.Archives.ArchiveFactory.OpenArchive(stream, options) + Return OpenArchiveFactoryCompat(stream, options) Catch ex As Exception When _ + TypeOf ex Is MissingMethodException OrElse + TypeOf ex Is System.Reflection.TargetInvocationException OrElse TypeOf ex Is InvalidOperationException OrElse TypeOf ex Is NotSupportedException OrElse TypeOf ex Is ArgumentException @@ -158,14 +160,53 @@ Namespace Global.Tomtastisch.FileClassifier Private Shared Function OpenGZipArchive(stream As Stream) As SharpCompress.Archives.IArchive Try Dim options = New SharpCompress.Readers.ReaderOptions() With {.LeaveStreamOpen = True} - Return SharpCompress.Archives.GZip.GZipArchive.OpenArchive(stream, options) + Return OpenGZipArchiveCompat(stream, options) Catch ex As Exception When _ + TypeOf ex Is MissingMethodException OrElse + TypeOf ex Is System.Reflection.TargetInvocationException OrElse TypeOf ex Is InvalidOperationException OrElse TypeOf ex Is NotSupportedException OrElse TypeOf ex Is ArgumentException Return Nothing End Try End Function + + Private Shared Function OpenArchiveFactoryCompat( + stream As Stream, + options As SharpCompress.Readers.ReaderOptions + ) As SharpCompress.Archives.IArchive + Dim method = GetOpenCompatMethod(GetType(SharpCompress.Archives.ArchiveFactory)) + Dim opened = method.Invoke(Nothing, New Object() {stream, options}) + Return CType(opened, SharpCompress.Archives.IArchive) + End Function + + Private Shared Function OpenGZipArchiveCompat( + stream As Stream, + options As SharpCompress.Readers.ReaderOptions + ) As SharpCompress.Archives.IArchive + Dim method = GetOpenCompatMethod(GetType(SharpCompress.Archives.GZip.GZipArchive)) + Dim opened = method.Invoke(Nothing, New Object() {stream, options}) + Return CType(opened, SharpCompress.Archives.IArchive) + End Function + + Private Shared Function GetOpenCompatMethod(type As Type) As System.Reflection.MethodInfo + Dim signature = New Type() {GetType(Stream), GetType(SharpCompress.Readers.ReaderOptions)} + Dim method = type.GetMethod("OpenArchive", System.Reflection.BindingFlags.Public Or + System.Reflection.BindingFlags.Static, + binder:=Nothing, + types:=signature, + modifiers:=Nothing) + If method IsNot Nothing Then Return method + + method = type.GetMethod("Open", System.Reflection.BindingFlags.Public Or + System.Reflection.BindingFlags.Static, + binder:=Nothing, + types:=signature, + modifiers:=Nothing) + If method IsNot Nothing Then Return method + + Throw New MissingMethodException(type.FullName, "OpenArchive/Open(Stream, ReaderOptions)") + End Function End Class ''' diff --git a/tests/FileTypeDetectionLib.Tests/Support/ArchivePayloadFactory.cs b/tests/FileTypeDetectionLib.Tests/Support/ArchivePayloadFactory.cs index d8fac7b..599f747 100644 --- a/tests/FileTypeDetectionLib.Tests/Support/ArchivePayloadFactory.cs +++ b/tests/FileTypeDetectionLib.Tests/Support/ArchivePayloadFactory.cs @@ -10,7 +10,7 @@ internal static class ArchivePayloadFactory internal static byte[] CreateZipWithSingleEntry(string entryName, string content) { using var ms = new MemoryStream(); - using (var writer = WriterFactory.OpenWriter(ms, ArchiveType.Zip, new WriterOptions(CompressionType.Deflate))) + using (var writer = SharpCompressApiCompat.OpenWriter(ms, ArchiveType.Zip, new WriterOptions(CompressionType.Deflate))) using (var payload = new MemoryStream(Encoding.UTF8.GetBytes(content))) { writer.Write(string.IsNullOrWhiteSpace(entryName) ? "note.txt" : entryName, payload, DateTime.UnixEpoch); @@ -22,7 +22,7 @@ internal static byte[] CreateZipWithSingleEntry(string entryName, string content internal static byte[] CreateTarWithSingleEntry(string entryName, string content) { using var ms = new MemoryStream(); - using (var writer = WriterFactory.OpenWriter(ms, ArchiveType.Tar, new WriterOptions(CompressionType.None))) + using (var writer = SharpCompressApiCompat.OpenWriter(ms, ArchiveType.Tar, new WriterOptions(CompressionType.None))) using (var payload = new MemoryStream(Encoding.UTF8.GetBytes(content))) { writer.Write(string.IsNullOrWhiteSpace(entryName) ? "note.txt" : entryName, payload, DateTime.UnixEpoch); @@ -34,7 +34,7 @@ internal static byte[] CreateTarWithSingleEntry(string entryName, string content internal static byte[] CreateGZipWithSingleEntry(string entryName, byte[] payload) { using var ms = new MemoryStream(); - using (var writer = WriterFactory.OpenWriter(ms, ArchiveType.GZip, new WriterOptions(CompressionType.GZip))) + using (var writer = SharpCompressApiCompat.OpenWriter(ms, ArchiveType.GZip, new WriterOptions(CompressionType.GZip))) using (var source = new MemoryStream(payload, false)) { writer.Write(string.IsNullOrWhiteSpace(entryName) ? "payload.bin" : entryName, source, DateTime.UnixEpoch); diff --git a/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs b/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs new file mode 100644 index 0000000..bfb552a --- /dev/null +++ b/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs @@ -0,0 +1,56 @@ +using SharpCompress.Archives; +using SharpCompress.Archives.Zip; +using SharpCompress.Common; +using SharpCompress.Readers; +using SharpCompress.Writers; + +namespace FileTypeDetectionLib.Tests.Support; + +internal static class SharpCompressApiCompat +{ + internal static IArchive OpenArchive(Stream stream) + { + var options = new ReaderOptions { LeaveStreamOpen = true }; + var opened = InvokeOpen(typeof(ArchiveFactory), stream, options); + return (IArchive)opened; + } + + internal static IArchive OpenZipArchive(Stream stream) + { + var options = new ReaderOptions { LeaveStreamOpen = true }; + var opened = InvokeOpen(typeof(ZipArchive), stream, options); + return (IArchive)opened; + } + + internal static IWriter OpenWriter(Stream stream, ArchiveType archiveType, WriterOptions options) + { + var args = new object[] { stream, archiveType, options }; + var signature = new[] { typeof(Stream), typeof(ArchiveType), typeof(WriterOptions) }; + + var method = typeof(WriterFactory).GetMethod("OpenWriter", signature); + method ??= typeof(WriterFactory).GetMethod("Open", signature); + + if (method is null) + { + throw new MissingMethodException(typeof(WriterFactory).FullName, "OpenWriter/Open(Stream, ArchiveType, WriterOptions)"); + } + + return (IWriter)method.Invoke(null, args)!; + } + + private static object InvokeOpen(Type type, Stream stream, ReaderOptions options) + { + var args = new object[] { stream, options }; + var signature = new[] { typeof(Stream), typeof(ReaderOptions) }; + + var method = type.GetMethod("OpenArchive", signature); + method ??= type.GetMethod("Open", signature); + + if (method is null) + { + throw new MissingMethodException(type.FullName, "OpenArchive/Open(Stream, ReaderOptions)"); + } + + return method.Invoke(null, args)!; + } +} diff --git a/tests/FileTypeDetectionLib.Tests/Unit/ArchiveInternalsNestedBranchUnitTests.cs b/tests/FileTypeDetectionLib.Tests/Unit/ArchiveInternalsNestedBranchUnitTests.cs index 84199c3..1388717 100644 --- a/tests/FileTypeDetectionLib.Tests/Unit/ArchiveInternalsNestedBranchUnitTests.cs +++ b/tests/FileTypeDetectionLib.Tests/Unit/ArchiveInternalsNestedBranchUnitTests.cs @@ -3,7 +3,6 @@ using SharpCompress.Archives; using SharpCompress.Archives.Zip; using SharpCompress.Common; -using SharpCompress.Readers; using SharpCompress.Writers; using Tomtastisch.FileClassifier; @@ -86,14 +85,14 @@ public void TryReadEntryPayloadBoundedWithOptions_ReturnsFalse_ForInvalidInputs( private static IArchiveEntry CreateZipArchiveEntry(string name, byte[] payload) { using var ms = new MemoryStream(); - using (var writer = WriterFactory.OpenWriter(ms, ArchiveType.Zip, new WriterOptions(CompressionType.Deflate))) + using (var writer = SharpCompressApiCompat.OpenWriter(ms, ArchiveType.Zip, new WriterOptions(CompressionType.Deflate))) using (var data = new MemoryStream(payload, false)) { writer.Write(name, data, DateTime.UnixEpoch); } ms.Position = 0; - var archive = ZipArchive.OpenArchive(ms, new ReaderOptions { LeaveStreamOpen = true }); + var archive = SharpCompressApiCompat.OpenZipArchive(ms); return archive.Entries.First(); } } diff --git a/tests/FileTypeDetectionLib.Tests/Unit/CoreAndArchiveInternalsFailClosedUnitTests.cs b/tests/FileTypeDetectionLib.Tests/Unit/CoreAndArchiveInternalsFailClosedUnitTests.cs index b422bff..d84cb4d 100644 --- a/tests/FileTypeDetectionLib.Tests/Unit/CoreAndArchiveInternalsFailClosedUnitTests.cs +++ b/tests/FileTypeDetectionLib.Tests/Unit/CoreAndArchiveInternalsFailClosedUnitTests.cs @@ -1,8 +1,6 @@ using FileTypeDetectionLib.Tests.Support; using Microsoft.Extensions.Logging; -using SharpCompress.Archives; using SharpCompress.Common; -using SharpCompress.Readers; using Tomtastisch.FileClassifier; namespace FileTypeDetectionLib.Tests.Unit; @@ -162,7 +160,7 @@ public void SharpCompressEntryModel_MapsArchiveEntryFields_ForConcreteEntry() { var payload = ArchivePayloadFactory.CreateTarWithSingleEntry("inner/note.txt", "hello"); using var ms = new MemoryStream(payload, false); - using var archive = ArchiveFactory.OpenArchive(ms, new ReaderOptions { LeaveStreamOpen = true }); + using var archive = SharpCompressApiCompat.OpenArchive(ms); var entry = archive.Entries.First(e => !e.IsDirectory); var model = new SharpCompressEntryModel(entry); diff --git a/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressArchiveBackendUnitTests.cs b/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressArchiveBackendUnitTests.cs index 3f4780d..f633f49 100644 --- a/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressArchiveBackendUnitTests.cs +++ b/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressArchiveBackendUnitTests.cs @@ -109,7 +109,7 @@ public void Process_ReturnsFalse_WhenExtractorReturnsFalse() private static byte[] CreateTarWithEntries(int entryCount, int entrySize) { using var ms = new MemoryStream(); - using (var writer = WriterFactory.OpenWriter(ms, ArchiveType.Tar, new WriterOptions(CompressionType.None))) + using (var writer = SharpCompressApiCompat.OpenWriter(ms, ArchiveType.Tar, new WriterOptions(CompressionType.None))) { for (var i = 0; i < entryCount; i++) { diff --git a/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs b/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs index 39379f1..be675a0 100644 --- a/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs +++ b/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs @@ -1,8 +1,8 @@ using System.Text; using SharpCompress.Archives; using SharpCompress.Common; -using SharpCompress.Readers; using SharpCompress.Writers; +using FileTypeDetectionLib.Tests.Support; using Tomtastisch.FileClassifier; namespace FileTypeDetectionLib.Tests.Unit; @@ -14,7 +14,7 @@ public void Properties_ReturnValues_ForRealArchiveEntry() { var payload = CreateTarWithEntry("note.txt", "hello"); using var stream = new MemoryStream(payload, false); - using var archive = ArchiveFactory.OpenArchive(stream, new ReaderOptions { LeaveStreamOpen = true }); + using var archive = SharpCompressApiCompat.OpenArchive(stream); var entry = archive.Entries.First(); var model = new SharpCompressEntryModel(entry); @@ -31,7 +31,7 @@ public void Properties_ReturnValues_ForRealArchiveEntry() private static byte[] CreateTarWithEntry(string name, string content) { using var ms = new MemoryStream(); - using (var writer = WriterFactory.OpenWriter(ms, ArchiveType.Tar, new WriterOptions(CompressionType.None))) + using (var writer = SharpCompressApiCompat.OpenWriter(ms, ArchiveType.Tar, new WriterOptions(CompressionType.None))) using (var data = new MemoryStream(Encoding.UTF8.GetBytes(content))) { writer.Write(name, data, DateTime.UnixEpoch); From b6063b2c060cf9365351271ca4bc0a8b94abb0e1 Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Thu, 19 Feb 2026 20:44:08 +0100 Subject: [PATCH 2/6] fix(test): using-reihenfolge fuer preflight-format-gate --- .../Unit/SharpCompressEntryModelNonNullUnitTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs b/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs index be675a0..356e515 100644 --- a/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs +++ b/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs @@ -1,8 +1,8 @@ using System.Text; +using FileTypeDetectionLib.Tests.Support; using SharpCompress.Archives; using SharpCompress.Common; using SharpCompress.Writers; -using FileTypeDetectionLib.Tests.Support; using Tomtastisch.FileClassifier; namespace FileTypeDetectionLib.Tests.Unit; From 92d2e3976ea3487b77b8fbd25f06bbed79e49318 Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Thu, 19 Feb 2026 20:45:55 +0100 Subject: [PATCH 3/6] chore(ci): trigger preflight nach pr-governance-update From b86908b9c663b07d5c86ead075891d164e8fbe8d Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Thu, 19 Feb 2026 20:48:43 +0100 Subject: [PATCH 4/6] chore(test): trigger frischen pr-lauf nach governance-update --- .../Support/SharpCompressApiCompat.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs b/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs index bfb552a..a4f9fb4 100644 --- a/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs +++ b/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs @@ -32,7 +32,7 @@ internal static IWriter OpenWriter(Stream stream, ArchiveType archiveType, Write if (method is null) { - throw new MissingMethodException(typeof(WriterFactory).FullName, "OpenWriter/Open(Stream, ArchiveType, WriterOptions)"); + throw new MissingMethodException(typeof(WriterFactory).FullName, "OpenWriter/Open(Stream, ArchiveType, WriterOptions) [compat]"); } return (IWriter)method.Invoke(null, args)!; From 1fa90576e632fdaad6106a20db1054537b9fa56d Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Thu, 19 Feb 2026 20:56:17 +0100 Subject: [PATCH 5/6] chore(ci): qodana-blocker minimal bereinigen --- .../Infrastructure/ArchiveInternals.vb | 40 ++++++++++--------- .../Support/SharpCompressApiCompat.cs | 20 +++------- .../ArchiveInternalsNestedBranchUnitTests.cs | 1 - ...SharpCompressEntryModelNonNullUnitTests.cs | 1 - 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb b/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb index 1e56304..66878b6 100644 --- a/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb +++ b/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb @@ -11,6 +11,8 @@ Option Strict On Option Explicit On Imports System.IO +Imports System.Reflection +Imports System.Security Namespace Global.Tomtastisch.FileClassifier ''' @@ -191,15 +193,15 @@ Namespace Global.Tomtastisch.FileClassifier Private Shared Function GetOpenCompatMethod(type As Type) As System.Reflection.MethodInfo Dim signature = New Type() {GetType(Stream), GetType(SharpCompress.Readers.ReaderOptions)} - Dim method = type.GetMethod("OpenArchive", System.Reflection.BindingFlags.Public Or - System.Reflection.BindingFlags.Static, + Dim method = type.GetMethod("OpenArchive", BindingFlags.Public Or + BindingFlags.Static, binder:=Nothing, types:=signature, modifiers:=Nothing) If method IsNot Nothing Then Return method - method = type.GetMethod("Open", System.Reflection.BindingFlags.Public Or - System.Reflection.BindingFlags.Static, + method = type.GetMethod("Open", BindingFlags.Public Or + BindingFlags.Static, binder:=Nothing, types:=signature, modifiers:=Nothing) @@ -228,7 +230,7 @@ Namespace Global.Tomtastisch.FileClassifier End Using Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -268,7 +270,7 @@ Namespace Global.Tomtastisch.FileClassifier End Using Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -283,7 +285,7 @@ Namespace Global.Tomtastisch.FileClassifier StreamGuard.RewindToStart(stream) Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is NotSupportedException OrElse TypeOf ex Is ArgumentException OrElse @@ -392,7 +394,7 @@ Namespace Global.Tomtastisch.FileClassifier Return entries.AsReadOnly() Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -430,7 +432,7 @@ Namespace Global.Tomtastisch.FileClassifier destinationFull = Path.GetFullPath(destinationDirectory) Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is PathTooLongException OrElse TypeOf ex Is NotSupportedException OrElse @@ -466,7 +468,7 @@ Namespace Global.Tomtastisch.FileClassifier Return True Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -481,7 +483,7 @@ Namespace Global.Tomtastisch.FileClassifier Directory.Delete(stageDir, recursive:=True) Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is NotSupportedException OrElse TypeOf ex Is ArgumentException @@ -507,7 +509,7 @@ Namespace Global.Tomtastisch.FileClassifier targetPath = Path.GetFullPath(Path.Combine(destinationPrefix, entryName)) Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is PathTooLongException OrElse TypeOf ex Is NotSupportedException OrElse @@ -550,7 +552,7 @@ Namespace Global.Tomtastisch.FileClassifier Return True Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -592,7 +594,7 @@ Namespace Global.Tomtastisch.FileClassifier Return True Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -691,7 +693,7 @@ Namespace Global.Tomtastisch.FileClassifier End Using Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -721,7 +723,7 @@ Namespace Global.Tomtastisch.FileClassifier End Using Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -834,7 +836,7 @@ Namespace Global.Tomtastisch.FileClassifier Return True Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -924,7 +926,7 @@ Namespace Global.Tomtastisch.FileClassifier End Using Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse @@ -984,7 +986,7 @@ Namespace Global.Tomtastisch.FileClassifier Return True Catch ex As Exception When _ TypeOf ex Is UnauthorizedAccessException OrElse - TypeOf ex Is System.Security.SecurityException OrElse + TypeOf ex Is SecurityException OrElse TypeOf ex Is IOException OrElse TypeOf ex Is InvalidDataException OrElse TypeOf ex Is NotSupportedException OrElse diff --git a/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs b/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs index a4f9fb4..2caed64 100644 --- a/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs +++ b/tests/FileTypeDetectionLib.Tests/Support/SharpCompressApiCompat.cs @@ -27,13 +27,9 @@ internal static IWriter OpenWriter(Stream stream, ArchiveType archiveType, Write var args = new object[] { stream, archiveType, options }; var signature = new[] { typeof(Stream), typeof(ArchiveType), typeof(WriterOptions) }; - var method = typeof(WriterFactory).GetMethod("OpenWriter", signature); - method ??= typeof(WriterFactory).GetMethod("Open", signature); - - if (method is null) - { - throw new MissingMethodException(typeof(WriterFactory).FullName, "OpenWriter/Open(Stream, ArchiveType, WriterOptions) [compat]"); - } + var method = typeof(WriterFactory).GetMethod("OpenWriter", signature) + ?? typeof(WriterFactory).GetMethod("Open", signature) + ?? throw new MissingMethodException(typeof(WriterFactory).FullName, "OpenWriter/Open(Stream, ArchiveType, WriterOptions) [compat]"); return (IWriter)method.Invoke(null, args)!; } @@ -43,13 +39,9 @@ private static object InvokeOpen(Type type, Stream stream, ReaderOptions options var args = new object[] { stream, options }; var signature = new[] { typeof(Stream), typeof(ReaderOptions) }; - var method = type.GetMethod("OpenArchive", signature); - method ??= type.GetMethod("Open", signature); - - if (method is null) - { - throw new MissingMethodException(type.FullName, "OpenArchive/Open(Stream, ReaderOptions)"); - } + var method = type.GetMethod("OpenArchive", signature) + ?? type.GetMethod("Open", signature) + ?? throw new MissingMethodException(type.FullName, "OpenArchive/Open(Stream, ReaderOptions)"); return method.Invoke(null, args)!; } diff --git a/tests/FileTypeDetectionLib.Tests/Unit/ArchiveInternalsNestedBranchUnitTests.cs b/tests/FileTypeDetectionLib.Tests/Unit/ArchiveInternalsNestedBranchUnitTests.cs index 1388717..bfe0419 100644 --- a/tests/FileTypeDetectionLib.Tests/Unit/ArchiveInternalsNestedBranchUnitTests.cs +++ b/tests/FileTypeDetectionLib.Tests/Unit/ArchiveInternalsNestedBranchUnitTests.cs @@ -1,7 +1,6 @@ using System.Reflection; using FileTypeDetectionLib.Tests.Support; using SharpCompress.Archives; -using SharpCompress.Archives.Zip; using SharpCompress.Common; using SharpCompress.Writers; using Tomtastisch.FileClassifier; diff --git a/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs b/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs index 356e515..dedc3d2 100644 --- a/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs +++ b/tests/FileTypeDetectionLib.Tests/Unit/SharpCompressEntryModelNonNullUnitTests.cs @@ -1,6 +1,5 @@ using System.Text; using FileTypeDetectionLib.Tests.Support; -using SharpCompress.Archives; using SharpCompress.Common; using SharpCompress.Writers; using Tomtastisch.FileClassifier; From e9e8bbe9ad0791ef8e44a5c05e960d3ca4f9691b Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Thu, 19 Feb 2026 21:02:52 +0100 Subject: [PATCH 6/6] fix(archive): targetinvocation nur fuer erwartete inner-fehler abfangen --- .../Infrastructure/ArchiveInternals.vb | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb b/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb index 66878b6..b9faba9 100644 --- a/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb +++ b/src/FileTypeDetection/Infrastructure/ArchiveInternals.vb @@ -129,9 +129,12 @@ Namespace Global.Tomtastisch.FileClassifier Try Dim options = New SharpCompress.Readers.ReaderOptions() With {.LeaveStreamOpen = True} Return OpenArchiveFactoryCompat(stream, options) + Catch ex As TargetInvocationException When IsExpectedInvocationException(ex) + Return Nothing + Catch ex As TargetInvocationException + Throw Catch ex As Exception When _ TypeOf ex Is MissingMethodException OrElse - TypeOf ex Is System.Reflection.TargetInvocationException OrElse TypeOf ex Is InvalidOperationException OrElse TypeOf ex Is NotSupportedException OrElse TypeOf ex Is ArgumentException @@ -163,9 +166,12 @@ Namespace Global.Tomtastisch.FileClassifier Try Dim options = New SharpCompress.Readers.ReaderOptions() With {.LeaveStreamOpen = True} Return OpenGZipArchiveCompat(stream, options) + Catch ex As TargetInvocationException When IsExpectedInvocationException(ex) + Return Nothing + Catch ex As TargetInvocationException + Throw Catch ex As Exception When _ TypeOf ex Is MissingMethodException OrElse - TypeOf ex Is System.Reflection.TargetInvocationException OrElse TypeOf ex Is InvalidOperationException OrElse TypeOf ex Is NotSupportedException OrElse TypeOf ex Is ArgumentException @@ -173,6 +179,17 @@ Namespace Global.Tomtastisch.FileClassifier End Try End Function + Private Shared Function IsExpectedInvocationException(ex As TargetInvocationException) As Boolean + Dim inner = ex?.InnerException + If inner Is Nothing Then Return False + + Return TypeOf inner Is InvalidOperationException OrElse + TypeOf inner Is NotSupportedException OrElse + TypeOf inner Is ArgumentException OrElse + TypeOf inner Is InvalidDataException OrElse + TypeOf inner Is IOException + End Function + Private Shared Function OpenArchiveFactoryCompat( stream As Stream, options As SharpCompress.Readers.ReaderOptions