diff --git a/ext/cbson/cbson.c b/ext/cbson/cbson.c index 57f1c63fc8..2999752e70 100644 --- a/ext/cbson/cbson.c +++ b/ext/cbson/cbson.c @@ -436,9 +436,9 @@ static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) { } if (strcmp(cls, "BSON::Timestamp") == 0) { write_name_and_type(buffer, key, 0x11); - int seconds = FIX2INT( + unsigned int seconds = NUM2UINT( rb_funcall(value, rb_intern("seconds"), 0)); - int increment = FIX2INT( + unsigned int increment = NUM2UINT( rb_funcall(value, rb_intern("increment"), 0)); SAFE_WRITE(buffer, (const char*)&increment, 4); @@ -830,12 +830,12 @@ static VALUE get_value(const char* buffer, int* position, int type) { } case 17: { - int sec, inc; + unsigned int sec, inc; VALUE argv[2]; memcpy(&inc, buffer + *position, 4); memcpy(&sec, buffer + *position + 4, 4); - argv[0] = INT2FIX(sec); - argv[1] = INT2FIX(inc); + argv[0] = UINT2NUM(sec); + argv[1] = UINT2NUM(inc); value = rb_class_new_instance(2, argv, Timestamp); *position += 8; break; diff --git a/test/bson/timestamp_test.rb b/test/bson/timestamp_test.rb index f12b24ff5c..b023f7701e 100644 --- a/test/bson/timestamp_test.rb +++ b/test/bson/timestamp_test.rb @@ -19,6 +19,16 @@ def test_timestamp_range end end + def test_timestamp_32bit_compatibility + max_32bit_fixnum = (1 << 30) - 1 + test_val = max_32bit_fixnum + 10 + + ts = Timestamp.new(test_val, test_val) + doc = {:ts => ts} + bson = BSON::BSON_CODER.serialize(doc) + assert_equal doc[:ts], BSON::BSON_CODER.deserialize(bson)['ts'] + end + def test_implements_array_for_backward_compatibility silently do ts = Timestamp.new(5000, 200)