[
https://issues.apache.org/jira/browse/COMPRESS-613?focusedWorklogId=836190&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-836190
]
ASF GitHub Bot logged work on COMPRESS-613:
-------------------------------------------
Author: ASF GitHub Bot
Created on: 30/Dec/22 02:28
Start Date: 30/Dec/22 02:28
Worklog Time Spent: 10m
Work Description: andrebrait commented on code in PR #345:
URL: https://github.com/apache/commons-compress/pull/345#discussion_r1059218171
##########
src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java:
##########
@@ -30,10 +33,85 @@
* @Immutable
*/
public abstract class ZipUtil {
+
/**
+ * DOS time constant for representing timestamps before 1980.
* Smallest date/time ZIP can handle.
+ * <p>
+ * MS-DOS records file dates and times as packed 16-bit values. An MS-DOS
date has the following format.
+ * </p>
+ * <p>
+ * Bits Contents
+ * </p>
+ * <ul>
+ * <li>0-4: Day of the month (1-31).</li>
+ * <li>5-8: Month (1 = January, 2 = February, and so on).</li>
+ * <li>9-15: Year offset from 1980 (add 1980 to get the actual
year).</li>
+ * </ul>
+ *
+ * An MS-DOS time has the following format.
+ * <p>
+ * Bits Contents
+ * </p>
+ * <ul>
+ * <li>0-4: Second divided by 2.</li>
+ * <li>5-10: Minute (0-59).</li>
+ * <li>11-15: Hour (0-23 on a 24-hour clock).</li>
+ * </ul>
+ *
+ * This constant expresses the minimum DOS date of January 1st 1980 at
00:00:00 or, bit-by-bit:
+ * <ul>
+ * <li>Year: 0000000</li>
+ * <li>Month: 0001</li>
+ * <li>Day: 00001</li>
+ * <li>Hour: 00000</li>
+ * <li>Minute: 000000</li>
+ * <li>Seconds: 00000</li>
+ * </ul>
+ *
+ * <p>
+ * This was copied from {@link ZipEntry}.
+ * </p>
+ *
+ * @since 1.23
*/
- private static final byte[] DOS_TIME_MIN = ZipLong.getBytes(0x00002100L);
Review Comment:
@garydgregory note: this was previously the wrong value. We were lucky we
never stumbled upon this as a bug.
Issue Time Tracking
-------------------
Worklog Id: (was: 836190)
Time Spent: 2h (was: 1h 50m)
> Write ZIP extra time fields automatically
> -----------------------------------------
>
> Key: COMPRESS-613
> URL: https://issues.apache.org/jira/browse/COMPRESS-613
> Project: Commons Compress
> Issue Type: Improvement
> Components: Archivers
> Affects Versions: 1.21
> Reporter: Andre Brait
> Priority: Major
> Labels: zip
> Time Spent: 2h
> Remaining Estimate: 0h
>
> When writing to a Zip file through ZipArchiveOutputStream, setting creation
> and access times in a ZipArchiveEntry does not cause these to be reflected as
> X5455 or X000A extra fields in the resulting zip file. This also happens for
> modification times that do not fit into an MS-DOS time.
> As a consequence, the date range is reduced, as well as the granularity (form
> 100ns intervals to seconds).
> ZipEntry and standard java.util.zip facilities do that automatically, but
> that's missing here.
> My proposal is to use the same logic the java.util.zip do and add those extra
> fields automatically, if situation requires them.
> See my existing logic for this here:
> [https://github.com/andrebrait/DATROMTool/blob/86a4f4978bab250ca54d047c58b4f91e7dbbcc7f/core/src/main/java/io/github/datromtool/io/FileCopier.java#L1425]
> It's (almost) the same logic from java.util.zip, but adapted to be used with
> ZipArchiveEntry.
> If you're ok with it, I can send a PR.
> Actual logic will be more like
> {{{}java.util.zip.ZipOutputStream#writeLOC(XEntry){}}}, represented below:
> {code:java}
> int elenEXTT = 0; // info-zip extended timestamp
> int flagEXTT = 0;
> long umtime = -1;
> long uatime = -1;
> long uctime = -1;
> if (e.mtime != null) {
> elenEXTT += 4;
> flagEXTT |= EXTT_FLAG_LMT;
> umtime = fileTimeToUnixTime(e.mtime);
> }
> if (e.atime != null) {
> elenEXTT += 4;
> flagEXTT |= EXTT_FLAG_LAT;
> uatime = fileTimeToUnixTime(e.atime);
> }
> if (e.ctime != null) {
> elenEXTT += 4;
> flagEXTT |= EXTT_FLAT_CT;
> uctime = fileTimeToUnixTime(e.ctime);
> }
> if (flagEXTT != 0) {
> // to use ntfs time if any m/a/ctime is beyond unixtime upper
> bound
> if (umtime > UPPER_UNIXTIME_BOUND ||
> uatime > UPPER_UNIXTIME_BOUND ||
> uctime > UPPER_UNIXTIME_BOUND) {
> elen += 36; // NTFS time, total 36 bytes
> } else {
> elen += (elenEXTT + 5); // headid(2) + size(2) + flag(1) +
> data
> }
> }
> writeShort(elen);
> writeBytes(nameBytes, 0, nameBytes.length);
> if (hasZip64) {
> writeShort(ZIP64_EXTID);
> writeShort(16);
> writeLong(e.size);
> writeLong(e.csize);
> }
> if (flagEXTT != 0) {
> if (umtime > UPPER_UNIXTIME_BOUND ||
> uatime > UPPER_UNIXTIME_BOUND ||
> uctime > UPPER_UNIXTIME_BOUND) {
> writeShort(EXTID_NTFS); // id
> writeShort(32); // data size
> writeInt(0); // reserved
> writeShort(0x0001); // NTFS attr tag
> writeShort(24);
> writeLong(e.mtime == null ? WINDOWS_TIME_NOT_AVAILABLE
> : fileTimeToWinTime(e.mtime));
> writeLong(e.atime == null ? WINDOWS_TIME_NOT_AVAILABLE
> : fileTimeToWinTime(e.atime));
> writeLong(e.ctime == null ? WINDOWS_TIME_NOT_AVAILABLE
> : fileTimeToWinTime(e.ctime));
> } else {
> writeShort(EXTID_EXTT);
> writeShort(elenEXTT + 1); // flag + data
> writeByte(flagEXTT);
> if (e.mtime != null)
> writeInt(umtime);
> if (e.atime != null)
> writeInt(uatime);
> if (e.ctime != null)
> writeInt(uctime);
> }
> }
> writeExtra(e.extra);
> locoff = written;
> {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)