This article originally appeared in TidBITS on 2009-11-19 at 8:59 p.m.
The permanent URL for this article is: http://tidbits.com/article/10772
Include images: Off

How to Fix Snow Leopard's Finder-Copying Bug

by Matt Neuburg

In "A Finder-Copying Bug in Snow Leopard [1]" (10 November 2009), I reported the existence of a bug related to copying files in Snow Leopard, and explained how to see the bug in action. Basically, the bug arises when you attempt to copy a "troublesome file" from a Snow Leopard machine to another computer via File Sharing. I also provided specific instructions for reproducing the bug using an example troublesome file that anyone could download.

In the previous article I suggested that perhaps the troublesome file was always an application, but readers have supplied examples of other bundles that can also trigger the bug. So, a troublesome file is always a bundle, but not every bundle is troublesome. Then the question is: What, exactly, makes a troublesome bundle troublesome?

By comparing two very similar applications, one of which is troublesome and the other not, even though they have nearly identical internal structures, I have discovered that the answer involves Unix permissions on symlinks inside the bundle.

Here's a quick Unix refresher. A symlink is a file that points to another file (the other file can be a folder). Unix permissions specify whether a file can be read (r), written (w), or executed (x), and they specify each of those with regard to three categories of person: the user that owns the file, the members of the group that owns the file, and the rest of the world.

A troublesome file turns out to be a bundle containing a symlink that is itself marked as writable by the group or the rest of the world. Here's an example (generated by the ls -al command, with much of the information omitted):

lrwxrwxrwx /Applications/Interarchy.app/Contents/Frameworks/Growl.framework/Growl
-> Versions/Current/Growl

It's a symlink (that's what the initial "l" means), and it is readable, writable, and executable ("rwx") by the user (the first "rwx"), the group (the second "rwx"), and everyone else (the third "rwx").

In theory, permissions on a symlink should be more or less meaningless; a Unix system should ignore them. But apparently Snow Leopard does not ignore them, and therein lies the trouble. Here's what seems to be happening. The user tries to copy the bundle, so the Finder proceeds to copy the bundle's contents. The symlink is encountered before the file it points to. So the symlink is copied to the remote machine, and now the system sees (I'm guessing) that the symlink's permissions are unusual, and tries to copy those permissions onto the file it points to, also on the remote machine. But the file that the symlink points to has not yet been copied to the remote machine, so this attempt to set its permissions fails, and the Finder raises an error (-36).

If you'd like to know whether you have any potentially troublesome bundles, run this command in Terminal:

sudo find / -type l -perm +g+w -ls

You'll be asked for your password. After you give it (and press Return), go get a cup of coffee, because this command takes a long time while your entire hard drive is traversed. In the end, a list appears showing all files that are symlinks ("-type l") and also give write permissions to the group ("-perm +g+w"). The symlinks are each inside some bundle, so if you read the pathname backwards you can see what bundle it is. For example, the symlink listed in the example above is inside Interarchy.app. So, that copy of Interarchy constitutes a troublesome file, and cannot be copied to another machine using the Finder via File Sharing.

Both TidBITS Publisher Adam Engst and I tried the above command, and came up with a list of bundles that are troublesome on our respective machines. The list includes, on Adam's machine, Interarchy, Nisus Thesaurus, Quicksilver, and an iPhoto Library, and on my machine, a bunch of Omni applications, including OmniWeb, OmniDazzle, and others. Why our results don't match - why, for example, my copy of Interarchy has different permissions on its symlinks than Adam's - remains a mystery. But what is clear is that, in both our tests, the bundles that are ferreted out in this way are exactly the ones that trigger the Finder copying bug.

If you'd like to fix the problem, by changing the permissions on the symlinks within a bundle, so that bundle can be successfully Finder-copied via File Sharing, here's how to do it. In the Terminal, type:

find

Then type a space. Now drag the troublesome file from the Finder into the Terminal window; this causes the Terminal to enter the pathname of the bundle. For example, if at this point Adam were to drag Interarchy into the Terminal window, the Terminal would now read:

find /Applications/Interarchy.app

Now continue typing, so that your command has this form:

find /Applications/Interarchy.app -type l -exec chmod -h go-w {} \;

At the end, press Return. The command means: Traverse down into Interarchy, looking for symlinks ("-type l"). When you find one, change the permissions ("-exec chmod") of the symlink itself ("-h") so that neither the group nor the rest of the world have write permission ("go-w"). I'm not going to explain the other stuff, but it's all essential, including the backslash before the semicolon. After running this command on a bundle, the bundle will still work fine, and it will no longer trigger the Finder-copying bug.

[1]: http://db.tidbits.com/article/10743