From a1e3041cd3d516549ac24ce300c9d8f4d865ee80 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Sun, 25 Oct 2026 03:05:39 +0900 Subject: [PATCH] Reject a negative length in Zlib.crc32_combine zlib 1.3.1 loops forever in x2nmodp() on a negative length, and the loop cannot be interrupted. Zlib.crc32_combine(0, 0, -1) #=> never returns (with zlib 1.3.1) Co-Authored-By: Claude Opus 5.5 --- ext/zlib/zlib.c | 8 +++++++- test/zlib/test_zlib.rb | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) 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)