summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKamil Musin <kamilm@google.com>2023-12-05 16:22:08 +0100
committerIvan Frade <ifrade@google.com>2023-12-05 16:00:41 -0800
commitab132937fbd5aadfae5fc271b680a2f7a8e7f3a2 (patch)
treee02f36c68e1f4501012b9d50e8a6fd3752267875
parentf75e8fb4253fc15c7364853b1e88a960a51b2ce1 (diff)
downloadjgit-ab132937fbd5aadfae5fc271b680a2f7a8e7f3a2.tar.gz
jgit-ab132937fbd5aadfae5fc271b680a2f7a8e7f3a2.zip
FooterLine: Protect from ill-formed message
A raw commit message has some headers and then the actual message. RawParseUtils.commitMessage returns the start position of the actual message, or -1 when the message is not raw. FooterLine is not handling this -1 and throws an IndexOutOfBounds exception. Consider than msgB can be -1 when looking for the beginning of the last paragraph. FooterLine javadoc and parameter talk only about "raw" but previous code accepted non-raw messages (used mostly in unit tests) so we need to keep this behavior. Change-Id: I4b88c507e210fdd200a85b01665c8524ab393b00
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java18
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java14
2 files changed, 29 insertions, 3 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
index ca6fd4644e..a6808f6351 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
@@ -80,6 +80,24 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
+ public void testNoFooters_noRawMsg_SingleLineNoHeaders() {
+ String noRawMsg = "commit message with no header lines\n";
+ List<FooterLine> footers = FooterLine.fromMessage(noRawMsg);
+ assertNotNull(footers);
+ assertEquals(0, footers.size());
+ }
+
+ @Test
+ public void testOneFooter_noRawMsg_MultiParagraphNoHeaders() {
+ String noRawMsg = "subject\n\n"
+ + "Not: footer\n\n"
+ + "Footer: value\n";
+ List<FooterLine> footers = FooterLine.fromMessage(noRawMsg);
+ assertNotNull(footers);
+ assertEquals(1, footers.size());
+ }
+
+ @Test
public void testSignedOffBy_OneUserNoLF() {
String msg = buildMessage("subject\n\nbody of commit\n" + "\n"
+ "Signed-off-by: A. U. Thor <a@example.com>");
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java
index 3968617f8f..d651b63afb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java
@@ -87,8 +87,15 @@ public final class FooterLine {
// Search for the beginning of last paragraph
int parStart = parEnd;
- for (; parStart > msgB && (raw[parStart - 1] != '\n' || raw[parStart - 2] != '\n'); --parStart) {
- // empty
+ for (; parStart > msgB; --parStart) {
+ if (parStart < 2) {
+ // Too close to beginning: this is not a raw message
+ parStart = 0;
+ break;
+ }
+ if (raw[parStart - 1] == '\n' && raw[parStart - 2] == '\n') {
+ break;
+ }
}
for (int ptr = parStart; ptr < parEnd;) {
@@ -101,7 +108,8 @@ public final class FooterLine {
}
// Skip over the ': *' at the end of the key before the value.
- int valStart, valEnd;
+ int valStart;
+ int valEnd;
for (valStart = keyEnd + 1; valStart < raw.length
&& raw[valStart] == ' '; ++valStart) {
// empty