merge in nyc-dr1-release history after reset to nyc-dr1-dev
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index 2dd0bb5..0aca53e 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -19,8 +19,11 @@
 import junit.framework.TestCase;
 
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.Date;
+import java.util.List;
 import java.util.Locale;
 import java.util.SimpleTimeZone;
 import java.util.TimeZone;
@@ -392,6 +395,54 @@
         assertEquals("Getter iterations", iterations, getterCount.get());
     }
 
+    // http://b/30979219
+    public void testSetDefaultRace() throws InterruptedException {
+        // Since this tests a race condition, the test is probabilistic: it's not guaranteed to
+        // fail if the problem exists
+
+        // These iterations are significantly faster than the ones in #testSetDefaultDeadlock
+        final int iterations = 10000;
+        List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<>());
+        Thread.UncaughtExceptionHandler handler = (t, e) -> exceptions.add(e);
+
+        CyclicBarrier startBarrier = new CyclicBarrier(2);
+        Thread clearer = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                // This is not public API but can effectively be invoked via
+                // java.util.TimeZone.setDefault. Call it directly to reduce the amount of code
+                // involved in this test.
+                android.icu.util.TimeZone.clearCachedDefault();
+            }
+        });
+        clearer.setName("testSetDefaultRace clearer");
+        clearer.setUncaughtExceptionHandler(handler);
+
+        Thread getter = new Thread(() -> {
+            waitFor(startBarrier);
+            for (int i = 0; i < iterations; i++) {
+                android.icu.util.TimeZone.getDefault();
+            }
+        });
+        getter.setName("testSetDefaultRace getter");
+        getter.setUncaughtExceptionHandler(handler);
+
+        clearer.start();
+        getter.start();
+
+        // 2 seconds is plenty: If successful, we usually complete much faster.
+        clearer.join(1000);
+        getter.join(1000);
+
+        if (!exceptions.isEmpty()) {
+            Throwable firstException = exceptions.get(0);
+            firstException.printStackTrace();
+            fail("Threads did not succeed successfully: " + firstException);
+        }
+        assertFalse("clearer thread is still alive", clearer.isAlive());
+        assertFalse("getter thread is still alive", getter.isAlive());
+    }
+
     private static void waitFor(CyclicBarrier barrier) {
         try {
             barrier.await();
diff --git a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
index 4f5d658..5471b1f 100644
--- a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
+++ b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
@@ -120,6 +120,30 @@
         expectExceptionInDNConstructor("l=\\g0");
     }
 
+    public void testNegativeLen() {
+        try {
+            X500Principal p = new X500Principal(new byte[]{
+                    0x30, // DerValue.tag_Sequence read in DerValue#getSequence
+                    9,    // Length of the vector. read in readVector.
+                          // DerInputStream.getLength will just return this as 10 & 0x80 == 0
+                    -1,   // Tag of the first value in the sequencevalue. Convenient so that it
+                          // doesn't hold DerIndefLenConverter.isEOC()
+                    (byte) 0x80, // Encoding in indefinite form
+                    -1,          // Second tag to be read by DerIndefLenConverter
+                    (byte) 0x84, // Second length byte to be read, 0x80 means long form, 4 bytes
+                    (byte) 0xff, // Length to be read by DerIndefLenConverter, -6, will move the
+                                 // buffer position to the second tag
+                    (byte) 0xff,
+                    (byte) 0xff,
+                    (byte) -6,
+                    0,           // Needed as otherwise it's detected that there's nothing after
+                    // the length
+            });
+            fail("expected IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
     private void expectExceptionInDNConstructor(String dn) {
         try {
             X500Principal principal = new X500Principal(dn);
diff --git a/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java b/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java
index 78d9e30..cbd5ecc 100755
--- a/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java
+++ b/ojluni/src/main/java/sun/security/util/DerIndefLenConverter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -156,12 +156,18 @@
         }
         if (isLongForm(lenByte)) {
             lenByte &= LEN_MASK;
-            if (lenByte > 4)
+            if (lenByte > 4) {
                 throw new IOException("Too much data");
-            if ((dataSize - dataPos) < (lenByte + 1))
+            }
+            if ((dataSize - dataPos) < (lenByte + 1)) {
                 throw new IOException("Too little data");
-            for (int i = 0; i < lenByte; i++)
+            }
+            for (int i = 0; i < lenByte; i++) {
                 curLen = (curLen << 8) + (data[dataPos++] & 0xff);
+            }
+            if (curLen < 0) {
+                throw new IOException("Invalid length bytes");
+            }
         } else {
            curLen = (lenByte & LEN_MASK);
         }
@@ -188,10 +194,15 @@
         }
         if (isLongForm(lenByte)) {
             lenByte &= LEN_MASK;
-            for (int i = 0; i < lenByte; i++)
+            for (int i = 0; i < lenByte; i++) {
                 curLen = (curLen << 8) + (data[dataPos++] & 0xff);
-        } else
+            }
+            if (curLen < 0) {
+                throw new IOException("Invalid length bytes");
+            }
+        } else {
             curLen = (lenByte & LEN_MASK);
+        }
         writeLength(curLen);
         writeValue(curLen);
     }
diff --git a/ojluni/src/main/java/sun/security/util/DerInputStream.java b/ojluni/src/main/java/sun/security/util/DerInputStream.java
index 8f51439..dae8afd 100755
--- a/ojluni/src/main/java/sun/security/util/DerInputStream.java
+++ b/ojluni/src/main/java/sun/security/util/DerInputStream.java
@@ -604,6 +604,10 @@
                 value <<= 8;
                 value += 0x0ff & in.read();
             }
+            if (value < 0) {
+                throw new IOException("DerInputStream.getLength(): "
+                        + "Invalid length bytes");
+            }
         }
         return value;
     }