Skip to content

Commit

Permalink
Fix for issue #47 - double free of COL_INFO object (#48)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* Fix spelling mistake in comment.

Signed-off-by: Alexandr Kuznetsov <[email protected]>

---------

Signed-off-by: Alexandr Kuznetsov <[email protected]>
  • Loading branch information
progmachine authored Sep 27, 2024
1 parent 0e4acc3 commit 563ad6c
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ windows-local.mak
/Makefile.in
/aclocal.m4
/autom4te.cache/
/autom4te.cache/*
/config/
/config.h
/config.h.in
/config.log
/config.status
/configure
/libtool
/psqlodbca.la
/psqlodbcw.la
/stamp-h1

Expand Down Expand Up @@ -107,6 +109,11 @@ bld/
[Ll]og/
[Ll]ogs/

# Eclipse project options
/.project
/.cproject
/.settings

# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
Expand Down
1 change: 1 addition & 0 deletions connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ CC_clear_col_info(ConnectionClass *self, BOOL destroy)
/* Going through COL_INFO cache table and releasing coli objects. */
if (coli = self->col_info[i], NULL != coli)
{
MYLOG(0, "!!!refcnt %p:%d -> %d\n", coli, coli->refcnt, coli->refcnt - 1);
coli->refcnt--;
if (coli->refcnt <= 0)
{
Expand Down
16 changes: 15 additions & 1 deletion parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 563ad6c

Please sign in to comment.