libcore: add tests in X500Principal and DistinguishedParserName

Change-Id: Ie6aa3cf7ad5c228c662cbbaf84fed041ba77db1b
diff --git a/luni/src/test/java/libcore/javax/net/ssl/DistinguishedNameParserTest.java b/luni/src/test/java/libcore/javax/net/ssl/DistinguishedNameParserTest.java
index 91c596f..0290509 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/DistinguishedNameParserTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/DistinguishedNameParserTest.java
@@ -19,8 +19,13 @@
 import javax.net.ssl.DistinguishedNameParser;
 import javax.security.auth.x500.X500Principal;
 import junit.framework.TestCase;
+
 import java.util.Arrays;
 
+/**
+ * See also {@link libcore.javax.security.auth.x500.X500PrincipalTest} as it shows some cases
+ * we are not checking as they are not allowed by the X500 principal in the first place.
+ */
 public final class DistinguishedNameParserTest extends TestCase {
     public void testGetCns() {
         assertCns("");
@@ -28,25 +33,91 @@
         assertCns("ou=xxx,cn=xxx", "xxx");
         assertCns("ou=xxx+cn=yyy,cn=zzz+cn=abc", "yyy", "zzz", "abc");
         assertCns("cn=a,cn=b", "a", "b");
+        assertCns("cn=a   c,cn=b", "a   c", "b");
+        assertCns("cn=a   ,cn=b", "a", "b");
         assertCns("cn=Cc,cn=Bb,cn=Aa", "Cc", "Bb", "Aa");
         assertCns("cn=imap.gmail.com", "imap.gmail.com");
         assertCns("l=\"abcn=a,b\", cn=c", "c");
+        assertCns("l=\"abcn=a,b\", cn=c", "c");
+        assertCns("l=\"abcn=a,b\", cn= c", "c");
+        assertCns("cn=<", "<");
+        assertCns("cn=>", ">");
+        assertCns("cn= >", ">");
+        assertCns("cn=a b", "a b");
+        assertCns("cn   =a b", "a b");
+        assertCns("Cn=a b", "a b");
+        assertCns("cN=a b", "a b");
+        assertCns("CN=a b", "a b");
+        assertCns("cn=a#b", "a#b");
+        assertCns("cn=#130161", "a");
+        assertCns("l=q\t+cn=p", "p");
+        assertCns("l=q\n+cn=p", "p");
+        assertCns("l=q\n,cn=p", "p");
+        assertCns("l=,cn=p", "p");
+        assertCns("l=\tq\n,cn=\tp", "\tp");
+    }
+
+    /** A cn=, generates an empty value, unless it's at the very end. */
+    public void emptyValues() {
+        assertCns("l=,cn=+cn=q", "", "q");
+        assertCns("l=,cn=,cn=q", "", "q");
+        assertCns("l=,cn=");
+        assertCns("l=,cn=q,cn=   ", "q");
+        assertCns("l=,cn=q  ,cn=   ", "q");
+        assertCns("l=,cn=\"\"");
+        assertCns("l=,cn=\"  \",cn=\"  \"","  ");
+        assertCns("l=,cn=  ,cn=  ","");
+        assertCns("l=,cn=,cn=  ,cn=  ", "", "");
+    }
+
+
+    public void testGetCns_escapedChars() {
+        assertCns("cn=\\,", ",");
+        assertCns("cn=\\#", "#");
+        assertCns("cn=\\+", "+");
+        assertCns("cn=\\\"", "\"");
+        assertCns("cn=\\\\", "\\");
+        assertCns("cn=\\<", "<");
+        assertCns("cn=\\>", ">");
+        assertCns("cn=\\;", ";");
+        assertCns("cn=\\+", "+");
+        assertCns("cn=\"\\+\"", "+");
+        assertCns("cn=\"\\,\"", ",");
+        assertCns("cn= a =", "a =");
+        assertCns("cn==", "=");
+    }
+
+    public void testGetCns_whitespace() {
+        assertCns("cn= p", "p");
+        assertCns("cn=\np", "\np");
+        assertCns("cn=\tp", "\tp");
     }
 
     public void testGetCnsWithOid() {
         assertCns("2.5.4.3=a,ou=xxx", "a");
+        assertCns("2.5.4.3=\" a \",ou=xxx", " a ");
+        assertCns("2.5.5.3=a,ou=xxx,cn=b", "b");
     }
 
     public void testGetCnsWithQuotedStrings() {
         assertCns("cn=\"\\\" a ,=<>#;\"", "\" a ,=<>#;");
         assertCns("cn=abc\\,def", "abc,def");
+        assertCns("cn=\"\\\" a ,\\=<>\\#;\"", "\" a ,=<>#;");
     }
 
     public void testGetCnsWithUtf8() {
+        assertCns("cn=\"Lu\\C4\\8Di\\C4\\87\"", "\u004c\u0075\u010d\u0069\u0107");
         assertCns("cn=Lu\\C4\\8Di\\C4\\87", "\u004c\u0075\u010d\u0069\u0107");
+        assertCns("cn=Lu\\C4\\8di\\c4\\87", "\u004c\u0075\u010d\u0069\u0107");
+        assertCns("cn=\"Lu\\C4\\8di\\c4\\87\"", "\u004c\u0075\u010d\u0069\u0107");
+        assertCns("cn=\u004c\u0075\u010d\u0069\u0107", "\u004c\u0075\u010d\u0069\u0107");
+        // \63=c
+        expectExceptionInPrincipal("\\63n=ab");
+        expectExceptionInPrincipal("cn=\\a");
     }
 
     public void testGetCnsWithWhitespace() {
+
         assertCns("ou=a, cn=  a  b  ,o=x", "a  b");
         assertCns("cn=\"  a  b  \" ,o=x", "  a  b  ");
     }
@@ -54,7 +125,6 @@
     private void assertCns(String dn, String... expected) {
         X500Principal principal = new X500Principal(dn);
         DistinguishedNameParser parser = new DistinguishedNameParser(principal);
-
         // Test getAllMostSpecificFirst
         assertEquals(dn, Arrays.asList(expected), parser.getAllMostSpecificFirst("cn"));
 
@@ -65,4 +135,28 @@
             assertNull(dn, parser.findMostSpecific("cn"));
         }
     }
+
+    private void assertGetAttribute(String dn, String attribute, String... expected) {
+        X500Principal principal = new X500Principal(dn);
+        DistinguishedNameParser parser = new DistinguishedNameParser(principal);
+        // Test getAllMostSpecificFirst
+        assertEquals(dn, Arrays.asList(expected), parser.getAllMostSpecificFirst(attribute));
+
+        // Test findMostSpecific
+        if (expected.length > 0) {
+            assertEquals(dn, expected[0], parser.findMostSpecific(attribute));
+        } else {
+            assertNull(dn, parser.findMostSpecific(attribute));
+        }
+    }
+
+    private void expectExceptionInPrincipal(String dn) {
+        try {
+            X500Principal principal = new X500Principal(dn);
+            fail("Expected " + IllegalArgumentException.class.getName()
+                    + " because of incorrect input name");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+    }
 }
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 571aa9c..4f5d658 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
@@ -103,6 +103,33 @@
                               new byte[] { 48, 21, 49, 19, 48, 17, 6, 10, 9, -110, 38, -119, -109, -14, 44, 100, 1, 25, 22, 3, 99, 111, 109 });
     }
 
+    public void testExceptionsForWrongDNs() {
+        expectExceptionInDNConstructor("cn=\\n");
+        expectExceptionInDNConstructor("cn=a;b");
+        expectExceptionInDNConstructor("cn=  #a");
+        expectExceptionInDNConstructor("l=a,cn=+p");
+        expectExceptionInDNConstructor("l=+a,cn=p");
+        expectExceptionInDNConstructor("\nl=q\n,cn=p");
+        expectExceptionInDNConstructor("\tl=q,cn=p");
+        expectExceptionInDNConstructor("<=q,cn=p");
+        expectExceptionInDNConstructor("l=q\n,,cn=p");
+        expectExceptionInDNConstructor("l=q\n+,cn=p");
+        expectExceptionInDNConstructor("+l=q,cn=p");
+        expectExceptionInDNConstructor(",l=q,cn=p");
+        expectExceptionInDNConstructor("l");
+        expectExceptionInDNConstructor("l=\\g0");
+    }
+
+    private void expectExceptionInDNConstructor(String dn) {
+        try {
+            X500Principal principal = new X500Principal(dn);
+            fail("Expected " + IllegalArgumentException.class.getName()
+                    + " because of incorrect input name");
+        } catch (IllegalArgumentException e) {
+            // Expected.
+        }
+    }
+
     private void testIA5StringEncoding(String name, byte[] expectedEncoded) {
         X500Principal original = new X500Principal(name);