8154093: [TIFF] NPE when reading LZW-compressed image
LZW decompressor was ignoring the value of the FillOrder field. Reviewed-by: prr
This commit is contained in:
parent
099928305c
commit
9ecae6db48
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -101,7 +101,8 @@ class TIFFFaxDecompressor extends TIFFDecompressor {
|
|||||||
0xff // 8
|
0xff // 8
|
||||||
};
|
};
|
||||||
|
|
||||||
// Table to be used when fillOrder = 2, for flipping bytes.
|
// Table to be used for flipping bytes when fillOrder is
|
||||||
|
// BaselineTIFFTagSet.FILL_ORDER_RIGHT_TO_LEFT (2).
|
||||||
static byte flipTable[] = {
|
static byte flipTable[] = {
|
||||||
0, -128, 64, -64, 32, -96, 96, -32,
|
0, -128, 64, -64, 32, -96, 96, -32,
|
||||||
16, -112, 80, -48, 48, -80, 112, -16,
|
16, -112, 80, -48, 48, -80, 112, -16,
|
||||||
@ -597,7 +598,8 @@ class TIFFFaxDecompressor extends TIFFDecompressor {
|
|||||||
TIFFField f;
|
TIFFField f;
|
||||||
|
|
||||||
f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER);
|
f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER);
|
||||||
this.fillOrder = f == null ? 1 : f.getAsInt(0);
|
this.fillOrder = f == null ?
|
||||||
|
BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT : f.getAsInt(0);
|
||||||
|
|
||||||
f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION);
|
f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION);
|
||||||
this.compression = f == null ?
|
this.compression = f == null ?
|
||||||
@ -612,7 +614,7 @@ class TIFFFaxDecompressor extends TIFFDecompressor {
|
|||||||
f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_T6_OPTIONS);
|
f = tmetadata.getTIFFField(BaselineTIFFTagSet.TAG_T6_OPTIONS);
|
||||||
this.t6Options = f == null ? 0 : f.getAsInt(0);
|
this.t6Options = f == null ? 0 : f.getAsInt(0);
|
||||||
} else {
|
} else {
|
||||||
this.fillOrder = 1; // MSB-to-LSB
|
this.fillOrder = BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT;
|
||||||
|
|
||||||
this.compression = BaselineTIFFTagSet.COMPRESSION_CCITT_RLE; // RLE
|
this.compression = BaselineTIFFTagSet.COMPRESSION_CCITT_RLE; // RLE
|
||||||
|
|
||||||
@ -1458,7 +1460,7 @@ class TIFFFaxDecompressor extends TIFFDecompressor {
|
|||||||
int l = data.length - 1;
|
int l = data.length - 1;
|
||||||
int bp = this.bytePointer;
|
int bp = this.bytePointer;
|
||||||
|
|
||||||
if (fillOrder == 1) {
|
if (fillOrder == BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT) {
|
||||||
b = data[bp];
|
b = data[bp];
|
||||||
|
|
||||||
if (bp == l) {
|
if (bp == l) {
|
||||||
@ -1471,7 +1473,7 @@ class TIFFFaxDecompressor extends TIFFDecompressor {
|
|||||||
next = data[bp + 1];
|
next = data[bp + 1];
|
||||||
next2next = data[bp + 2];
|
next2next = data[bp + 2];
|
||||||
}
|
}
|
||||||
} else if (fillOrder == 2) {
|
} else if (fillOrder == BaselineTIFFTagSet.FILL_ORDER_RIGHT_TO_LEFT) {
|
||||||
b = flipTable[data[bp] & 0xff];
|
b = flipTable[data[bp] & 0xff];
|
||||||
|
|
||||||
if (bp == l) {
|
if (bp == l) {
|
||||||
@ -1527,14 +1529,14 @@ class TIFFFaxDecompressor extends TIFFDecompressor {
|
|||||||
int l = data.length - 1;
|
int l = data.length - 1;
|
||||||
int bp = this.bytePointer;
|
int bp = this.bytePointer;
|
||||||
|
|
||||||
if (fillOrder == 1) {
|
if (fillOrder == BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT) {
|
||||||
b = data[bp];
|
b = data[bp];
|
||||||
if (bp == l) {
|
if (bp == l) {
|
||||||
next = 0x00;
|
next = 0x00;
|
||||||
} else {
|
} else {
|
||||||
next = data[bp + 1];
|
next = data[bp + 1];
|
||||||
}
|
}
|
||||||
} else if (fillOrder == 2) {
|
} else if (fillOrder == BaselineTIFFTagSet.FILL_ORDER_RIGHT_TO_LEFT) {
|
||||||
b = flipTable[data[bp] & 0xff];
|
b = flipTable[data[bp] & 0xff];
|
||||||
if (bp == l) {
|
if (bp == l) {
|
||||||
next = 0x00;
|
next = 0x00;
|
||||||
|
@ -1174,7 +1174,14 @@ public class TIFFImageReader extends ImageReader {
|
|||||||
int predictor = ((predictorField == null)
|
int predictor = ((predictorField == null)
|
||||||
? BaselineTIFFTagSet.PREDICTOR_NONE
|
? BaselineTIFFTagSet.PREDICTOR_NONE
|
||||||
: predictorField.getAsInt(0));
|
: predictorField.getAsInt(0));
|
||||||
this.decompressor = new TIFFLZWDecompressor(predictor);
|
|
||||||
|
TIFFField fillOrderField
|
||||||
|
= imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER);
|
||||||
|
int fillOrder = ((fillOrderField == null)
|
||||||
|
? BaselineTIFFTagSet.FILL_ORDER_LEFT_TO_RIGHT
|
||||||
|
: fillOrderField.getAsInt(0));
|
||||||
|
|
||||||
|
this.decompressor = new TIFFLZWDecompressor(predictor, fillOrder);
|
||||||
} else if (compression
|
} else if (compression
|
||||||
== BaselineTIFFTagSet.COMPRESSION_JPEG) {
|
== BaselineTIFFTagSet.COMPRESSION_JPEG) {
|
||||||
this.decompressor = new TIFFJPEGDecompressor();
|
this.decompressor = new TIFFJPEGDecompressor();
|
||||||
|
@ -30,6 +30,10 @@ import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
|
|||||||
|
|
||||||
class TIFFLZWDecompressor extends TIFFDecompressor {
|
class TIFFLZWDecompressor extends TIFFDecompressor {
|
||||||
|
|
||||||
|
private static final int CLEAR_CODE = 256;
|
||||||
|
private static final int EOI_CODE = 257;
|
||||||
|
private static final int FIRST_CODE = 258;
|
||||||
|
|
||||||
private static final int andTable[] = {
|
private static final int andTable[] = {
|
||||||
511,
|
511,
|
||||||
1023,
|
1023,
|
||||||
@ -39,6 +43,10 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
|
|||||||
|
|
||||||
private int predictor;
|
private int predictor;
|
||||||
|
|
||||||
|
// whether to reverse the bits in each byte of the input data, i.e.,
|
||||||
|
// convert right-to-left fill order (lsb) to left-to-right (msb).
|
||||||
|
private boolean flipBits;
|
||||||
|
|
||||||
private byte[] srcData;
|
private byte[] srcData;
|
||||||
private byte[] dstData;
|
private byte[] dstData;
|
||||||
|
|
||||||
@ -51,7 +59,8 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
|
|||||||
private int nextData = 0;
|
private int nextData = 0;
|
||||||
private int nextBits = 0;
|
private int nextBits = 0;
|
||||||
|
|
||||||
public TIFFLZWDecompressor(int predictor) throws IIOException {
|
public TIFFLZWDecompressor(int predictor, int fillOrder)
|
||||||
|
throws IIOException {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
if (predictor != BaselineTIFFTagSet.PREDICTOR_NONE &&
|
if (predictor != BaselineTIFFTagSet.PREDICTOR_NONE &&
|
||||||
@ -62,6 +71,8 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.predictor = predictor;
|
this.predictor = predictor;
|
||||||
|
|
||||||
|
flipBits = fillOrder == BaselineTIFFTagSet.FILL_ORDER_RIGHT_TO_LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void decodeRaw(byte[] b,
|
public void decodeRaw(byte[] b,
|
||||||
@ -88,6 +99,12 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
|
|||||||
byte[] sdata = new byte[byteCount];
|
byte[] sdata = new byte[byteCount];
|
||||||
stream.readFully(sdata);
|
stream.readFully(sdata);
|
||||||
|
|
||||||
|
if (flipBits) {
|
||||||
|
for (int i = 0; i < byteCount; i++) {
|
||||||
|
sdata[i] = TIFFFaxDecompressor.flipTable[sdata[i] & 0xff];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8;
|
int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8;
|
||||||
byte[] buf;
|
byte[] buf;
|
||||||
int bufOffset;
|
int bufOffset;
|
||||||
@ -133,11 +150,11 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
|
|||||||
int code, oldCode = 0;
|
int code, oldCode = 0;
|
||||||
byte[] string;
|
byte[] string;
|
||||||
|
|
||||||
while ((code = getNextCode()) != 257) {
|
while ((code = getNextCode()) != EOI_CODE) {
|
||||||
if (code == 256) {
|
if (code == CLEAR_CODE) {
|
||||||
initializeStringTable();
|
initializeStringTable();
|
||||||
code = getNextCode();
|
code = getNextCode();
|
||||||
if (code == 257) {
|
if (code == EOI_CODE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,12 +203,12 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
|
|||||||
public void initializeStringTable() {
|
public void initializeStringTable() {
|
||||||
stringTable = new byte[4096][];
|
stringTable = new byte[4096][];
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < CLEAR_CODE; i++) {
|
||||||
stringTable[i] = new byte[1];
|
stringTable[i] = new byte[1];
|
||||||
stringTable[i][0] = (byte)i;
|
stringTable[i][0] = (byte)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
tableIndex = 258;
|
tableIndex = FIRST_CODE;
|
||||||
bitsToGet = 9;
|
bitsToGet = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +298,7 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
|
|||||||
return code;
|
return code;
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
// Strip not terminated as expected: return EndOfInformation code.
|
// Strip not terminated as expected: return EndOfInformation code.
|
||||||
return 257;
|
return EOI_CODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user