It looks to me like QuotedPrintableDecoderStream’s read() method doesn’t look like it fulfills the contract from InputStream. InputStream says it will return -1 when there is no more data to be read. However, QuotedPrintableDecoderStream returns 0 in this case. The result is that IOUtils.copy() in commons-io will go into an endless loop if it’s fed a QuotedPrintableDecoderStream.
Should I go ahead and report this in JIRA?