summaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
authorAlexandr Kuznetsov2024-09-27 10:23:20 +0000
committerGitHub2024-09-27 10:23:20 +0000
commit563ad6c470ea5bf235f45f14f52d8f1df0040488 (patch)
treeb82e840aaa3a9ac6f6e64f006b13f6a2ca9d6a72 /parse.c
parent0e4acc3e5b333b4706bdd71e9c3c872dbe3c60d1 (diff)
Fix for issue #47 - double free of COL_INFO object (#48)
* Fix for issue #47 - double free of COL_INFO object due to refcount breakage during reuse of directly found object in getColumnsInfo(...). One more possible memory leak of COL_INFO objects in getColumnsInfo(...). Signed-off-by: Alexandr Kuznetsov <progmachine@xenlab.one> * Fix spelling mistake in comment. Signed-off-by: Alexandr Kuznetsov <progmachine@xenlab.one> --------- Signed-off-by: Alexandr Kuznetsov <progmachine@xenlab.one>
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/parse.c b/parse.c
index f63f3fc..a8445af 100644
--- a/parse.c
+++ b/parse.c
@@ -829,7 +829,7 @@ getColumnsInfo(ConnectionClass *conn, TABLE_INFO *wti, OID greloid, StatementCla
{
BOOL coli_exist = FALSE;
COL_INFO *coli = NULL, *ccoli = NULL, *tcoli;
- int k;
+ int k, tmp_refcnt = 0;
time_t acctime = 0;
MYLOG(0, " Success\n");
@@ -882,6 +882,8 @@ getColumnsInfo(ConnectionClass *conn, TABLE_INFO *wti, OID greloid, StatementCla
if (coli_exist)
{
/* We have ready to use coli object. Cleaning it. */
+ tmp_refcnt = coli->refcnt; /* If we found coli with greloid, then some TABLE_INFO objects may have references to it -> save refcnt for them. */
+ tmp_refcnt--; /* Down the road we will increase refcnt again to account for the reference from ConnectionClass object to coli object. */
free_col_info_contents(coli);
}
else
@@ -921,6 +923,7 @@ getColumnsInfo(ConnectionClass *conn, TABLE_INFO *wti, OID greloid, StatementCla
}
col_info_initialize(coli);
+ coli->refcnt = tmp_refcnt;
coli->refcnt++; /* Counting one reference to coli object from connection COL_INFO cache table. */
coli->result = res;
if (res && QR_get_num_cached_tuples(res) > 0)
@@ -976,6 +979,17 @@ MYLOG(DETAIL_LOG_LEVEL, "oid item == %s\n", (const char *) QR_get_value_backend_
MYLOG(0, "Created col_info table='%s', ntables=%d\n", PRINT_NAME(wti->table_name), conn->ntables);
/* Associate a table from the statement with a SQLColumn info */
found = TRUE;
+ if (wti->col_info)
+ {
+ /* wti also has reference to COL_INFO object, so we must release it. */
+MYLOG(0, "!!!refcnt %p:%d -> %d\n", wti->col_info, wti->col_info->refcnt, wti->col_info->refcnt - 1);
+ wti->col_info->refcnt--;
+ if (wti->col_info->refcnt <= 0)
+ {
+ free_col_info_contents(wti->col_info);
+ free(wti->col_info);
+ }
+ }
coli->refcnt++; /* Counting another one reference to coli object from TABLE_INFO wti object. */
wti->col_info = coli;
}