diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 982933b..0163129 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -434,7 +434,9 @@ do_checksum(int argc, VALUE *argv, checksum_func func) } if (NIL_P(str)) { - sum = func(mask32(sum), Z_NULL, 0); + /* zlib returns the initial value for a NULL buffer, which would discard + * an explicitly given running checksum; behave like an empty string */ + sum = NIL_P(vsum) ? func(0, Z_NULL, 0) : func(mask32(sum), (const Bytef *)"", 0); } else if (rb_obj_is_kind_of(str, rb_cIO)) { VALUE buf; diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index 1f9cb81..efacd24 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -1647,6 +1647,15 @@ def test_crc32_combine end end + def test_checksum_nil_with_initial_value + assert_equal(Zlib.crc32("", 1234), Zlib.crc32(nil, 1234)) + assert_equal(1234, Zlib.crc32(nil, 1234)) # was 0 + assert_equal(1234, Zlib.adler32(nil, 1234)) # was 1 + assert_equal(Zlib.adler32("", 2**31 - 1), Zlib.adler32(nil, 2**31 - 1)) + assert_equal(0, Zlib.crc32(nil)) + assert_equal(1, Zlib.adler32(nil)) + end + def test_crc_table t = Zlib.crc_table assert_instance_of(Array, t)