Why is the return value of String.addingPercentEncoding() optional?

六眼飞鱼酱① 提交于 2019-11-27 21:08:34

I filed a bug report with Apple about this, and heard back — with a very helpful response, no less!

Turns out (much to my surprise) that it’s possible to successfully create Swift strings that contain invalid Unicode in the form of unpaired UTF-16 surrogate chars. Such a string can cause UTF-8 encoding to fail. Here’s some code that illustrates this behavior:

// Succeeds (wat?!):
let str = String(
    bytes: [0xD8, 0x00] as [UInt8],
    encoding: String.Encoding.utf16BigEndian)!

// Returns nil:
str.addingPercentEncoding(withAllowedCharacters:
    CharacterSet.alphanumerics)

Based on Paul Cantrell answer, small demonstration that it's also possible for the same method to also return null in Objective-C, despite String and NSString being different beasts when it comes to encodings:

uint8_t bytes[2] = { 0xD8, 0x00 };
NSString *string = [[NSString alloc] initWithBytes:bytes length:2 encoding:NSUTF16BigEndianStringEncoding];
// \ud800
NSLog(@"%@", string);

NSString *escapedString = [string stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLHostAllowedCharacterSet];
// (null)
NSLog(@"%@", escapedString);

For fun, https://r12a.github.io/app-conversion/ will percent escape the same as:

Error%20in%20convertUTF162Char%3A%20low%20surrogate%20expected%2C%20b%3D0%21%00

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!