1 /*
   2  * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 4244499 4532049 4700978 4820807 4980042
  27  * @summary Test ZipInputStream, ZipOutputStream and ZipFile with non-UTF8 encoding
  28  */
  29 
  30 import java.io.*;
  31 import java.nio.charset.*;
  32 import java.util.*;
  33 import java.util.zip.*;
  34 
  35 public class ZipCoding {
  36 
  37     public static void main(String[] args) throws Exception {
  38 
  39         test("MS932",
  40              "\u4e00\u4e01", "\uff67\uff68\uff69\uff6a\uff6b\uff6c");
  41 
  42         test("ibm437",
  43              "\u00e4\u00fc", "German Umlaut \u00fc in comment");
  44 
  45         test("utf-8",
  46              "\u4e00\u4e01", "\uff67\uff68\uff69\uff6a\uff6b\uff6c");
  47 
  48         test("utf-8",
  49              "\u00e4\u00fc", "German Umlaut \u00fc in comment");
  50 
  51         test("utf-8",
  52              "Surrogate\ud801\udc01", "Surrogates \ud800\udc00 in comment");
  53 
  54     }
  55 
  56     static void testZipInputStream(InputStream is, Charset cs,
  57                                    String name, String comment, byte[] bb)
  58         throws Exception
  59     {
  60         try (ZipInputStream zis = new ZipInputStream(is, cs)) {
  61             ZipEntry e = zis.getNextEntry();
  62             if (e == null || ! name.equals(e.getName()))
  63                 throw new RuntimeException("ZipIS name doesn't match!");
  64             byte[] bBuf = new byte[bb.length << 1];
  65             int n = zis.read(bBuf, 0, bBuf.length);
  66             if (n != bb.length ||
  67                 !Arrays.equals(bb, Arrays.copyOf(bBuf, n))) {
  68                 throw new RuntimeException("ZipIS content doesn't match!");
  69             }
  70         }
  71     }
  72 
  73     static void testZipFile(File f, Charset cs,
  74                             String name, String comment, byte[] bb)
  75         throws Exception
  76     {
  77         try (ZipFile zf = new ZipFile(f, cs)) {
  78             Enumeration<? extends ZipEntry> zes = zf.entries();
  79             ZipEntry e = (ZipEntry)zes.nextElement();
  80             if (! name.equals(e.getName()) ||
  81                 ! comment.equals(e.getComment()))
  82                 throw new RuntimeException("ZipFile: name/comment doesn't match!");
  83             InputStream is = zf.getInputStream(e);
  84             if (is == null)
  85                 throw new RuntimeException("ZipFile: getIS failed!");
  86             byte[] bBuf = new byte[bb.length << 1];
  87             int n = 0;
  88             int nn =0;
  89             while ((nn = is.read(bBuf, n, bBuf.length-n)) != -1) {
  90                 n += nn;
  91             }
  92             if (n != bb.length ||
  93                 !Arrays.equals(bb, Arrays.copyOf(bBuf, n))) {
  94                 throw new RuntimeException("ZipFile content doesn't match!");
  95             }
  96         }
  97     }
  98 
  99     static void test(String csn, String name, String comment)
 100         throws Exception
 101     {
 102         byte[] bb = "This is the content of the zipfile".getBytes("ISO-8859-1");
 103         Charset cs = Charset.forName(csn);
 104         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 105         try (ZipOutputStream zos = new ZipOutputStream(baos, cs)) {
 106             ZipEntry e = new ZipEntry(name);
 107             e.setComment(comment);
 108             zos.putNextEntry(e);
 109             zos.write(bb, 0, bb.length);
 110             zos.closeEntry();
 111         }
 112         ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
 113         testZipInputStream(bis, cs, name, comment, bb);
 114 
 115         if ("utf-8".equals(csn)) {
 116             // EFS should be set
 117             bis.reset();
 118             testZipInputStream(bis, Charset.forName("MS932"), name, comment, bb);
 119         }
 120 
 121         File f = new File(new File(System.getProperty("test.dir", ".")),
 122                           "zfcoding.zip");
 123         try (FileOutputStream fos = new FileOutputStream(f)) {
 124             baos.writeTo(fos);
 125         }
 126         testZipFile(f, cs, name, comment, bb);
 127         if ("utf-8".equals(csn)) {
 128             testZipFile(f, Charset.forName("MS932"), name, comment, bb);
 129         }
 130         f.delete();
 131     }
 132 }