Skip to content

Commit 39d7ac2

Browse files
committed
test: add edge-case tests for CompressionCodec
1 parent eb55a84 commit 39d7ac2

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

logstash-core/src/main/java/org/logstash/ackedqueue/AbstractDeflateAwareCompressionCodec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public byte[] decode(final byte[] data) throws IOException {
101101
int count = inflater.inflate(intermediateBuffer);
102102
baos.write(intermediateBuffer, 0, count);
103103
} catch (DataFormatException e) {
104-
throw new RuntimeException("Failed to decode", e);
104+
throw new IOException("Failed to decode", e);
105105
}
106106
} while (!inflater.finished());
107107

logstash-core/src/test/java/org/logstash/ackedqueue/CompressionCodecTest.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
import org.junit.Test;
55
import org.mockito.Mockito;
66

7+
import java.security.SecureRandom;
78
import java.util.Arrays;
89
import java.util.Set;
910
import java.util.zip.Deflater;
1011

1112
import static org.hamcrest.MatcherAssert.assertThat;
1213
import static org.hamcrest.Matchers.*;
14+
import static org.junit.Assert.assertThrows;
1315
import static org.mockito.Matchers.argThat;
1416

1517
public class CompressionCodecTest {
@@ -137,6 +139,69 @@ public void testSizeCompressionCodecLogging() throws Exception {
137139
Mockito.verify(mockLogger).info(argThat(stringContainsInOrder("compression support", "enabled", "size")));
138140
}
139141

142+
@Test(timeout=1000)
143+
public void testCompressionCodecDecodeTailTruncated() throws Exception {
144+
final byte[] truncatedInput = copyWithTruncatedTail(DEFLATE_BALANCED_BYTES.bytes(), 32);
145+
146+
final RuntimeException thrownException = assertThrows(RuntimeException.class, () -> codecNone.decode(truncatedInput));
147+
assertThat(thrownException.getMessage(), containsString("IOException while decoding"));
148+
final Throwable rootCause = extractRootCause(thrownException);
149+
assertThat(rootCause.getMessage(), anyOf(containsString("prematurely reached end"), containsString("incorrect data check")));
150+
}
151+
152+
byte[] copyWithTruncatedTail(final byte[] input, final int tailSize) {
153+
int startIndex = (input.length < tailSize) ? 0 : input.length - tailSize;
154+
155+
final byte[] result = Arrays.copyOf(input, input.length);
156+
Arrays.fill(result, startIndex, result.length, (byte) 0);
157+
158+
return result;
159+
}
160+
161+
@Test(timeout=1000)
162+
public void testCompressionCodecDecodeTailScrambled() throws Exception {
163+
final byte[] scrambledInput = copyWithScrambledTail(DEFLATE_BALANCED_BYTES.bytes(), 32);
164+
165+
final RuntimeException thrownException = assertThrows(RuntimeException.class, () -> codecNone.decode(scrambledInput));
166+
assertThat(thrownException.getMessage(), containsString("IOException while decoding"));
167+
final Throwable rootCause = extractRootCause(thrownException);
168+
assertThat(rootCause.getMessage(), anyOf(containsString("prematurely reached end"), containsString("incorrect data check")));
169+
}
170+
171+
byte[] copyWithScrambledTail(final byte[] input, final int tailSize) {
172+
final SecureRandom secureRandom = new SecureRandom();
173+
int startIndex = (input.length < tailSize) ? 0 : input.length - tailSize;
174+
175+
byte[] randomBytes = new byte[input.length - startIndex];
176+
secureRandom.nextBytes(randomBytes);
177+
178+
final byte[] result = Arrays.copyOf(input, input.length);
179+
System.arraycopy(randomBytes, 0, result, startIndex, randomBytes.length);
180+
181+
return result;
182+
}
183+
184+
@Test(timeout=1000)
185+
public void testCompressionDecodeTailNullPadded() throws Exception {
186+
final byte[] nullPaddedInput = copyWithNullPaddedTail(DEFLATE_BALANCED_BYTES.bytes(), 32);
187+
188+
assertThat(codecNone.decode(nullPaddedInput), is(equalTo(RAW_BYTES.bytes())));
189+
}
190+
191+
byte[] copyWithNullPaddedTail(final byte[] input, final int tailSize) {
192+
return Arrays.copyOf(input, Math.addExact(input.length, tailSize));
193+
}
194+
195+
Throwable extractRootCause(final Throwable throwable) {
196+
Throwable current;
197+
Throwable cause = throwable;
198+
do {
199+
current = cause;
200+
cause = current.getCause();
201+
} while (cause != null && cause != current);
202+
return current;
203+
}
204+
140205
void assertDecodesRaw(final CompressionCodec codec) {
141206
assertThat(codec.decode(RAW_BYTES.bytes()), is(equalTo(RAW_BYTES.bytes())));
142207
}

0 commit comments

Comments
 (0)