This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push: new 17167a7 Fix a bug in TIFF LZW compression when the code size is about to move to 13 bits (which is illegal) but is immediately followed by a `CLEAR_CODE` (which make it okay). 17167a7 is described below commit 17167a7b18f6f9dc7ba0b1773182214af4ed1295 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Wed Feb 2 00:08:16 2022 +0100 Fix a bug in TIFF LZW compression when the code size is about to move to 13 bits (which is illegal) but is immediately followed by a `CLEAR_CODE` (which make it okay). --- .../apache/sis/internal/storage/inflater/LZW.java | 34 +++++++++++++--------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/LZW.java b/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/LZW.java index 583732f..cf7fe90 100644 --- a/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/LZW.java +++ b/storage/sis-geotiff/src/main/java/org/apache/sis/internal/storage/inflater/LZW.java @@ -115,7 +115,7 @@ final class LZW extends CompressionChannel { */ public LZW(final ChannelDataInput input) { super(input); - sequencesForCodes = new byte[(1 << MAX_CODE_SIZE) - FIRST_ADAPTATIVE_CODE][]; + sequencesForCodes = new byte[(1 << MAX_CODE_SIZE) - OFFSET_TO_MAXIMUM][]; } /** @@ -151,19 +151,17 @@ final class LZW extends CompressionChannel { */ if (pending != null) { final int r = target.remaining(); - if (pending.length <= r) { + final int n = pending.length; + if (n <= r) { target.put(pending); pending = null; - if (done) return r; + if (done) return n; } else { target.put(pending, 0, r); - pending = Arrays.copyOfRange(pending, r, pending.length); + pending = Arrays.copyOfRange(pending, r, n); return r; // Can not write more than what we just wrote. } - } else { - done |= finished(); - } - if (done) { + } else if (done |= finished()) { return -1; } /* @@ -228,11 +226,21 @@ final class LZW extends CompressionChannel { throw unexpectedData(); } } - sequencesForCodes[nextAvailableEntry] = addToTable; + try { + sequencesForCodes[nextAvailableEntry] = addToTable; + } catch (ArrayIndexOutOfBoundsException e) { + throw (IOException) unexpectedData().initCause(e); + } if (++nextAvailableEntry == maximumIndex) { - maximumIndex = (1 << ++codeSize) - OFFSET_TO_MAXIMUM; - if (codeSize > MAX_CODE_SIZE) { - throw new IOException(); + if (codeSize < MAX_CODE_SIZE) { + maximumIndex = (1 << ++codeSize) - OFFSET_TO_MAXIMUM; + } else { + /* + * Incrementing the size to 13 bits is an error because the TIFF specification + * limits the size to 12 bits, but some files encode an EOI_CODE or CLEAR_CODE + * immediately after this code. If this is not the case, we will have an index + * out of bounds exception in the next iteration, which is caught above. + */ } } /* @@ -248,7 +256,7 @@ final class LZW extends CompressionChannel { } } previousSequence = write; - done = (code == EOI_CODE && pending != null); + done = (code == EOI_CODE); return target.position() - start; }