-
Notifications
You must be signed in to change notification settings - Fork 15.7k
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
fix(ruby): Fix crash when calculating Message hash values on 64-bit Windows #8565
Conversation
Updated with a uniform mapping. |
ruby/ext/google/protobuf_c/message.c
Outdated
return INT2FIX(Message_Hash(self->msg, self->msgdef, 0)); | ||
uint64_t hash_value = Message_Hash(self->msg, self->msgdef, 0); | ||
// Fixnum is restricted to signed long, so downcast if necessary. | ||
long long_value = (long)hash_value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about:
// RUBY_FIXNUM_MAX should be one less than a power of 2.
assert(RUBY_FIXNUM_MAX & (RUBY_FIXNUM_MAX + 1) == 0);
return INT2FIX(hash_value & RUBY_FIXNUM_MAX);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that works. It restricts hash values to positive, but I think 32-bit hashes are always positive for most Ruby objects anyway.
Looking at the failed Ruby 2.4 test, I think we can address it by pinning the |
ruby/ext/google/protobuf_c/message.c
Outdated
return INT2FIX(Message_Hash(self->msg, self->msgdef, 0)); | ||
uint64_t hash_value = Message_Hash(self->msg, self->msgdef, 0); | ||
// RUBY_FIXNUM_MAX should be one less than a power of 2. | ||
assert(RUBY_FIXNUM_MAX & (RUBY_FIXNUM_MAX + 1) == 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, this is my bad, I always forget that the precedence of &
is low. It should be:
assert((RUBY_FIXNUM_MAX & (RUBY_FIXNUM_MAX + 1)) == 0);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, I forgot that too. Fixed.
SGTM. |
I added this change to the Gemfile. We can try rerunning the tests to make sure it works. |
Fixes #8564
On 64-bit Windows, it is unsafe to try to create a Fixnum from a 64-bit integer, because longs can hold only 32 bits. The code change below:
INT2FIX
./attn @haberman