From 75d9041dbfe474e959ccfc4a74951c9fdcf364fe Mon Sep 17 00:00:00 2001 From: Sergey Mikolaytis Date: Tue, 20 Oct 2020 20:37:13 +0300 Subject: [PATCH] [System.IO.Compression] ZipHelper.DosTimeToDateTime handle empty LastModified fields in zip archive entry header without internal exception (#43008) * [System.IO.Compression] ZipHelper.DosTimeToDateTime handle empty LastModified field without internal exception to improve debugging performance on several zip files opening asynchronously * [Test][Compression][ZipArhiveEntry] Add unit test to test empty lastModified field in zip entry * refactor unit test code * do not use arraypool in tests * fix test after azure pipeline checks with errors * fix invalid assert in new test --- .../src/System/IO/Compression/ZipHelper.cs | 5 +++++ .../tests/ZipArchive/zip_ReadTests.cs | 24 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.cs index 0695452..57ff0ea 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.cs @@ -55,6 +55,11 @@ namespace System.IO.Compression // will silently return InvalidDateIndicator if the uint is not a valid Dos DateTime internal static DateTime DosTimeToDateTime(uint dateTime) { + if (dateTime == 0) + { + return s_invalidDateIndicator; + } + // DosTime format 32 bits // Year: 7 bits, 0 is ValidZipDate_YearMin, unsigned (ValidZipDate_YearMin = 1980) // Month: 4 bits diff --git a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_ReadTests.cs b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_ReadTests.cs index d23f3f2..577c60a 100644 --- a/src/libraries/System.IO.Compression/tests/ZipArchive/zip_ReadTests.cs +++ b/src/libraries/System.IO.Compression/tests/ZipArchive/zip_ReadTests.cs @@ -183,5 +183,29 @@ namespace System.IO.Compression.Tests s.Dispose(); } + + [Fact] + public static void TestEmptyLastModifiedEntryValueNotThrowingInternalException() + { + var emptyDateIndicator = new DateTimeOffset(new DateTime(1980, 1, 1, 0, 0, 0)); + var buffer = new byte[100];//empty archive we will make will have exact this size + using var memoryStream = new MemoryStream(buffer); + + using (var singleEntryArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) + { + singleEntryArchive.CreateEntry("1"); + } + + //set LastWriteTime bits to 0 in this trivial archive + const int lastWritePosition = 43; + buffer[lastWritePosition] = 0; + buffer[lastWritePosition + 1] = 0; + buffer[lastWritePosition + 2] = 0; + buffer[lastWritePosition + 3] = 0; + memoryStream.Seek(0, SeekOrigin.Begin); + + using var archive = new ZipArchive(memoryStream, ZipArchiveMode.Read, true); + Assert.Equal(archive.Entries[0].LastWriteTime, emptyDateIndicator); + } } } -- 2.7.4