NSItemProvider throwing exception related to secure coding

Our app has a share extension. And we recently noticed something with iOS 17.3.1.

From Safari, when we receive the plist and try to load it, we are seeing exceptions for classes not allowed to be unarchived.

[itemProvider loadItemForTypeIdentifier:[UTTypePropertyList identifier] options:nil completionHandler:^(NSDictionary *jsDict, NSError *error) {
}

We see these exceptions:

value for key 'NS.keys' was of unexpected class 'NSString' (0x1ee7d2970) [/System/Library/Frameworks/Foundation.framework].
Allowed classes are:
 {(
    "'NSDictionary' (0x1ee7cad38) [/System/Library/Frameworks/CoreFoundation.framework]"
)}
(null)

Our preprocessing javascript file is basic, and only passes a title and URL as part of the payload.

arguments.completionFunction({
    "URL": document.URL
    "title": document.title,
});
value for key 'NS.keys' was of unexpected class 'NSString' (0x1ee7d2970) [/System/Library/Frameworks/Foundation.framework].
Allowed classes are:
 {(
    "'NSDictionary' (0x1ee7cad38) [/System/Library/Frameworks/CoreFoundation.framework]"
)}
(null)
Printing description of exception->exception:
Exception while decoding argument 0 (#1 of invocation):
<NSInvocation: 0x28224e600>
return value: {v} void
target: {@?} 0x0 (block)
argument 1: {@} 0x0
argument 2: {@} 0x0
Exception: value for key 'NS.keys' was of unexpected class 'NSString' (0x1ee7d2970) [/System/Library/Frameworks/Foundation.framework].
Allowed classes are:
 {(
    "'NSDictionary' (0x1ee7cad38) [/System/Library/Frameworks/CoreFoundation.framework]"
)}
(
	0   CoreFoundation                      0x000000019d576684 5A6C1F41-BF70-32F6-A1D6-5B894DD21362 + 968324
	...
)

This is interesting as well. I had a fix that was working, but now all of the sudden it's not.

[itemProvider loadDataRepresentationForTypeIdentifier:[UTTypePropertyList identifier] completionHandler:^(NSData * _Nullable data, NSError * _Nullable error) {
    ///use NSKeyedUnarchver to unarchive a dictionary.
}

The dictionary is decoded, but the result is empty:

{
    NSExtensionJavaScriptPreprocessingResultsKey =     {
    };
}

If you set an exception breakpoint (using the plus button at the bottom left of the Breakpoints navigator), what does the backtrace look like?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I have the same issue。

<NSXPCConnection: 0x2831280a0> connection to service with pid 1367 created from an endpoint: Exception caught during decoding of reply to message 'resolveWithIdentifier:className:options:reply:', dropping incoming message and calling failure block.

Ignored Exception: Exception while decoding argument 0 (#1 of invocation): <NSInvocation: 0x28153aec0> return value: {v} void target: {@?} 0x0 (block) argument 1: {@} 0x0 argument 2: {@} 0x0

Exception: value for key 'NS.objects' was of unexpected class 'NSString' (0x20286a970) [/System/Library/Frameworks/Foundation.framework]. Allowed classes are: {( "'NSDictionary' (0x202862d38) [/System/Library/Frameworks/CoreFoundation.framework]" )}

@eskimo Do you have any internal Apple connections to help investigate this?

qiuyg wrote:

I have the same issue.

Is it actually the same issue?

I realise it’s the same exception, but gngrwzrd was specifically talking about interacting with Safari, and the backtrace in your post has no evidence to confirm or deny that. Can you explain more about the context in which you’re seeing this failure?


Do you have any internal Apple connections to help investigate this?

Well, yes, that’s pretty much my day job here in DTS (-:

However, I was hoping to handle this here, so everyone can benefit. Were you able to run the test I suggested earlier?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo Thanks. Yes here is the stack trace. I had to take an image because the forum is not letting me include it - it's saying something is inappropriate :).

Also to add a bit more info - this only happens from the Safari share button that's built into the window chrome. And I attached an another screen - the red circle is where this exception is thrown from.

@eskimo There's also a second exception but this doesn't appear to be the source.

So, lemme see if I understand the sequence correctly:

  1. Use taps the share button and invokes your extension.

  2. Your extension calls -loadItemForTypeIdentifier:options:completionHandler:, as you showed in your first post, supplying a completion handler.

  3. Your process crashes with this exception before that completion handler is called.

Is that right?

And this happens with any website, not just the one you specifically mentioned?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo Correct. Any website. Not just the screenshot provided.

OK.

This worked in previous systems, right?

Your code snippet shows you requesting the UTTypePropertyList type (com.apple.property-list). Presumably that returned a dictionary of properties. What properties were you relying on?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo Yes it worked in previous systems. It seemed to be the release iOS 17.3.1. As I mentioned in my first post. When the share button is pressed, Apple / Safari runs a preprocessor.js file, which has a callback that gets encoded as a plist, and passed to the share extension. Ours sends only two keys:

arguments.completionFunction({
    "URL": document.URL
    "title": document.title,
});

So the plist (dictionary) only contains NSString type. Which is currently not allowed to be decoded based on the exception thrown.

Hmmm, tricky.

Does this reproduce on the 17.4rc?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo Yes in iOS 17.4 simulator it still happens.

@eskimo I put together a demo. I actually stumbled across the solution as I was putting this together. The issue is Objective-C VS Swift. My project is using Objectice-C to ask for a plist from NSItemProvider. When I use swift however, there's no problem. My demo has both so you can see it. Look at ViewController for instructions, and ShareViewController for objective-c VS swift. Also make sure to set an exception breakpoint for all objc exceptions.

How can I send you this demo, I can't upload zip files here.

@eskimo http://gngrwzrd.com/NSItemProvider.zip

@eskimo http://gngrwzrd.com/NSItemProvider.zip

Yes in iOS 17.4 simulator it still happens.

You really want to be testing this on a device rather than the sim, but let’s assume that it fails there for the moment.

The issue is Objective-C VS Swift.

Interesting. I’m struggling to come up with any explanation for that.

At this point I’m going to recommend that you open a DTS tech support incident and discuss this with my colleague who supports this technology.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo Were you able to see the demo I built?

@qiuyg Have you seen updates from this thread? I put together a demo project. What I see is Objc throws the exception, but a swift implementation doesn't have any errors.

Were you able to see the demo I built?

Yes.

However, per my response yesterday, I recommend that you start a DTS TSI for this. We’ve reached the limit of my expertise here. Specifically, we’ve strayed from Foundation and secure coding, which is very much my bailiwick, into Safari extensions, which is very much not.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo We've already updated ours to use the Swift equivalent API and it fixes it. If I open a DTS TSI for this does it count against us? Can you just forward my demo to your contact at Apple?

If I open a DTS TSI for this does it count against us?

Generally a TSI is ‘consumed’ if the assigned DTS engineer spends a significant amount of time working on it. As I’ve mentioned above, I’m not the expert in this area and thus this TSI won’t come to me and thus I can’t offer guidance as to its eventual fate.

I will say that, if you’re going to open a TSI, it’s best to have a specific goal in mind.

Can you just forward my demo to your contact at Apple?

To what end? If you think that this is a bug that should be fixed, you can put this in your bug report. OTOH, if you have a specific question you want answered, you can open a TSI and include it there.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

We ran into this issue as well.

Our Action Share extension worked properly in iOS 17.2.x but failed with this exception in 17.4.x:

Exception: value for key 'NS.objects' was of unexpected class 'NSString'

(
	0   CoreFoundation                      0x00007ff8004cd571 __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x00007ff8000837e8 objc_exception_throw + 48
	2   Foundation                          0x00007ff800fb2f5e -[NSXPCDecoder _validateAllowedClass:forKey:allowingInvocations:] + 474
	3   Foundation                          0x00007ff800fb393e _decodeObject + 733
	4   Foundation                          0x00007ff800fb4c11 __44-[NSXPCDecoder _decodeArrayOfObjectsForKey:]_block_invoke + 40
	5   Foundation                          0x00007ff800fcba65 _NSXPCSerializationIterateArrayObject + 192
	6   Foundation                          0x00007ff800fb4bc4 -[NSXPCDecoder _decodeArrayOfObjectsForKey:] + 205
	7   Foundation                          0x00007ff800dcd106 -[NSDictionary(NSDictionary) initWithCoder:] + 173
	8   Foundation                          0x00007ff800fb3b31 _decodeObject + 1232
	9   Foundation                          0x00007ff800fb4c11 __44-[NSXPCDecoder _decodeArrayOfObjectsForKey:]_block_invoke + 40
	10  Foundation                          0x00007ff800fcba65 _NSXPCSerializationIterateArrayObject + 192
	11  Foundation                          0x00007ff800fb4bc4 -[NSXPCDecoder _decodeArrayOfObjectsForKey:] + 205
	12  Foundation                          0x00007ff800dcd106 -[NSDictionary(NSDictionary) initWithCoder:] + 173
	13  Foundation                          0x00007ff800fb3b31 _decodeObject + 1232
	14  Foundation                          0x00007ff800fb35d6 -[NSXPCDecoder _decodeObjectOfClasses:atObject:] + 128
	15  Foundation                          0x00007ff800e1b28b _NSXPCSerializationDecodeTypedObjCValuesFromArray + 942
	16  Foundation                          0x00007ff800e1baf8 _NSXPCSerializationDecodeInvocationArgumentArray + 552
	17  Foundation                          0x00007ff800fb44fb -[NSXPCDecoder __decodeXPCObject:allowingSimpleMessageSend:outInvocation:outArguments:outArgumentsMaxCount:outMethodSignature:outSelector:isReply:replySelector:] + 822
	18  Foundation                          0x00007ff800fb41a6 -[NSXPCDecoder _decodeReplyFromXPCObject:forSelector:] + 78
	19  Foundation                          0x00007ff800fa42b4 -[NSXPCConnection _decodeAndInvokeReplyBlockWithEvent:sequence:replyInfo:] + 212
	20  Foundation                          0x00007ff800fa8fd7 __88-[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:]_block_invoke_3 + 205
	21  libxpc.dylib                        0x00007ff8000c8bec _xpc_connection_reply_callout + 36
	22  libxpc.dylib                        0x00007ff8000bd40c _xpc_connection_call_reply_async + 69
	23  libdispatch.dylib                   0x00007ff80017973e _dispatch_client_callout3 + 8
	24  libdispatch.dylib                   0x00007ff800197c37 _dispatch_mach_msg_async_reply_invoke + 609
	25  libdispatch.dylib                   0x00007ff800180f59 _dispatch_lane_serial_drain + 424
	26  libdispatch.dylib                   0x00007ff800181e17 _dispatch_lane_invoke + 406
	27  libdispatch.dylib                   0x00007ff80018d9a8 _dispatch_root_queue_drain_deferred_wlh + 276
	28  libdispatch.dylib                   0x00007ff80018cf72 _dispatch_workloop_worker_thread + 552
	29  libsystem_pthread.dylib             0x0000000108ec7c47 _pthread_wqthread + 327
	30  libsystem_pthread.dylib             0x0000000108ec6b97 start_wqthread + 15
)

Looks like there may be an Apple bug within NSXPCDecoder

As noted, the swift variant outputs this warning/error but still includes the applicable data:

-[_EXSinkLoadOperator loadItemForTypeIdentifier:completionHandler:expectedValueClass:options:] nil expectedValueClass allowing {(
    NSArray,
    NSMutableDictionary,
    NSUUID,
    NSDate,
    NSMutableData,
    _EXItemProviderSandboxedResource,
    NSValue,
    NSMutableArray,
    UIImage,
    NSNumber,
    NSError,
    NSMutableString,
    NSData,
    NSURL,
    NSDictionary,
    NSString,
    CKShare
)}

As a workaround, to get the Objective C variant to work we've adjusted our loadItemForTypeIdentifier:options:completionHandler: method code from this:

                [itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypePropertyList options:nil completionHandler:^(NSDictionary *itemDict, NSError *error) {
                    // process itemDict
                }];

to this:

                [itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypePropertyList options:nil completionHandler:^(id item, NSError *error) {
                    NSDictionary *itemDict = (NSDictionary *)item;
                    // process itemDict
                }];

which outputs the same warning/error as the swift variant but properly includes the data.

@eskimo Should I report this through feedback assistant as a bug? If so which "area" is appropriate to submit it under?

Should I report this through feedback assistant as a bug?

Yes. If nothing else, this is a binary compatibility regression.

If so which "area" is appropriate to submit it under?

Choose Developer Technologies & SDKs at the top level, and pick a framework from the technologies popup. For this and other tips, see Bug Reporting: How and Why?.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

NSItemProvider throwing exception related to secure coding
 
 
Q