From 047419a1729b3b0cb57dc7f78b93d18fb430b6c4 Mon Sep 17 00:00:00 2001 From: Brendan Ribera Date: Tue, 30 Aug 2016 16:21:33 -0700 Subject: failing test for #2036: * add a repeated field to the tested hash * also assert that two messages with identical values produce identical hashes --- ruby/tests/basic.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ruby') diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index 8b6d329e..989a047e 100644 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -183,12 +183,15 @@ module BasicTest def test_hash m1 = TestMessage.new(:optional_int32 => 42) - m2 = TestMessage.new(:optional_int32 => 102) + m2 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?']) + m3 = TestMessage.new(:optional_int32 => 102, repeated_string: ['please', 'work', 'ok?']) assert m1.hash != 0 assert m2.hash != 0 + assert m3.hash != 0 # relying on the randomness here -- if hash function changes and we are # unlucky enough to get a collision, then change the values above. assert m1.hash != m2.hash + assert_equal m2.hash, m3.hash end def test_unknown_field_errors -- cgit v1.2.3 From de028631fce33b77811f2a29c83c36ab875c751c Mon Sep 17 00:00:00 2001 From: Brendan Ribera Date: Tue, 30 Aug 2016 16:22:49 -0700 Subject: fix #2036: use `rb_hash_*` to accumulate hashes Instead of shifting/xoring the hash at each field, use the built-in ruby apis for generating a hash from multiple input values. Now returns a Fixnum. --- ruby/ext/google/protobuf_c/repeated_field.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'ruby') diff --git a/ruby/ext/google/protobuf_c/repeated_field.c b/ruby/ext/google/protobuf_c/repeated_field.c index 47c207a5..1c651c19 100644 --- a/ruby/ext/google/protobuf_c/repeated_field.c +++ b/ruby/ext/google/protobuf_c/repeated_field.c @@ -447,9 +447,8 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) { */ VALUE RepeatedField_hash(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); - - VALUE hash = LL2NUM(0); - + st_index_t h = rb_hash_start(0); + VALUE hash_sym = rb_intern("hash"); upb_fieldtype_t field_type = self->field_type; VALUE field_type_class = self->field_type_class; size_t elem_size = native_slot_size(field_type); @@ -457,12 +456,11 @@ VALUE RepeatedField_hash(VALUE _self) { for (int i = 0; i < self->size; i++, off += elem_size) { void* mem = ((uint8_t *)self->elements) + off; VALUE elem = native_slot_get(field_type, field_type_class, mem); - hash = rb_funcall(hash, rb_intern("<<"), 1, INT2NUM(2)); - hash = rb_funcall(hash, rb_intern("^"), 1, - rb_funcall(elem, rb_intern("hash"), 0)); + h = rb_hash_uint(h, NUM2LONG(rb_funcall(elem, hash_sym, 0))); } + h = rb_hash_end(h); - return hash; + return INT2FIX(h); } /* -- cgit v1.2.3