Merge "Test fix: Handle missing dummy0 network interface" into nyc-mr2-dev
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index 51c2a94..9082209 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -1537,8 +1537,13 @@
     sockaddr* from = (javaInetSocketAddress != NULL) ? reinterpret_cast<sockaddr*>(&ss) : NULL;
     socklen_t* fromLength = (javaInetSocketAddress != NULL) ? &sl : 0;
     jint recvCount = NET_FAILURE_RETRY(env, ssize_t, recvfrom, javaFd, bytes.get() + byteOffset, byteCount, flags, from, fromLength);
-    if (recvCount > 0) {
-        fillInetSocketAddress(env, javaInetSocketAddress, ss);
+    if (recvCount >= 0) {
+        // The socket may have performed orderly shutdown and recvCount would return 0 (see man 2
+        // recvfrom), in which case ss.ss_family == AF_UNIX and fillInetSocketAddress would fail.
+        // Don't fill in the address if recvfrom didn't succeed. http://b/33483694
+        if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) {
+            fillInetSocketAddress(env, javaInetSocketAddress, ss);
+        }
     }
     return recvCount;
 }
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index b2c3775..9729cf2 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -150,7 +150,20 @@
         // allow (but strip) trailing \n, \r and \r\n
         // assertForbiddenRequestHeaderValue("\r");
         // End of workaround
-        assertEquals("a valid\tvalue", setAndReturnRequestHeaderValue("a valid\tvalue"));
+
+        // '\t' in header values can either be (a) forbidden or (b) allowed.
+        // The original version of Android N (API 23) implemented behavior
+        // (a), but OEMs can backport a fix that changes the behavior to (b).
+        // Therefore, this test has been relaxed for Android N CTS to allow
+        // either behavior. It is planned that future versions of Android only
+        // allow behavior (b).
+        try {
+            // throws IAE in case (a), passes in case (b)
+            assertEquals("a valid\tvalue", setAndReturnRequestHeaderValue("a valid\tvalue"));
+        } catch (IllegalArgumentException tolerated) {
+            // verify case (a)
+            assertForbiddenRequestHeaderValue("\t");
+        }
         assertForbiddenRequestHeaderValue("\u001f");
         assertForbiddenRequestHeaderValue("\u007f");
 
diff --git a/luni/src/test/java/libcore/java/net/URLTest.java b/luni/src/test/java/libcore/java/net/URLTest.java
index 789e3e9..629015f 100644
--- a/luni/src/test/java/libcore/java/net/URLTest.java
+++ b/luni/src/test/java/libcore/java/net/URLTest.java
@@ -757,4 +757,26 @@
         assertEquals("/some/path", new URL("http://foobar.com/some/path#").getFile());
         assertEquals("/some/path", new URL("http://foobar.com/some/path?#").getFile());
     }
+
+    // http://b/31858037
+    public void testFragmentWithSlash() throws Exception {
+        final String host = "example.com";
+        final String fragment = "@not-a-host-name/a";
+        URL url = new URL(String.format("http://%s#%s", host, fragment));
+        assertNull(url.getUserInfo());
+        assertEquals(host, url.getAuthority());
+        assertEquals(host, url.getHost());
+        assertEquals(fragment, url.getRef());
+    }
+
+    // http://b/31858037
+    public void testFragmentWithQuery() throws Exception {
+        final String host = "example.com";
+        final String fragment = "@not-a-host-name?a";
+        URL url = new URL(String.format("http://%s#%s", host, fragment));
+        assertNull(url.getUserInfo());
+        assertEquals(host, url.getAuthority());
+        assertEquals(host, url.getHost());
+        assertEquals(fragment, url.getRef());
+    }
 }
diff --git a/luni/src/test/java/libcore/java/nio/BufferTest.java b/luni/src/test/java/libcore/java/nio/BufferTest.java
index 9a2cb12..9063e27 100644
--- a/luni/src/test/java/libcore/java/nio/BufferTest.java
+++ b/luni/src/test/java/libcore/java/nio/BufferTest.java
@@ -1429,4 +1429,41 @@
         assertFalse(bigEndian.asFloatBuffer().slice().get() ==
                 littleEndian.asFloatBuffer().slice().get());
     }
+
+    // http://b/32655865
+    public void test_ByteBufferAsXBuffer_ByteOrder_2() {
+        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(10);
+        byteBuffer.order(ByteOrder.BIG_ENDIAN);
+        // Fill a ByteBuffer with different bytes that make it easy to tell byte ordering issues.
+        for (int i = 0; i < 10; i++) {
+            byteBuffer.put((byte)i);
+        }
+        byteBuffer.rewind();
+
+        // Create BIG_ENDIAN views of the buffer.
+        ShortBuffer sb_be = byteBuffer.asShortBuffer();
+        LongBuffer lb_be = byteBuffer.asLongBuffer();
+        IntBuffer ib_be = byteBuffer.asIntBuffer();
+        DoubleBuffer db_be = byteBuffer.asDoubleBuffer();
+        CharBuffer cb_be = byteBuffer.asCharBuffer();
+        FloatBuffer fb_be = byteBuffer.asFloatBuffer();
+
+        // Change the order of the underlying buffer.
+        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
+
+        // Create LITTLE_ENDIAN views of the buffer.
+        ShortBuffer sb_le = byteBuffer.asShortBuffer();
+        LongBuffer lb_le = byteBuffer.asLongBuffer();
+        IntBuffer ib_le = byteBuffer.asIntBuffer();
+        DoubleBuffer db_le = byteBuffer.asDoubleBuffer();
+        CharBuffer cb_le = byteBuffer.asCharBuffer();
+        FloatBuffer fb_le = byteBuffer.asFloatBuffer();
+
+        assertFalse(sb_be.get() == sb_le.get());
+        assertFalse(lb_be.get() == lb_le.get());
+        assertFalse(ib_be.get() == ib_le.get());
+        assertFalse(db_be.get() == db_le.get());
+        assertFalse(cb_be.get() == cb_le.get());
+        assertFalse(fb_be.get() == fb_le.get());
+    }
 }
diff --git a/luni/src/test/java/libcore/java/util/FormatterTest.java b/luni/src/test/java/libcore/java/util/FormatterTest.java
index e87fee5..aed9ca0 100644
--- a/luni/src/test/java/libcore/java/util/FormatterTest.java
+++ b/luni/src/test/java/libcore/java/util/FormatterTest.java
@@ -17,7 +17,11 @@
 package libcore.java.util;
 
 import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
 import java.util.Calendar;
+import java.util.Formatter;
 import java.util.GregorianCalendar;
 import java.util.Locale;
 import java.util.TimeZone;
@@ -183,4 +187,24 @@
       assertEquals(expected, String.format(Locale.US, "%t" + pattern, c));
       assertEquals(expected, String.format(Locale.US, "%T" + pattern, c));
     }
+
+    // http://b/33245708: Some locales have a group separator != '\0' but a default decimal format
+    // pattern without grouping (e.g. a group size of zero). This would throw divide by zero when
+    // working out where to place the separator.
+    public void testGroupingSizeZero() {
+        Locale localeWithoutGrouping = new Locale("hy");
+        DecimalFormat decimalFormat =
+                (DecimalFormat) NumberFormat.getInstance(localeWithoutGrouping);
+
+        // Confirm the locale is still a good example: it has a group separator, but no grouping in
+        // the default decimal format.
+        assertEquals(0, decimalFormat.getGroupingSize());
+        assertFalse(decimalFormat.isGroupingUsed());
+        DecimalFormatSymbols symbols = decimalFormat.getDecimalFormatSymbols();
+        assertTrue(symbols.getGroupingSeparator() != '\0');
+
+        Formatter formatter = new Formatter(localeWithoutGrouping);
+        formatter.format("%,d", 123456789);
+        // No exception expected
+    }
 }
diff --git a/ojluni/src/main/java/java/net/URLStreamHandler.java b/ojluni/src/main/java/java/net/URLStreamHandler.java
index e177363..ddea036 100755
--- a/ojluni/src/main/java/java/net/URLStreamHandler.java
+++ b/ojluni/src/main/java/java/net/URLStreamHandler.java
@@ -175,6 +175,14 @@
                     i = limit;
             }
 
+            // ----- BEGIN android -----
+            // i may become greater than limit
+            // b/31858037
+            if (i > limit) {
+                i = limit;
+            }
+            // ----- END android -----
+
             host = authority = spec.substring(start, i);
 
             int ind = authority.indexOf('@');
diff --git a/ojluni/src/main/java/java/nio/ByteBuffer.java b/ojluni/src/main/java/java/nio/ByteBuffer.java
index 523bbda..1e50922 100644
--- a/ojluni/src/main/java/java/nio/ByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBuffer.java
@@ -555,14 +555,14 @@
             // isDirect() doesn't imply !hasArray(), ByteBuffer.allocateDirect allocated buffer will
             // have a backing, non-gc-movable byte array. JNI allocated direct byte buffers WILL NOT
             // have a backing array.
-            final Object srcObject = src.isDirect() ? src : src.array();
+            final Object srcObject = src.isDirect() ? src : src.hb;
             int srcOffset = src.position();
             if (!src.isDirect()) {
                 srcOffset += src.offset;
             }
 
             final ByteBuffer dst = this;
-            final Object dstObject = dst.isDirect() ? dst : dst.array();
+            final Object dstObject = dst.isDirect() ? dst : dst.hb;
             int dstOffset = dst.position();
             if (!dst.isDirect()) {
                 dstOffset += dst.offset;
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsCharBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsCharBuffer.java
index c94bc37..9dbb8a6 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsCharBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsCharBuffer.java
@@ -37,7 +37,7 @@
                            int mark, int pos, int lim, int cap,
                            int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java
index f9c13fa..ff4a6bf 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsDoubleBuffer.java
@@ -38,7 +38,7 @@
                              int mark, int pos, int lim, int cap,
                              int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java
index 667c8bd..8e4e2e8 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsFloatBuffer.java
@@ -37,7 +37,7 @@
                             int mark, int pos, int lim, int cap,
                             int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsIntBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsIntBuffer.java
index 275f37e..e340426 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsIntBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsIntBuffer.java
@@ -37,7 +37,7 @@
                           int mark, int pos, int lim, int cap,
                           int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsLongBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsLongBuffer.java
index 1ea65e3..70f59c9 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsLongBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsLongBuffer.java
@@ -37,7 +37,7 @@
                            int mark, int pos, int lim, int cap,
                            int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/nio/ByteBufferAsShortBuffer.java b/ojluni/src/main/java/java/nio/ByteBufferAsShortBuffer.java
index 90aec35..5178a7e 100644
--- a/ojluni/src/main/java/java/nio/ByteBufferAsShortBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBufferAsShortBuffer.java
@@ -37,7 +37,7 @@
                             int mark, int pos, int lim, int cap,
                             int off, ByteOrder order) {
         super(mark, pos, lim, cap);
-        this.bb = bb;
+        this.bb = bb.duplicate();
         this.isReadOnly = bb.isReadOnly;
         // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
         // HeapByteBuffer. We only have to initialize the field when bb is an instance of
diff --git a/ojluni/src/main/java/java/util/Formatter.java b/ojluni/src/main/java/java/util/Formatter.java
index 9a4e234..c656e9c 100755
--- a/ojluni/src/main/java/java/util/Formatter.java
+++ b/ojluni/src/main/java/java/util/Formatter.java
@@ -4193,6 +4193,14 @@
                     grpSep = dfs.getGroupingSeparator();
                     DecimalFormat df = (DecimalFormat) NumberFormat.getIntegerInstance(l);
                     grpSize = df.getGroupingSize();
+                    // Android-changed: http://b/33245708 : Some locales have a group separator but
+                    // also patterns without groups. If we do not clear the group separator in these
+                    // cases a divide by zero is thrown when determining where to place the
+                    // separators.
+                    if (!df.isGroupingUsed() || df.getGroupingSize() == 0) {
+                        grpSep = '\0';
+                    }
+                    // Android-changed: end http://b/33245708.
                 }
             }
 
diff --git a/ojluni/src/main/java/java/util/LinkedHashMap.java b/ojluni/src/main/java/java/util/LinkedHashMap.java
index 0396e8c..2a24a2e 100755
--- a/ojluni/src/main/java/java/util/LinkedHashMap.java
+++ b/ojluni/src/main/java/java/util/LinkedHashMap.java
@@ -33,6 +33,7 @@
 import java.util.function.Consumer;
 import java.util.function.BiConsumer;
 
+// Android-added: Note about spliterator order b/33945212 in Android N
 /**
  * <p>Hash table and linked list implementation of the <tt>Map</tt> interface,
  * with predictable iteration order.  This implementation differs from
@@ -140,6 +141,23 @@
  * returned by all of this class's collection view methods are
  * <em><a href="Spliterator.html#binding">late-binding</a></em>,
  * <em>fail-fast</em>, and additionally report {@link Spliterator#ORDERED}.
+ * <em>Note</em>: The implementation of these spliterators in Android Nougat
+ * (API levels 24 and 25) uses the wrong order (inconsistent with the
+ * iterators, which use the correct order), despite reporting
+ * {@link Spliterator#ORDERED}. You may use the following code fragments
+ * to obtain a correctly ordered Spliterator on API level 24 and 25:
+ * <ul>
+ *     <li>For a Collection view {@code c = lhm.keySet()},
+ *         {@code c = lhm.keySet()} or {@code c = lhm.values()}, use
+ *         {@code java.util.Spliterators.spliterator(c, c.spliterator().characteristics())}
+ *         instead of {@code c.spliterator()}.
+ *     <li>Instead of {@code lhm.stream()} or {@code lhm.parallelStream()}, use
+ *         {@code java.util.stream.StreamSupport.stream(spliterator, false)}
+ *         to construct a (nonparallel) {@link java.util.stream.Stream} from
+ *         such a {@code Spliterator}.
+ * </ul>
+ * Note that these workarounds are only suggested where {@code lhm} is a
+ * {@code LinkedHashMap}.
  *
  * <p>This class is a member of the
  * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/collections/index.html">