aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java2
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java23
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java26
3 files changed, 38 insertions, 13 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
index ab86bc2e27..aa50697172 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
@@ -368,7 +368,7 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase {
+ "[user]\n"
+ " email = A U Thor <thor@example.com> # Just an example...\n"
+ " name = \"A Thor \\\\ \\\"\\t \"\n"
- + " defaultCheckInComment = \"a many line\\ncomment\\n to test\"\n";
+ + " defaultCheckInComment = a many line\\ncomment\\n to test\n";
assertEquals(expectedStr, new String(IO.readFully(cfg), Constants.CHARSET));
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
index 44714faa70..a952db764f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
@@ -977,14 +977,25 @@ public class ConfigTest {
}
@Test
- public void testEscapeSpecialCharacters() throws ConfigInvalidException {
+ public void testNoEscapeSpecialCharacters() throws ConfigInvalidException {
+ assertValueRoundTrip("x\\y", "x\\\\y");
+ assertValueRoundTrip("x\"y", "x\\\"y");
+ assertValueRoundTrip("x\ny", "x\\ny");
+ assertValueRoundTrip("x\ty", "x\\ty");
+ assertValueRoundTrip("x\by", "x\\by");
+ }
+
+ @Test
+ public void testParseLiteralBackspace() throws ConfigInvalidException {
+ // This is round-tripped with an escape sequence by JGit, but C git writes
+ // it out as a literal backslash.
+ assertEquals("x\by", parseEscapedValue("x\by"));
+ }
+
+ @Test
+ public void testEscapeCommentCharacters() throws ConfigInvalidException {
assertValueRoundTrip("x#y", "\"x#y\"");
assertValueRoundTrip("x;y", "\"x;y\"");
- assertValueRoundTrip("x\\y", "\"x\\\\y\"");
- assertValueRoundTrip("x\"y", "\"x\\\"y\"");
- assertValueRoundTrip("x\ny", "\"x\\ny\"");
- assertValueRoundTrip("x\ty", "\"x\\ty\"");
- assertValueRoundTrip("x\by", "\"x\\by\"");
}
@Test
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
index 39161214de..f46b7f37a8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
@@ -155,9 +155,18 @@ public class Config {
StringBuilder r = new StringBuilder(x.length());
for (int k = 0; k < x.length(); k++) {
char c = x.charAt(k);
- boolean thisCharNeedsQuote = true;
-
- // git-config(1) lists the limited set of supported escape sequences.
+ // git-config(1) lists the limited set of supported escape sequences, but
+ // the documentation is otherwise not especially normative. In particular,
+ // which ones of these produce and/or require escaping and/or quoting
+ // around them is not documented and was discovered by trial and error.
+ // In summary:
+ //
+ // * Quotes are only required if there is leading/trailing whitespace or a
+ // comment character.
+ // * Bytes that have a supported escape sequence are escaped, except for
+ // \b for some reason which isn't.
+ // * Needing an escape sequence is not sufficient reason to quote the
+ // value.
switch (c) {
case '\0':
// Unix command line calling convention cannot pass a '\0' as an
@@ -175,25 +184,30 @@ public class Config {
break;
case '\b':
+ // Doesn't match `git config foo.bar $'x\by'`, which doesn't escape the
+ // \x08, but since both escaped and unescaped forms are readable, we'll
+ // prefer internal consistency here.
r.append('\\').append('b');
break;
case '\\':
+ r.append('\\').append('\\');
+ break;
+
case '"':
- r.append('\\').append(c);
+ r.append('\\').append('"');
break;
case '#':
case ';':
+ needQuote = true;
r.append(c);
break;
default:
- thisCharNeedsQuote = false;
r.append(c);
break;
}
- needQuote |= thisCharNeedsQuote;
}
return needQuote ? '"' + r.toString() + '"' : r.toString();