[System.IO.Compression] ZipHelper.DosTimeToDateTime handle empty LastModified fields...
authorSergey Mikolaytis <blasterloremaster@gmail.com>
Tue, 20 Oct 2020 17:37:13 +0000 (20:37 +0300)
committerGitHub <noreply@github.com>
Tue, 20 Oct 2020 17:37:13 +0000 (10:37 -0700)
* [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/libraries/System.IO.Compression/src/System/IO/Compression/ZipHelper.cs
src/libraries/System.IO.Compression/tests/ZipArchive/zip_ReadTests.cs

index 0695452..57ff0ea 100644 (file)
@@ -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
index d23f3f2..577c60a 100644 (file)
@@ -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);
+        }
     }
 }