From: nobu@... Date: 2016-12-10T03:48:44+00:00 Subject: [ruby-core:78569] [Ruby trunk Bug#13021] `Zlib.gunzip` modifies argument String Issue #13021 has been updated by Nobuyoshi Nakada. ```patch diff --git i/ext/zlib/zlib.c w/ext/zlib/zlib.c index 78860132df..0ce14198cc 100644 --- i/ext/zlib/zlib.c +++ w/ext/zlib/zlib.c @@ -879,9 +879,8 @@ zstream_discard_input(struct zstream *z, long len) z->input = Qnil; } else { - memmove(RSTRING_PTR(z->input), RSTRING_PTR(z->input) + len, - RSTRING_LEN(z->input) - len); - rb_str_resize(z->input, RSTRING_LEN(z->input) - len); + z->input = rb_str_substr(z->input, len, + RSTRING_LEN(z->input) - len); } } @@ -2406,9 +2405,7 @@ gzfile_read_raw_ensure(struct gzfile *gz, long size) VALUE str; if (gz->io == Qundef) { /* Zlib.gunzip */ - if (NIL_P(gz->z.input)) - rb_bug("unexpected condition: both gz->io and gz->z.input are nil"); - if (RSTRING_LEN(gz->z.input) < size) + if (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) rb_raise(cGzError, "unexpected end of string"); } while (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) { diff --git i/test/zlib/test_zlib.rb w/test/zlib/test_zlib.rb index 60fb84dd0d..7f9ec981fd 100644 --- i/test/zlib/test_zlib.rb +++ w/test/zlib/test_zlib.rb @@ -1128,25 +1128,25 @@ end def test_gzip - actual = Zlib.gzip("foo") + actual = Zlib.gzip("foo".freeze) actual[4, 4] = "\x00\x00\x00\x00" # replace mtime actual[9] = "\xff" # replace OS expected = %w[1f8b08000000000000ff4bcbcf07002165738c03000000].pack("H*") assert_equal expected, actual - actual = Zlib.gzip("foo", 0) + actual = Zlib.gzip("foo".freeze, 0) actual[4, 4] = "\x00\x00\x00\x00" # replace mtime actual[9] = "\xff" # replace OS expected = %w[1f8b08000000000000ff010300fcff666f6f2165738c03000000].pack("H*") assert_equal expected, actual - actual = Zlib.gzip("foo", 9) + actual = Zlib.gzip("foo".freeze, 9) actual[4, 4] = "\x00\x00\x00\x00" # replace mtime actual[9] = "\xff" # replace OS expected = %w[1f8b08000000000002ff4bcbcf07002165738c03000000].pack("H*") assert_equal expected, actual - actual = Zlib.gzip("foo", 9, Zlib::FILTERED) + actual = Zlib.gzip("foo".freeze, 9, Zlib::FILTERED) actual[4, 4] = "\x00\x00\x00\x00" # replace mtime actual[9] = "\xff" # replace OS expected = %w[1f8b08000000000002ff4bcbcf07002165738c03000000].pack("H*") @@ -1155,7 +1155,7 @@ def test_gunzip src = %w[1f8b08000000000000034bcbcf07002165738c03000000].pack("H*") - assert_equal 'foo', Zlib.gunzip(src) + assert_equal 'foo', Zlib.gunzip(src.freeze) src = %w[1f8b08000000000000034bcbcf07002165738c03000001].pack("H*") assert_raise(Zlib::GzipFile::LengthError){ Zlib.gunzip(src) } ``` ---------------------------------------- Bug #13021: `Zlib.gunzip` modifies argument String https://bugs.ruby-lang.org/issues/13021#change-61954 * Author: Kazuhiro NISHIYAMA * Status: Open * Priority: Normal * Assignee: Yui NARUSE * ruby -v: ruby 2.4.0dev (2016-12-10 trunk 57036) [x86_64-linux] * Backport: 2.1: DONTNEED, 2.2: DONTNEED, 2.3: DONTNEED ---------------------------------------- ``` % irb -r irb/completion --simple-prompt >> RUBY_DESCRIPTION => "ruby 2.4.0dev (2016-12-10 trunk 57036) [x86_64-linux]" >> require 'zlib' => true >> gz=Zlib.gzip('test') => "\x1F\x8B\b\x00\xBF`KX\x00\x03+I-.\x01\x00\f~\x7F\xD8\x04\x00\x00\x00" >> Zlib.gunzip(gz) => "test" >> gz => "+I-.\x01\x00\f~\x7F\xD8\x04\x00\x00\x00" ``` -- https://bugs.ruby-lang.org/ Unsubscribe: