Skip to content

Support internal null characters in NSString initializers [SR-2225] #496

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed

Support internal null characters in NSString initializers [SR-2225] #496

wants to merge 2 commits into from

Conversation

xwu
Copy link
Contributor

@xwu xwu commented Jul 31, 2016

This PR aims to fix a discrepancy in NSString between corelibs-foundation and Apple Foundation. Namely, initialization of an NSString from a byte sequence currently calls CFStringCreateWithBytes(_:_:_:_:_:), which cannot accept null characters. Instead, switch to using CFStringCreateFromExternalRepresentation(_:_:_:).

Resolves SR-2225.

Note: I'm having trouble getting TestFoundation to compile in Xcode at the moment, but I've checked that previous builds of corelibs-foundation fail the test supplied, while Apple Foundation passes that test.

@DaveLiu888
Copy link
Contributor

@xwu how are you building AppFoundation and Tests? Which snapshot are you using and Xcode version. I am having trouble building and testing as well after i update to master from 7/29?

return CFStringCreateWithBytes(kCFAllocatorDefault, bytes, data.count, CFStringConvertNSStringEncodingToEncoding(encoding), true)
}) else { return nil }

guard let cf = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, data._cfObject, CFStringConvertNSStringEncodingToEncoding(encoding)) else { return nil }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The story of what happens on Darwin here is fairly complicated, which is probably why this was different in the first place, but it boils down to this:

- initWithData:(NSData *)data encoding:(NSStringEncoding)encoding {
    return (id)CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, (CFDataRef)data, CFStringConvertNSStringEncodingToEncoding(encoding));
}

So this change looks correct.

@parkera
Copy link
Contributor

parkera commented Aug 13, 2016

I debugged this a bit. I'm not finished yet, but I think the discrepancy has to do with the bridging happening after the CFString initialization. The CFString call returns the same result on both platforms (reading past the NULL).

@xwu
Copy link
Contributor Author

xwu commented Aug 14, 2016

Wow, that's neat. CFStringGetLength() is showing that there's more characters returned from CFStringCreateWithBytes than what's printed after bridging.

For now, I'll create another PR with the change for init?(data:encoding:). I can think of maybe some hacky ways to get the rest to work, but since you're already debugging I'll defer to you.

@xwu
Copy link
Contributor Author

xwu commented Aug 14, 2016

@parkera I bet you've found it too, but things go awry during bridging because, if type(of: x) == _NSCFString.self, bridging is performed by calling CFStringGetCStringPtr(_:_:) followed by String(cString:). If the cost isn't too great, one solution would be to use this result only if result.utf16.count == CFStringGetLength(cf).

@xwu
Copy link
Contributor Author

xwu commented Aug 14, 2016

@DaveLiu888 Sorry for the delayed reply. I put off hacking on corelibs-foundation directly for a few days. Everything is now building fine for me with the 8/7 snapshot (although I did have to disable the NSString reflection test, which segfaults).

@parkera
Copy link
Contributor

parkera commented Aug 15, 2016

I actually didn't get too much further on this (we've been busy getting all of those API changes landed).

@DaveLiu888
Copy link
Contributor

@xwu thanks for the update yea everything is working for me as well. 👍

@xwu
Copy link
Contributor Author

xwu commented Aug 15, 2016

@parkera OK, I will forge ahead and see how far I get with this. Since the solution is taking a different turn, I'll close this PR and open another one once I have something presentable. I'll roll in the init?(data:encoding:) change there as well.

@xwu xwu closed this Aug 15, 2016
@parkera
Copy link
Contributor

parkera commented Aug 15, 2016

Cool, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants