Hi there,
I have some trouble with an OSX app distributed on the Apple Store.
It has been one month since I first notified Apple, still trying to find a solution.
So I tried as a test, to apply sandboxing to the JUCE OSX Demorunner. And, as for my app, the result was that the user can’t access outside its container.
BUT if I understand well my readings and as I have been told by the Apple Support, “The user can dynamically extend your sandbox by various user-level actions (the open and save panels, drag and drop, AppleScript).”. Isn’t the basic FileBrowser able to allow the user to do such a thing? Because they also suggested to use NSDocument
and NSDocumentController
… This is not a path I would like to take using JUCE.
JUCE uses an NSOpenSavePanelDelegate
internally in the FileChooser
.
This SO answer, cocoa - NSSavePanel and the Sandbox - Stack Overflow, provides this information:
After contacting Apple, I can confirm what Rob Keniger wrote:
NSOpenSavePanelDelegate
method’s don’t have access to the filesystem in sandboxed applications.
Ooh, thank you so much t0m. Should we infer that we can’t publish a signed OSX app with JUCE, within which the user will have the possibility to navigate outside the app container? I would be so surprised not to have seen other people complaining.
It appears that SO link was only for the NSOpenSavePanelDelegate
's methods itself. NSOpenPanel
should work. Have you tried enabling User Selected File
in the sandboxing settings?
I have checked com.apple.security.files.user-selected.read-write = true.
About NSOpenPanel: Apple answered me that " You typically [extend your sandbox] by using the open and save panels (NSOpenPanel
and NSSavePanel
). If your app uses the standard Cocoa document architecture (NSDocument
and NSDocumentController
) this mostly works by default. "
For some reason I had’nt seen that FileChooser uses NSOpenPanel. So it should work - but it doesn’t.
Also, a problem seems to show itself when I compile with “debug executable” on. The app breaks around the point below:
0x7fff6cff5af2 <+1873>: leaq 0x11f5(%rip), %r8 ; "Sandbox registration internal error: %s"
I have been troubleshooting the same issue today with Open/Save dialogs in a Sandboxed app on macOS. I’m building on macOS 12, where it works fine, but I had a report of the dialogs not working on an older macOS. So I’ve been testing on 10.11 (El Capitan) and I can reproduce the broken dialogs there.
If I don’t include an entitlements file when codesigning my app, it actually works fine on 10.11.
However, if I do include the entitlements file (which has the entry for com.apple.security.files.user-selected.read-write
), when the app is supposed to show an open or save dialog, it does nothing.
Looking in the Console app, I see errors shown like these:
SaveSavePanel_e57cba400d957299 is not a supported subclass for sandboxing
or
SaveOpenPanel_fa4915e8e75dbbeb is not a supported subclass for sandboxing
(Side note: the “SaveSave” wording looks weird on those – I’m pretty sure that’s due to a typo in juce_mac_FileChooser.mm, and it should be “SafeSave” and “SafeOpen” instead. I just submitted a pull request to address that.)
Anyways, fixing that typo didn’t make the sandboxed app work correctly in 10.11. Any other ideas as to what might be broken here, or should I just give up on sandboxing the app?
Here is the full error message with the trace, as appears in Console when trying to show a Save dialog:
1/10/23 2:00:08.733 PM MyApp[3790]: SaveSavePanel_e57cba400d957299 is not a supported subclass for sandboxing
1/10/23 2:00:08.896 PM MyApp[3790]: (
0 CoreFoundation 0x00007fff92ead452 __exceptionPreprocess + 178
1 libobjc.A.dylib 0x00007fff9971e73c objc_exception_throw + 48
2 CoreFoundation 0x00007fff92f1449d +[NSException raise:format:] + 205
3 AppKit 0x00007fff9a864433 +[NSSavePanel newRemotePanel] + 157
4 AppKit 0x00007fff9ac70f40 -[NSSavePanel initWithContentRect:styleMask:backing:defer:] + 94
5 AppKit 0x00007fff9a8648c0 -[NSPanel init] + 87
6 MyApp 0x000000010c2db56d _ZN4juce11FileChooser6NativeC2ERS0_iPNS_20FilePreviewComponentE + 669
7 MyApp 0x000000010c2db13b _ZN4juce11FileChooser6NativeC1ERS0_iPNS_20FilePreviewComponentE + 43
8 MyApp 0x000000010c2db093 _ZNSt3__120__shared_ptr_emplaceIN4juce11FileChooser6NativeENS_9allocatorIS3_EEEC2IJRS2_RiRPNS1_20FilePreviewComponentEEEES5_DpOT_ + 163
9 MyApp 0x000000010c2dad5d _ZNSt3__120__shared_ptr_emplaceIN4juce11FileChooser6NativeENS_9allocatorIS3_EEEC1IJRS2_RiRPNS1_20FilePreviewComponentEEEES5_DpOT_ + 45
10 MyApp 0x000000010c2dac34 _ZNSt3__1L15allocate_sharedIN4juce11FileChooser6NativeENS_9allocatorIS3_EEJRS2_RiRPNS1_20FilePreviewComponentEEvEENS_10shared_ptrIT_EERKT0_DpOT1_ + 148
11 MyApp 0x000000010c10f257 _ZNSt3__1L11make_sharedIN4juce11FileChooser6NativeEJRS2_RiRPNS1_20FilePreviewComponentEEvEENS_10shared_ptrIT_EEDpOT0_ + 103
12 MyApp 0x000000010c054457 _ZN4juce11FileChooser18showPlatformDialogERS0_iPNS_20FilePreviewComponentE + 55
13 MyApp 0x000000010c054030 _ZN4juce11FileChooser11createPimplEiPNS_20FilePreviewComponentE + 368
14 MyApp 0x000000010c053ce8 _ZN4juce11FileChooser10showDialogEiPNS_20FilePreviewComponentE + 56
15 MyApp 0x000000010c053e83 _ZN4juce11FileChooser19browseForFileToSaveEb + 51
16 MyApp 0x000000010c3f6937 _ZN14UserDataKeeper14exportAllAsZipEv + 1415
17 MyApp 0x000000010bc42227 _ZZN13SettingsPanelC1EvENKUlvE0_clEv + 39
18 MyApp 0x000000010bc421dd _ZNSt3__1L8__invokeIRZN13SettingsPanelC1EvEUlvE0_JEEEDTclclsr3std3__1E7forwardIT_Efp_Espclsr3std3__1E7forwardIT0_Efp0_EEEOS4_DpOS5_ + 29
19 MyApp 0x000000010bc4218d _ZNSt3__128__invoke_void_return_wrapperIvLb1EE6__callIJRZN13SettingsPanelC1EvEUlvE0_EEEvDpOT_ + 29
20 MyApp 0x000000010bc4215d _ZNSt3__110__function12__alloc_funcIZN13SettingsPanelC1EvEUlvE0_NS_9allocatorIS3_EEFvvEEclEv + 29
21 MyApp 0x000000010bc40ea9 _ZNSt3__110__function6__funcIZN13SettingsPanelC1EvEUlvE0_NS_9allocatorIS3_EEFvvEEclEv + 25
22 MyApp 0x000000010bc2bdc2 _ZNKSt3__110__function12__value_funcIFvvEEclEv + 50
23 MyApp 0x000000010bc2bd45 _ZNKSt3__18functionIFvvEEclEv + 21
24 MyApp 0x000000010c03e760 _ZN4juce6Button16sendClickMessageERKNS_12ModifierKeysE + 368
25 MyApp 0x000000010c03ee66 _ZN4juce6Button21internalClickCallbackERKNS_12ModifierKeysE + 166
26 MyApp 0x000000010c03f712 _ZN4juce6Button7mouseUpERKNS_10MouseEventE + 178
27 MyApp 0x000000010c02b25c _ZN4juce9Component15internalMouseUpENS_16MouseInputSourceERKNS_12PointerStateENS_4TimeENS_12ModifierKeysE + 572
28 MyApp 0x000000010c11a2b4 _ZN4juce24MouseInputSourceInternal11sendMouseUpERNS_9ComponentERKNS_12PointerStateENS_4TimeENS_12ModifierKeysE + 196
29 MyApp 0x000000010c118a5e _ZN4juce24MouseInputSourceInternal10setButtonsERKNS_12PointerStateENS_4TimeENS_12ModifierKeysE + 414
30 MyApp 0x000000010c031493 _ZN4juce24MouseInputSourceInternal11handleEventERNS_13ComponentPeerENS_5PointIfEENS_4TimeENS_12ModifierKeysEffNS_10PenDetailsE + 515
31 MyApp 0x000000010c03127d _ZN4juce16MouseInputSource11handleEventERNS_13ComponentPeerENS_5PointIfEExNS_12ModifierKeysEffRKNS_10PenDetailsE + 173
32 MyApp 0x000000010c0f414c _ZN4juce13ComponentPeer16handleMouseEventENS_16MouseInputSource15InputSourceTypeENS_5PointIfEENS_12ModifierKeysEffxNS_10PenDetailsEi + 204
33 MyApp 0x000000010c1c311b _ZN4juce19NSViewComponentPeer14sendMouseEventEP7NSEvent + 171
34 MyApp 0x000000010c1c3fe8 _ZN4juce19NSViewComponentPeer15redirectMouseUpEP7NSEvent + 88
35 MyApp 0x000000010c1c2519 _ZN4juce15JuceNSViewClass11callOnOwnerIMNS_19NSViewComponentPeerEFvP7NSEventEJRS4_EEEvP11objc_objectOT_DpOT0_ + 153
36 MyApp 0x000000010c1b6398 _ZN4juce15JuceNSViewClass12asyncMouseUpEP11objc_objectP13objc_selectorP7NSEvent + 56
37 MyApp 0x000000010c1b6447 _ZN4juce15JuceNSViewClass7mouseUpEP11objc_objectP13objc_selectorP7NSEvent + 55
38 AppKit 0x00007fff9adc7713 -[NSWindow _handleMouseUpEvent:isDelayedEvent:] + 119
39 AppKit 0x00007fff9adc83ad -[NSWindow _reallySendEvent:isDelayedEvent:] + 212
40 AppKit 0x00007fff9a807539 -[NSWindow sendEvent:] + 517
41 AppKit 0x00007fff9a787a38 -[NSApplication sendEvent:] + 2540
42 AppKit 0x00007fff9a5eedf2 -[NSApplication run] + 796
43 MyApp 0x000000010bedc7a9 _ZN4juce14MessageManager15runDispatchLoopEv + 153
44 MyApp 0x000000010bedc68f _ZN4juce19JUCEApplicationBase4mainEv + 399
45 MyApp 0x000000010bedc49c _ZN4juce19JUCEApplicationBase4mainEiPPKc + 60
46 MyApp 0x000000010bc7ce03 main + 51
47 libdyld.dylib 0x00007fff936bb5ad start + 1
48 ??? 0x0000000000000001 0x0 + 1
)
OK, I found the commit that broke the FileChooser
when running a Sandboxed app on an older macOS (again, I’m testing on macOS 10.11):
I tested with the DialogsDemo before and after this commit. When Sandboxed, the app after the commit will not show an open or save dialog, and it throws the console error I mentioned above, that the panel “is not a supported subclass for sandboxing”.
Before this commit, the file chooser works fine in a sandboxed build. And, if the app is not sandboxed, then it works fine regardless.
@reuk is it possible to keep your custom panel implementations, and still have them subclass the appropriate classes that make sandboxing happy (NSSavePanel
and NSOpenPanel
, as I understand it)?
Thanks for reporting, I’ve got a fix on the way.
A fix is now available:
Great, thank you. I’ll test it and let you know.
EDIT: It seems to have fixed the issue.
For those wanting to cherry pick the commit @reuk posted above, I’ll note that commit a9a95fe is also needed, so that SystemStats::isAppSandboxEnabled
exists