You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Thomas Ledoux (JIRA)" <ji...@apache.org> on 2006/08/02 19:15:13 UTC

[jira] Created: (IO-90) Infinite loop in FileSystemUtils.freeSpaceWindows if share directory empty

Infinite loop in FileSystemUtils.freeSpaceWindows if share directory empty
--------------------------------------------------------------------------

                 Key: IO-90
                 URL: http://issues.apache.org/jira/browse/IO-90
             Project: Commons IO
          Issue Type: Bug
          Components: Utilities
    Affects Versions: 1.2
         Environment: Windows NT or higher
            Reporter: Thomas Ledoux


When using FileSystemUtils.freeSpaceWindows in an empty share directory, the line containing the free space does not exist which causes an infinite loop (the outerloop doesn't decrease the i index).

In fact to deal with all possible errors, I propose to test the exitCode of the dir command.

Here is a proposed new code for this function :

    /**
     * Find free space on the Windows platform using the 'dir' command.
     *
     * @param path  the path to get free space for, including the colon
     * @return the amount of free drive space on the drive
     * @throws IOException if an error occurs
     */
    long freeSpaceWindows(String path) throws IOException {
        path = FilenameUtils.normalize(path);
        if (path.length() > 2 && path.charAt(1) == ':') {
            path = path.substring(0, 2);  // seems to make it work
        }

        // build and run the 'dir' command
        String[] cmdAttrbs = new String[] {"cmd.exe", "/C", "dir /-c " + path};

        // read in the output of the command to an ArrayList
        BufferedReader in = null;
        String line = null;
        ArrayList lines = new ArrayList();
        int errorLevel = 0;
        
        try {
            Process proc = Runtime.getRuntime().exec(cmdAttrbs);
            in = new BufferedReader(
                new InputStreamReader(proc.getInputStream()));
            line = in.readLine();
            while (line != null) {
                line = line.toLowerCase().trim();
                lines.add(line);
                line = in.readLine();
            }
            
            proc.waitFor();
            errorLevel = proc.exitValue();
           
        } finally {
            IOUtils.closeQuietly(in);
        }

        if (lines.size() == 0) {
            // unknown problem, throw exception
            throw new IOException(
                    "Command line 'dir /-c' did not return any info " +
                    "for command '" + cmdAttrbs[2] + "'");
        }

        if (errorLevel != 0) {
            if (errorLevel == 2) {
                // Empty directory : unable to calculate the freeSpace
                return Integer.MAX_VALUE; // ???
            } else {
                // unknown problem, throw exception
                throw new IOException(
                        "Command line 'dir /-c' error [" + errorLevel +
                        "] for command '" + cmdAttrbs[2] + "'");
            }
        }
        
        // now iterate over the lines we just read and find the LAST
        // non-empty line (the free space bytes should be in the last element
        // of the ArrayList anyway, but this will ensure it works even if it's
        // not, still assuming it is on the last non-blank line)
        long bytes = -1;
        int i = lines.size() - 1;
        int bytesStart = 0;
        int bytesEnd = 0;
        outerLoop: while (i > 0) {
            line = (String) lines.get(i);
            if (line.length() > 0) {
                // found it, so now read from the end of the line to find the
                // last numeric character on the line, then continue until we
                // find the first non-numeric character, and everything between
                // that and the last numeric character inclusive is our free
                // space bytes count
                int j = line.length() - 1;
                innerLoop1: while (j >= 0) {
                    char c = line.charAt(j);
                    if (Character.isDigit(c)) {
                      // found the last numeric character, this is the end of
                      // the free space bytes count
                      bytesEnd = j + 1;
                      break innerLoop1;
                    }
                    j--;
                }
                innerLoop2: while (j >= 0) {
                    char c = line.charAt(j);
                    if (!Character.isDigit(c) && c != ',' && c != '.') {
                      // found the next non-numeric character, this is the
                      // beginning of the free space bytes count
                      bytesStart = j + 1;
                      break innerLoop2;
                    }
                    j--;
                }
                break outerLoop;
            } else {
                // If the last line is empty we are unable to parse the freeSpace
                throw new IOException(
                        "Command line 'dir /-c' did not return valid info " +
                        "for command '" + cmdAttrbs[2] + "'");
            }
        }

        // remove commas and dots in the bytes count
        StringBuffer buf = new StringBuffer(line.substring(bytesStart, bytesEnd));
        for (int k = 0; k < buf.length(); k++) {
            if (buf.charAt(k) == ',' || buf.charAt(k) == '.') {
                buf.deleteCharAt(k--);
            }
        }
        bytes = Long.parseLong(buf.toString());
        return bytes;
    }


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


[jira] Closed: (IO-90) Infinite loop in FileSystemUtils.freeSpaceWindows if share directory empty

Posted by "Stephen Colebourne (JIRA)" <ji...@apache.org>.
     [ http://issues.apache.org/jira/browse/IO-90?page=all ]

Stephen Colebourne closed IO-90.
--------------------------------

    Resolution: Fixed

Fixed (with many other changes for robustness) in rv437031

> Infinite loop in FileSystemUtils.freeSpaceWindows if share directory empty
> --------------------------------------------------------------------------
>
>                 Key: IO-90
>                 URL: http://issues.apache.org/jira/browse/IO-90
>             Project: Commons IO
>          Issue Type: Bug
>          Components: Utilities
>    Affects Versions: 1.2
>         Environment: Windows NT or higher
>            Reporter: Thomas Ledoux
>             Fix For: 1.3
>
>
> When using FileSystemUtils.freeSpaceWindows in an empty share directory, the line containing the free space does not exist which causes an infinite loop (the outerloop doesn't decrease the i index).
> In fact to deal with all possible errors, I propose to test the exitCode of the dir command.
> Here is a proposed new code for this function :
>     /**
>      * Find free space on the Windows platform using the 'dir' command.
>      *
>      * @param path  the path to get free space for, including the colon
>      * @return the amount of free drive space on the drive
>      * @throws IOException if an error occurs
>      */
>     long freeSpaceWindows(String path) throws IOException {
>         path = FilenameUtils.normalize(path);
>         if (path.length() > 2 && path.charAt(1) == ':') {
>             path = path.substring(0, 2);  // seems to make it work
>         }
>         // build and run the 'dir' command
>         String[] cmdAttrbs = new String[] {"cmd.exe", "/C", "dir /-c " + path};
>         // read in the output of the command to an ArrayList
>         BufferedReader in = null;
>         String line = null;
>         ArrayList lines = new ArrayList();
>         int errorLevel = 0;
>         
>         try {
>             Process proc = Runtime.getRuntime().exec(cmdAttrbs);
>             in = new BufferedReader(
>                 new InputStreamReader(proc.getInputStream()));
>             line = in.readLine();
>             while (line != null) {
>                 line = line.toLowerCase().trim();
>                 lines.add(line);
>                 line = in.readLine();
>             }
>             
>             proc.waitFor();
>             errorLevel = proc.exitValue();
>            
>         } finally {
>             IOUtils.closeQuietly(in);
>         }
>         if (lines.size() == 0) {
>             // unknown problem, throw exception
>             throw new IOException(
>                     "Command line 'dir /-c' did not return any info " +
>                     "for command '" + cmdAttrbs[2] + "'");
>         }
>         if (errorLevel != 0) {
>             if (errorLevel == 2) {
>                 // Empty directory : unable to calculate the freeSpace
>                 return Integer.MAX_VALUE; // ???
>             } else {
>                 // unknown problem, throw exception
>                 throw new IOException(
>                         "Command line 'dir /-c' error [" + errorLevel +
>                         "] for command '" + cmdAttrbs[2] + "'");
>             }
>         }
>         
>         // now iterate over the lines we just read and find the LAST
>         // non-empty line (the free space bytes should be in the last element
>         // of the ArrayList anyway, but this will ensure it works even if it's
>         // not, still assuming it is on the last non-blank line)
>         long bytes = -1;
>         int i = lines.size() - 1;
>         int bytesStart = 0;
>         int bytesEnd = 0;
>         outerLoop: while (i > 0) {
>             line = (String) lines.get(i);
>             if (line.length() > 0) {
>                 // found it, so now read from the end of the line to find the
>                 // last numeric character on the line, then continue until we
>                 // find the first non-numeric character, and everything between
>                 // that and the last numeric character inclusive is our free
>                 // space bytes count
>                 int j = line.length() - 1;
>                 innerLoop1: while (j >= 0) {
>                     char c = line.charAt(j);
>                     if (Character.isDigit(c)) {
>                       // found the last numeric character, this is the end of
>                       // the free space bytes count
>                       bytesEnd = j + 1;
>                       break innerLoop1;
>                     }
>                     j--;
>                 }
>                 innerLoop2: while (j >= 0) {
>                     char c = line.charAt(j);
>                     if (!Character.isDigit(c) && c != ',' && c != '.') {
>                       // found the next non-numeric character, this is the
>                       // beginning of the free space bytes count
>                       bytesStart = j + 1;
>                       break innerLoop2;
>                     }
>                     j--;
>                 }
>                 break outerLoop;
>             } else {
>                 // If the last line is empty we are unable to parse the freeSpace
>                 throw new IOException(
>                         "Command line 'dir /-c' did not return valid info " +
>                         "for command '" + cmdAttrbs[2] + "'");
>             }
>         }
>         // remove commas and dots in the bytes count
>         StringBuffer buf = new StringBuffer(line.substring(bytesStart, bytesEnd));
>         for (int k = 0; k < buf.length(); k++) {
>             if (buf.charAt(k) == ',' || buf.charAt(k) == '.') {
>                 buf.deleteCharAt(k--);
>             }
>         }
>         bytes = Long.parseLong(buf.toString());
>         return bytes;
>     }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


[jira] Updated: (IO-90) Infinite loop in FileSystemUtils.freeSpaceWindows if share directory empty

Posted by "Henri Yandell (JIRA)" <ji...@apache.org>.
     [ http://issues.apache.org/jira/browse/IO-90?page=all ]

Henri Yandell updated IO-90:
----------------------------

    Fix Version/s: 1.3

An important fix for 1.3.

> Infinite loop in FileSystemUtils.freeSpaceWindows if share directory empty
> --------------------------------------------------------------------------
>
>                 Key: IO-90
>                 URL: http://issues.apache.org/jira/browse/IO-90
>             Project: Commons IO
>          Issue Type: Bug
>          Components: Utilities
>    Affects Versions: 1.2
>         Environment: Windows NT or higher
>            Reporter: Thomas Ledoux
>             Fix For: 1.3
>
>
> When using FileSystemUtils.freeSpaceWindows in an empty share directory, the line containing the free space does not exist which causes an infinite loop (the outerloop doesn't decrease the i index).
> In fact to deal with all possible errors, I propose to test the exitCode of the dir command.
> Here is a proposed new code for this function :
>     /**
>      * Find free space on the Windows platform using the 'dir' command.
>      *
>      * @param path  the path to get free space for, including the colon
>      * @return the amount of free drive space on the drive
>      * @throws IOException if an error occurs
>      */
>     long freeSpaceWindows(String path) throws IOException {
>         path = FilenameUtils.normalize(path);
>         if (path.length() > 2 && path.charAt(1) == ':') {
>             path = path.substring(0, 2);  // seems to make it work
>         }
>         // build and run the 'dir' command
>         String[] cmdAttrbs = new String[] {"cmd.exe", "/C", "dir /-c " + path};
>         // read in the output of the command to an ArrayList
>         BufferedReader in = null;
>         String line = null;
>         ArrayList lines = new ArrayList();
>         int errorLevel = 0;
>         
>         try {
>             Process proc = Runtime.getRuntime().exec(cmdAttrbs);
>             in = new BufferedReader(
>                 new InputStreamReader(proc.getInputStream()));
>             line = in.readLine();
>             while (line != null) {
>                 line = line.toLowerCase().trim();
>                 lines.add(line);
>                 line = in.readLine();
>             }
>             
>             proc.waitFor();
>             errorLevel = proc.exitValue();
>            
>         } finally {
>             IOUtils.closeQuietly(in);
>         }
>         if (lines.size() == 0) {
>             // unknown problem, throw exception
>             throw new IOException(
>                     "Command line 'dir /-c' did not return any info " +
>                     "for command '" + cmdAttrbs[2] + "'");
>         }
>         if (errorLevel != 0) {
>             if (errorLevel == 2) {
>                 // Empty directory : unable to calculate the freeSpace
>                 return Integer.MAX_VALUE; // ???
>             } else {
>                 // unknown problem, throw exception
>                 throw new IOException(
>                         "Command line 'dir /-c' error [" + errorLevel +
>                         "] for command '" + cmdAttrbs[2] + "'");
>             }
>         }
>         
>         // now iterate over the lines we just read and find the LAST
>         // non-empty line (the free space bytes should be in the last element
>         // of the ArrayList anyway, but this will ensure it works even if it's
>         // not, still assuming it is on the last non-blank line)
>         long bytes = -1;
>         int i = lines.size() - 1;
>         int bytesStart = 0;
>         int bytesEnd = 0;
>         outerLoop: while (i > 0) {
>             line = (String) lines.get(i);
>             if (line.length() > 0) {
>                 // found it, so now read from the end of the line to find the
>                 // last numeric character on the line, then continue until we
>                 // find the first non-numeric character, and everything between
>                 // that and the last numeric character inclusive is our free
>                 // space bytes count
>                 int j = line.length() - 1;
>                 innerLoop1: while (j >= 0) {
>                     char c = line.charAt(j);
>                     if (Character.isDigit(c)) {
>                       // found the last numeric character, this is the end of
>                       // the free space bytes count
>                       bytesEnd = j + 1;
>                       break innerLoop1;
>                     }
>                     j--;
>                 }
>                 innerLoop2: while (j >= 0) {
>                     char c = line.charAt(j);
>                     if (!Character.isDigit(c) && c != ',' && c != '.') {
>                       // found the next non-numeric character, this is the
>                       // beginning of the free space bytes count
>                       bytesStart = j + 1;
>                       break innerLoop2;
>                     }
>                     j--;
>                 }
>                 break outerLoop;
>             } else {
>                 // If the last line is empty we are unable to parse the freeSpace
>                 throw new IOException(
>                         "Command line 'dir /-c' did not return valid info " +
>                         "for command '" + cmdAttrbs[2] + "'");
>             }
>         }
>         // remove commas and dots in the bytes count
>         StringBuffer buf = new StringBuffer(line.substring(bytesStart, bytesEnd));
>         for (int k = 0; k < buf.length(); k++) {
>             if (buf.charAt(k) == ',' || buf.charAt(k) == '.') {
>                 buf.deleteCharAt(k--);
>             }
>         }
>         bytes = Long.parseLong(buf.toString());
>         return bytes;
>     }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org