diff options
author | Tim Allison <tallison@apache.org> | 2017-07-13 16:20:28 +0000 |
---|---|---|
committer | Tim Allison <tallison@apache.org> | 2017-07-13 16:20:28 +0000 |
commit | 34cb8609982f26f1d82a8a343d368217aca45def (patch) | |
tree | babe36247f0ba75a7b25c3b2bac3269845b0a94e /src/java/org/apache/poi/util/IOUtils.java | |
parent | b5e74d4b6494210acd80cff6e565fae3389b6bfe (diff) | |
download | poi-34cb8609982f26f1d82a8a343d368217aca45def.tar.gz poi-34cb8609982f26f1d82a8a343d368217aca45def.zip |
bug 61294 -- prevent infinite loop in IOUtils' skipFully.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1801844 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/poi/util/IOUtils.java')
-rw-r--r-- | src/java/org/apache/poi/util/IOUtils.java | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/java/org/apache/poi/util/IOUtils.java b/src/java/org/apache/poi/util/IOUtils.java index d8938a61db..62001d1e05 100644 --- a/src/java/org/apache/poi/util/IOUtils.java +++ b/src/java/org/apache/poi/util/IOUtils.java @@ -361,7 +361,7 @@ public final class IOUtils { } /** - * Skips bytes from a stream. Returns -1L if EOF was hit before + * Skips bytes from a stream. Returns -1L if len > available() or if EOF was hit before * the end of the stream. * * @param in inputstream @@ -370,11 +370,22 @@ public final class IOUtils { * @throws IOException on IOException */ public static long skipFully(InputStream in, long len) throws IOException { - int total = 0; + long total = 0; while (true) { + long toSkip = len-total; + //check that the stream has the toSkip available + //FileInputStream can mis-report 20k skipped on a 10k file + if (toSkip > in.available()) { + return -1L; + } long got = in.skip(len-total); if (got < 0) { return -1L; + } else if (got == 0) { + got = fallBackToReadFully(len-total, in); + if (got < 0) { + return -1L; + } } total += got; if (total == len) { @@ -382,4 +393,24 @@ public final class IOUtils { } } } + + //an InputStream can return 0 whether or not it hits EOF + //if it returns 0, back off to readFully to test for -1 + private static long fallBackToReadFully(long lenToRead, InputStream in) throws IOException { + byte[] buffer = new byte[8192]; + long readSoFar = 0; + + while (true) { + int toSkip = (lenToRead > Integer.MAX_VALUE || + (lenToRead-readSoFar) > buffer.length) ? buffer.length : (int)(lenToRead-readSoFar); + long readNow = readFully(in, buffer, 0, toSkip); + if (readNow < toSkip) { + return -1L; + } + readSoFar += readNow; + if (readSoFar == lenToRead) { + return readSoFar; + } + } + } } |