[前][次][番号順一覧][スレッド一覧]

ruby-changes:50054

From: nagachika <ko1@a...>
Date: Sat, 3 Feb 2018 11:25:42 +0900 (JST)
Subject: [ruby-changes:50054] nagachika:r62172 (ruby_2_4): merge revision(s) 60042, 60130, 60131: [Backport #13982]

nagachika	2018-02-03 11:25:37 +0900 (Sat, 03 Feb 2018)

  New Revision: 62172

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62172

  Log:
    merge revision(s) 60042,60130,60131: [Backport #13982]
    
    ext: adjust indent [ci skip]
    
    zlib.c: memory leak in gunzip
    
    * ext/zlib/zlib.c (zlib_gunzip): clear zstream to fix memory leak.
      [ruby-core:83162] [Bug #13982]
    
    zlib.c: ensure to free
    
    * ext/zlib/zlib.c (zlib_gunzip): gz0 is a structure variable on
      the stack, no longer valid after exit by an exception.  ensure
      to free instead.  [Bug #13982]

  Modified directories:
    branches/ruby_2_4/
  Modified files:
    branches/ruby_2_4/ext/dbm/dbm.c
    branches/ruby_2_4/ext/etc/etc.c
    branches/ruby_2_4/ext/sdbm/_sdbm.c
    branches/ruby_2_4/ext/stringio/stringio.c
    branches/ruby_2_4/ext/syslog/syslog.c
    branches/ruby_2_4/ext/zlib/zlib.c
    branches/ruby_2_4/test/zlib/test_zlib.rb
    branches/ruby_2_4/version.h
Index: ruby_2_4/version.h
===================================================================
--- ruby_2_4/version.h	(revision 62171)
+++ ruby_2_4/version.h	(revision 62172)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/version.h#L1
 #define RUBY_VERSION "2.4.4"
 #define RUBY_RELEASE_DATE "2018-02-03"
-#define RUBY_PATCHLEVEL 229
+#define RUBY_PATCHLEVEL 230
 
 #define RUBY_RELEASE_YEAR 2018
 #define RUBY_RELEASE_MONTH 2
Index: ruby_2_4/ext/sdbm/_sdbm.c
===================================================================
--- ruby_2_4/ext/sdbm/_sdbm.c	(revision 62171)
+++ ruby_2_4/ext/sdbm/_sdbm.c	(revision 62172)
@@ -176,24 +176,24 @@ sdbm_open(register char *file, register https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/sdbm/_sdbm.c#L176
 static int
 fd_set_cloexec(int fd)
 {
-  /* MinGW don't have F_GETFD and FD_CLOEXEC.  [ruby-core:40281] */
+	/* MinGW don't have F_GETFD and FD_CLOEXEC.  [ruby-core:40281] */
 #ifdef F_GETFD
-    int flags, ret;
-    flags = fcntl(fd, F_GETFD); /* should not fail except EBADF. */
-    if (flags == -1) {
-        return -1;
-    }
-    if (2 < fd) {
-        if (!(flags & FD_CLOEXEC)) {
-            flags |= FD_CLOEXEC;
-            ret = fcntl(fd, F_SETFD, flags);
-            if (ret == -1) {
-                return -1;
-            }
-        }
-    }
+	int flags, ret;
+	flags = fcntl(fd, F_GETFD); /* should not fail except EBADF. */
+	if (flags == -1) {
+		return -1;
+	}
+	if (2 < fd) {
+		if (!(flags & FD_CLOEXEC)) {
+			flags |= FD_CLOEXEC;
+			ret = fcntl(fd, F_SETFD, flags);
+			if (ret == -1) {
+				return -1;
+			}
+		}
+	}
 #endif
-    return 0;
+	return 0;
 }
 
 DBM *
@@ -400,20 +400,20 @@ makroom(register DBM *db, long int hash, https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/sdbm/_sdbm.c#L400
  */
 
 #if defined _WIN32
-	/*
-	 * Fill hole with 0 if made it.
-	 * (hole is NOT read as 0)
-	 */
-	oldtail = lseek(db->pagf, 0L, SEEK_END);
-	memset(zer, 0, PBLKSIZ);
-	while (OFF_PAG(newp) > oldtail) {
-		if (lseek(db->pagf, 0L, SEEK_END) < 0 ||
-		    write(db->pagf, zer, PBLKSIZ) < 0) {
-
-			return 0;
+		/*
+		 * Fill hole with 0 if made it.
+		 * (hole is NOT read as 0)
+		 */
+		oldtail = lseek(db->pagf, 0L, SEEK_END);
+		memset(zer, 0, PBLKSIZ);
+		while (OFF_PAG(newp) > oldtail) {
+			if (lseek(db->pagf, 0L, SEEK_END) < 0 ||
+			    write(db->pagf, zer, PBLKSIZ) < 0) {
+
+				return 0;
+			}
+			oldtail += PBLKSIZ;
 		}
-		oldtail += PBLKSIZ;
-	}
 #endif
 
 		if (hash & (db->hmask + 1)) {
Index: ruby_2_4/ext/zlib/zlib.c
===================================================================
--- ruby_2_4/ext/zlib/zlib.c	(revision 62171)
+++ ruby_2_4/ext/zlib/zlib.c	(revision 62172)
@@ -451,7 +451,7 @@ rb_zlib_adler32(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L451
 static VALUE
 rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
 {
-  return ULONG2NUM(
+    return ULONG2NUM(
 	adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
 }
 #else
@@ -489,7 +489,7 @@ rb_zlib_crc32(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L489
 static VALUE
 rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
 {
-  return ULONG2NUM(
+    return ULONG2NUM(
 	crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
 }
 #else
@@ -644,7 +644,7 @@ zstream_expand_buffer(struct zstream *z) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L644
 	}
 	else {
 	    zstream_expand_buffer_into(z,
-		    ZSTREAM_AVAIL_OUT_STEP_MAX - buf_filled);
+				       ZSTREAM_AVAIL_OUT_STEP_MAX - buf_filled);
 	}
     }
     else {
@@ -1381,7 +1381,7 @@ rb_zstream_data_type(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L1381
 static VALUE
 rb_zstream_adler(VALUE obj)
 {
-	return rb_uint2inum(get_zstream(obj)->stream.adler);
+    return rb_uint2inum(get_zstream(obj)->stream.adler);
 }
 
 /*
@@ -2673,7 +2673,7 @@ gzfile_calc_crc(struct gzfile *gz, VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L2673
     }
     else {
 	gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
-			RSTRING_LEN(str) - gz->ungetc);
+				RSTRING_LEN(str) - gz->ungetc);
 	gz->ungetc = 0;
     }
 }
@@ -4245,6 +4245,14 @@ rb_gzreader_external_encoding(VALUE self https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L4245
     return rb_enc_from_encoding(get_gzfile(self)->enc);
 }
 
+static VALUE
+zlib_gzip_ensure(VALUE arg)
+{
+    struct gzfile *gz = (struct gzfile *)arg;
+    rb_rescue((VALUE(*)())gz->end, arg, NULL, Qnil);
+    return Qnil;
+}
+
 static void
 zlib_gzip_end(struct gzfile *gz)
 {
@@ -4257,6 +4265,7 @@ zlib_gzip_end(struct gzfile *gz) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L4265
 #define OPTHASH_GIVEN_P(opts) \
     (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
 static ID id_level, id_strategy;
+static VALUE zlib_gzip_run(VALUE arg);
 
 /*
  * call-seq:
@@ -4285,9 +4294,8 @@ zlib_s_gzip(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L4294
 {
     struct gzfile gz0;
     struct gzfile *gz = &gz0;
-    long len;
     int err;
-    VALUE src, opts, level=Qnil, strategy=Qnil;
+    VALUE src, opts, level=Qnil, strategy=Qnil, args[2];
 
     if (OPTHASH_GIVEN_P(opts)) {
 	ID keyword_ids[2];
@@ -4309,9 +4317,23 @@ zlib_s_gzip(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L4317
     err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
 		       -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
     if (err != Z_OK) {
+	zlib_gzip_end(gz);
 	raise_zlib_error(err, gz->z.stream.msg);
     }
     ZSTREAM_READY(&gz->z);
+    args[0] = (VALUE)gz;
+    args[1] = src;
+    return rb_ensure(zlib_gzip_run, (VALUE)args, zlib_gzip_ensure, (VALUE)gz);
+}
+
+static VALUE
+zlib_gzip_run(VALUE arg)
+{
+    VALUE *args = (VALUE *)arg;
+    struct gzfile *gz = (struct gzfile *)args[0];
+    VALUE src = args[1];
+    long len;
+
     gzfile_make_header(gz);
     len = RSTRING_LEN(src);
     if (len > 0) {
@@ -4327,10 +4349,11 @@ static void https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L4349
 zlib_gunzip_end(struct gzfile *gz)
 {
     gz->z.flags |= ZSTREAM_FLAG_CLOSING;
-    gzfile_check_footer(gz);
     zstream_end(&gz->z);
 }
 
+static VALUE zlib_gunzip_run(VALUE arg);
+
 /*
  * call-seq:
  *   Zlib.gunzip(src) -> String
@@ -4355,7 +4378,6 @@ zlib_gunzip(VALUE klass, VALUE src) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L4378
     struct gzfile gz0;
     struct gzfile *gz = &gz0;
     int err;
-    VALUE dst;
 
     StringValue(src);
 
@@ -4367,14 +4389,24 @@ zlib_gunzip(VALUE klass, VALUE src) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/zlib/zlib.c#L4389
     gz->io = Qundef;
     gz->z.input = src;
     ZSTREAM_READY(&gz->z);
+    return rb_ensure(zlib_gunzip_run, (VALUE)gz, zlib_gzip_ensure, (VALUE)gz);
+}
+
+static VALUE
+zlib_gunzip_run(VALUE arg)
+{
+    struct gzfile *gz = (struct gzfile *)arg;
+    VALUE dst;
+
     gzfile_read_header(gz);
     dst = zstream_detach_buffer(&gz->z);
     gzfile_calc_crc(gz, dst);
-	    if (!ZSTREAM_IS_FINISHED(&gz->z)) {
-		rb_raise(cGzError, "unexpected end of file");
-	    }
-    if (NIL_P(gz->z.input))
+    if (!ZSTREAM_IS_FINISHED(&gz->z)) {
+	rb_raise(cGzError, "unexpected end of file");
+    }
+    if (NIL_P(gz->z.input)) {
 	rb_raise(cNoFooter, "footer is not found");
+    }
     gzfile_check_footer(gz);
     return dst;
 }
Index: ruby_2_4/ext/dbm/dbm.c
===================================================================
--- ruby_2_4/ext/dbm/dbm.c	(revision 62171)
+++ ruby_2_4/ext/dbm/dbm.c	(revision 62172)
@@ -191,24 +191,24 @@ fdbm_initialize(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/dbm/dbm.c#L191
     }
 
     if (dbm) {
-    /*
-     * History of dbm_pagfno() and dbm_dirfno() in ndbm and its compatibles.
-     * (dbm_pagfno() and dbm_dirfno() is not standardized.)
-     *
-     * 1986: 4.3BSD provides ndbm.
-     *       It provides dbm_pagfno() and dbm_dirfno() as macros.
-     * 1991: gdbm-1.5 provides them as functions.
-     *       They returns a same descriptor.
-     *       (Earlier releases may have the functions too.)
-     * 1991: Net/2 provides Berkeley DB.
-     *       It doesn't provide dbm_pagfno() and dbm_dirfno().
-     * 1992: 4.4BSD Alpha provides Berkeley DB with dbm_dirfno() as a function.
-     *       dbm_pagfno() is a macro as DBM_PAGFNO_NOT_AVAILABLE.
-     * 1997: Berkeley DB 2.0 is released by Sleepycat Software, Inc.
-     *       It defines dbm_pagfno() and dbm_dirfno() as macros.
-     * 2011: gdbm-1.9 creates a separate dir file.
-     *       dbm_pagfno() and dbm_dirfno() returns different descriptors.
-     */
+	/*
+	 * History of dbm_pagfno() and dbm_dirfno() in ndbm and its compatibles.
+	 * (dbm_pagfno() and dbm_dirfno() is not standardized.)
+	 *
+	 * 1986: 4.3BSD provides ndbm.
+	 *       It provides dbm_pagfno() and dbm_dirfno() as macros.
+	 * 1991: gdbm-1.5 provides them as functions.
+	 *       They returns a same descriptor.
+	 *       (Earlier releases may have the functions too.)
+	 * 1991: Net/2 provides Berkeley DB.
+	 *       It doesn't provide dbm_pagfno() and dbm_dirfno().
+	 * 1992: 4.4BSD Alpha provides Berkeley DB with dbm_dirfno() as a function.
+	 *       dbm_pagfno() is a macro as DBM_PAGFNO_NOT_AVAILABLE.
+	 * 1997: Berkeley DB 2.0 is released by Sleepycat Software, Inc.
+	 *       It defines dbm_pagfno() and dbm_dirfno() as macros.
+	 * 2011: gdbm-1.9 creates a separate dir file.
+	 *       dbm_pagfno() and dbm_dirfno() returns different descriptors.
+	 */
 #if defined(HAVE_DBM_PAGFNO)
         rb_fd_fix_cloexec(dbm_pagfno(dbm));
 #endif
@@ -217,8 +217,8 @@ fdbm_initialize(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/dbm/dbm.c#L217
 #endif
 
 #if defined(RUBYDBM_DB_HEADER) && defined(HAVE_TYPE_DBC)
-    /* Disable Berkeley DB error messages such as:
-     * DB->put: attempt to modify a read-only database */
+	/* Disable Berkeley DB error messages such as:
+	 * DB->put: attempt to modify a read-only database */
         ((DBC*)dbm)->dbp->set_errfile(((DBC*)dbm)->dbp, NULL);
 #endif
     }
Index: ruby_2_4/ext/etc/etc.c
===================================================================
--- ruby_2_4/ext/etc/etc.c	(revision 62171)
+++ ruby_2_4/ext/etc/etc.c	(revision 62172)
@@ -1014,7 +1014,7 @@ etc_nprocessors(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/etc/etc.c#L1014
 
     ncpus = etc_nprocessors_affin();
     if (ncpus != -1) {
-       return INT2NUM(ncpus);
+	return INT2NUM(ncpus);
     }
     /* fallback to _SC_NPROCESSORS_ONLN */
 #endif
Index: ruby_2_4/ext/stringio/stringio.c
===================================================================
--- ruby_2_4/ext/stringio/stringio.c	(revision 62171)
+++ ruby_2_4/ext/stringio/stringio.c	(revision 62172)
@@ -1551,7 +1551,7 @@ strio_external_encoding(VALUE self) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/stringio/stringio.c#L1551
 static VALUE
 strio_internal_encoding(VALUE self)
 {
-     return Qnil;
+    return Qnil;
 }
 
 /*
Index: ruby_2_4/ext/syslog/syslog.c
===================================================================
--- ruby_2_4/ext/syslog/syslog.c	(revision 62171)
+++ ruby_2_4/ext/syslog/syslog.c	(revision 62172)
@@ -506,7 +506,7 @@ void Init_syslog(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/syslog/syslog.c#L506
     rb_define_syslog_facility(LOG_NEWS);
 #endif
 #ifdef LOG_NTP
-   rb_define_syslog_facility(LOG_NTP);
+    rb_define_syslog_facility(LOG_NTP);
 #endif
 #ifdef LOG_SECURITY
     rb_define_syslog_facility(LOG_SECURITY);
Index: ruby_2_4/test/zlib/test_zlib.rb
===================================================================
--- ruby_2_4/test/zlib/test_zlib.rb	(revision 62171)
+++ ruby_2_4/test/zlib/test_zlib.rb	(revision 62172)
@@ -1196,5 +1196,13 @@ if defined? Zlib https://github.com/ruby/ruby/blob/trunk/ruby_2_4/test/zlib/test_zlib.rb#L1196
       src = %w[1f8b080000000000000].pack("H*")
       assert_raise(Zlib::GzipFile::Error){ Zlib.gunzip(src) }
     end
+
+    def test_gunzip_no_memory_leak
+      assert_no_memory_leak(%[-rzlib], "#{<<~"{#"}", "#{<<~'};'}")
+      d = Zlib.gzip("data")
+      {#
+        10_000.times {Zlib.gunzip(d)}
+      };
+    end
   end
 end
Index: ruby_2_4
===================================================================
--- ruby_2_4	(revision 62171)
+++ ruby_2_4	(revision 62172)

Property changes on: ruby_2_4
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /trunk:r60042,60130-60131

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]