From de7a010a502517d7a38d702646f2101e48a50129 Mon Sep 17 00:00:00 2001 From: rhe Date: Sun, 22 Oct 2017 07:18:54 +0000 Subject: 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60355 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/gdbm/gdbm.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'ext/gdbm/gdbm.c') diff --git a/ext/gdbm/gdbm.c b/ext/gdbm/gdbm.c index 5cd9f145d0..2aa9010c57 100644 --- a/ext/gdbm/gdbm.c +++ b/ext/gdbm/gdbm.c @@ -102,7 +102,6 @@ closed_dbm(void) #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) 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) 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, VALUE obj) 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, VALUE obj) 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; -- cgit v1.2.3