From 7547c426dabb342a8adae31f9793c14fb1d073a2 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 6 Jun 2024 11:01:06 -0300 Subject: [PATCH 1/2] Fix some unsafe reads. If they failed to read the number of bytes, the return of `-1` would cause infinite loops, with `-1` always less than the minimum `offset` of `0`. --- .../edu/illinois/library/cantaloupe/image/exif/Reader.java | 5 +---- .../cantaloupe/processor/codec/gif/GIFMetadataReader.java | 6 +----- .../cantaloupe/processor/codec/jpeg/JPEGMetadataReader.java | 6 +----- .../processor/codec/jpeg2000/JPEG2000MetadataReader.java | 6 +----- 4 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/main/java/edu/illinois/library/cantaloupe/image/exif/Reader.java b/src/main/java/edu/illinois/library/cantaloupe/image/exif/Reader.java index bc4261823..1c4ba8037 100644 --- a/src/main/java/edu/illinois/library/cantaloupe/image/exif/Reader.java +++ b/src/main/java/edu/illinois/library/cantaloupe/image/exif/Reader.java @@ -155,10 +155,7 @@ private Directory read(TagSet tagSet) throws IOException { private byte[] readBytes(int length) throws IOException { byte[] data = new byte[length]; - int n, offset = 0; - while ((n = inputStream.read(data, offset, data.length - offset)) < offset) { - offset += n; - } + inputStream.readFully(data); return data; } diff --git a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/gif/GIFMetadataReader.java b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/gif/GIFMetadataReader.java index 1978807d2..14887dad3 100644 --- a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/gif/GIFMetadataReader.java +++ b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/gif/GIFMetadataReader.java @@ -340,11 +340,7 @@ private void readPlainTextExtension() throws IOException { private byte[] read(int length) throws IOException { byte[] data = new byte[length]; - int n, offset = 0; - while ((n = inputStream.read( - data, offset, data.length - offset)) < offset) { - offset += n; - } + inputStream.readFully(data); return data; } diff --git a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg/JPEGMetadataReader.java b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg/JPEGMetadataReader.java index b54056c0c..44be18b2d 100644 --- a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg/JPEGMetadataReader.java +++ b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg/JPEGMetadataReader.java @@ -296,11 +296,7 @@ private void readAPP14Segment() throws IOException { private byte[] read(int length) throws IOException { byte[] data = new byte[length]; - int n, offset = 0; - while ((n = inputStream.read( - data, offset, data.length - offset)) < offset) { - offset += n; - } + inputStream.readFully(data); return data; } diff --git a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg2000/JPEG2000MetadataReader.java b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg2000/JPEG2000MetadataReader.java index ab9252d2a..24da4bef5 100644 --- a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg2000/JPEG2000MetadataReader.java +++ b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg2000/JPEG2000MetadataReader.java @@ -434,11 +434,7 @@ private void readCOCSegment() throws IOException { private byte[] read(int length) throws IOException { byte[] data = new byte[length]; - int n, offset = 0; - while ((n = inputStream.read( - data, offset, data.length - offset)) < offset) { - offset += n; - } + inputStream.readFully(data); return data; } From 73119cd675173997ad73f80737da65a633d85600 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 31 Jul 2024 13:18:26 -0300 Subject: [PATCH 2/2] Attempt to wrap JPEG2000 reads to consistently throw SourceFormatException. --- .../jpeg2000/JPEG2000MetadataReader.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg2000/JPEG2000MetadataReader.java b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg2000/JPEG2000MetadataReader.java index 24da4bef5..ecf2b947f 100644 --- a/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg2000/JPEG2000MetadataReader.java +++ b/src/main/java/edu/illinois/library/cantaloupe/processor/codec/jpeg2000/JPEG2000MetadataReader.java @@ -8,6 +8,7 @@ import javax.imageio.stream.ImageInputStream; import javax.xml.bind.DatatypeConverter; +import java.io.EOFException; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -268,23 +269,29 @@ private void readData() throws IOException { throw new IllegalStateException("Source not set"); } - inputStream.mark(); - byte[] bytes = read(JP2_SIGNATURE.length); - if (!Arrays.equals(JP2_SIGNATURE, bytes)) { - String hexStr = DatatypeConverter.printHexBinary(bytes); - throw new SourceFormatException("Invalid signature: " + hexStr + - " (is this a JP2?)"); - } - inputStream.reset(); + try { + inputStream.mark(); + byte[] bytes = read(JP2_SIGNATURE.length); + if (!Arrays.equals(JP2_SIGNATURE, bytes)) { + String hexStr = DatatypeConverter.printHexBinary(bytes); + throw new SourceFormatException("Invalid signature: " + hexStr + + " (is this a JP2?)"); + } + inputStream.reset(); - final Stopwatch watch = new Stopwatch(); - while (readBox() != -1) { - // Read boxes. - isReadAttempted = true; - } + final Stopwatch watch = new Stopwatch(); + + while (readBox() != -1) { + // Read boxes. + isReadAttempted = true; + } - LOGGER.debug("Read in {}: {}", watch, this); + LOGGER.debug("Read in {}: {}", watch, this); + } + catch (EOFException e) { + throw (SourceFormatException)(new SourceFormatException("JP2 appears to be corrupt; encountered EOF.").initCause(e)); + } } private int readBox() throws IOException {