Mojave changes make osadecompile fail on AppleScript Debugger files

I noticed on Mojave decompiling AppleScript files that have been saved in debug-mode doesn’t work anymore (it still works on El Capitan):

$ osadecompile assets/asdbg.scpt 
2019-03-03 15:27:24.956 osadecompile[58178:10948949] Error loading /Users/xxx/Library/Components/Script Debugger.component/Contents/MacOS/Script Debugger:  dlopen(/Users/xxx/Library/Components/Script Debugger.component/Contents/MacOS/Script Debugger, 0x0106): code signature in (/Users/xxx/Library/Components/Script Debugger.component/Contents/MacOS/Script Debugger) not valid for use in process: mapping process is a platform binary, but mapped file is not
osadecompile: assets/asdbg.scpt: Can't connect to scripting system with that ID 

This is not a big problem; I just want to check if Mojave’s security changes is the source of this (since nothing shows up in the Privacy > Automation tab in system preferences). Also, I used OSAScript ObjC to detect the language of an scpt file. That doesn’t work either, and gives me the same error on AppleScript Debugger files.

I now think of detecting file type by checking the headers of these files, like this:

script_content=$(head -c 8 "$1")
if [[ ${script_content:0:7} == "FasdUAS" ]]; then
    echo "AppleScript"
elif [[ ${script_content:0:8} == "MarY3.00" ]]; then
    echo "AppleScript Debugger"
elif [[ ${script_content:0:8} == "JsOsaDAS" ]]; then
    echo "JavaScript"

Will this work? I just guessed from some sample files…

You could use something like this:

use framework "Foundation"
use framework "OSAKit"

set theURL to choose file
set theScript to current application's OSAScript's alloc()'s initWithContentsOfURL:theURL |error|:(missing value)
if theScript = missing value then return "Debugger"
return theScript's language()'s |name|() as text

I could do that. However, since OSAScript thinks even a JPEG-image is an AppleScript file, I already need to check for the header (the command file has a check for AppleScript files in /usr/share/file/magic/apple) for AppleScript file-types. And I suspect a broken AppleScript file will get a false detection as Debugger in this case.

Since it’s an undocumented API anyways, I’m hesitant to keep using it. Also: when I look at the error message, does the wording (“mapping process is a platform binary”) suggest these API calls would work if I made a ObjC binary?

It ended up being something like this. In a shell-context, OSAScript throws an exception and also writes an error message to stderr. In a GUI-context it returns the missing value. I have not yet decided what to do: use this code, or go for the header-detection mentioned above.

	set the_script to current application's OSAScript's alloc()'s initWithContentsOfURL:source_nsurl |error|:(missing value)
on error number -10000
	return "AppleScript Debugger"
end try
if the_script is missing value then
	return "AppleScript Debugger"

I think it’s a shame you can’t use osacompile on the command line to decompile AppleScript Debugger files. It shows how debuggers actually work, but a bit more readable than assembly code…

@ShaneStanley Could you confirm the header detection for AppleScript Debugger works for every file saved like this? I know I don’t get certainty that other types of files start with the same header, but it would be good to know…

I don’t think there’s any header detection involved.

If you want the error, use something like:

set {theScript, theError} to current application's OSAScript's alloc()'s initWithContentsOfURL:source_nsurl |error|:(reference)

Two other pieces of OSAScript that might be useful are the compiled property, and the compileAndReturnError: method.

Sorry I was not really clear about the question I want to be answered. I just realized now what the question actually is :blush:.

I work on a command line program that determines whether a file is an OSA file or not, and if so, it determines the language of that file. I kind of like the fact that this program itself is written in AppleScript.

However, the internal logic is getting pretty complicated. I also have a different version that checks the file’s header. That logic is much more simple (and it’s quicker too. Not sure if the difference is important at the moment). One downside of this solution is, that I inferred the detection method from the OSA files I had at hand (with the help of the magic file definition I mentioned earlier, but it’s unclear if that header is based on knowledge of Apple’s source code).

So I am considering to use the header-detection version of the script. And since you guys created the AppleScript Debugger file format, you probably know if my assumption is correct. But it’s no problem if you do not confirm my assumption. No hard feelings.

Thanks actually for the reference suggestion to get a NSError returned. However, the line still throws an exception on Mojave. Maybe I’ll dig deeper into the OSA api, but for now I leave the compiled and compileAndReturnError messages for what they are…

There’s no guarantee the file format won’t change – it has in the past.

API’s change too (like now with Mojave).

But true, file formats change too. Good argument.

Edit: just encountered this dialog. Nice!