Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zip stream created by conflux cannot be parsed by Java (java.util.zip) #98

Open
fuweichin opened this issue Oct 8, 2021 · 1 comment

Comments

@fuweichin
Copy link

fuweichin commented Oct 8, 2021

I need to upload a directory (of files) to server, so I

Then I did an integration test, and I got a problem:

  • The server side throwed an error/exception which says

    java.util.zip.ZipException: only DEFLATED entries can have EXT descriptor

But for STORE zip file created by 7Zip, its stream can be successfully parsed by Java (java.util.zip)

@fuweichin
Copy link
Author

By the way, I created a java unit test to reproduce the error, see code below.
conflux.zip standands for a zip file created with conflux
7zip.zip standands for a zip file created with 7Zip using STORE method

ZipTest.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributeView;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.junit.Test;

public class ZipTest {
  @Test
  public void unpackZip() {
    //XXX conflux.zip 7zip.zip
    File inputFile=new File(System.getProperty("user.home"), "Downloads"+File.separator+"conflux.zip");
    File outputDir=new File(inputFile.getPath().replaceFirst("\\.zip$", ""));
    try(FileInputStream input=new FileInputStream(inputFile)){
      ZipTest.unpack(input, outputDir);
    }catch(IOException e){
      e.printStackTrace();
    }
  }
  public static void unpack(InputStream input, File outputDir) throws IOException {
    boolean setFileTimes=true;
    boolean doNameCheck=false;
    outputDir.mkdirs();
    ArrayList<File> dirs=new ArrayList<File>();
    ArrayList<ZipEntry> entries=new ArrayList<ZipEntry>();
    byte[] buffer=new byte[8192];
    try(ZipInputStream zipInput=new ZipInputStream(input);){
      for(ZipEntry entry=zipInput.getNextEntry(); entry!=null; entry=zipInput.getNextEntry()){
        System.out.println(entry.getName()); //XXX
        if(doNameCheck){
          // TODO checkEntryPath(entry.getName());
        }
        File file=new File(outputDir, entry.getName()).getCanonicalFile();
        if(entry.isDirectory()){
          if(!file.exists() && !file.mkdir()){
            throw new IOException("Failed to mkdir "+entry.getName());
          }
          if(setFileTimes){
            // Note: directory's file time should be set later, from inner to outer
            dirs.add(file);
            entries.add(entry);
          }
        }else{
          File parentFile=file.getParentFile();
          // TODO ensureParentDirectories(parentFile);
          try(FileOutputStream output=new FileOutputStream(file)){
            int len;
            while ((len = zipInput.read(buffer)) > 0) {
              output.write(buffer, 0, len);
            }
          }
          if(setFileTimes){
            Files.getFileAttributeView(file.toPath(), BasicFileAttributeView.class)
                .setTimes(entry.getLastModifiedTime(), entry.getLastAccessTime(), entry.getCreationTime());
          }
        }
      }
      zipInput.closeEntry();
      if(setFileTimes){
        for(int i=dirs.size()-1; i>=0; i--){
          File dir=dirs.get(i);
          ZipEntry entry=entries.get(i);
          Files.getFileAttributeView(dir.toPath(), BasicFileAttributeView.class)
              .setTimes(entry.getLastModifiedTime(), entry.getLastAccessTime(), entry.getCreationTime());
        }
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant