]> source.dussan.org Git - jgit.git/commitdiff
Recognize CRLF when parsing the short message of a commit or tag 76/15576/2
authorRobin Rosenberg <robin.rosenberg@dewire.com>
Sat, 30 Mar 2013 10:03:33 +0000 (11:03 +0100)
committerMatthias Sohn <matthias.sohn@sap.com>
Wed, 21 Aug 2013 12:44:46 +0000 (14:44 +0200)
Bug: 400707
Change-Id: I9b09bb88528af465018fc0278f5441f7e6b75986

org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
org.eclipse.jgit.test/tst/org/eclipse/jgit/util/StringUtilsTest.java
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java
org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java

index 574f85c91afdff627f44da986715b6ab9331be4d..beda2a7b97b5eefecee6410632cd4b323b56119f 100644 (file)
@@ -383,6 +383,19 @@ public class RevCommitParseTest extends RepositoryTestCase {
                assertEquals(src.getMessage(), p.getFullMessage());
        }
 
+       @Test
+       public void testParse_GitStyleMessageWithCRLF() throws Exception {
+               final String shortMsgIn = "This fixes a\r\nbug.\r\n\r\n";
+               final String shortMsg = "This fixes a bug.";
+               final String body = "We do it with magic and pixie dust\r\nand stuff.\r\n"
+                               + "\r\n\r\n"
+                               + "Signed-off-by: A U. Thor <author@example.com>\r\n";
+               final String fullMsg = shortMsgIn + "\r\n" + "\r\n" + body;
+               final RevCommit c = create(fullMsg);
+               assertEquals(fullMsg, c.getFullMessage());
+               assertEquals(shortMsg, c.getShortMessage());
+       }
+
        private static ObjectId id(final String str) {
                return ObjectId.fromString(str);
        }
index d7b92ade9da7badc00e9ca1c60ecca70762ea5c0..86fed22afe6fc9e339d8b66aa68e0f4735778d17 100644 (file)
@@ -91,4 +91,16 @@ public class StringUtilsTest {
                assertTrue(StringUtils.equalsIgnoreCase("A", "a"));
                assertTrue(StringUtils.equalsIgnoreCase("a", "A"));
        }
+
+       @Test
+       public void testReplaceLineBreaks() {
+               assertEquals("a b c ",
+                               StringUtils.replaceLineBreaksWithSpace("a b\nc\r"));
+               assertEquals("a b c ",
+                               StringUtils.replaceLineBreaksWithSpace("a b\nc\n"));
+               assertEquals("a b c ",
+                               StringUtils.replaceLineBreaksWithSpace("a b\nc\r\n"));
+               assertEquals("a b c d",
+                               StringUtils.replaceLineBreaksWithSpace("a\r\nb\nc d"));
+       }
 }
index 9f2ccfd97e0afdf764a87dbadc1c54d6eb673d74..93d28aaf5a222181e14f9802d38037d28f010441 100644 (file)
@@ -59,6 +59,7 @@ import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.util.RawParseUtils;
+import org.eclipse.jgit.util.StringUtils;
 
 /** A commit reference to a commit in the DAG. */
 public class RevCommit extends RevObject {
@@ -421,7 +422,7 @@ public class RevCommit extends RevObject {
                final int msgE = RawParseUtils.endOfParagraph(raw, msgB);
                String str = RawParseUtils.decode(enc, raw, msgB, msgE);
                if (hasLF(raw, msgB, msgE))
-                       str = str.replace('\n', ' ');
+                       str = StringUtils.replaceLineBreaksWithSpace(str);
                return str;
        }
 
index 12693a03e2cdd7ce68fb6952a22d455c4e5a0140..1a59b440c3c23446f59d10f84ee5ce1866f1b69c 100644 (file)
@@ -58,6 +58,7 @@ import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.util.MutableInteger;
 import org.eclipse.jgit.util.RawParseUtils;
+import org.eclipse.jgit.util.StringUtils;
 
 /** An annotated tag. */
 public class RevTag extends RevObject {
@@ -234,7 +235,7 @@ public class RevTag extends RevObject {
                final int msgE = RawParseUtils.endOfParagraph(raw, msgB);
                String str = RawParseUtils.decode(enc, raw, msgB, msgE);
                if (RevCommit.hasLF(raw, msgB, msgE))
-                       str = str.replace('\n', ' ');
+                       str = StringUtils.replaceLineBreaksWithSpace(str);
                return str;
        }
 
index 9114d500ee316ac743fd727ae6ecdadad05c40a8..2f9a6d12c7935e824144ce378b5c424e4db3ce32 100644 (file)
@@ -1058,7 +1058,7 @@ public final class RawParseUtils {
        /**
         * Locate the end of a paragraph.
         * <p>
-        * A paragraph is ended by two consecutive LF bytes.
+        * A paragraph is ended by two consecutive LF bytes or CRLF pairs
         *
         * @param b
         *            buffer to scan.
@@ -1072,9 +1072,11 @@ public final class RawParseUtils {
        public static final int endOfParagraph(final byte[] b, final int start) {
                int ptr = start;
                final int sz = b.length;
-               while (ptr < sz && b[ptr] != '\n')
+               while (ptr < sz && (b[ptr] != '\n' && b[ptr] != '\r'))
                        ptr = nextLF(b, ptr);
-               while (0 < ptr && start < ptr && b[ptr - 1] == '\n')
+               if (ptr > start && b[ptr - 1] == '\n')
+                       ptr--;
+               if (ptr > start && b[ptr - 1] == '\r')
                        ptr--;
                return ptr;
        }
index cb4895025d2a212edb6dc880a2b923a154a50f4f..bfefc50c3b6ee23a49fbf1a2bcc5383069af2eab 100644 (file)
@@ -279,4 +279,30 @@ public final class StringUtils {
        public static boolean isEmptyOrNull(String stringValue) {
                return stringValue == null || stringValue.length() == 0;
        }
+
+       /**
+        * Replace CRLF, CR or LF with a single space.
+        *
+        * @param in
+        *            A string with line breaks
+        * @return in without line breaks
+        */
+       public static String replaceLineBreaksWithSpace(String in) {
+               char[] buf = new char[in.length()];
+               int o = 0;
+               for (int i = 0; i < buf.length; ++i) {
+                       char ch = in.charAt(i);
+                       if (ch == '\r') {
+                               if (i + 1 < buf.length && in.charAt(i + 1) == '\n') {
+                                       buf[o++] = ' ';
+                                       ++i;
+                               } else
+                                       buf[o++] = ' ';
+                       } else if (ch == '\n')
+                               buf[o++] = ' ';
+                       else
+                               buf[o++] = ch;
+               }
+               return new String(buf, 0, o);
+       }
 }