Add test for StrictJarFile (moved to framework from libcore)
Bug: 25337946
Change-Id: Idffd5e5069815f3b1ff5c42b8405e97c2e8757d3
diff --git a/tests/tests/util/Android.mk b/tests/tests/util/Android.mk
index 3e92d10..b63e637 100644
--- a/tests/tests/util/Android.mk
+++ b/tests/tests/util/Android.mk
@@ -30,6 +30,4 @@
LOCAL_PACKAGE_NAME := CtsUtilTestCases
-LOCAL_SDK_VERSION := current
-
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/util/assets/Integrate.jar b/tests/tests/util/assets/Integrate.jar
new file mode 100644
index 0000000..16e9c55
--- /dev/null
+++ b/tests/tests/util/assets/Integrate.jar
Binary files differ
diff --git a/tests/tests/util/assets/Modified_Class.jar b/tests/tests/util/assets/Modified_Class.jar
new file mode 100644
index 0000000..d8113c7
--- /dev/null
+++ b/tests/tests/util/assets/Modified_Class.jar
Binary files differ
diff --git a/tests/tests/util/assets/Modified_Manifest_EntryAttributes.jar b/tests/tests/util/assets/Modified_Manifest_EntryAttributes.jar
new file mode 100644
index 0000000..bd1dbb1
--- /dev/null
+++ b/tests/tests/util/assets/Modified_Manifest_EntryAttributes.jar
Binary files differ
diff --git a/tests/tests/util/assets/Modified_Manifest_MainAttributes.jar b/tests/tests/util/assets/Modified_Manifest_MainAttributes.jar
new file mode 100644
index 0000000..5bc60e6
--- /dev/null
+++ b/tests/tests/util/assets/Modified_Manifest_MainAttributes.jar
Binary files differ
diff --git a/tests/tests/util/assets/Modified_SF_EntryAttributes.jar b/tests/tests/util/assets/Modified_SF_EntryAttributes.jar
new file mode 100644
index 0000000..7b76694
--- /dev/null
+++ b/tests/tests/util/assets/Modified_SF_EntryAttributes.jar
Binary files differ
diff --git a/tests/tests/util/assets/hyts_patch.jar b/tests/tests/util/assets/hyts_patch.jar
new file mode 100644
index 0000000..f3c51d0
--- /dev/null
+++ b/tests/tests/util/assets/hyts_patch.jar
Binary files differ
diff --git a/tests/tests/util/assets/removed.jar b/tests/tests/util/assets/removed.jar
new file mode 100644
index 0000000..2100322
--- /dev/null
+++ b/tests/tests/util/assets/removed.jar
Binary files differ
diff --git a/tests/tests/util/src/android/util/cts/StrictJarFileTest.java b/tests/tests/util/src/android/util/cts/StrictJarFileTest.java
new file mode 100644
index 0000000..e7eedfd
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/StrictJarFileTest.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.util.cts;
+
+import android.test.AndroidTestCase;
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Iterator;
+import android.util.jar.StrictJarFile;
+import java.util.zip.ZipEntry;
+import libcore.io.Streams;
+
+public class StrictJarFileTest extends AndroidTestCase {
+
+ // A well formed jar file with 6 entries.
+ private static final String JAR_1 = "hyts_patch.jar";
+
+ private File resources;
+
+ @Override
+ protected void setUp() {
+ try {
+ resources = File.createTempFile("sjf_resources", "", null);
+ resources.delete();
+ resources.mkdirs();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to create temp folder", e);
+ }
+ resources.deleteOnExit();
+ }
+
+ public void testConstructor() throws Exception {
+ try {
+ StrictJarFile jarFile = new StrictJarFile("Wrong.file");
+ fail("Should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+
+ copyFile(JAR_1);
+ String fileName = (new File(resources, JAR_1)).getCanonicalPath();
+ StrictJarFile jarFile = new StrictJarFile(fileName);
+ jarFile.close();
+ }
+
+ public void testIteration() throws Exception {
+ copyFile(JAR_1);
+ StrictJarFile jarFile = new StrictJarFile(new File(resources, JAR_1).getAbsolutePath());
+
+ Iterator<ZipEntry> it = jarFile.iterator();
+ HashMap<String, ZipEntry> entries = new HashMap<String, ZipEntry>();
+ while (it.hasNext()) {
+ final ZipEntry ze = it.next();
+ entries.put(ze.getName(), ze);
+ }
+
+ assertEquals(6, entries.size());
+ assertTrue(entries.containsKey("META-INF/"));
+
+ assertTrue(entries.containsKey("META-INF/MANIFEST.MF"));
+ ZipEntry ze = entries.get("META-INF/MANIFEST.MF");
+ assertEquals(62, ze.getSize());
+ assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+ assertEquals(61, ze.getCompressedSize());
+
+ assertTrue(entries.containsKey("Blah.txt"));
+ ze = entries.get("Blah.txt");
+ assertEquals(4, ze.getSize());
+ assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+ assertEquals(6, ze.getCompressedSize());
+ assertEquals("Blah", new String(Streams.readFully(jarFile.getInputStream(ze)),
+ Charset.forName("UTF-8")));
+
+ assertTrue(entries.containsKey("foo/"));
+ assertTrue(entries.containsKey("foo/bar/"));
+ assertTrue(entries.containsKey("foo/bar/A.class"));
+ ze = entries.get("foo/bar/A.class");
+ assertEquals(311, ze.getSize());
+ assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+ assertEquals(225, ze.getCompressedSize());
+ }
+
+ public void testFindEntry() throws Exception {
+ copyFile(JAR_1);
+ StrictJarFile jarFile = new StrictJarFile(new File(resources, JAR_1).getAbsolutePath());
+
+ assertNull(jarFile.findEntry("foobar"));
+ assertNull(jarFile.findEntry("blah.txt"));
+ assertNotNull(jarFile.findEntry("Blah.txt"));
+ final ZipEntry ze = jarFile.findEntry("Blah.txt");
+ assertEquals(4, ze.getSize());
+ assertEquals(ZipEntry.DEFLATED, ze.getMethod());
+ assertEquals(6, ze.getCompressedSize());
+ assertEquals("Blah", new String(Streams.readFully(jarFile.getInputStream(ze)),
+ Charset.forName("UTF-8")));
+ }
+
+ public void testGetManifest() throws Exception {
+ copyFile(JAR_1);
+ StrictJarFile jarFile = new StrictJarFile(new File(resources, JAR_1).getAbsolutePath());
+
+ assertNotNull(jarFile.getManifest());
+ assertEquals("1.4.2 (IBM Corporation)", jarFile.getManifest().getMainAttributes().getValue("Created-By"));
+ }
+
+ public void testJarSigning_wellFormed() throws IOException {
+ copyFile("Integrate.jar");
+ StrictJarFile jarFile = new StrictJarFile(new File(resources, "Integrate.jar").getAbsolutePath());
+ Iterator<ZipEntry> entries = jarFile.iterator();
+ while (entries.hasNext()) {
+ ZipEntry zipEntry = entries.next();
+ jarFile.getInputStream(zipEntry).skip(Long.MAX_VALUE);
+ if ("Test.class".equals(zipEntry.getName())) {
+ assertNotNull(jarFile.getCertificates(zipEntry));
+ assertNotNull(jarFile.getCertificateChains(zipEntry));
+ }
+ }
+ }
+
+ public void testJarSigning_fudgedEntry() throws IOException {
+ copyFile("Integrate.jar");
+ StrictJarFile jarFile = new StrictJarFile(
+ new File(resources, "Integrate.jar").getAbsolutePath());
+
+ ZipEntry ze = jarFile.findEntry("Test.class");
+ jarFile.getInputStream(ze).skip(Long.MAX_VALUE);
+
+ // Fudge the size so that certificates do not match.
+ ze.setSize(ze.getSize() - 1);
+ try {
+ jarFile.getInputStream(ze).skip(Long.MAX_VALUE);
+ fail();
+ } catch (SecurityException expected) {
+ }
+ }
+
+ public void testJarSigning_modifiedClass() throws IOException {
+ copyFile("Modified_Class.jar");
+ StrictJarFile jarFile = new StrictJarFile(
+ new File(resources, "Modified_Class.jar").getAbsolutePath());
+
+ ZipEntry ze = jarFile.findEntry("Test.class");
+ try {
+ jarFile.getInputStream(ze).skip(Long.MAX_VALUE);
+ fail();
+ } catch (SecurityException expected) {
+ }
+ }
+
+ public void testJarSigning_brokenMainAttributes() throws Exception {
+ assertThrowsOnInit("Modified_Manifest_MainAttributes.jar");
+ }
+
+ public void testJarSigning_brokenEntryAttributes() throws Exception {
+ assertThrowsOnInit("Modified_Manifest_EntryAttributes.jar");
+ }
+
+ public void testJarSigning_brokenSignatureFile() throws Exception {
+ assertThrowsOnInit("Modified_SF_EntryAttributes.jar");
+ }
+
+ public void testJarSigning_removedEntry() throws Exception {
+ assertThrowsOnInit("removed.jar");
+ }
+
+ private void assertThrowsOnInit(String name) throws Exception {
+ copyFile(name);
+ try {
+ StrictJarFile jarFile = new StrictJarFile(
+ new File(resources, name).getAbsolutePath());
+ fail();
+ } catch (SecurityException expected) {
+ }
+ }
+
+
+ public File copyFile(String file) {
+ File dest = new File(resources.toString() + "/" + file);
+
+ if (!dest.exists()) {
+ try {
+ InputStream in = getContext().getAssets().open(file);
+ FileOutputStream out = new FileOutputStream(dest);
+ byte[] buffer = new byte[8192];
+ int c;
+ while ((c = in.read(buffer)) != -1) {
+ out.write(buffer, 0, c);
+ }
+ out.close();
+ dest.deleteOnExit();
+ in.close();
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Unable to copy file from resource " + file + " to file " + dest, e);
+ }
+ }
+ return dest;
+ }
+}