未验证 提交 237948d9 编写于 作者: C Chris Bracken 提交者: GitHub

Decode empty message to nil in standard codec (#25064)

This updates Flutter.*Codec `decode:` implementations to treat empty
messages as equivalent to nil or NSNull, which avoids a crash when we
subsequently otherwise try to read the type/value from the message. This
handles the case where the sender were to send `null` over the channel.
e.g.,

    final channel = BasicMessageChannel<Object?>('somechannel', StandardMessageCodec());
    channel.send(null);

It also updates the macOS embedder to send nil to the decoder when a
zero-length message is received in order to be consistent with the iOS
embedding.

Previously, the macOS embedder always encoded platform messages as
NSData regardless of length:
https://github.com/flutter/engine/blob/ba93431e6885f94614d91c291ae0336bac6b70b0/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm#L498-L500

The iOS embedder did not have this issue since it special-cased
zero-length messages as nil:
https://github.com/flutter/engine/blob/ba93431e6885f94614d91c291ae0336bac6b70b0/shell/platform/darwin/ios/framework/Source/platform_message_router.mm#L23-L26

Bug: https://github.com/flutter/flutter/issues/78003
上级 de59c6fc
......@@ -78,7 +78,7 @@
}
- (id)decode:(NSData*)message {
if (message == nil)
if ([message length] == 0)
return nil;
BOOL isSimpleValue = NO;
id decoded = nil;
......
......@@ -45,7 +45,7 @@
}
- (id)decode:(NSData*)message {
if (message == nil)
if ([message length] == 0)
return nil;
FlutterStandardReader* reader = [_readerWriter readerWithData:message];
id value = [reader readValue];
......
......@@ -42,6 +42,11 @@ TEST(FlutterStringCodec, CanEncodeAndDecodeNonBMPString) {
ASSERT_TRUE([value isEqualTo:decoded]);
}
TEST(FlutterJSONCodec, CanDecodeZeroLength) {
FlutterJSONMessageCodec* codec = [FlutterJSONMessageCodec sharedInstance];
ASSERT_TRUE([codec decode:[NSData data]] == nil);
}
TEST(FlutterJSONCodec, CanEncodeAndDecodeNil) {
FlutterJSONMessageCodec* codec = [FlutterJSONMessageCodec sharedInstance];
ASSERT_TRUE([codec encode:nil] == nil);
......
......@@ -30,6 +30,12 @@ void checkEncodeDecode(id value) {
ASSERT_TRUE([value isEqual:decoded]);
}
TEST(FlutterStandardCodec, CanDecodeZeroLength) {
FlutterStandardMessageCodec* codec = [FlutterStandardMessageCodec sharedInstance];
id decoded = [codec decode:[NSData data]];
ASSERT_TRUE(decoded == nil);
}
TEST(FlutterStandardCodec, CanEncodeAndDecodeNil) {
checkEncodeDecode(nil, nil);
}
......
......@@ -495,9 +495,12 @@ static void OnPlatformMessage(const FlutterPlatformMessage* message, FlutterEngi
}
- (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message {
NSData* messageData = [NSData dataWithBytesNoCopy:(void*)message->message
length:message->message_size
freeWhenDone:NO];
NSData* messageData = nil;
if (message->message_size > 0) {
messageData = [NSData dataWithBytesNoCopy:(void*)message->message
length:message->message_size
freeWhenDone:NO];
}
NSString* channel = @(message->channel);
__block const FlutterPlatformMessageResponseHandle* responseHandle = message->response_handle;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册