protobufjs / protobuf.js

Protocol Buffers for JavaScript & TypeScript.
Other
9.86k stars 1.41k forks source link

Not correctly handling default value for proto3 doubles #923

Open judebusarello opened 6 years ago

judebusarello commented 6 years ago

protobuf.js version: 5.0.1

When decoding a proto3 message, if a double field is missing, protobufjs decodes it as null. It is supposed to default to 0.

https://developers.google.com/protocol-buffers/docs/proto3#default

dcodeIO commented 6 years ago

No plans to maintain 5.x anymore, sorry.

dhbaird commented 6 years ago

@dcodeIO I notice the same issue in protobuf.js 6.8.6. And I notice it for both double and int32 (possibly others?).

To reproduce:

  1. gRPC encodes { value: 0 } as an empty buffer (because proto3 doesn't require default values to be encoded).
  2. Protobuf.js incorrectly decodes the buffer as {} (expected { value: 0 }).

So, it seems protobuf.js is unable to decode the value zero (or perhaps any default value) being sent from a gRPC service. Is this already a known issue? Is there a flag I can set somewhere (either to force gRPC to encode default values; or force protobuf.js to do the right thing)?

Thanks.

dcodeIO commented 6 years ago

It doesn't decode the value zero, because it isn't on the wire, but the returned object still has value: 0 on its prototype. If you need a plain old JS object instead, there's .toObject that can populate the defaults as well.

dhbaird commented 6 years ago

Excellent, that helped. Thanks. (I still have some issues now with oneof decoding different in gRPC vs protobuf.js, but that's another issue.) For reference, here's my old (non-working) and new code,

// Old (bad)
pbjsDecode = function(buf) {
    return root.Msg.decode(buf);
}

// New (better)
pbjsDecode = function(buf) {
    return root.Msg.toObject(root.Msg.decode(buf), {
        defaults:true,
        oneofs:true
    });
}