From cef5453d225f14ca1d5afcf3d43606b9da572eb4 Mon Sep 17 00:00:00 2001 From: Bastian Eicher Date: Tue, 7 Sep 2021 11:04:15 +0200 Subject: [PATCH] feat: add support for old Info-ZIP extra block for Unix (Info-ZIP Unix Extra Field type 1) --- src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs | 3 + .../Zip/ZipExtraData.cs | 107 ++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs index f14b005f2..17ded342d 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs @@ -955,6 +955,9 @@ internal void ProcessExtraData(bool localHeader) ExtendedUnixData unixData = extraData.GetData(); if (unixData != null && unixData.Include.HasFlag(ExtendedUnixData.Flags.ModificationTime)) return unixData.ModificationTime; + OldExtendedUnixData oldUnixData = extraData.GetData(); + if (oldUnixData != null) + return oldUnixData.ModificationTime; return null; } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs index 4e075dc8d..b993bffa7 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs @@ -320,6 +320,113 @@ public Flags Include #endregion Instance Fields } + /// + /// Class representing old format for extended unix date time values. + /// + public class OldExtendedUnixData : ITaggedData + { + #region ITaggedData Members + + /// + /// Get the ID + /// + public short TagID + { + get { return 0x5855; } + } + + /// + /// Set the data from the raw values provided. + /// + /// The raw data to extract values from. + /// The index to start extracting values from. + /// The number of bytes available. + public void SetData(byte[] data, int index, int count) + { + using (MemoryStream ms = new MemoryStream(data, index, count, false)) + using (ZipHelperStream helperStream = new ZipHelperStream(ms)) + { + int iTime = helperStream.ReadLEInt(); + + _modificationTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) + + new TimeSpan(0, 0, 0, iTime, 0); + + iTime = helperStream.ReadLEInt(); + + _lastAccessTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) + + new TimeSpan(0, 0, 0, iTime, 0); + } + } + + /// + /// Get the binary data representing this instance. + /// + /// The raw binary data representing this instance. + public byte[] GetData() + { + using (MemoryStream ms = new MemoryStream()) + using (ZipHelperStream helperStream = new ZipHelperStream(ms)) + { + helperStream.IsStreamOwner = false; + + TimeSpan span = _modificationTime - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + var seconds = (int)span.TotalSeconds; + helperStream.WriteLEInt(seconds); + + span = _lastAccessTime - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + seconds = (int)span.TotalSeconds; + helperStream.WriteLEInt(seconds); + + return ms.ToArray(); + } + } + + #endregion ITaggedData Members + + /// + /// Get /set the Modification Time + /// + /// + public DateTime ModificationTime + { + get { return _modificationTime; } + set + { + if (!ExtendedUnixData.IsValidValue(value)) + { + throw new ArgumentOutOfRangeException(nameof(value)); + } + + _modificationTime = value; + } + } + + /// + /// Get / set the Access Time + /// + /// + public DateTime AccessTime + { + get { return _lastAccessTime; } + set + { + if (!ExtendedUnixData.IsValidValue(value)) + { + throw new ArgumentOutOfRangeException(nameof(value)); + } + + _lastAccessTime = value; + } + } + + #region Instance Fields + + private DateTime _modificationTime = new DateTime(1970, 1, 1); + private DateTime _lastAccessTime = new DateTime(1970, 1, 1); + + #endregion Instance Fields + } + /// /// Class handling NT date time values. ///