Skip to content

Decoder throws exception when decoding an empty map #719

@kika

Description

@kika

I'm sending a message from the Rust backend which has almost all fields set to default (either 0 or empty string or empty repeated). I understand that in such case protobuf just "optimizes away" such values. Upon receiving this message the Dart code throws a nullcheck exception from runtime.

Here's the .proto code:

syntax = "proto3";
message ProtoPara {
    string id = 1;
}
message ProtoPage {
    uint32  page_id = 1;
    repeated ProtoPara paras = 2;
}
message ProtoBoard {
    string id       = 1;
    string team_id  = 2;
    map<uint32, ProtoPage> pages = 3;
}
message ProtoMessage {
    oneof msg {
        ProtoBoard board = 1;
    }
    optional string request_id = 100;
}

The message only has ProtoBoard.id set to something and also the ProtoMessage.request_id. The pages map contains a default a single value of ProtoPage (page_id is 0 and paras array is empty). A binary dump of the message which is read by protoc --decode without a problem: ChAKDDNIVkJHVGpJODBLZhoAogYRb3BlbmJvYXJkTmpkOTc3ZjA=

$ echo "ChAKDDNIVkJHVGpJODBLZhoAogYRb3BlbmJvYXJkTmpkOTc3ZjA=" | base64 -d |protoc -I . --decode ProtoMessage proto.proto
board {
  id: "3HVBGTjI80Kf"
  pages {
    key: 0
    value {
    }
  }
}

$ dart pub global list
protoc_plugin 20.0.1

protobuf package is at 2.1.0

Stack trace:

packages/protobuf/src/protobuf/pb_map.dart 110:73                                 [_mergeEntry]
packages/protobuf/src/protobuf/coded_buffer.dart 190:48                           _mergeFromCodedBufferReader
packages/protobuf/src/protobuf/generated_message.dart 170:5                       mergeFromCodedBufferReader
packages/protobuf/src/protobuf/coded_buffer_reader.dart 103:12                    readMessage
packages/protobuf/src/protobuf/coded_buffer.dart 122:14                           _mergeFromCodedBufferReader
packages/protobuf/src/protobuf/generated_message.dart 185:5                       mergeFromBuffer
packages/myprotocol/generated/myprotocol.pb.dart 1195:130                  <fn>
packages/myprotocol/generated/myprotocol.pb.dart 1195:150                  fromBuffer
packages/myapp/backend/websocket.dart 129:42                                 receive
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 325:40               runBody
dart-sdk/lib/async/zone.dart 1685:54                                              runUnary

(skipped all below zone)

Changelog refers to some similar bug fixed in 2.0.1 but I can' seem to be able to find it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions