summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--ext/zlib/zlib.c20
-rw-r--r--test/zlib/test_zlib.rb23
3 files changed, 47 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 7388d14051..3722311746 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sat Feb 11 08:23:02 2012 Eric Hodel <drbrain@segment7.net>
+
+ * ext/zlib/zlib.c (do_inflate): Inflate more data if buffered data
+ exists. Allows Zlib::Inflate#set_dictionary to work.
+ [ruby-trunk - Bug #5929]
+
Sat Feb 11 06:00:48 2012 NARUSE, Yui <naruse@ruby-lang.org>
* dir.c (fnmatch): The * needs to be escaped to avoid formatting in
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index a235cbb621..6cc6d5571f 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -1732,7 +1732,7 @@ do_inflate(struct zstream *z, VALUE src)
return;
}
StringValue(src);
- if (RSTRING_LEN(src) > 0) { /* prevent Z_BUF_ERROR */
+ if (RSTRING_LEN(src) > 0 || z->stream.avail_in > 0) { /* prevent Z_BUF_ERROR */
zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
}
}
@@ -1749,7 +1749,23 @@ do_inflate(struct zstream *z, VALUE src)
*
* Raises a Zlib::NeedDict exception if a preset dictionary is needed to
* decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
- * call this method again with an empty string. (<i>???</i>)
+ * call this method again with an empty string to flush the stream:
+ *
+ * inflater = Zlib::Inflate.new
+ *
+ * begin
+ * out = inflater.inflate compressed
+ * rescue Zlib::NeedDict
+ * # ensure the dictionary matches the stream's required dictionary
+ * raise unless inflater.adler == Zlib.adler32(dictionary)
+ *
+ * inflater.set_dictionary dictionary
+ * inflater.inflate ''
+ * end
+ *
+ * # ...
+ *
+ * inflater.close
*
* See also Zlib::Inflate.new
*/
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index 8c2fbde8d9..da4f74c475 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -195,6 +195,29 @@ if defined? Zlib
z << "foo" # ???
end
+ def test_inflate_dictionary
+ dictionary = "foo"
+
+ deflate = Zlib::Deflate.new
+ deflate.set_dictionary dictionary
+ compressed = deflate.deflate "foofoofoo", Zlib::FINISH
+ deflate.close
+
+ out = nil
+ inflate = Zlib::Inflate.new
+
+ begin
+ out = inflate.inflate compressed
+
+ flunk "Zlib::NeedDict was not raised"
+ rescue Zlib::NeedDict
+ inflate.set_dictionary dictionary
+ out = inflate.inflate ""
+ end
+
+ assert_equal "foofoofoo", out
+ end
+
def test_sync
z = Zlib::Deflate.new
s = z.deflate("foo" * 1000, Zlib::FULL_FLUSH)