aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/poi/util/IOUtils.java
diff options
context:
space:
mode:
authorTim Allison <tallison@apache.org>2017-07-13 16:20:28 +0000
committerTim Allison <tallison@apache.org>2017-07-13 16:20:28 +0000
commit34cb8609982f26f1d82a8a343d368217aca45def (patch)
treebabe36247f0ba75a7b25c3b2bac3269845b0a94e /src/java/org/apache/poi/util/IOUtils.java
parentb5e74d4b6494210acd80cff6e565fae3389b6bfe (diff)
downloadpoi-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.java35
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;
+ }
+ }
+ }
}