JDK-4532049 : IllegalArgumentException in ZipInputStream while reading unicode file
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_98
  • CPU: x86
  • Submitted: 2001-11-28
  • Updated: 2009-04-25
  • Resolved: 2009-04-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b57Fixed
Related Reports
Relates :  
Description
Name: nt126004			Date: 11/27/2001


java version "1.4.0-beta3"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)

java.until.zip.ZipFile or ZipInputStream can't unzip file(unicode name) in zip
by winzip8.0

source code:
import java.util.zip.*;
import java.io.*;
public class UnzipF {
    
   private String filename;
    
   public UnzipF(String filename){
      this.filename = filename;
   }
    
   public boolean unzip(){
      try {
         String topdir = filename.substring(0,filename.indexOf(".zip"));
         if (!(new java.io.File(topdir)).mkdir()) System.out.println("topdir of
filename can't created!");
          
         ZipInputStream in = new ZipInputStream(new FileReader(filename));
         //ZipInputStream in = new ZipInputStream(new DataInputStream(new
java.io.FileInputStream(filename)));
         ZipEntry entry;
         String entryname;
         byte[] buf = new byte[4096];
         int len,length;
         String outFilename;
         OutputStream out;
         String dirname;
         while ((entry = in.getNextEntry()) != null) {
            entryname = entry.getName();
            if (!entry.isDirectory()){
               int index = entryname.lastIndexOf('/');
               if(index != -1){
                  dirname = entryname.substring(0,index+1);
                  if (!(new java.io.File(topdir+'/'+dirname)).exists()) (new
java.io.File(topdir+'/'+dirname)).mkdirs() ;
               }
               outFilename = topdir + '/' + entryname;
               out = new java.io.FileOutputStream(outFilename);
               length = 0 ;
               while ((len = in.read(buf)) > 0) {
                  out.write(buf, 0, len);
                  length=length+len;
               }
               out.close();
               System.out.print("outFilename:"+outFilename);
               System.out.println("  length:"+length);
               //System.in.read();
            }
            else {
               if (!(new java.io.File(topdir+'/'+entryname)).exists()) (new
java.io.File(topdir+'/'+entryname)).mkdirs() ;
               System.out.println("topdir+'/'+entryname:"+topdir+'/'+entryname);
            }
         }
         in.close();
         return true;
      } catch (IOException e) {
      	System.out.println("test");
      	System.out.println(e.getMessage());
        return false;
      }
   }
   public static void main(String args[]) {
     UnzipF uf = new UnzipF(args[0]);
     uf.unzip();
   }
}

readme.zip's entry(zip by winzip8.0):
复件 readme.txt
readme.txt


commad:java UnzipF readme.zip

Exception:
Exception in thread "main" java.lang.IllegalArgumentException
        at java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:291)
        at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:230)
        at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:75)
        at UnzipF.unzip(UnzipF.java:24)
        at UnzipF.main(UnzipF.java:58)
(Review ID: 135772) 
======================================================================

Comments
EVALUATION To use the newly added constructor with a charset ZipInputStream in = new ZipInputStream(new FileInputStream(filename), Charset.forName("ibm437"));
16-04-2009

EVALUATION First four character's-Ansi-numbers from one of the file in readme.zip are 184, 180, 188 and 254. When getUTF8String function from ZipInputStream.java is invoked during execution, these characters fall under default case (for above characters case:11 and case:15) in the switch block. The default case is: default: // 10xxxxxx, 1111xxxx throw new IllegalArgumentException(); Hence, message 'Exception in thread "main" java.lang.IllegalArgumentException' gets generated. So, the question remains is: Do we need to remove case:11 and case:15 from the default case ? I removed the case:11 and case:15 from default case and put them in the first case in switch statement as: case:0 case:1 case:2 case:3 case:4 case:5 case:6 case:7 case:11 case:15. The testcase runs fine without any errors/exceptions and unzips the readme.zip to generate two files. ###@###.### 2002-07-09 The above evaluation is incorrect. The real issue is that non-jar zip files usually use encodings other than UTF-8 to encode file names within zip files. This bug is really a duplicate of 4244499. ###@###.### 2005-1-29 00:22:42 GMT
29-01-2005