]> source.dussan.org Git - jgit.git/commitdiff
PersonIdent: Strip some special chars from external strings 11/71711/2
authorDave Borowitz <dborowitz@google.com>
Fri, 29 Apr 2016 15:10:36 +0000 (11:10 -0400)
committerDave Borowitz <dborowitz@google.com>
Fri, 29 Apr 2016 15:27:14 +0000 (11:27 -0400)
The special characters <> and '\n' interfere with parsing of
identities. C git strips these special characters, so we should too.

Rather than allocating extra strings by calling String#trim(), add a
few lines to our sanitization method to perform the same trimming as
described in String's Javadoc.

Change-Id: I96edcb93a2fc194ee354d60566d352299742a52f

org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java
org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java

index 48d2c480a949708a8dbe622e0b85476365f2fb30..86d8206b36b58693476be75767fcfecd62efd9be 100644 (file)
@@ -89,14 +89,47 @@ public class T0001_PersonIdentTest {
 
        @Test
        public void testToExternalStringTrimsNameAndEmail() throws Exception {
-               PersonIdent personIdent = new PersonIdent("  A U Thor  ",
-                               "  author@example.com  ");
+               PersonIdent personIdent = new PersonIdent(" \u0010A U Thor  ",
+                               "  author@example.com \u0009");
 
-               assertEquals("  A U Thor  ", personIdent.getName());
-               assertEquals("  author@example.com  ", personIdent.getEmailAddress());
+               assertEquals(" \u0010A U Thor  ", personIdent.getName());
+               assertEquals("  author@example.com \u0009", personIdent.getEmailAddress());
 
                String externalString = personIdent.toExternalString();
                assertTrue(externalString.startsWith("A U Thor <author@example.com>"));
        }
 
+       @Test
+       public void testToExternalStringTrimsAllWhitespace() {
+               String ws = "  \u0001 \n ";
+               PersonIdent personIdent = new PersonIdent(ws, ws);
+               assertEquals(ws, personIdent.getName());
+               assertEquals(ws, personIdent.getEmailAddress());
+
+               String externalString = personIdent.toExternalString();
+               assertTrue(externalString.startsWith(" <>"));
+       }
+
+       @Test
+       public void testToExternalStringTrimsOtherBadCharacters() {
+               String name = " Foo\r\n<Bar> ";
+               String email = " Baz>\n\u1234<Quux ";
+               PersonIdent personIdent = new PersonIdent(name, email);
+               assertEquals(name, personIdent.getName());
+               assertEquals(email, personIdent.getEmailAddress());
+
+               String externalString = personIdent.toExternalString();
+               assertTrue(externalString.startsWith("Foo\rBar <Baz\u1234Quux>"));
+       }
+
+       @Test
+       public void testEmptyNameAndEmail() {
+               PersonIdent personIdent = new PersonIdent("", "");
+               assertEquals("", personIdent.getName());
+               assertEquals("", personIdent.getEmailAddress());
+
+               String externalString = personIdent.toExternalString();
+               assertTrue(externalString.startsWith(" <>"));
+       }
+
 }
index aa304634baed60d0614dd6e6d904ffcf554c9ffe..f352f3996872d7cbb85dd3c35451c3fcf8517fd1 100644 (file)
@@ -111,6 +111,43 @@ public class PersonIdent implements Serializable {
                r.append(offsetMins);
        }
 
+       /**
+        * Sanitize the given string for use in an identity and append to output.
+        * <p>
+        * Trims whitespace from both ends and special characters {@code \n < >} that
+        * interfere with parsing; appends all other characters to the output.
+        * Analogous to the C git function {@code strbuf_addstr_without_crud}.
+        *
+        * @param r
+        *            string builder to append to.
+        * @param str
+        *            input string.
+        */
+       private static void appendSanitized(StringBuilder r, String str) {
+               // Trim any whitespace less than \u0020 as in String#trim().
+               int i = 0;
+               while (i < str.length() && str.charAt(i) <= ' ') {
+                       i++;
+               }
+               int end = str.length();
+               while (end > i && str.charAt(end - 1) <= ' ') {
+                       end--;
+               }
+
+               for (; i < end; i++) {
+                       char c = str.charAt(i);
+                       switch (c) {
+                               case '\n':
+                               case '<':
+                               case '>':
+                                       continue;
+                               default:
+                                       r.append(c);
+                                       break;
+                       }
+               }
+       }
+
        private final String name;
 
        private final String emailAddress;
@@ -305,9 +342,9 @@ public class PersonIdent implements Serializable {
         */
        public String toExternalString() {
                final StringBuilder r = new StringBuilder();
-               r.append(getName().trim());
+               appendSanitized(r, getName());
                r.append(" <"); //$NON-NLS-1$
-               r.append(getEmailAddress().trim());
+               appendSanitized(r, getEmailAddress());
                r.append("> "); //$NON-NLS-1$
                r.append(when / 1000);
                r.append(' ');