You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "quat1024 (via GitHub)" <gi...@apache.org> on 2023/02/14 02:08:37 UTC

[GitHub] [commons-compress] quat1024 commented on pull request #360: pack200: Fix FileBands misusing InputStream#read(byte[])

quat1024 commented on PR #360:
URL: https://github.com/apache/commons-compress/pull/360#issuecomment-1429003923

   A little bit more code digging, just for fun:
   
   * If the provided `InputStream` does not support marking, [`unpack200.Segment` will wrap it in a `BufferedInputStream`](https://github.com/apache/commons-compress/blob/e6930d06cfebbdbee586b863481779b2c4b9b202/src/main/java/org/apache/commons/compress/harmony/unpack200/Segment.java#L499-L502), which does.
   * `BufferedInputStream`, "as a convenience", repeatedly calls `read` until it fills as many bytes of the user-provided input array as possible, using a driver loop not unlike the one in this PR. However, if the wrapped stream's `available` method returns `0` (signaling that further `read` calls will block), `BufferedInputStream` will stop early before filling the entire array (because it doesn't want to block).
   * `LZMACompressorInputStream` [delegates the `available` method](https://github.com/apache/commons-compress/blob/e6930d06cfebbdbee586b863481779b2c4b9b202/src/main/java/org/apache/commons/compress/compressors/lzma/LZMACompressorInputStream.java#L102-L106) through to `xz`'s `LZMAInputStream`.
   * [`LZMAInputStream` doesn't override `available`](https://git.tukaani.org/?p=xz-java.git;a=blob;f=src/org/tukaani/xz/LZMAInputStream.java;h=1432eb1037a513dcd997fb0a946cc978032565aa;hb=HEAD), so the default implementation is used.
   * The default implementation always returns 0,
   * -> causing `BufferedInputStream` to be okay with returning a half-filled buffer,
   * -> triggering the correctness error in the code that assumes `read(byte[])` fills the whole byte array,
   * -> breaking the file parse.
   
   A cheeky workaround is to wrap the stream provided to `Pack200CompressorInputStream` in one that returns `false` in `markSupported` and `Integer.MAX_VALUE` in `available`, this makes `BufferedInputStream` do your work for you.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org