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         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         zis.close();
  71     }
  72 
  73     static void testZipFile(File f, Charset cs,
  74                             String name, String comment, byte[] bb)
  75         throws Exception
  76     {
  77         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         zf.close();
  97     }
  98 
  99     static void test(String csn, String name, String comment)
 100         throws Exception
 101     {
 102         byte[] bb = "This is the conent of the zipfile".getBytes("ISO-8859-1");
 103         Charset cs = Charset.forName(csn);
 104         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 105         ZipOutputStream zos = new ZipOutputStream(baos, cs);
 106 
 107         ZipEntry e = new ZipEntry(name);
 108         e.setComment(comment);
 109         zos.putNextEntry(e);
 110         zos.write(bb, 0, bb.length);
 111         zos.closeEntry();
 112         zos.close();
 113         ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
 114         testZipInputStream(bis, cs, name, comment, bb);
 115 
 116         if ("utf-8".equals(csn)) {
 117             // EFS should be set
 118             bis.reset();
 119             testZipInputStream(bis, Charset.forName("MS932"), name, comment, bb);
 120         }
 121 
 122         File f = new File(new File(System.getProperty("test.dir", ".")),
 123                           "zfcoding.zip");
 124         FileOutputStream fos = new FileOutputStream(f);
 125         baos.writeTo(fos);
 126         fos.close();
 127         testZipFile(f, cs, name, comment, bb);
 128         if ("utf-8".equals(csn)) {
 129             testZipFile(f, Charset.forName("MS932"), name, comment, bb);
 130         }
 131         f.delete();
 132     }
 133 }