test and fix for BSON w/ negative integers. raise RangeError for out of range ints
This commit is contained in:
parent
a9aa5e5271
commit
37d6e16fe7
|
@ -151,6 +151,10 @@ static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow
|
|||
switch(TYPE(value)) {
|
||||
case T_BIGNUM:
|
||||
{
|
||||
if (rb_funcall(value, rb_intern(">"), 1, INT2NUM(2147483647)) == Qtrue ||
|
||||
rb_funcall(value, rb_intern("<"), 1, INT2NUM(-2147483648)) == Qtrue) {
|
||||
rb_raise(rb_eRangeError, "MongoDB can only handle 4-byte ints - try converting to a double before saving");
|
||||
}
|
||||
write_name_and_type(buffer, key, 0x10);
|
||||
VALUE as_f = rb_funcall(value, rb_intern("to_f"), 0);
|
||||
int int_value = NUM2LL(as_f);
|
||||
|
|
|
@ -248,7 +248,10 @@ class BSON
|
|||
end
|
||||
|
||||
def deserialize_number_int_data(buf)
|
||||
buf.get_int
|
||||
# sometimes ruby makes me angry... why would the same code pack as signed
|
||||
# but unpack as unsigned
|
||||
unsigned = buf.get_int
|
||||
unsigned >= 2**32 / 2 ? unsigned - 2**32 : unsigned
|
||||
end
|
||||
|
||||
def deserialize_object_data(buf)
|
||||
|
@ -387,6 +390,9 @@ class BSON
|
|||
if type == NUMBER
|
||||
buf.put_double(val)
|
||||
else
|
||||
if val > 2**32 / 2 - 1 or val < -2**32 / 2
|
||||
raise RangeError.new "MongoDB can only handle 4-byte ints - try converting to a double before saving"
|
||||
end
|
||||
buf.put_int(val)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,6 +36,18 @@ class BSONTest < Test::Unit::TestCase
|
|||
doc = {'doc' => 42}
|
||||
@b.serialize(doc)
|
||||
assert_equal doc, @b.deserialize
|
||||
|
||||
doc = {"doc" => -5600}
|
||||
@b.serialize(doc)
|
||||
assert_equal doc, @b.deserialize
|
||||
|
||||
doc = {"doc" => 2147483647}
|
||||
@b.serialize(doc)
|
||||
assert_equal doc, @b.deserialize
|
||||
|
||||
doc = {"doc" => -2147483648}
|
||||
@b.serialize(doc)
|
||||
assert_equal doc, @b.deserialize
|
||||
end
|
||||
|
||||
def test_ordered_hash
|
||||
|
@ -195,6 +207,21 @@ class BSONTest < Test::Unit::TestCase
|
|||
0x00, 0x00, 0x00])
|
||||
end
|
||||
|
||||
def test_overflow
|
||||
doc = {"x" => 2**45}
|
||||
assert_raise RangeError do
|
||||
@b.serialize(doc)
|
||||
end
|
||||
|
||||
doc = {"x" => 2147483647}
|
||||
assert_equal doc, @b.deserialize(@b.serialize(doc).to_a)
|
||||
|
||||
doc["x"] = doc["x"] + 1
|
||||
assert_raise RangeError do
|
||||
@b.serialize(doc)
|
||||
end
|
||||
end
|
||||
|
||||
def test_do_not_change_original_object
|
||||
val = OrderedHash.new
|
||||
val['not_id'] = 1
|
||||
|
|
Loading…
Reference in New Issue