From bebccaae28f07bc23a9c9704dd21f3e5d4f78868 Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Mon, 9 Jul 2018 18:44:46 -0700 Subject: [PATCH] Avoid throwing `NotSupportedException` in `ReaderFactory` hot path `ReaderFactory.Open()` calls `ZipArchive.IsZipFile()` to determine if the `Stream` is a zip archive, which calls into `ZipHeaderFactory.ReadHeader()`, which throws a `NotSupportedException` when the `Stream` is not a zip archive. To be clear, this exception is caught and `IsZipFile()` returns `false`, but when called in a hot-path, these exceptions can become expensive. To address this issue, `ReadHeader` now returns `null` in the default cause instead of throwing. All callsites were already checking for and handling `null`, so no behavior changes. --- src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs | 1 + src/SharpCompress/Common/Zip/ZipHeaderFactory.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs index 1148c53c..f17c5d7e 100644 --- a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs +++ b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs @@ -49,6 +49,7 @@ namespace SharpCompress.Common.Zip _lastEntryHeader = null; uint headerBytes = reader.ReadUInt32(); header = ReadHeader(headerBytes, reader); + if (header == null) { yield break; } //entry could be zero bytes so we need to know that. if (header.ZipHeaderType == ZipHeaderType.LocalEntry) diff --git a/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs index bc8187c2..3810da0a 100644 --- a/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs +++ b/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs @@ -91,7 +91,7 @@ namespace SharpCompress.Common.Zip return entry; } default: - throw new NotSupportedException("Unknown header: " + headerBytes); + return null; } }