Merge "Prevent SocketTest off-thread Exception from escaping" am: 6ad1e2b8fd am: 7006f185d3
am: aa4af0588a

Change-Id: Id9cd4ca1043caca9f62b0e9e9ef714187071dbf3
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java
index e81224a..af5fce5 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectInputStream2Test.java
@@ -17,10 +17,8 @@
 
 package org.apache.harmony.tests.java.io;
 
-import dalvik.system.DexFile;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InvalidClassException;
@@ -29,9 +27,6 @@
 import java.io.ObjectStreamClass;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
 
 import junit.framework.TestCase;
@@ -215,54 +210,4 @@
             // Excpected
         }
     }
-
-    // http://b/29721023
-    public void test_sameName() throws Exception {
-        // Load class from dex, it's not possible to create a class with same-named
-        // fields in java (but it's allowed in dex).
-        File sameFieldNames = File.createTempFile("sameFieldNames", ".dex");
-        InputStream dexIs = this.getClass().getClassLoader().
-            getResourceAsStream("tests/api/java/io/sameFieldNames.dex");
-        assertNotNull(dexIs);
-
-        Class<?> clazz = null;
-
-        // Get the class object
-        try {
-            Files.copy(dexIs, sameFieldNames.toPath(), StandardCopyOption.REPLACE_EXISTING);
-            DexFile dexFile = new DexFile(sameFieldNames);
-            clazz = dexFile.loadClass("sameFieldNames", getClass().getClassLoader());
-            dexFile.close();
-        } finally {
-            if (sameFieldNames.exists()) {
-                sameFieldNames.delete();
-            }
-        }
-
-        // Create class instance, fill it with content
-        Object o1 = clazz.getConstructor().newInstance();
-        int v = 123;
-        for(Field f : clazz.getFields()) {
-            if (f.getType() == Integer.class) {
-                f.set(o1, new Integer(v++));
-            } else if (f.getType() == Long.class) {
-                f.set(o1, new Long(v++));
-            }
-        }
-
-        // Serialize and deserialize
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = new ObjectOutputStream(baos);
-        oos.writeObject(o1);
-        oos.close();
-        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
-                baos.toByteArray()));
-        Object o2 = ois.readObject();
-        ois.close();
-
-        // Compare content
-        for(Field f : clazz.getFields()) {
-            assertEquals(f.get(o1), f.get(o2));
-        }
-    }
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
index 948059b..7fa5fbb 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamClassTest.java
@@ -17,21 +17,15 @@
 
 package org.apache.harmony.tests.java.io;
 
-import dalvik.system.DexFile;
 import java.io.Externalizable;
-import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.ObjectStreamClass;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
 import junit.framework.TestCase;
 
 public class ObjectStreamClassTest extends TestCase {
@@ -300,27 +294,4 @@
                     hasStaticInitializer.invoke(null, NoClinitChildWithNoClinitParent.class,
                                                 true /* checkSuperclass */));
     }
-
-    // http://b/29721023
-    public void testClassWithSameFieldName() throws Exception {
-        // Load class from dex, it's not possible to create a class with same-named
-        // fields in java (but it's allowed in dex).
-        File sameFieldNames = File.createTempFile("sameFieldNames", ".dex");
-        InputStream dexIs = this.getClass().getClassLoader().
-            getResourceAsStream("tests/api/java/io/sameFieldNames.dex");
-        assertNotNull(dexIs);
-
-        try {
-            Files.copy(dexIs, sameFieldNames.toPath(), StandardCopyOption.REPLACE_EXISTING);
-            DexFile dexFile = new DexFile(sameFieldNames);
-            Class<?> clazz = dexFile.loadClass("sameFieldNames", getClass().getClassLoader());
-            ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
-            assertEquals(4, osc.getFields().length);
-            dexFile.close();
-        } finally {
-            if (sameFieldNames.exists()) {
-                sameFieldNames.delete();
-            }
-        }
-    }
 }
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index d1d26a8..1f8b527 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -2293,8 +2293,13 @@
         testUrlToRequestMapping("$", "$", "$");
         testUrlToUriMapping("&", "&", "&", "&", "&");
         testUrlToRequestMapping("&", "&", "&");
-        testUrlToUriMapping("'", "'", "'", "%27", "'");
-        testUrlToRequestMapping("'", "'", "%27");
+
+        // http://b/30405333 - upstream OkHttp encodes single quote (') as %27 in query parameters
+        // but this breaks iTunes remote apps: iTunes currently does not accept %27 so we have a
+        // local patch to retain the historic Android behavior of not encoding single quote.
+        testUrlToUriMapping("'", "'", "'", "'", "'");
+        testUrlToRequestMapping("'", "'", "'");
+
         testUrlToUriMapping("(", "(", "(", "(", "(");
         testUrlToRequestMapping("(", "(", "(");
         testUrlToUriMapping(")", ")", ")", ")", ")");
diff --git a/luni/src/test/java/libcore/java/text/OldBidiTest.java b/luni/src/test/java/libcore/java/text/OldBidiTest.java
index fbf68ea..fe8b6cb 100644
--- a/luni/src/test/java/libcore/java/text/OldBidiTest.java
+++ b/luni/src/test/java/libcore/java/text/OldBidiTest.java
@@ -17,6 +17,7 @@
 
 package libcore.java.text;
 
+import java.text.AttributedCharacterIterator;
 import java.text.Bidi;
 import junit.framework.TestCase;
 
@@ -192,4 +193,16 @@
         }
     }
 
+    // http://b/30652865
+    public void testUnicode9EmojisAreLtrNeutral() {
+        String callMeHand = "\uD83E\uDD19"; // U+1F919 in UTF-16
+        String hebrewAndEmoji = "\u05e9\u05dc" + callMeHand + "\u05d5\u05dd";
+        String latinAndEmoji = "Hel" + callMeHand + "lo";
+        Bidi hebrew = new Bidi(hebrewAndEmoji, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        assertFalse("Hebrew bidi is mixed: " + hebrew, hebrew.isMixed());
+        assertTrue("Hebrew bidi is not right to left: " + hebrew, hebrew.isRightToLeft());
+        Bidi latin = new Bidi(latinAndEmoji, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        assertFalse("Latin bidi is mixed: " + latin, latin.isMixed());
+        assertTrue("latin bidi is not left to right: " + latin, latin.isLeftToRight());
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
index 03fa29a..2175289 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
@@ -22,6 +22,7 @@
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -74,4 +75,14 @@
         long currentOffset = android.system.Os.lseek(fd, 0, OsConstants.SEEK_CUR);
         assertEquals(initialOffset, currentOffset);
     }
+
+    // b/31077136
+    public void test_FileNotFound() throws Exception {
+        File nonExistentFile = new File("fileThatDefinitelyDoesntExist.zip");
+        assertFalse(nonExistentFile.exists());
+
+        try (ZipFile zipFile = new ZipFile(nonExistentFile, ZipFile.OPEN_READ)) {
+            fail();
+        } catch(FileNotFoundException expected) {}
+    }
 }
diff --git a/ojluni/src/main/java/java/util/zip/ZipFile.java b/ojluni/src/main/java/java/util/zip/ZipFile.java
index 9ff661a..6a5a366 100644
--- a/ojluni/src/main/java/java/util/zip/ZipFile.java
+++ b/ojluni/src/main/java/java/util/zip/ZipFile.java
@@ -31,6 +31,7 @@
 import java.io.IOException;
 import java.io.EOFException;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
@@ -203,9 +204,15 @@
                                                Integer.toHexString(mode));
         }
 
-        // Android-changed: Error out early if the file is too short.
-        if (file.length() < ZipConstants.ENDHDR) {
-            throw new ZipException("File too short to be a zip file: " + file.length());
+
+        // Android-changed: Error out early if the file is too short or non-existent.
+        long length = file.length();
+        if (length < ZipConstants.ENDHDR) {
+            if (length == 0 && !file.exists()) {
+                throw new FileNotFoundException("File doesn't exist: " + file);
+            } else {
+                throw new ZipException("File too short to be a zip file: " + file.length());
+            }
         }
         String name = file.getPath();