More probably an error in your script, not in the save
method.
It was the save command inside the tell block of Mail.app that did it. The code before it was a variable to get name of mail attachment (string).
No matter what a user do in any tell block of AppleScript shouldn’t have privileges to remove files and subfolder inside a folder. Why do we have checks if a folder or file do excists if there are way to ignore it. Nothing of my code in AppleScript make it possible to delete every file and subfolder of some folder.
Sure, my code was wrong, but 99.9999% of whose times I get a error… but in this case it didn’t and for me that is a bug.
And if you did a delete in tell block of Finder it will end-up in the bin. It means that Mail.app removes files of desktop folder include all subfolder and I was not able to recover anything. How is that possible if that is not a bug but instead a user who find a way with some AppleScript code to do it. Mail.app do not have any privileges what so ever to do something like that. Finder.app have privileges to do something like that.
It would be nice to post the actual script you ran so others can debug to determine if it is indeed a bug in AppleScript or your script.
@robertfern
If a AppleScript is executed without error. And do things that it shouldn’t do. It’s enough for me to consider it a bug. If the code should return a error but do not is enough for me to consider it a bug. And other people who use Monterey had problem with save command.
This topic was to give user an alert what happen to me. I do not have more to say on this.
And I will not ‘try’ to reproduce a bug to prove my point.
Hi @Fredrik71.
Thanks for your intention to warn others of a potentially destructive bug. But robertfern and chrillek, who’ve taken an interest in your post, are right. If you can’t or won’t show in detail what the script was doing, and no-one else has so far encountered the same problem, your warning’s of little help.
It sounds as if you were trying to save the attachment to your desktop. The save
command’s in
parameter requires the complete path for the saved file, not just the path to the folder where you want it to go. If you just used (path to desktop)
, the save will have saved the file with your desktop folder path, thus overwriting the folder. This isn’t a bug, but a misunderstanding of the probably poorly explained dictionary entry. The paradigm is that you save data in (or to) a file, not a file in (or to) a folder.
I hope this solves both the mystery and the problem.
@Nigel_Garvey
You may be right, Thanks
So the reality is (for me) there is no protection if a AppleScript user (me) do something wrong or missunderstood the dictionary. And who knows what will happen if that was ‘home folder’ instead. Bug or bad implementation… sometimes they go hand in hand.
And if a save command need a reference to an file and got folder instead wouldn’t it be error. Folders and Files is different things and when we think they are the same its something wrong with the implementation. If the argument is ‘user missunderstood’ and thats why it happen doesn’t make it more safe for anyone.
The Desktop folder is protected for delete, but rewrite the entire folder is possible with not warning at all.
ls -ale show the group that Desktop folder belong to.
drwx------@ 9 f.gustafsson.user staff 288 Mar 12 17:18 Desktop
0: group:everyone deny delete
Lets me say this, I’m not angry but I’m very disappointment that this is possible.
After reading the latest posts I think I finally understand the issue you encountered.
So yes, IF you by mistake specified an existing folder path instead of a file path as a result of which the entire folder got overwritten, then I would also consider it a severe bug. If you can reproduce it then I think you should report it to Apple.
I made a feedback to Apple… and describe the situation.
Though I can understand that you’re disappointed, I doubt that Apple will do anything about it. This is clearly a user error. Like when you type rm -rf *
in Terminal while your current folder is ~/Desktop
. The fact that save
overwrites folders is well known:
http://books.gigatux.nl/mirror/applescript/0596008503/applescripttmm-chp-5-sect-7.html
Make sure you specify a file, not a folder! If you put a path to a folder after the in option, AppleScript overwrites that folder completely. And if that folder were your desktop, the script would instantly trash your Desktop folder and every file inside it, leaving your desktop files as mere memories.
The scripting dictionary for the Standard Suite clearly says, “[in: file] : The file in which to save the document.” Not “the file or folder”.
@chrillek
I understand what you mean, but I do not agree. If the save command expect a file and get a folder it should return a error. That is exactly what NSFileManager class does. Why would it be different in AppleScript. if Apple’s framework do not allow it. It doesn’t matter if its a user error when implemintation allow it to happen. And when did Apple overse the specification that is more 20 years old. When nobody care about security.
Would you also consider the command make new folder to overwrite a excisted one to be possible.
Save command is different from remove command. And that is not what happen. Desktop folder is protected folder from delete. Meaning you couldn’t remove it from AppleScript or FileManager class. And when you are talking about unix command mkdir could not make a folder with name Desktop in the home folder. I wonder why if your claim it is a ‘user error’ but maybe you think mkdir should allow it then.
The dictionary also say it could only save document and window. When did we define documents to be folder. A document is a reference to a application that contants content. This content could be saved to specifict format. Thats why it never could be a folder becouse a document is a file. And when a software do not know the different between a folder and file its a implemination bug.
Because AppleScript was there long before NSFileManager. And because it’s a loosely typed language based on messages (not on methods as the ObjC/Swift frameworks). And because there might be apps which do The Right Thing when save
is passed a folder.
It can’t if the folder is already there. If it isn’t, it can (which makes sense, I guess). And my example was actually rm
, not mkdir
. There are a lot of possibilites to shoot yourself into the foot, and a scripting language will only protect you against some of them. You can easily run a shell command from AppleScript than does very bad things to your files …
Because you passed a folder instead of a file, and because the behavior is well documented since ages. Which is not to say that it is a nice behavior. But the save
command might be related to the NSDocument
’s similarly named method. Which allows saving to a package, and a package is just a glorified folder.
I can assure you that Apple is not going to change anything about this. Never. They’re simply not interested in scripting anymore.
If Apple do change they will not tell anyone… and that could be the same to think ‘they will not do anything about it’. The problem many times is not to report a bug its when the user do not get any feedback in return. Any software developer properly know they need users to find bugs… and when people start to thing ‘they will not do anything’ it also means the bug is still there.
And it would be impossible for Apple’s engineers to do anything without knowing.
Maybe it takes 100 times of same complain before a manager do anything. That is the life when people do not share the same experience. And still some do not give up when others do. The problem is when companies start to ask why custommer no longer care its to late. To care about something also means we like to have something back.
that’s very true
And it become more clear when Finder define Folder and File as 2 different thing.
Specially if you do something like this
tell application "Finder"
set thePath to (path to desktop)
set thePath to (thePath as text)
set thePath to file thePath
end tell
The reason the below script works is becouse ‘file’ is a document file that do exists.
tell application "Finder"
set thePath to (path to desktop)
set thePath to (thePath as text) & "SomeFileThatDoExists.txt"
set thePath to file thePath
end tell
So iif the argument still are its a ‘user error’ when I guess the standard ot implemintation is all over the place with different ideas how it should work.
I believe that I am on the receiving end of this script behavior, although I hesitate to call it a bug; most saves are functionally equal to delete, unless otherwise specified. I was attempting to download attachments from Mail to the desktop, when I noticed folders disappearing; at first, I thought the script was resource intensive and producing a graphics glitch. As the full horror dawned on me, I mashed the power button to force quit the machine, but several GBs of data was lost forever, and it was entirely my fault for not specifying a file name.
saves are functionally equal to delete
If a method couldn’t write data of a class of document file to other class that is a folder. If that was possible . Then I guess it wouldn’t be different to say. We allow to add variable of type string in a array. The array will remove or replace everything that was there before with only 1 item. Why is that not allowed. Because add method do not do same things as remove or delete a object in array. When a program allow this to happen the implementation is weak. If a method is allowed to write or over write a excited object. We also have to check if the class is the same.
Document file and Folder is 2 different classes in AppleScript.
It would be a good to use a check. So I made this…
use framework "Foundation"
use scripting additions
set thePath to POSIX path of (path to desktop)
if isFile(thePath) then
log "do something with my file"
end if
on isFile(thePath)
set theURL to current application's |NSURL|'s fileURLWithPath:thePath
if theURL's hasDirectoryPath then error "The URL is a directory."
return true
end isFile
Here is an Vanilla AppleScript version
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
set thePath to (path to desktop)
if isFile(thePath) then
log "do something with my file"
end if
on isFile(thePath) -- accepts thePath as text or as alias
local tid, flag
set tid to text item delimiters
set text item delimiters to ":"
if class of thePath is alias then set thePath to thePath as text
if last text item of thePath is "" then -- its a folder
set flag to false
else
set flag to true
end if
set text item delimiters to tid
return flag
end isFile
and an even simpler one below
-- works with HFS paths, change the ":" to "/" for posix paths
on isFile(thePath)
if class of thePath is alias then set thePath to thePath as text
if text -1 of thePath is ":" then -- its a folder
return false
else
return true
end if
end isFile
May I suggest to use this method instead:
+ (NSURL *)fileURLWithPath:(NSString *)path isDirectory:(BOOL)isDir;
It will check if the object at the target path is actually a directory or not. hasDirectoryPath
will only check the path string without checking the actual item at this path.
Thanks @robertfern @zevrix
Here is other with Finder.
set thePath to choose folder
log isClass(thePath)
set thePath to choose file --> if we choose a file it will return document file
log isClass(thePath)
set thePath to (path to desktop as text) & "somefile.txt"
log isClass(thePath)
set thePath to (path to desktop)
log isClass(thePath)
set thePath to POSIX path of (path to desktop) & "somefile.txt"
log isClass(thePath)
set thePath to POSIX path of (path to desktop)
log isClass(thePath)
on isClass(thePath)
tell application "Finder"
if thePath's class is text and (last character of thePath) is ":" then
return folder
else if thePath's class is text and (last character of thePath) is "/" then
return folder
end if
if thePath's class is alias then
set theProperties to thePath's properties
return theProperties's class
end if
end tell
return file
end isClass