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