Uploaded image for project: 'Commons IO'
  1. Commons IO
  2. IO-452

FileUtils.isSymlink returns false for broken symlinks.

    XMLWordPrintableJSON

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 2.5
    • Fix Version/s: 2.5
    • Component/s: Utilities
    • Labels:
      None
    • Environment:

      Description

      FileUtils.isSymlink returns false for broken symlinks.

      In contrast, java 7 java.nio.file.Files.isSymbolicLink() returns true for broken symlink.

      One possible work around for java 6 and below is to use the fact that File.exists() returns false for a broken symlink and the fact that the file is found in its parents directory listing.

      I don't have a compelling argument for fixing this, here is a candidate patch.

      someguy@weeble:~/prog/java/commons-io/commons-io$ svn diff src/main/java/org/apache/commons/io/FileUtils.java 
      Index: src/main/java/org/apache/commons/io/FileUtils.java
      ===================================================================
      --- src/main/java/org/apache/commons/io/FileUtils.java  (revision 1609743)
      +++ src/main/java/org/apache/commons/io/FileUtils.java  (working copy)
      @@ -3068,10 +3068,41 @@
               }
       
               if (fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile())) {
      -            return false;
      +            return isBrokenSymlink(file);
               } else {
                   return true;
               }
           }
       
      +    /**
      +     * Determines if the specified file is possibly a broken symbolic link.
      +     * 
      +     * @param file the file to check
      +     * @return true if the file is a Symbolic Link
      +     * @throws IOException if an IO error occurs while checking the file
      +     */
      +    private static boolean isBrokenSymlink(final File file) throws IOException {
      +        // if file exists then if it is a symlink it's not broken   
      +        if ( file.exists() ) {
      +            return false;
      +        }
      +        // a broken symlink will show up in the list of files of its parent directory
      +        final File canon = file.getCanonicalFile();
      +        File parentDir = canon.getParentFile();
      +        if ( parentDir == null || ! parentDir.exists() ) {
      +            return false;
      +        }
      +        
      +        // is it worthwhile to create a FileFilterUtil method for this?
      +        // is it worthwhile to create an "identity"  IOFileFilter for this?
      +        File[] fileInDir = parentDir.listFiles(
      +            new FileFilter() {
      +                public boolean accept( File aFile ) {
      +                    return aFile.equals(canon);
      +                }
      +                }
      +            );
      +        return fileInDir.length > 0;
      +    }
      +
       }
      
      someguy@weeble:~/prog/java/commons-io/commons-io$ svn diff src/test/java/org/apache/commons/io/FileUtilsCleanSymlinksTestCase.java 
      Index: src/test/java/org/apache/commons/io/FileUtilsCleanSymlinksTestCase.java
      ===================================================================
      --- src/test/java/org/apache/commons/io/FileUtilsCleanSymlinksTestCase.java     (revision 1609743)
      +++ src/test/java/org/apache/commons/io/FileUtilsCleanSymlinksTestCase.java     (working copy)
      @@ -203,6 +203,25 @@
               assertFalse(FileUtils.isSymlink(randomFile));
           }
       
      +    public void testIdentifiesBrokenSymlinkFile() throws Exception {
      +        if (System.getProperty("os.name").startsWith("Win")) {
      +            // cant create symlinks in windows.
      +            return;
      +        }
      +
      +        final File noexistFile = new File(top, "noexist");
      +        final File symlinkFile = new File(top, "fakeinner");
      +        final File badSymlinkInPathFile = new File(symlinkFile, "fakeinner");
      +        final File noexistParentFile = new File("noexist", "file");
      +        
      +        setupSymlink(noexistFile, symlinkFile);
      +
      +        assertTrue(FileUtils.isSymlink(symlinkFile));
      +        assertFalse(FileUtils.isSymlink(noexistFile));
      +        assertFalse(FileUtils.isSymlink(noexistParentFile));
      +        assertFalse(FileUtils.isSymlink(badSymlinkInPathFile));
      +    }
      +
           public void testCorrectlyIdentifySymlinkWithParentSymLink() throws Exception {
               if (System.getProperty("os.name").startsWith("Win")) {
                   // cant create symlinks in windows.
      

        Attachments

          Activity

            People

            • Assignee:
              krosenvold Kristian Rosenvold
              Reporter:
              standish David Standish
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: