Home | History | Annotate | Download | only in jar
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package org.apache.harmony.archive.tests.java.util.jar;
     19 
     20 import tests.support.resource.Support_Resources;
     21 
     22 import java.io.File;
     23 import java.io.IOException;
     24 import java.io.InputStream;
     25 import java.net.URL;
     26 import java.util.Arrays;
     27 import java.util.HashSet;
     28 import java.util.Set;
     29 import java.util.jar.JarEntry;
     30 import java.util.jar.JarInputStream;
     31 import java.util.jar.Manifest;
     32 import java.util.zip.ZipEntry;
     33 import java.util.zip.ZipException;
     34 
     35 public class JarInputStreamTest extends junit.framework.TestCase {
     36     // a 'normal' jar file
     37     private String jarName;
     38 
     39     // same as patch.jar but without a manifest file
     40     private String jarName2;
     41 
     42     private final String entryName = "foo/bar/A.class";
     43 
     44     private static final int indexofDSA = 2;
     45 
     46     private static final int indexofTESTCLASS = 4;
     47 
     48     private static final int totalEntries = 4;
     49 
     50     @Override
     51     protected void setUp() {
     52         jarName = Support_Resources.getURL("morestuff/hyts_patch.jar");
     53         jarName2 = Support_Resources.getURL("morestuff/hyts_patch2.jar");
     54     }
     55 
     56     /**
     57      * @tests java.util.jar.JarInputStream#JarInputStream(java.io.InputStream)
     58      */
     59     public void test_ConstructorLjava_io_InputStream() {
     60         // Test for method java.util.jar.JarInputStream(java.io.InputStream)
     61         InputStream is = null;
     62         JarInputStream jis = null;
     63         try {
     64             is = new URL(jarName).openConnection().getInputStream();
     65             boolean hasCorrectEntry = false;
     66             jis = new JarInputStream(is);
     67             assertNotNull("The jar input stream should have a manifest", jis
     68                     .getManifest());
     69             JarEntry je = jis.getNextJarEntry();
     70             while (je != null) {
     71                 if (je.getName().equals(entryName)) {
     72                     hasCorrectEntry = true;
     73                 }
     74                 je = jis.getNextJarEntry();
     75             }
     76             assertTrue(
     77                     "The jar input stream does not contain the correct entries",
     78                     hasCorrectEntry);
     79         } catch (Exception e) {
     80             fail("Exception during test: " + e.toString());
     81         }
     82 
     83         try {
     84             is.close();
     85             jis = new JarInputStream(is);
     86             fail("IOException expected");
     87         } catch (IOException ee) {
     88             // expected
     89         }
     90     }
     91 
     92     /**
     93      * @tests java.util.jar.JarInputStream#getManifest()
     94      */
     95     public void test_getManifest() {
     96         // Test for method java.util.jar.Manifest
     97         // java.util.jar.JarInputStream.getManifest()
     98         try {
     99             Manifest m;
    100 
    101             InputStream is = new URL(jarName2).openConnection()
    102                     .getInputStream();
    103             JarInputStream jis = new JarInputStream(is);
    104             m = jis.getManifest();
    105             assertNull("The jar input stream should not have a manifest", m);
    106 
    107             is = new URL(jarName).openConnection().getInputStream();
    108             jis = new JarInputStream(is);
    109             m = jis.getManifest();
    110             assertNotNull("The jar input stream should have a manifest", m);
    111         } catch (Exception e) {
    112             fail("Exception during test: " + e.toString());
    113         }
    114 
    115     }
    116 
    117     /**
    118      * @tests java.util.jar.JarInputStream#getNextJarEntry()
    119      */
    120     public void test_getNextJarEntry() throws Exception {
    121         final Set<String> desired = new HashSet<String>(Arrays
    122                 .asList(new String[] {
    123                         "foo/", "foo/bar/", "foo/bar/A.class", "Blah.txt"}));
    124         Set<String> actual = new HashSet<String>();
    125         InputStream is = new URL(jarName).openConnection().getInputStream();
    126         JarInputStream jis = new JarInputStream(is);
    127         JarEntry je = jis.getNextJarEntry();
    128         while (je != null) {
    129             actual.add(je.toString());
    130             je = jis.getNextJarEntry();
    131         }
    132         assertEquals(actual, desired);
    133         jis.close();
    134 
    135         try {
    136             jis.getNextJarEntry();
    137             fail("IOException expected");
    138         } catch (IOException ee) {
    139             // expected
    140         }
    141 
    142         File resources = Support_Resources.createTempFolder();
    143         Support_Resources.copyFile(resources, null, "Broken_entry.jar");
    144         is = Support_Resources.getStream("Broken_entry.jar");
    145         jis = new JarInputStream(is, false);
    146         jis.getNextJarEntry();
    147         try {
    148             jis.getNextJarEntry();
    149             fail("ZipException expected");
    150         } catch (ZipException ee) {
    151             // expected
    152         }
    153     }
    154 
    155     public void test_getNextJarEntry_Ex() throws Exception {
    156         final Set<String> desired = new HashSet<String>(Arrays
    157                 .asList("foo/", "foo/bar/", "foo/bar/A.class", "Blah.txt"));
    158         Set<String> actual = new HashSet<String>();
    159         InputStream is = new URL(jarName).openConnection().getInputStream();
    160         JarInputStream jis = new JarInputStream(is);
    161         JarEntry je = jis.getNextJarEntry();
    162         while (je != null) {
    163             actual.add(je.toString());
    164             je = jis.getNextJarEntry();
    165         }
    166         assertEquals(actual, desired);
    167         jis.close();
    168 
    169         try {
    170             jis.getNextJarEntry();
    171             fail("IOException expected");
    172         } catch (IOException ee) {
    173             // expected
    174         }
    175 
    176         File resources = Support_Resources.createTempFolder();
    177         Support_Resources.copyFile(resources, null, "Broken_entry.jar");
    178         is = Support_Resources.getStream("Broken_entry.jar");
    179         jis = new JarInputStream(is, false);
    180         jis.getNextJarEntry();
    181         try {
    182             jis.getNextJarEntry();
    183             fail("ZipException expected");
    184         } catch (ZipException ee) {
    185             // expected
    186         }
    187     }
    188 
    189     public void test_JarInputStream_Integrate_Jar_getNextEntry()
    190             throws IOException {
    191         String intJarName = Support_Resources.getURL("Integrate.jar");
    192         InputStream is = new URL(intJarName).openConnection().getInputStream();
    193         JarInputStream jin = new JarInputStream(is, true);
    194         ZipEntry entry = null;
    195         int count = 0;
    196         while (count == 0 || entry != null) {
    197             count++;
    198             entry = jin.getNextEntry();
    199         }
    200         assertEquals(totalEntries + 1, count);
    201         jin.close();
    202     }
    203 
    204     public void test_JarInputStream_Modified_Class_getNextEntry()
    205             throws IOException {
    206         String modJarName = Support_Resources.getURL("Modified_Class.jar");
    207         InputStream is = new URL(modJarName).openConnection().getInputStream();
    208         JarInputStream jin = new JarInputStream(is, true);
    209         ZipEntry zipEntry = null;
    210 
    211         int count = 0;
    212         while (count == 0 || zipEntry != null) {
    213             count++;
    214             try {
    215                 zipEntry = jin.getNextEntry();
    216                 if (count == indexofTESTCLASS + 1) {
    217                     fail("Should throw Security Exception");
    218                 }
    219             } catch (SecurityException e) {
    220                 if (count != indexofTESTCLASS + 1) {
    221                     throw e;
    222                 }
    223 
    224             }
    225         }
    226         assertEquals(totalEntries + 2, count);
    227         jin.close();
    228     }
    229 
    230     public void test_JarInputStream_Modified_Manifest_MainAttributes_getNextEntry()
    231             throws IOException {
    232         String modJarName = Support_Resources.getURL("Modified_Manifest_MainAttributes.jar");
    233         InputStream is = new URL(modJarName).openConnection()
    234                 .getInputStream();
    235         JarInputStream jin = new JarInputStream(is, true);
    236 
    237         assertEquals("META-INF/TESTROOT.SF", jin.getNextEntry().getName());
    238         assertEquals("META-INF/TESTROOT.DSA", jin.getNextEntry().getName());
    239         try {
    240             jin.getNextEntry();
    241             fail();
    242         } catch (SecurityException expected) {
    243         }
    244         assertEquals("META-INF/", jin.getNextEntry().getName());
    245         assertEquals("Test.class", jin.getNextEntry().getName());
    246         assertNull(jin.getNextEntry());
    247         jin.close();
    248     }
    249 
    250     public void test_JarInputStream_Modified_Manifest_EntryAttributes_getNextEntry()
    251             throws IOException {
    252         String modJarName = Support_Resources
    253                 .getURL("Modified_Manifest_EntryAttributes.jar");
    254         InputStream is = new URL(modJarName).openConnection().getInputStream();
    255         JarInputStream jin = new JarInputStream(is, true);
    256         ZipEntry zipEntry = null;
    257 
    258         int count = 0;
    259         while (count == 0 || zipEntry != null) {
    260             count++;
    261             try {
    262                 zipEntry = jin.getNextEntry();
    263                 if (count == indexofDSA + 1) {
    264                     fail("Should throw Security Exception");
    265                 }
    266             } catch (SecurityException e) {
    267                 if (count != indexofDSA + 1) {
    268                     throw e;
    269                 }
    270             }
    271         }
    272         assertEquals(totalEntries + 2, count);
    273         jin.close();
    274     }
    275 
    276     public void test_JarInputStream_Modified_SF_EntryAttributes_getNextEntry()
    277             throws IOException {
    278         String modJarName = Support_Resources
    279                 .getURL("Modified_SF_EntryAttributes.jar");
    280         InputStream is = new URL(modJarName).openConnection().getInputStream();
    281         JarInputStream jin = new JarInputStream(is, true);
    282         ZipEntry zipEntry = null;
    283 
    284         int count = 0;
    285         while (count == 0 || zipEntry != null) {
    286             count++;
    287             try {
    288                 zipEntry = jin.getNextEntry();
    289                 if (count == indexofDSA + 1) {
    290                     fail("Should throw Security Exception");
    291                 }
    292             } catch (SecurityException e) {
    293                 if (count != indexofDSA + 1) {
    294                     throw e;
    295                 }
    296             }
    297         }
    298         assertEquals(totalEntries + 2, count);
    299         jin.close();
    300     }
    301 
    302     public void test_JarInputStream_Modified_Class_read() throws IOException {
    303         String modJarName = Support_Resources.getURL("Modified_Class.jar");
    304         InputStream is = new URL(modJarName).openConnection().getInputStream();
    305         JarInputStream jin = new JarInputStream(is, true);
    306         int count = 0;
    307         ZipEntry zipEntry = null;
    308         while (count == 0 || zipEntry != null) {
    309             count++;
    310             zipEntry = jin.getNextEntry();
    311             byte[] buffer = new byte[1024];
    312             try {
    313                 int length = 0;
    314                 while (length >= 0) {
    315                     length = jin.read(buffer);
    316                 }
    317                 if (count == indexofTESTCLASS) {
    318                     fail("Should throw Security Exception");
    319                 }
    320             } catch (SecurityException e) {
    321                 if (count < indexofTESTCLASS) {
    322                     throw e;
    323                 }
    324             }
    325         }
    326         assertEquals(totalEntries + 1, count);
    327         jin.close();
    328     }
    329 
    330     public void test_Integrate_Jar_read() throws IOException {
    331         String intJarName = Support_Resources.getURL("Integrate.jar");
    332         InputStream is = new URL(intJarName).openConnection().getInputStream();
    333         JarInputStream jin = new JarInputStream(is, true);
    334         int count = 0;
    335         ZipEntry zipEntry = null;
    336         while (count == 0 || zipEntry != null) {
    337             count++;
    338             zipEntry = jin.getNextEntry();
    339             byte[] buffer = new byte[1024];
    340             int length = 0;
    341             while (length >= 0) {
    342                 length = jin.read(buffer);
    343             }
    344 
    345         }
    346         assertEquals(totalEntries + 1, count);
    347         jin.close();
    348     }
    349 
    350     public void test_JarInputStream_Modified_Manifest_MainAttributes_read()
    351             throws IOException {
    352         String modJarName = Support_Resources
    353                 .getURL("Modified_Manifest_MainAttributes.jar");
    354         InputStream is = new URL(modJarName).openConnection().getInputStream();
    355         JarInputStream jin = new JarInputStream(is, true);
    356         int count = 0;
    357         ZipEntry zipEntry = null;
    358         while (count == 0 || zipEntry != null) {
    359             count++;
    360             zipEntry = jin.getNextEntry();
    361             byte[] buffer = new byte[1024];
    362             try {
    363                 int length = 0;
    364                 while (length >= 0) {
    365                     length = jin.read(buffer);
    366                 }
    367                 if (count == indexofDSA) {
    368                     fail("Should throw Security Exception");
    369                 }
    370             } catch (SecurityException e) {
    371                 if (count != indexofDSA) {
    372                     throw e;
    373                 }
    374             }
    375         }
    376         assertEquals(totalEntries + 1, count);
    377         jin.close();
    378     }
    379 
    380     public void test_JarInputStream_Modified_SF_EntryAttributes_read()
    381             throws IOException {
    382         String modJarName = Support_Resources
    383                 .getURL("Modified_SF_EntryAttributes.jar");
    384         InputStream is = new URL(modJarName).openConnection().getInputStream();
    385         JarInputStream jin = new JarInputStream(is, true);
    386         int count = 0;
    387         ZipEntry zipEntry = null;
    388         while (count == 0 || zipEntry != null) {
    389             count++;
    390             zipEntry = jin.getNextEntry();
    391             byte[] buffer = new byte[1024];
    392             try {
    393                 int length = 0;
    394                 while (length >= 0) {
    395                     length = jin.read(buffer);
    396                 }
    397                 if (count == indexofDSA) {
    398                     fail("Should throw Security Exception");
    399                 }
    400             } catch (SecurityException e) {
    401                 if (count != indexofDSA) {
    402                     throw e;
    403                 }
    404             }
    405         }
    406         assertEquals(totalEntries + 1, count);
    407         jin.close();
    408     }
    409 
    410     public void test_ConstructorLjava_io_InputStreamZ() {
    411         // Test for method java.util.jar.JarInputStream(java.io.InputStream)
    412         InputStream is = null;
    413         JarInputStream jis = null;
    414         try {
    415             is = new URL(jarName).openConnection().getInputStream();
    416             boolean hasCorrectEntry = false;
    417             jis = new JarInputStream(is, true);
    418             assertNotNull("The jar input stream should have a manifest", jis
    419                     .getManifest());
    420             JarEntry je = jis.getNextJarEntry();
    421             while (je != null) {
    422                 if (je.getName().equals(entryName)) {
    423                     hasCorrectEntry = true;
    424                 }
    425                 je = jis.getNextJarEntry();
    426             }
    427             assertTrue(
    428                     "The jar input stream does not contain the correct entries",
    429                     hasCorrectEntry);
    430         } catch (Exception e) {
    431             fail("Exception during test: " + e.toString());
    432         }
    433 
    434         try {
    435             is.close();
    436             jis = new JarInputStream(is, false);
    437             fail("IOException expected");
    438         } catch (IOException ee) {
    439             // expected
    440         }
    441     }
    442 
    443     public void test_closeAfterException() throws Exception {
    444         File resources = Support_Resources.createTempFolder();
    445         Support_Resources.copyFile(resources, null, "Broken_entry.jar");
    446         InputStream is = Support_Resources.getStream("Broken_entry.jar");
    447         JarInputStream jis = new JarInputStream(is, false);
    448         jis.getNextEntry();
    449         try {
    450             jis.getNextEntry();
    451             fail("ZipException expected");
    452         } catch (ZipException ee) {
    453             // expected
    454         }
    455         jis.close();
    456         try {
    457             jis.getNextEntry();
    458             fail("IOException expected");
    459         } catch (IOException ee) {
    460             // expected
    461         }
    462     }
    463 
    464     public void test_getNextEntry() throws Exception {
    465         File resources = Support_Resources.createTempFolder();
    466         Support_Resources.copyFile(resources, null, "Broken_entry.jar");
    467         InputStream is = Support_Resources.getStream("Broken_entry.jar");
    468         JarInputStream jis = new JarInputStream(is, false);
    469         jis.getNextEntry();
    470         try {
    471             jis.getNextEntry();
    472             fail("ZipException expected");
    473         } catch (ZipException ee) {
    474             // expected
    475         }
    476 
    477         try {
    478             jis.close();  // Android throws exception here, already!
    479             jis.getNextEntry();  // But RI here, only!
    480             fail("IOException expected");
    481         } catch (IOException ee) {
    482             // expected
    483         }
    484     }
    485 
    486     class Mock_JarInputStream extends JarInputStream {
    487 
    488         public Mock_JarInputStream(InputStream in) throws IOException {
    489             super(in);
    490         }
    491 
    492         public ZipEntry createZipEntry(String str) {
    493             return super.createZipEntry(str);
    494         }
    495     }
    496 
    497     public void test_createZipEntryLjava_lang_String() throws Exception {
    498         File resources = Support_Resources.createTempFolder();
    499         Support_Resources.copyFile(resources, null, "Broken_entry.jar");
    500         InputStream is = Support_Resources.getStream("Broken_entry.jar");
    501         Mock_JarInputStream mjis = new Mock_JarInputStream(is);
    502         assertNotNull(mjis.createZipEntry("New entry"));
    503     }
    504 
    505     public void test_read$ZII() throws Exception {
    506         File resources = Support_Resources.createTempFolder();
    507         Support_Resources.copyFile(resources, null, "Broken_entry_data.jar");
    508         InputStream is = Support_Resources.getStream("Broken_entry_data.jar");
    509         JarInputStream jis = new JarInputStream(is, true);
    510         byte b[] = new byte[100];
    511 
    512         jis.getNextEntry();
    513         jis.read(b, 0, 100);
    514         jis.getNextEntry();
    515         jis.getNextEntry();
    516         jis.getNextEntry();
    517 
    518         try {
    519             jis.read(b, 0, 100);
    520             fail("ZipException expected");
    521         } catch (ZipException ee) {
    522             // expected
    523         }
    524 
    525         try {
    526             jis.close();  // Android throws exception here, already!
    527             jis.read(b, 0, 100);  // But RI here, only!
    528             fail("IOException expected");
    529         } catch (IOException ee) {
    530             // expected
    531         }
    532     }
    533 }
    534