Browse Source

Handle escaped CR-LF in git config files

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>
stable-5.5
Thomas Wolf 6 years ago committed by Matthias Sohn
parent
commit
f24ad3da66
  1. 35
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
  2. 23
      org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java

35
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java

@ -1457,6 +1457,41 @@ public class ConfigTest {
parse("[foo \"bar\" ]\nfoo=bar\n"); 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) private static void assertValueRoundTrip(String value)
throws ConfigInvalidException { throws ConfigInvalidException {
assertValueRoundTrip(value, value); assertValueRoundTrip(value, value);

23
org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java

@ -1413,11 +1413,23 @@ public class Config {
case '"': case '"':
value.append('"'); value.append('"');
continue; continue;
case '\r': {
int next = in.read();
if (next == '\n') {
continue; // CR-LF
} else if (next >= 0) {
in.reset();
}
break;
}
default: default:
throw new ConfigInvalidException(MessageFormat.format( break;
JGitText.get().badEscape,
Character.valueOf(((char) c))));
} }
throw new ConfigInvalidException(
MessageFormat.format(JGitText.get().badEscape,
Character.isAlphabetic(c)
? Character.valueOf(((char) c))
: toUnicodeLiteral(c)));
} }
if ('"' == c) { if ('"' == c) {
@ -1430,6 +1442,11 @@ public class Config {
return value.length() > 0 ? value.toString() : null; 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. * Parses a section of the configuration into an application model object.
* <p> * <p>

Loading…
Cancel
Save