Skip to content

Commit 9735988

Browse files
committed
fix: prevent crash when invoking cloudsync functions after cloudsync_terminate()
The cloudsync_terminate function only finalizes the cloudsync statements but it doesn't free the cloudsync_context anymore. Instead, the cloudsync_context pointer is deallocated by the distructor callback of one of the registered custom functions.
1 parent 21535c0 commit 9735988

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed

src/cloudsync.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,22 +1489,14 @@ void *cloudsync_context_create (void) {
14891489
return data;
14901490
}
14911491

1492-
void cloudsync_context_free (cloudsync_context *data, sqlite3 *db) {
1492+
void cloudsync_context_free (void *ptr) {
14931493
DEBUG_SETTINGS("cloudsync_context_free %p", data);
1494-
if (!data) return;
1494+
if (!ptr) return;
14951495

1496-
for (int i=0; i<data->tables_count; ++i) {
1497-
if (data->tables[i]) table_free(data->tables[i]);
1498-
data->tables[i] = NULL;
1499-
}
1500-
1501-
if (data->schema_version_stmt) sqlite3_finalize(data->schema_version_stmt);
1502-
if (data->data_version_stmt) sqlite3_finalize(data->data_version_stmt);
1503-
if (data->db_version_stmt) sqlite3_finalize(data->db_version_stmt);
1504-
if (data->getset_siteid_stmt) sqlite3_finalize(data->getset_siteid_stmt);
1505-
1496+
cloudsync_context *data = (cloudsync_context*)ptr;
15061497
cloudsync_memory_free(data->tables);
15071498
cloudsync_memory_free(data);
1499+
cloudsync_memory_finalize();
15081500
}
15091501

15101502
const char *cloudsync_context_init (sqlite3 *db, cloudsync_context *data, sqlite3_context *context) {
@@ -2804,10 +2796,26 @@ void cloudsync_is_enabled (sqlite3_context *context, int argc, sqlite3_value **a
28042796
void cloudsync_terminate (sqlite3_context *context, int argc, sqlite3_value **argv) {
28052797
DEBUG_FUNCTION("cloudsync_terminate");
28062798

2807-
sqlite3 *db = sqlite3_context_db_handle(context);
28082799
cloudsync_context *data = (cloudsync_context *)sqlite3_user_data(context);
2809-
cloudsync_context_free(data, db);
2810-
cloudsync_memory_finalize();
2800+
2801+
for (int i=0; i<data->tables_count; ++i) {
2802+
if (data->tables[i]) table_free(data->tables[i]);
2803+
data->tables[i] = NULL;
2804+
}
2805+
2806+
if (data->schema_version_stmt) sqlite3_finalize(data->schema_version_stmt);
2807+
if (data->data_version_stmt) sqlite3_finalize(data->data_version_stmt);
2808+
if (data->db_version_stmt) sqlite3_finalize(data->db_version_stmt);
2809+
if (data->getset_siteid_stmt) sqlite3_finalize(data->getset_siteid_stmt);
2810+
2811+
data->schema_version_stmt = NULL;
2812+
data->data_version_stmt = NULL;
2813+
data->db_version_stmt = NULL;
2814+
data->getset_siteid_stmt = NULL;
2815+
2816+
// reset the site_id so the cloudsync_context_init will be executed again
2817+
// if any other cloudsync function is called after terminate
2818+
data->site_id[0] = 0;
28112819
}
28122820

28132821
// MARK: -
@@ -3151,7 +3159,7 @@ APIEXPORT int sqlite3_cloudsync_init (sqlite3 *db, char **pzErrMsg, const sqlite
31513159
// register functions
31523160

31533161
// PUBLIC functions
3154-
rc = dbutils_register_function(db, "cloudsync_version", cloudsync_version, 0, pzErrMsg, ctx, NULL);
3162+
rc = dbutils_register_function(db, "cloudsync_version", cloudsync_version, 0, pzErrMsg, ctx, cloudsync_context_free);
31553163
if (rc != SQLITE_OK) return rc;
31563164

31573165
rc = dbutils_register_function(db, "cloudsync_init", cloudsync_init, 1, pzErrMsg, ctx, NULL);

0 commit comments

Comments
 (0)