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

ruby-changes:48240

From: rhe <ko1@a...>
Date: Sun, 22 Oct 2017 16:18:58 +0900 (JST)
Subject: [ruby-changes:48240] rhe:r60355 (trunk): gdbm, dbm, sdbm: prevent memory leak in #initialize

rhe	2017-10-22 16:18:54 +0900 (Sun, 22 Oct 2017)

  New Revision: 60355

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

  Log:
    gdbm, dbm, sdbm: prevent memory leak in #initialize
    
    Have the allocator function allocate struct dbmdata too. #initialize
    should not call ALLOC() after opening a file since it can fail with
    NoMemoryError, leaking the opened file.

  Modified files:
    trunk/ext/dbm/dbm.c
    trunk/ext/gdbm/gdbm.c
    trunk/ext/sdbm/init.c
Index: ext/sdbm/init.c
===================================================================
--- ext/sdbm/init.c	(revision 60354)
+++ ext/sdbm/init.c	(revision 60355)
@@ -79,7 +79,6 @@ closed_sdbm(void) https://github.com/ruby/ruby/blob/trunk/ext/sdbm/init.c#L79
 
 #define GetDBM(obj, dbmp) do {\
     TypedData_Get_Struct((obj), struct dbmdata, &sdbm_type, (dbmp));\
-    if ((dbmp) == 0) closed_sdbm();\
     if ((dbmp)->di_dbm == 0) closed_sdbm();\
 } while (0)
 
@@ -148,8 +147,6 @@ fsdbm_closed(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/sdbm/init.c#L147
     struct dbmdata *dbmp;
 
     TypedData_Get_Struct(obj, struct dbmdata, &sdbm_type, dbmp);
-    if (dbmp == 0)
-	return Qtrue;
     if (dbmp->di_dbm == 0)
 	return Qtrue;
 
@@ -159,7 +156,9 @@ fsdbm_closed(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/sdbm/init.c#L156
 static VALUE
 fsdbm_alloc(VALUE klass)
 {
-    return TypedData_Wrap_Struct(klass, &sdbm_type, 0);
+    struct dbmdata *dbmp;
+
+    return TypedData_Make_Struct(klass, struct dbmdata, &sdbm_type, dbmp);
 }
 /*
  * call-seq:
@@ -184,6 +183,7 @@ fsdbm_initialize(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/sdbm/init.c#L183
     struct dbmdata *dbmp;
     int mode;
 
+    TypedData_Get_Struct(obj, struct dbmdata, &sdbm_type, dbmp);
     if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
 	mode = 0666;		/* default value */
     }
@@ -208,8 +208,8 @@ fsdbm_initialize(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/sdbm/init.c#L208
 	rb_sys_fail_str(file);
     }
 
-    dbmp = ALLOC(struct dbmdata);
-    DATA_PTR(obj) = dbmp;
+    if (dbmp->di_dbm)
+	sdbm_close(dbmp->di_dbm);
     dbmp->di_dbm = dbm;
     dbmp->di_size = -1;
 
Index: ext/dbm/dbm.c
===================================================================
--- ext/dbm/dbm.c	(revision 60354)
+++ ext/dbm/dbm.c	(revision 60355)
@@ -47,7 +47,6 @@ closed_dbm(void) https://github.com/ruby/ruby/blob/trunk/ext/dbm/dbm.c#L47
 
 #define GetDBM(obj, dbmp) do {\
     TypedData_Get_Struct((obj), struct dbmdata, &dbm_type, (dbmp));\
-    if ((dbmp) == 0) closed_dbm();\
     if ((dbmp)->di_dbm == 0) closed_dbm();\
 } while (0)
 
@@ -115,8 +114,6 @@ fdbm_closed(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/dbm/dbm.c#L114
     struct dbmdata *dbmp;
 
     TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
-    if (dbmp == 0)
-	return Qtrue;
     if (dbmp->di_dbm == 0)
 	return Qtrue;
 
@@ -126,7 +123,9 @@ fdbm_closed(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/dbm/dbm.c#L123
 static VALUE
 fdbm_alloc(VALUE klass)
 {
-    return TypedData_Wrap_Struct(klass, &dbm_type, 0);
+    struct dbmdata *dbmp;
+
+    return TypedData_Make_Struct(klass, struct dbmdata, &dbm_type, dbmp);
 }
 
 /*
@@ -150,6 +149,7 @@ fdbm_initialize(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/ext/dbm/dbm.c#L149
     struct dbmdata *dbmp;
     int mode, flags = 0;
 
+    TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
     if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
 	mode = 0666;		/* default value */
     }
@@ -228,8 +228,8 @@ fdbm_initialize(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/ext/dbm/dbm.c#L228
 	rb_sys_fail_str(file);
     }
 
-    dbmp = ALLOC(struct dbmdata);
-    DATA_PTR(obj) = dbmp;
+    if (dbmp->di_dbm)
+	dbm_close(dbmp->di_dbm);
     dbmp->di_dbm = dbm;
     dbmp->di_size = -1;
 
Index: ext/gdbm/gdbm.c
===================================================================
--- ext/gdbm/gdbm.c	(revision 60354)
+++ ext/gdbm/gdbm.c	(revision 60355)
@@ -102,7 +102,6 @@ closed_dbm(void) https://github.com/ruby/ruby/blob/trunk/ext/gdbm/gdbm.c#L102
 
 #define GetDBM(obj, dbmp) do {\
     TypedData_Get_Struct((obj), struct dbmdata, &dbm_type, (dbmp));\
-    if ((dbmp) == 0) closed_dbm();\
     if ((dbmp)->di_dbm == 0) closed_dbm();\
 } while (0)
 
@@ -170,8 +169,6 @@ fgdbm_closed(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/gdbm/gdbm.c#L169
     struct dbmdata *dbmp;
 
     TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
-    if (dbmp == 0)
-        return Qtrue;
     if (dbmp->di_dbm == 0)
         return Qtrue;
 
@@ -181,7 +178,9 @@ fgdbm_closed(VALUE obj) https://github.com/ruby/ruby/blob/trunk/ext/gdbm/gdbm.c#L178
 static VALUE
 fgdbm_s_alloc(VALUE klass)
 {
-    return TypedData_Wrap_Struct(klass, &dbm_type, 0);
+    struct dbmdata *dbmp;
+
+    return TypedData_Make_Struct(klass, struct dbmdata, &dbm_type, dbmp);
 }
 
 /*
@@ -215,6 +214,7 @@ fgdbm_initialize(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/gdbm/gdbm.c#L214
     struct dbmdata *dbmp;
     int mode, flags = 0;
 
+    TypedData_Get_Struct(obj, struct dbmdata, &dbm_type, dbmp);
     if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
         mode = 0666;            /* default value */
     }
@@ -268,9 +268,8 @@ fgdbm_initialize(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/gdbm/gdbm.c#L268
             rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
     }
 
-    dbmp = ALLOC(struct dbmdata);
-    free_dbm(DATA_PTR(obj));
-    DATA_PTR(obj) = dbmp;
+    if (dbmp->di_dbm)
+	gdbm_close(dbmp->di_dbm);
     dbmp->di_dbm = dbm;
     dbmp->di_size = -1;
 

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

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