#645 AAIOBE in CCITTFaxDecoderStream now wrapped in IOException

(cherry picked from commit 3911191b0442b0f818111344d9ac74e514363f77)
This commit is contained in:
Harald Kuhr 2021-12-11 17:48:57 +01:00
parent fdbbcc54a8
commit a39bca4d2f
3 changed files with 29 additions and 5 deletions

View File

@ -30,14 +30,14 @@
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.lang.Validate;
import java.io.EOFException;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import com.twelvemonkeys.lang.Validate;
/**
* CCITT Modified Huffman RLE, Group 3 (T4) and Group 4 (T6) fax compression.
*
@ -198,6 +198,10 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
try {
decodeRow();
}
catch (ArrayIndexOutOfBoundsException e) {
// Mask the AIOOBE as an IOException
throw new IOException("Malformed CCITT stream", e);
}
catch (EOFException e) {
// TODO: Rewrite to avoid throw/catch for normal flow...
if (decodedLength != 0) {

View File

@ -253,7 +253,7 @@ public class CCITTFaxDecoderStreamTest {
@Test
public void testDecodeMissingRows() throws IOException {
// See https://github.com/haraldk/TwelveMonkeys/pull/225 and https://github.com/haraldk/TwelveMonkeys/issues/232
InputStream inputStream = getClass().getResourceAsStream("/tiff/ccitt_tolessrows.tif");
InputStream inputStream = getResourceAsStream("/tiff/ccitt_tolessrows.tif");
// Skip until StripOffsets: 8
for (int i = 0; i < 8; i++) {
@ -299,7 +299,7 @@ public class CCITTFaxDecoderStreamTest {
public void testMoreChangesThanColumnsFile() throws IOException {
// See https://github.com/haraldk/TwelveMonkeys/issues/328
// 26 changes on 24 columns: H0w1b, H1w1b, ..., H1w0b
InputStream stream = getClass().getResourceAsStream("/tiff/ccitt-too-many-changes.tif");
InputStream stream = getResourceAsStream("/tiff/ccitt-too-many-changes.tif");
// Skip bytes before StripOffsets: 86
for (int i = 0; i < 86; i++) {
@ -336,7 +336,7 @@ public class CCITTFaxDecoderStreamTest {
@Test
public void testG3AOE() throws IOException {
InputStream inputStream = getClass().getResourceAsStream("/tiff/ccitt/g3aoe.tif");
InputStream inputStream = getResourceAsStream("/tiff/ccitt/g3aoe.tif");
// Skip until StripOffsets: 8
for (int i = 0; i < 8; i++) {
@ -353,4 +353,17 @@ public class CCITTFaxDecoderStreamTest {
byte[] bytes = new byte[216 * 1168]; // 1728 x 1168 pixel, 1 bpp => 216 bytes * 1168
new DataInputStream(stream).readFully(bytes);
}
@SuppressWarnings("StatementWithEmptyBody")
@Test(expected = IOException.class)
public void testAIOBEInCorruptStreamShouldThrowIOException() throws IOException {
// From #645
try (InputStream ccittFaxDecoderStream = new CCITTFaxDecoderStream(getResourceAsStream("/ccitt/645.ccitt"), 7, 4, 0, false)) {
while(ccittFaxDecoderStream.read() != -1); // Just read until the end
}
}
private InputStream getResourceAsStream(String name) {
return getClass().getResourceAsStream(name);
}
}

View File

@ -0,0 +1,7 @@
<EFBFBD><EFBFBD>δΨ]LΓ Hΰ„t\eΡΔGΘDn0<6E>£ά―θ<E28095>σ<08><>βθΎGFtGGΔmΡ|<7C>Ρβρ6<1C>ήGD|Η
N΄T<04>JΝΕΡ<>1<><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Μ²θ<C2B2>Ί<>H!eΒ"Ψ4Α":DqC”;#Άρ΄B"&$Κ<1D>@<40>|6)Θ&V{ ΄<10>Aq‡H·!;<3B>ς‡PΪ&8„‰cΠ"θ$&΄GD|Ό<>EZ(<28>#TΕ^|[<5B>`†96<39>σPPα ¤Δ1²?SHpdq<64>,!Ζ!„“#°A$ <20><>
@Η;r±<72>AΔDDπΑ BvR
΅Α$C G<47> @… <20>BVw "c¤%<e~Θθ(s<>1h<31>£ΐ¤#/ΠQ.b0Δ$
ΒD<>8@…""C<E28098>t0„Y|Έt£<74>Κph$<24>Η;<3B>pAF
ώ":<10>8Π<>ΐν<04>΅<><76>ε8bΈ<><CE88>±$9Η<φβΎ" ‰qR<08>ΘΰΉ<΅Θ8βqΒ <0B>ΠA28Λ ¬¨EΠEAP!a5²9<C2B2>Dq—FdG9NS<4E>1HJ›¤&<1C>β1†nM(DDB*<2A>HωΡ<>Ε<08><>H!)α>Pι>%<0E> <0C>ηΓ‘,Γ<>Ο
Λ”X+—"‡ ": ΔYΈ¤‘!Ι<>β<CEB2>rpcƒ.lL8"8.G0Ζ<30>H K<>‰C°ΌDp@„γβ'<27><EFBFBD><7F>