]> source.dussan.org Git - jgit.git/commitdiff
Fix boundary conditions in AutoCRLFOutputStream 87/11887/2
authorRobin Rosenberg <robin.rosenberg@dewire.com>
Sun, 14 Apr 2013 17:15:53 +0000 (19:15 +0200)
committerRobin Rosenberg <robin.rosenberg@dewire.com>
Sun, 14 Apr 2013 17:53:48 +0000 (19:53 +0200)
This fixes some problems with inputs around the size of the internal
buffer in AutoCRLFOutputStream (8000).

Tests supplied by Robin Stocker.

Bug: 405672
Change-Id: I6147897290392b3bfd4040e8006da39c302a3d49

org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoCRLFOutputStreamTest.java
org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java

index b370468f6bc5e2b4c6587d2931f31505a6bf72fc..df175196fd6b65d4d25013343b2fc497b4a091e6 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2011, Robin Rosenberg
+ * Copyright (C) 2011, 2013 Robin Rosenberg
+ * Copyright (C) 2013 Robin Stocker
  * and other copyright owners as documented in the project's IP log.
  *
  * This program and the accompanying materials are made available
@@ -67,6 +68,29 @@ public class AutoCRLFOutputStreamTest {
                assertNoCrLf("\r\n\r\n\r", "\n\r\n\r");
        }
 
+       @Test
+       public void testBoundary() throws IOException {
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE - 5);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE - 4);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE - 3);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE - 2);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE - 1);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE + 1);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE + 2);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE + 3);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE + 4);
+               assertBoundaryCorrect(AutoCRLFOutputStream.BUFFER_SIZE + 5);
+       }
+
+       private void assertBoundaryCorrect(int size) throws IOException {
+               StringBuilder sb = new StringBuilder(size);
+               for (int i = 0; i < size; i++)
+                       sb.append('a');
+               String s = sb.toString();
+               assertNoCrLf(s, s);
+       }
+
        private void assertNoCrLf(String string, String string2) throws IOException {
                assertNoCrLfHelper(string, string2);
                // \u00e5 = LATIN SMALL LETTER A WITH RING ABOVE
index fe073d83b154cb9879b0173ce19cbe481829d653..1ce277439c517fe60e55b936df07bcd5881d470c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, Robin Rosenberg
+ * Copyright (C) 2011, 2013 Robin Rosenberg
  * and other copyright owners as documented in the project's IP log.
  *
  * This program and the accompanying materials are made available
@@ -55,11 +55,15 @@ import org.eclipse.jgit.diff.RawText;
  */
 public class AutoCRLFOutputStream extends OutputStream {
 
+       static final int BUFFER_SIZE = 8000;
+
        private final OutputStream out;
 
        private int buf = -1;
 
-       private byte[] binbuf = new byte[8000];
+       private byte[] binbuf = new byte[BUFFER_SIZE];
+
+       private byte[] onebytebuf = new byte[1];
 
        private int binbufcnt = 0;
 
@@ -74,29 +78,8 @@ public class AutoCRLFOutputStream extends OutputStream {
 
        @Override
        public void write(int b) throws IOException {
-               int overflow = buffer((byte) b);
-               if (overflow >= 0)
-                       return;
-               if (isBinary) {
-                       out.write(b);
-                       return;
-               }
-               if (b == '\n') {
-                       if (buf == '\r') {
-                               out.write('\n');
-                               buf = -1;
-                       } else if (buf == -1) {
-                               out.write('\r');
-                               out.write('\n');
-                               buf = -1;
-                       }
-               } else if (b == '\r') {
-                       out.write(b);
-                       buf = '\r';
-               } else {
-                       out.write(b);
-                       buf = -1;
-               }
+               onebytebuf[0] = (byte) b;
+               write(onebytebuf, 0, 1);
        }
 
        @Override
@@ -144,15 +127,6 @@ public class AutoCRLFOutputStream extends OutputStream {
                        buf = '\r';
        }
 
-       private int buffer(byte b) throws IOException {
-               if (binbufcnt > binbuf.length)
-                       return 1;
-               binbuf[binbufcnt++] = b;
-               if (binbufcnt == binbuf.length)
-                       decideMode();
-               return 0;
-       }
-
        private int buffer(byte[] b, int off, int len) throws IOException {
                if (binbufcnt > binbuf.length)
                        return len;
@@ -174,7 +148,7 @@ public class AutoCRLFOutputStream extends OutputStream {
 
        @Override
        public void flush() throws IOException {
-               if (binbufcnt < binbuf.length)
+               if (binbufcnt <= binbuf.length)
                        decideMode();
                buf = -1;
                out.flush();