Author: sebb Date: Mon Jun 3 20:59:05 2013 New Revision: 1489171 URL: http://svn.apache.org/r1489171 Log: IO-385 FileUtils.doCopyFile can potentially loop for ever
Modified: commons/proper/io/trunk/src/changes/changes.xml commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java Modified: commons/proper/io/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/changes/changes.xml?rev=1489171&r1=1489170&r2=1489171&view=diff ============================================================================== --- commons/proper/io/trunk/src/changes/changes.xml (original) +++ commons/proper/io/trunk/src/changes/changes.xml Mon Jun 3 20:59:05 2013 @@ -47,6 +47,10 @@ The <action> type attribute can be add,u <body> <!-- The release date is the date RC is cut --> <release version="2.5" date="2013-??-??" description="New features and bug fixes."> + <action issue="IO-385" dev="sebb" type="fix"> + FileUtils.doCopyFile can potentially loop for ever + Exit loop if no data to copy + </action> <action issue="IO-383" dev="sebb" type="fix"> FileUtils.doCopyFile caches the file size; needs to be documented Added Javadoc; show file lengths in exception message Modified: commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java URL: http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java?rev=1489171&r1=1489170&r2=1489171&view=diff ============================================================================== --- commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java (original) +++ commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java Mon Jun 3 20:59:05 2013 @@ -1152,8 +1152,13 @@ public class FileUtils { long pos = 0; long count = 0; while (pos < size) { - count = size - pos > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : size - pos; - pos += output.transferFrom(input, pos, count); + final long remain = size - pos; + count = remain > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : remain; + final long bytesCopied = output.transferFrom(input, pos, count); + if (bytesCopied == 0) { // IO-385 - can happen if file is truncated after caching the size + break; // ensure we don't loop forever + } + pos += bytesCopied; } } finally { IOUtils.closeQuietly(output);