mirror of https://github.com/apache/poi.git
handle case where toByteArray truncates stream because max len is less than stream len
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1898876 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1efd809e6c
commit
3573e5c44f
|
@ -230,7 +230,7 @@ public final class IOUtils {
|
||||||
checkLength(length, derivedMaxLength);
|
checkLength(length, derivedMaxLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int derivedLen = Math.min(length, derivedMaxLength);
|
final int derivedLen = isLengthKnown ? Math.min(length, derivedMaxLength) : derivedMaxLength;
|
||||||
final int byteArrayInitLen = calculateByteArrayInitLength(isLengthKnown, length, derivedMaxLength);
|
final int byteArrayInitLen = calculateByteArrayInitLength(isLengthKnown, length, derivedMaxLength);
|
||||||
final int internalBufferLen = DEFAULT_BUFFER_SIZE;
|
final int internalBufferLen = DEFAULT_BUFFER_SIZE;
|
||||||
try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream(byteArrayInitLen)) {
|
try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream(byteArrayInitLen)) {
|
||||||
|
@ -242,18 +242,15 @@ public final class IOUtils {
|
||||||
if (readBytes > 0) {
|
if (readBytes > 0) {
|
||||||
baos.write(buffer, 0, readBytes);
|
baos.write(buffer, 0, readBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkByteSizeLimit(totalBytes);
|
checkByteSizeLimit(totalBytes);
|
||||||
} while (totalBytes < derivedLen && readBytes > -1);
|
} while (totalBytes < derivedLen && readBytes > -1);
|
||||||
|
|
||||||
if (checkEOFException) {
|
if (BYTE_ARRAY_MAX_OVERRIDE < 0 && readBytes > -1 && !isLengthKnown && stream.read() >= 0) {
|
||||||
if (derivedMaxLength != Integer.MAX_VALUE && totalBytes == derivedMaxLength) {
|
throwRecordTruncationException(derivedMaxLength);
|
||||||
throw new IOException("MaxLength (" + derivedMaxLength + ") reached - stream seems to be invalid.");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (derivedLen != Integer.MAX_VALUE && totalBytes < derivedLen) {
|
if (checkEOFException && derivedLen != Integer.MAX_VALUE && totalBytes < derivedLen) {
|
||||||
throw new EOFException("unexpected EOF - expected len: " + derivedLen + " - actual len: " + totalBytes);
|
throw new EOFException("unexpected EOF - expected len: " + derivedLen + " - actual len: " + totalBytes);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
|
@ -586,7 +583,7 @@ public final class IOUtils {
|
||||||
* Simple utility function to check that you haven't hit EOF
|
* Simple utility function to check that you haven't hit EOF
|
||||||
* when reading a byte.
|
* when reading a byte.
|
||||||
*
|
*
|
||||||
* @param is inputstream to read
|
* @param is input stream to read
|
||||||
* @return byte read, unless
|
* @return byte read, unless
|
||||||
* @throws IOException on IOException or EOF if -1 is read
|
* @throws IOException on IOException or EOF if -1 is read
|
||||||
*/
|
*/
|
||||||
|
@ -608,4 +605,14 @@ public final class IOUtils {
|
||||||
length, maxLength));
|
length, maxLength));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void throwRecordTruncationException(final int maxLength) {
|
||||||
|
throw new RecordFormatException(String.format(Locale.ROOT, "Tried to read data but the maximum length " +
|
||||||
|
"for this record type is %,d.\n" +
|
||||||
|
"If the file is not corrupt or large, please open an issue on bugzilla to request \n" +
|
||||||
|
"increasing the maximum allowable size for this record type.\n"+
|
||||||
|
"As a temporary workaround, consider setting a higher override value with " +
|
||||||
|
"IOUtils.setByteArrayMaxOverride()", maxLength));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,6 +151,30 @@ final class TestIOUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testToByteArrayMaxLengthWithByteArrayInitLenShort() throws IOException {
|
||||||
|
final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
|
||||||
|
IOUtils.setMaxByteArrayInitSize(2);
|
||||||
|
try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
|
||||||
|
assertEquals(2, IOUtils.getMaxByteArrayInitSize());
|
||||||
|
assertArrayEquals(array, IOUtils.toByteArrayWithMaxLength(is, 7));
|
||||||
|
} finally {
|
||||||
|
IOUtils.setMaxByteArrayInitSize(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testToByteArrayMaxLengthWithByteArrayInitLenLong() throws IOException {
|
||||||
|
final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
|
||||||
|
IOUtils.setMaxByteArrayInitSize(8192);
|
||||||
|
try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
|
||||||
|
assertEquals(8192, IOUtils.getMaxByteArrayInitSize());
|
||||||
|
assertArrayEquals(array, IOUtils.toByteArrayWithMaxLength(is, 7));
|
||||||
|
} finally {
|
||||||
|
IOUtils.setMaxByteArrayInitSize(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testToByteArrayMaxLengthLongerThanArray() throws IOException {
|
void testToByteArrayMaxLengthLongerThanArray() throws IOException {
|
||||||
final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
|
final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
|
||||||
|
@ -163,7 +187,18 @@ final class TestIOUtils {
|
||||||
void testToByteArrayMaxLengthShorterThanArray() throws IOException {
|
void testToByteArrayMaxLengthShorterThanArray() throws IOException {
|
||||||
final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
|
final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
|
||||||
try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
|
try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
|
||||||
assertArrayEquals(new byte[]{1, 2, 3}, IOUtils.toByteArrayWithMaxLength(is, 3));
|
assertThrows(RecordFormatException.class, () -> IOUtils.toByteArrayWithMaxLength(is, 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testToByteArrayMaxLengthShorterThanArrayWithByteArrayOverride() throws IOException {
|
||||||
|
final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
|
||||||
|
IOUtils.setByteArrayMaxOverride(30 * 1024 * 1024);
|
||||||
|
try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
|
||||||
|
assertArrayEquals(array, IOUtils.toByteArrayWithMaxLength(is, 3));
|
||||||
|
} finally {
|
||||||
|
IOUtils.setByteArrayMaxOverride(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue