Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save hannahwhy/1261040 to your computer and use it in GitHub Desktop.

Select an option

Save hannahwhy/1261040 to your computer and use it in GitHub Desktop.
[PATCH] Zlib::GzipWriter#write segfaults when given large (2^23 byte) strings
From 28fa610732b8621bbac1019be00622ac77caee24 Mon Sep 17 00:00:00 2001
From: David Yip <[email protected]>
Date: Fri, 30 Sep 2011 21:34:24 -0500
Subject: [PATCH 1/2] Example for compression of large strings. #1178.
The expected output was generated by the following Ruby program run in
Ruby 1.8.7-p352:
require 'stringio'
require 'zlib'
io = StringIO.new
input = '.' * (2 ** 23)
Zlib::GzipWriter.wrap(io) do |gzio|
gzio.write(input)
end
print io.string
It was run as
ruby gen.rb | hexdump -C
which resulted in the following output:
00000000 1f 8b 08 00 b9 a8 8a 4e 00 03 ec c1 81 00 00 00 |.......N........|
00000010 00 80 20 a3 fd f1 16 a9 0a 00 00 00 00 00 00 00 |.. .............|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001010 00 00 00 00 00 00 00 80 db 83 03 02 00 00 00 00 |................|
00001020 21 ff 5f 37 24 00 00 00 00 00 00 00 00 00 00 00 |!._7$...........|
00001030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001fe0 00 00 00 00 00 00 9c 05 c2 9f 5a 5a 00 00 80 00 |..........ZZ....|
00001ff0
This output was then transcribed into a concatenation of Ruby strings.
---
spec/ruby/library/zlib/gzipwriter/write_spec.rb | 27 +++++++++++++++++++---
1 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/spec/ruby/library/zlib/gzipwriter/write_spec.rb b/spec/ruby/library/zlib/gzipwriter/write_spec.rb
index 21c6f4e..0e6fe2c 100644
--- a/spec/ruby/library/zlib/gzipwriter/write_spec.rb
+++ b/spec/ruby/library/zlib/gzipwriter/write_spec.rb
@@ -6,19 +6,38 @@ require 'zlib'
describe "GzipWriter#write" do
before :each do
- @data = '12345abcde'
- @zip = "\037\213\b\000,\334\321G\000\00334261MLJNI\005\000\235\005\000$\n\000\000\000"
@io = StringIO.new ""
end
it "writes some compressed data" do
+ input = '12345abcde'
+ output = "\037\213\b\000,\334\321G\000\00334261MLJNI\005\000\235\005\000$\n\000\000\000"
+
Zlib::GzipWriter.wrap @io do |gzio|
- gzio.write @data
+ gzio.write input
end
# skip gzip header for now
- @io.string[10..-1].should == @zip[10..-1]
+ @io.string[10..-1].should == output[10..-1]
end
+ it "handles inputs of 2^23 bytes" do
+ input = '.' * (2 ** 23)
+ output = "\x1F\x8B\x08\x00\x5D\xA3\x8A\x4E" + "\x00\x03\xEC\xC1\x81\x00\x00\x00" +
+ "\x00\x80\x20\xA3\xFD\xF1\x16\xA9" + "\x0A\x00\x00\x00\x00\x00\x00\x00" +
+ "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" +
+ ("\x00" * 0xFE0) +
+ "\x00\x00\x00\x00\x00\x00\x00\x80" + "\xDB\x83\x03\x02\x00\x00\x00\x00" +
+ "\x21\xFF\x5F\x37\x24\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" +
+ "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00" +
+ ("\x00" * 0xFA0) +
+ "\x00\x00\x00\x00\x00\x00\x9C\x05" + "\xC2\x9F\x5A\x5A\x00\x00\x80\x00"
+
+ Zlib::GzipWriter.wrap @io do |gzio|
+ gzio.write input
+ end
+
+ @io.string[10..-1].should == output[10..-1]
+ end
end
--
1.7.6.3
From f0fd2c4c2175ea8769e5d79c20a632825dd6a73a Mon Sep 17 00:00:00 2001
From: David Yip <[email protected]>
Date: Tue, 4 Oct 2011 01:07:43 -0500
Subject: [PATCH 2/2] Calculate a checksum CHUNK bytes at a time. #1178.
---
lib/zlib.rb.ffi | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/lib/zlib.rb.ffi b/lib/zlib.rb.ffi
index 867816e..73ac7d6 100644
--- a/lib/zlib.rb.ffi
+++ b/lib/zlib.rb.ffi
@@ -1,3 +1,5 @@
+require 'stringio'
+
##
# The Zlib module contains several classes for compressing and decompressing
# streams, and for working with "gzip" files.
@@ -1305,11 +1307,15 @@ module Zlib
data = String data
if data.length > 0 or sync? then
- @crc = Zlib.crc32_c @crc, data, data.length
+ io = StringIO.new(data)
+
+ while chunk = io.read(CHUNK)
+ @crc = Zlib.crc32_c @crc, chunk, chunk.length
- flush = sync? ? Zlib::SYNC_FLUSH : Zlib::NO_FLUSH
+ flush = sync? ? Zlib::SYNC_FLUSH : Zlib::NO_FLUSH
- @zstream.run data, flush
+ @zstream.run chunk, flush
+ end
end
write_raw
--
1.7.6.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment