Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converting message in ruby to proto and then back results nil instead of the original message #7355

Closed
iuri-gg opened this issue Apr 3, 2020 · 3 comments

Comments

@iuri-gg
Copy link

iuri-gg commented Apr 3, 2020

What version of protobuf and what language are you using?
Version: v3.11.4
Language: Ruby (v2.6.5)

What operating system (Linux, Windows, ...) and version?
MacOS 10.15

What runtime / compiler are you using (e.g., python version or gcc version)

What did you do?
Steps to reproduce the behavior:

  1. Load IRB and require protobuf value wrappers: require "google/protobuf/wrappers_pb"
  2. Create new Int64Value object with value set to 0: v = Google::Protobuf::Int64Value.new(value: 0)
  3. Convert v to serialized string and back to object: new_v = Google::Protobuf::Int64Value.decode(v.to_proto)
  4. Observer that new_v is nil instead of Int64Value: v == new_v # => false

What did you expect to see
I expected new_v to be Int64Value with value set to 0

What did you see instead?
new_v is nil

Bigger problem
My issue actually is more complicated but the root cause boils down to this issue above. To see how this issue is actually causing weird exceptions within the protobuf gem itself, consider a new message type:

message Value {
  oneof types {
    google.protobuf.StringValue id = 1;
    google.protobuf.Int64Value integer = 2;
  }
}

When compiled into ruby code, we will get code similar to one below:

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: value.proto

require 'google/protobuf'

require 'google/protobuf/wrappers_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
  add_file("value.proto", :syntax => :proto3) do
    add_message "Value" do
      oneof :types do
        optional :id, :message, 1, "google.protobuf.StringValue"
        optional :integer, :message, 2, "google.protobuf.Int64Value"
      end
    end
  end
end

Value = Google::Protobuf::DescriptorPool.generated_pool.lookup("Value").msgclass

Now if you try to create new Value with integer set to 0, you will not be able to decode proto version of it:

v = Value.new(integer: Google::Protobuf::Int64Value.new(value: 0))
Value.decode(v.to_proto) # => Google::Protobuf::TypeError (Expected number type for integral field 'value' (given FalseClass).)
@kruczjak
Copy link

kruczjak commented Oct 1, 2020

Hi, I have exactly same problem using same protobuf version but on linux.

I've also just tested it on latest version (3.13.0) and same problem happens.

@ob-stripe
Copy link

It looks like this issue was fixed in 3.15.0.

Using this test script:

require "google/protobuf/wrappers_pb"

v = Google::Protobuf::Int64Value.new(value: 0)
p v

new_v = Google::Protobuf::Int64Value.decode(v.to_proto)
p new_v

With google-protobuf 3.14.0, the output is:

<Google::Protobuf::Int64Value: value: 0>
nil

With google-protobuf 3.15.0, the output is:

<Google::Protobuf::Int64Value: value: 0>
<Google::Protobuf::Int64Value: value: 0>

I suspect the refactor in #8184 may have fixed this issue.

@haberman
Copy link
Member

Thanks for the udpate! I think you are correct that #8184 was what fixed this. I'll resolve this issue now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants