Browse Source

Fix boundary conditions in AutoCRLFOutputStream

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
stable-3.0
Robin Rosenberg 12 years ago
parent
commit
4c638be79f
  1. 26
      org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoCRLFOutputStreamTest.java
  2. 44
      org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java

26
org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoCRLFOutputStreamTest.java

@ -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

44
org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java

@ -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();

Loading…
Cancel
Save