You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "ASF GitHub Bot (Jira)" <ji...@apache.org> on 2022/12/28 20:47:00 UTC

[jira] [Work logged] (COMPRESS-613) Write ZIP extra time fields automatically

     [ https://issues.apache.org/jira/browse/COMPRESS-613?focusedWorklogId=836010&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-836010 ]

ASF GitHub Bot logged work on COMPRESS-613:
-------------------------------------------

                Author: ASF GitHub Bot
            Created on: 28/Dec/22 20:46
            Start Date: 28/Dec/22 20:46
    Worklog Time Spent: 10m 
      Work Description: andrebrait opened a new pull request, #345:
URL: https://github.com/apache/commons-compress/pull/345

   This adds support for extra time data (InfoZip and NTFS Extra fields) to Zip archives.
   This supports both reading and writing to these fields automatically, including when creating a ZipArchiveEntry from an existing file on the disk, with proper fall backs.
   
   Additionally:
   
   1. Works around a bug involving Integer Overflow in Java 8 and Zip archives: https://bugs.openjdk.org/browse/JDK-8130914
   2. Consolidates a few more time conversions into TimeUtils
   3. Works around an oversight in Java 8 where the NTFS fields on Zip archives are only read to the precision of microseconds instead of their maximum of 100ns.
   
   Currently, it's missing a few test cases for reading/writing, though I have tested them myself. Submitting for this review because the code itself is likely final (and there are enough tests to cover most of them, and I'll submit the rest of the test cases in the coming days).




Issue Time Tracking
-------------------

            Worklog Id:     (was: 836010)
    Remaining Estimate: 0h
            Time Spent: 10m

> 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: 10m
>  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)