]> source.dussan.org Git - jgit.git/commitdiff
Handle escaped CR-LF in git config files 38/140138/4
authorThomas Wolf <thomas.wolf@paranor.ch>
Fri, 5 Apr 2019 19:33:14 +0000 (21:33 +0200)
committerMatthias Sohn <matthias.sohn@sap.com>
Fri, 7 Jun 2019 23:43:22 +0000 (01:43 +0200)
Canonical git treats CR-LF in config files as LF.[1][2] JGit does so,
too, except when escaped as a line continuation. Correct this and
treat the sequence \-CR-LF as a line continuation.

[1] https://github.com/git/git/commit/db2c075d9
[2] https://github.com/git/git/blob/v2.21.0/config.c#L485

Bug: 545850
Change-Id: I51e7378a22c21b3baa3701163c423d04c900af5a
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java

index 5a4bd886ab9c9801cbb7485db27ecd9e7e8276b2..e3985cc970516f8949a3c28f61b005e29a41b7a9 100644 (file)
@@ -1457,6 +1457,41 @@ public class ConfigTest {
                parse("[foo \"bar\" ]\nfoo=bar\n");
        }
 
+       @Test
+       public void testCrLf() throws ConfigInvalidException {
+               assertEquals("true", parseEscapedValue("true\r\n"));
+       }
+
+       @Test
+       public void testLfContinuation() throws ConfigInvalidException {
+               assertEquals("true", parseEscapedValue("tr\\\nue"));
+       }
+
+       @Test
+       public void testCrCharContinuation() throws ConfigInvalidException {
+               expectedEx.expect(ConfigInvalidException.class);
+               expectedEx.expectMessage("Bad escape: \\u000d");
+               parseEscapedValue("tr\\\rue");
+       }
+
+       @Test
+       public void testCrEOFContinuation() throws ConfigInvalidException {
+               expectedEx.expect(ConfigInvalidException.class);
+               expectedEx.expectMessage("Bad escape: \\u000d");
+               parseEscapedValue("tr\\\r");
+       }
+
+       @Test
+       public void testCrLfContinuation() throws ConfigInvalidException {
+               assertEquals("true", parseEscapedValue("tr\\\r\nue"));
+       }
+
+       @Test
+       public void testWhitespaceContinuation() throws ConfigInvalidException {
+               assertEquals("tr   ue", parseEscapedValue("tr \\\n  ue"));
+               assertEquals("tr   ue", parseEscapedValue("tr \\\r\n  ue"));
+       }
+
        private static void assertValueRoundTrip(String value)
                        throws ConfigInvalidException {
                assertValueRoundTrip(value, value);
index 4726975d07822d731e1859f4e0024bf6e1bcae4b..2c01d603816905374cc3afb8958bd3e104266943 100644 (file)
@@ -1413,11 +1413,23 @@ public class Config {
                                case '"':
                                        value.append('"');
                                        continue;
+                               case '\r': {
+                                       int next = in.read();
+                                       if (next == '\n') {
+                                               continue; // CR-LF
+                                       } else if (next >= 0) {
+                                               in.reset();
+                                       }
+                                       break;
+                               }
                                default:
-                                       throw new ConfigInvalidException(MessageFormat.format(
-                                                       JGitText.get().badEscape,
-                                                       Character.valueOf(((char) c))));
+                                       break;
                                }
+                               throw new ConfigInvalidException(
+                                               MessageFormat.format(JGitText.get().badEscape,
+                                                               Character.isAlphabetic(c)
+                                                                               ? Character.valueOf(((char) c))
+                                                                               : toUnicodeLiteral(c)));
                        }
 
                        if ('"' == c) {
@@ -1430,6 +1442,11 @@ public class Config {
                return value.length() > 0 ? value.toString() : null;
        }
 
+       private static String toUnicodeLiteral(int c) {
+               return String.format("\\u%04x", //$NON-NLS-1$
+                               Integer.valueOf(c));
+       }
+
        /**
         * Parses a section of the configuration into an application model object.
         * <p>