diff options
author | Dave Borowitz <dborowitz@google.com> | 2016-04-29 11:10:36 -0400 |
---|---|---|
committer | Dave Borowitz <dborowitz@google.com> | 2016-04-29 11:27:14 -0400 |
commit | 125a8959d2b639dbb8f4665335f369f67c455d74 (patch) | |
tree | 0209ea1663cc0d52bc0e5947168adf12d387d56e | |
parent | 773f9661d0634fb3ad69466c0f0ec4d65cb2122d (diff) | |
download | jgit-125a8959d2b639dbb8f4665335f369f67c455d74.tar.gz jgit-125a8959d2b639dbb8f4665335f369f67c455d74.zip |
PersonIdent: Strip some special chars from external strings
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
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java | 41 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java | 41 |
2 files changed, 76 insertions, 6 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java index 48d2c480a9..86d8206b36 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java @@ -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(" <>")); + } + } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java index aa304634ba..f352f39968 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java @@ -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(' '); |