diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index bcdd32a..fcd4928 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -532,8 +532,14 @@ rb_zlib_crc32(int argc, VALUE *argv, VALUE klass) static VALUE rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2) { + long len = NUM2LONG(len2); + + /* zlib 1.3.1 loops forever on a negative length */ + if (len < 0) { + rb_raise(rb_eArgError, "negative length"); + } return ULONG2NUM( - crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2))); + crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), len)); } #else #define rb_zlib_crc32_combine rb_f_notimplement diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index e1ecbf8..0794f9a 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -1634,6 +1634,12 @@ def test_crc32_combine end end + def test_crc32_combine_negative_length + assert_raise(ArgumentError) { Zlib.crc32_combine(0, 0, -1) } + rescue NotImplementedError + omit "crc32_combine is not implemented" + end + def test_crc_table t = Zlib.crc_table assert_instance_of(Array, t)