# HG changeset patch # User jbe # Date 1452219033 -3600 # Node ID 7d43be9afa565d1a781251188070b689fc42e7dd # Parent 02a53308f008011387a26f20da8e0986457f3e86 Improved memory cleanup in case of out-of-memory errors (PQnotifies and PQunescapeBytea) diff -r 02a53308f008 -r 7d43be9afa56 libraries/mondelefant/mondelefant_native.c --- a/libraries/mondelefant/mondelefant_native.c Thu Jan 07 17:44:32 2016 +0100 +++ b/libraries/mondelefant/mondelefant_native.c Fri Jan 08 03:10:33 2016 +0100 @@ -471,13 +471,24 @@ lua_setfield(L, 2, "message"); return 1; } + // avoid cumulating memory leaks in case of previous out-of-memory errors: + if (conn->todo_PQfreemem) { + PQfreemem(conn->todo_PQfreemem); + conn->todo_PQfreemem = NULL; + } notify = PQnotifies(conn->pgconn); if (notify) { + // ensure call of PQfreemem in case of out-of-memory errors: + conn->todo_PQfreemem = notify; + // do Lua operations: lua_pushnil(L); lua_pushstring(L, notify->relname); lua_pushstring(L, notify->extra); lua_pushinteger(L, notify->be_pid); + // free memory allocated by PQnotifies: PQfreemem(notify); + // avoid double call of PQfreemem later: + conn->todo_PQfreemem = NULL; return 4; } } @@ -628,7 +639,7 @@ return luaL_error(L, "Could not allocate memory for binary quoting."); } } - // ensure call of PQfreemem in case of repeated out-of-memory errors: + // ensure call of PQfreemem in case of out-of-memory errors: conn->todo_PQfreemem = output; // create Lua string enclosed by single quotes: luaL_buffinit(L, &buf); @@ -947,7 +958,7 @@ pgstatus = PQresultStatus(res); rows = PQntuples(res); cols = PQnfields(res); - // ensure call of PQclear in case of repeated Lua errors: + // ensure call of PQclear in case of Lua errors: conn->todo_PQclear = res; } } @@ -1170,6 +1181,12 @@ } else if (binary[col]) { size_t binlen; char *binval; + // avoid cumulating memory leaks in case of previous out-of-memory errors: + if (conn->todo_PQfreemem) { + PQfreemem(conn->todo_PQfreemem); + conn->todo_PQfreemem = NULL; + } + // Unescape binary data: binval = (char *)PQunescapeBytea( (unsigned char *)PQgetvalue(res, row, col), &binlen ); @@ -1178,8 +1195,14 @@ "Could not allocate memory for binary unescaping." ); } + // ensure call of PQfreemem in case of out-of-memory error: + conn->todo_PQfreemem = binval; + // create Lua string: lua_pushlstring(L, binval, binlen); + // free memory allocated by PQunescapeBytea: PQfreemem(binval); + // avoid double call of PQfreemem later: + conn->todo_PQfreemem = NULL; } else { lua_pushstring(L, PQgetvalue(res, row, col)); } @@ -1194,6 +1217,12 @@ } else if (binary[col]) { size_t binlen; char *binval; + // avoid cumulating memory leaks in case of previous out-of-memory errors: + if (conn->todo_PQfreemem) { + PQfreemem(conn->todo_PQfreemem); + conn->todo_PQfreemem = NULL; + } + // Unescape binary data: binval = (char *)PQunescapeBytea( (unsigned char *)PQgetvalue(res, 0, col), &binlen ); @@ -1202,8 +1231,14 @@ "Could not allocate memory for binary unescaping." ); } + // ensure call of PQfreemem in case of out-of-memory error: + conn->todo_PQfreemem = binval; + // create Lua string: lua_pushlstring(L, binval, binlen); + // free memory allocated by PQunescapeBytea: PQfreemem(binval); + // avoid double call of PQfreemem later: + conn->todo_PQfreemem = NULL; } else { lua_pushstring(L, PQgetvalue(res, 0, col)); }