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/