I have a project with an .scpt file in the MacOS folder of the application bundle. While the binary and the .scpt are signed by Xcode, GateKeeper complains when I try to distribute the app. Why ? Because AppleScript self-modifies the script.
In other words, when executed (e.g. last test before creating the .dmg), the script writes inside its own binary code.
I tried to compare the contents of both the used and unused .scpt:
1- the text versions (as shown by Applescript Editor) are identical
2- the binaries are different but it is difficult to find which actions are responsible for that odd behaviour due to the binary coding. http://alain.filhol1.perso.sfr.fr/scpt-binaries-before-after.jpg
AppleScript modifying its own code :
Is this normal ?
Is it documented somewhere ?
is there an option to avoid it ?
is that inherited from the old times of the resource fork (MacOS classic) ?
a self-modifying code, does that complies with Apple’s safety rules ?
If you think this is a bug, not a feature, I wlll prepare a short demo.
As far as I know, it’s not the code itself which is modified.
It’s a feature known and explained for years.
The script store a lot of variables - those which are global -
If the script changes the values of these variables the stored file will change.
It’s why when I write scripts form me, since some months, I enclose everything in handlers and put the global variables in a script object.
It’s a bit cumbersome but when it’s done, the binary file doesn’t change.
It’s important for scripters signing their scripts.
Yvan KOENIG running El Capitan 10.11.6 in French (VALLAURIS, France) vendredi 2 septembre 2016 15:40:09
What gets saved in a .scpt file is both the code and the top-level values – properties, globals, variables in the run handler. When you run a script and any of these change, AppleScript normally saves the new version back to disk. This is how properties are persisted. So it’s self-modifying and it’s odd, but it’s always been that way.
The solution is to set the permissions of the file so that changes can’t be made, using chmod a-w or something similar. I believe Script Editor does this to main.scpt when you export codesigned. If you’re developing in Xcode, you’ll need to add a build phase to do it.
Another option that might be practical in Xcode would be to start your code by setting a top-level variable to a Cocoa object. That should also stop modifications being saved, because pointers can’t be saved.
Thank you for your explanations. It is a relief to know it is a feature of AppleScript and a problem to be solved for signing scripts.
I am not an AppleScript expert and I am not sure I understand how you do that.
Excellent, I will try this! I thought that doing so would be at risk and would block AppleScript.
Is there any known side effect of stopping modifications being saved ? Probably no since you say
The obvious one is that you can’t rely on properties being persistent, so any vlaues you wish to retain between runs needs to be stored in some other way.