JDK-8327690 : Unzipping Dropbox Files: Only DEFLATED entries can have EXT descriptor
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Affected Version: 11,17,21,23
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 2024-03-06
  • Updated: 2024-03-18
  • Resolved: 2024-03-18
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Windows 11

A DESCRIPTION OF THE PROBLEM :
When a zip file from dropbox is read/extracted using java.util.zip.ZipInputStream, you get the following exception:

```
java.util.zip.ZipException: only DEFLATED entries can have EXT descriptor
        at java.base/java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:529)
        at java.base/java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:153)
        at my.namespace.JavaZipper.unzipFile(JavaZipper.java:111)
```

Here is a simple reproducer:
```
@Test
public static void TestUnzip() throws FileNotFoundException, IOException {
    var inputZipFile = new File("C:\\my\\path\\src\\file.zip");
    var outputPathStr = "C:\\my\\path\\dest";

    try(ZipInputStream zipStreamIn = new ZipInputStream(new FileInputStream(inputZipFile))) {
        ZipEntry zipEntry = null;
        
        while((zipEntry = zipStreamIn.getNextEntry()) != null) {
            final String entryName = zipEntry.getName().replace("/", "\\");    // normalise path (windows-format)
            
            // ignore directories
            if(zipEntry.isDirectory())
                continue;
            
            // prepare destination path
            File targetFile = new File( outputPathStr + "\\" + entryName );
            targetFile.getParentFile().mkdirs();
            
            // zip stream to file
            System.out.println("Extract File: " + entryName);
            try(var zipStreamOut = new FileOutputStream(targetFile)) {
                zipStreamIn.transferTo(zipStreamOut);
            }
        }
    }
}
```

All commonly used zipper tools are able to extract such files (with EXT descriptor), hence it would be very useful if the Java Runtime could do the same.



Comments
Closing this as WontFix since it is inherently impossible to determine the file data length of a STORED entry using streaming mode. Dropbox should fix their ZIP files to not use streaming mode and include size information in their local file headers. Developers using Java to process such files should use the java.util.zip.ZipFile API instead.
18-03-2024

An observation: The current exception message is perhaps not super helpful: "Only DEFLATED entries can have EXT descriptor" The problem here is that ZipInputStream cannot determine the file data size of a STORED entry in streaming mode. So perhaps the exception message should rather say something like: "Cannot determine the file data size of a STORED entry in streaming mode".
09-03-2024

I'd say this is a bug on Dropbox's side. Here is an example Local File Header followed by an EXT header: ``` 000000 LOCAL HEADER #1 04034B50 000004 Extract Zip Spec 14 '2.0' 000005 Extract OS 00 'MS-DOS' 000006 General Purpose Flag 0808 [Bit 3] 1 'Streamed' [Bit 11] 1 'Language Encoding' 000008 Compression Method 0000 'Stored' 00000A Last Mod Time 5869759D 'Sat Mar 9 14:44:58 2024' 00000E CRC 00000000 000012 Compressed Length 00000000 000016 Uncompressed Length 00000000 00001A Filename Length 000D 00001C Extra Length 0009 00001E Filename 'IMG_5768.HEIC' 00002B Extra ID #0001 5455 'UT: Extended Timestamp' 00002D Length 0005 00002F Flags '01 mod' 000030 Mod Time 65EC75EB 'Sat Mar 9 15:44:59 2024' 000034 PAYLOAD 02EFAA STREAMING DATA HEADER 08074B50 02EFAE CRC 76C5864B 02EFB2 Compressed Length 0002EF76 02EFB6 Uncompressed Length 0002EF76 ``` This uses the STORED compression method in combination with streaming mode (bit 3 of the General Purpose Flag is set). In this case, the Local File Header contains no information about the size of the payload file. (Both size fields and also the CRC field is 0). That information is instead put in the EXT header. The problem here is that ZipInputStream cannot safely determine the length of the payload. We could imagine scanning for the EXT header signature, but that's not safe since the payload may contain arbitrary data. The claim that "All commonly used zipper tools are able to extract such files" is probably true because these tools look at size information in the the Central Directory at the end of the file to determine the size of the payload. As such, they are not limited by the lack of this information in the Local File Header. A work-around in the Java context is to use the ZipFile API to read this ZIP. That also uses the Central Directory. I propose that we close this as WontFix. I also suggest that the reporter contact DropBox to have them include size information for STORED entries and not use streaming mode.
09-03-2024

Observation on Windows 10 -------------------------------------------- JDK 11.0.21+9-LTS-193 : Failed with ZipException: only DEFLATED entries can have EXT descriptor JDK 17.0.4+11-LTS-179 : Failed JDK 21.0.1+9-LTS-23 : Failed JDK 22-ea+9 : Failed JDK 23-ea+6 : Failed
08-03-2024