Skip to content

Commit 82d5d26

Browse files
nobuhsbt
authored andcommitted
Fix buffer overflow at ungetc
1 parent f1ce5e3 commit 82d5d26

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

ext/zlib/zlib.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -851,9 +851,7 @@ zstream_buffer_ungets(struct zstream *z, const Bytef *b, unsigned long len)
851851
char *bufptr;
852852
long filled;
853853

854-
if (NIL_P(z->buf) || (long)rb_str_capacity(z->buf) <= ZSTREAM_BUF_FILLED(z)) {
855-
zstream_expand_buffer_into(z, len);
856-
}
854+
zstream_expand_buffer_into(z, len);
857855

858856
RSTRING_GETMEM(z->buf, bufptr, filled);
859857
memmove(bufptr + len, bufptr, filled);

test/zlib/test_zlib.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,25 @@ def test_ungetc_at_start_of_file
868868
assert_equal(-1, r.pos, "[ruby-core:81488][Bug #13616]")
869869
end
870870

871+
def test_ungetc_buffer_underflow
872+
initial_bufsize = 1024
873+
payload = "A" * initial_bufsize
874+
gzip_io = StringIO.new
875+
Zlib::GzipWriter.wrap(gzip_io) { |gz| gz.write(payload) }
876+
compressed = gzip_io.string
877+
878+
reader = Zlib::GzipReader.new(StringIO.new(compressed))
879+
reader.read(1)
880+
overflow_bytes = "B" * (initial_bufsize)
881+
reader.ungetc(overflow_bytes)
882+
data = reader.read(overflow_bytes.bytesize)
883+
assert_equal overflow_bytes.bytesize, data.bytesize, data
884+
assert_empty data.delete("B"), data
885+
data = reader.read()
886+
assert_equal initial_bufsize - 1, data.bytesize, data
887+
assert_empty data.delete("A"), data
888+
end
889+
871890
def test_open
872891
Tempfile.create("test_zlib_gzip_reader_open") {|t|
873892
t.close

0 commit comments

Comments
 (0)