feat: Introduce FlutterStringUtils for sanitizing UTF-8 data and JSON escape sequences.#179978
feat: Introduce FlutterStringUtils for sanitizing UTF-8 data and JSON escape sequences.#179978mahmuttaskiran wants to merge 2 commits into
Conversation
… escape sequences.
There was a problem hiding this comment.
Code Review
This pull request introduces a new Objective-C++ utility, FlutterStringUtils, containing the function FlutterSanitizeUTF8ForJSON. This function is designed to sanitize NSData by performing a lossy UTF-8 decoding and replacing unpaired surrogate escape sequences. The FlutterJSONMessageCodec is modified to use this sanitization function on incoming NSData before attempting JSON deserialization, aiming to prevent crashes on invalid input. The changes include the implementation and header for FlutterStringUtils, along with corresponding unit tests in FlutterStringUtilsTest.mm and flutter_codecs_unittest.mm. Build files (BUILD.gn, framework_common.gni) are updated to include the new files. My feedback includes a suggestion to simplify the UTF-8 decoding logic for improved maintainability.
LongCatIsLooong
left a comment
There was a problem hiding this comment.
I did some experiments and it turns out NSJSONSerialization can handle unpaired surrogates, if the input data is using UTF16 encoding, unfortunately the process is still lossy (those surrogates are replace with U+FFFD, same as this implementation).
Since this is a rare and "best-effort" case so ease of maintenance > performance, I think we can first turn the NSData to utf16 string and let NSJSONSerialization deserialize the utf16 data?
|
In other words I think we can reuse logic that already exists in my example Swift playground does this and it seems to work fine: import UIKit
var data = "hello".data(using: .utf16)!
data.append(Data([0x00, 0xDB]))
let string = NSString(data: data, encoding: NSUTF16StringEncoding)!
let rawJSON = "[\"\(string)\"]"
let json = try? JSONSerialization.jsonObject(with: rawJSON.data(using: .utf16)!) |
Thanks for the suggestion! I tried implementing the UTF-16 approach, but unfortunately it didn't work When I changed the code to:
OR in FlutterJSONMessageCodec::decode NSString* string = [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding];
NSData* utf16Message = [string dataUsingEncoding:NSUTF16StringEncoding];The app crashes because When trying with Swift's |
|
I looked into what did the string sanitization in the swift case, it turns out to be one of the |
Alright, then I'm going to close this PR? |
I made #181921 but ran into issues with swift name mangling. I'm going to turn this into a draft since #181921 should fix the crash when merged. |
|
Hey @mahmuttaskiran, checking in here during triage. Is this superseded by #181921? |
Hey, it's yes. Closing it now. Sorry for late |
This change addresses #179727 by introducing
FlutterStringUtils. With this approach, iOS and Android now behave consistently.Please also refer to #179775 for the previous discussion and related context.
Pre-launch Checklist
///).