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

Copying symbolic links. how should FileUtils.copyDirectory. behave?

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • None
    • None
    • None
    • None

    Description

      The current 2.15.1 release and earlier versions have bugs in the copying of symbolic link cycles using FileUtils.copyDirectory. There are also bugs in copying broken symbolic links reported in IO-807. These are fixed at head because symbolic links to directories are now copied as symbolic links rather than by resolving the files. However this causes problems for some non-hypothetical existing code that relied on the old behavior for copying directories containing non-cyclical symbolic links.In particular, Google has reported failures in some of their internal projects when using the version at head as a result of this. However I don't think that the directories Google is copying contain cycles, so they weren't hitting the old bugs.

      The question is how to resolve this so that FileUtils.copyDirectory behaves reasonably with all possible directories whether cycles are present or not. Is there a consistent and reasonable way we can or should copy some links to directories as directories and others as actual directories? There are a number of cases to consider:

      1. No symbolic links. Just copy everything and we're good.

      2. Symbolic links but only to files, not directories. Copy the file or copy the link?

      3. Symbolic links but only to files within the root directory being copied. Right now at head we create a link to the old directory in the source. We could instead create a link to the new directory in the target.

      4. Symbolic links to files outside the root directory being copied. Right now at head we create a link to the old directory in the source. We should probably keep this behavior.

      I think the behavior we want is as follows, and then I think we handle most use cases while avoiding cycle problems:

      1. Start from a root directory, the source.
      2. Never copy anything that is not contained in that directory to the target.
      3. When walking the directory tree, if a symbolic link is encountered:
      3.1 If the symbolic link points outside the source, create a new symbolic link to the same target.
      3.2 If the symbolic link points to a target inside the source, create a new symbolic link to the copy of the target.

      However every symbolic link in the source turns into a symbolic link in the copy. Cycles do not cause problems because they are not followed. The only discrepancy I see in this approach is that a link to a directory outside the source that is a link that points back into the source still points back into the source, not the target. Thus the copy can point back into the source indirectly. Perhaps when copying links that point outside the source we can fully resolve them to and repoint as needed.

      I don't know that this actually fixes Google's problem. They sort of want files if not directories to be resolved when copying. Maybe that's a argument. Maybe that's a separate method like FileUtils.actualizeFiles(directory) that walks a file tree and replaces every link to a file with the contents of the target file.

      Attachments

        Activity

          People

            Unassigned Unassigned
            elharo Elliotte Rusty Harold
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: