Changeset: dd08c6628fb2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/dd08c6628fb2 Modified Files: clients/odbc/tests/odbcconnect.c Branch: Aug2024 Log Message:
Simplify memory management in odbcconnect.c diffs (truncated from 316 to 300 lines): diff --git a/clients/odbc/tests/odbcconnect.c b/clients/odbc/tests/odbcconnect.c --- a/clients/odbc/tests/odbcconnect.c +++ b/clients/odbc/tests/odbcconnect.c @@ -40,13 +40,13 @@ static const char *USAGE = " -v Be verbose\n" " TARGET DSN or with -d and -b, Connection String\n"; -typedef int (action_t)(SQLCHAR *); +typedef int (action_t)(const char *); static action_t do_sqlconnect; static action_t do_sqldriverconnect; static action_t do_sqlbrowseconnect; -static int do_actions(action_t action, int ntargets, SQLCHAR **targets); +static int do_actions(action_t action, int ntargets, char **targets); static int do_listdrivers(void); static int do_listdsns(const char *prefix, SQLSMALLINT dir); @@ -57,17 +57,13 @@ static void ensure_ok_impl(SQLSMALLINT t #define ensure_ok(type, handle, message, ret) ensure_ok_impl(type, handle, message, ret, __LINE__) -#define MARGIN 100 -static SQLCHAR* sqldup_with_margin(const char *str); -static void fuzz_sql_nts(SQLCHAR **str, SQLSMALLINT *len); +static void make_arg(const char *arg, SQLCHAR**bufp, SQLSMALLINT *buflen); + int verbose = 0; -SQLCHAR *user = NULL; -SQLSMALLINT user_len = SQL_NTS; -SQLCHAR *password = NULL; -SQLSMALLINT password_len = SQL_NTS; -SQLCHAR *query = NULL; -SQLSMALLINT query_len = SQL_NTS; +char *user = NULL; +char *password = NULL; +char *query = NULL; bool use_counted_strings = false; SQLHANDLE env = NULL; @@ -77,12 +73,25 @@ SQLHANDLE stmt = NULL; SQLCHAR outbuf[4096]; SQLCHAR attrbuf[4096]; +// This free-list will be processed by cleanup(). +// It is added to by alloc() +unsigned int ngarbage = 0; +void *garbage[100] = { NULL }; + + +static void* +alloc(size_t size) +{ + void *p = calloc(size, 1); + assert(p); + if (ngarbage < sizeof(garbage) / sizeof(garbage[0])) + garbage[ngarbage++] = p; + return p; +} + static void cleanup(void) { - free(user); - free(password); - free(query); if (stmt) SQLFreeHandle(SQL_HANDLE_STMT, stmt); if (conn) { @@ -91,14 +100,18 @@ cleanup(void) } if (env) SQLFreeHandle(SQL_HANDLE_DBC, env); + + while (ngarbage > 0) { + free(garbage[--ngarbage]); + } } int main(int argc, char **argv) { - int (*action)(SQLCHAR *); + int (*action)(const char*); action = do_sqlconnect; - SQLCHAR **targets = calloc(argc, sizeof(argv[0])); + char **targets = alloc(argc * sizeof(argv[0])); int ntargets = 0; int ret; @@ -111,17 +124,17 @@ main(int argc, char **argv) else if (strcmp(arg, "-l") == 0) action = NULL; else if (strcmp(arg, "-u") == 0 && i + 1 < argc) - user = sqldup_with_margin(argv[++i]); + user = argv[++i]; else if (strcmp(arg, "-p") == 0 && i + 1 < argc) - password = sqldup_with_margin(argv[++i]); + password = argv[++i]; else if (strcmp(arg, "-q") == 0 && i + 1 < argc) - query = sqldup_with_margin(argv[++i]); + query = argv[++i]; else if (strcmp(arg, "-0") == 0) use_counted_strings = true; else if (strcmp(arg, "-v") == 0) verbose += 1; else if (arg[0] != '-') - targets[ntargets++] = sqldup_with_margin(arg); + targets[ntargets++] = arg; else { fprintf(stderr, "\nERROR: invalid argument: %s\n%s", arg, USAGE); ret = 1; @@ -137,11 +150,6 @@ main(int argc, char **argv) SQL_HANDLE_ENV, env, "set odbc version", SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0)); - if (use_counted_strings) { - fuzz_sql_nts(&user, &user_len); - fuzz_sql_nts(&password, &password_len); - } - if (action) { if (ntargets == 0) { fprintf(stderr, "\nERROR: pass at least one target\n%s", USAGE); @@ -161,9 +169,6 @@ main(int argc, char **argv) } end: - for (int i = 0; i < ntargets; i++) - free(targets[i]); - free(targets); cleanup(); return ret; @@ -232,14 +237,14 @@ ensure_ok_impl(SQLSMALLINT type, SQLHAND static int -do_actions(action_t action, int ntargets, SQLCHAR **targets) +do_actions(action_t action, int ntargets, char **targets) { ensure_ok( SQL_HANDLE_ENV, env, "allocate conn handle", SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); for (int i = 0; i < ntargets; i++) { - SQLCHAR *t = targets[i]; + char *t = targets[i]; if (verbose) printf("\nTarget: %s\n", t); outbuf[0] = '\0'; @@ -252,15 +257,23 @@ do_actions(action_t action, int ntargets } static int -do_sqlconnect(SQLCHAR *target) +do_sqlconnect(const char *target) { + SQLCHAR *target_buf; SQLSMALLINT target_len = SQL_NTS; - if (use_counted_strings) - fuzz_sql_nts(&target, &target_len); + make_arg(target, &target_buf, &target_len); + + SQLCHAR *user_buf; + SQLSMALLINT user_len = SQL_NTS; + make_arg(user, &user_buf, &user_len); + + SQLCHAR *password_buf; + SQLSMALLINT password_len = SQL_NTS; + make_arg(password, &password_buf, &password_len); ensure_ok( SQL_HANDLE_DBC, conn, "SQLConnect", - SQLConnectA(conn, target, target_len, user, user_len, password, password_len)); + SQLConnectA(conn, target_buf, target_len, user_buf, user_len, password_buf, password_len)); printf("OK\n"); int exitcode = do_execute_stmt(); @@ -273,18 +286,19 @@ do_sqlconnect(SQLCHAR *target) } static int -do_sqldriverconnect(SQLCHAR *target) +do_sqldriverconnect(const char *target) { + SQLCHAR *target_buf; + SQLSMALLINT target_len = SQL_NTS; + make_arg(target, &target_buf, &target_len); + SQLSMALLINT n; - SQLSMALLINT target_len = SQL_NTS; - if (use_counted_strings) - fuzz_sql_nts(&target, &target_len); ensure_ok( SQL_HANDLE_DBC, conn, "SQLDriverConnect", SQLDriverConnectA( conn, NULL, - target, target_len, + target_buf, target_len, outbuf, sizeof(outbuf), &n, SQL_DRIVER_NOPROMPT )); @@ -301,16 +315,18 @@ do_sqldriverconnect(SQLCHAR *target) } static int -do_sqlbrowseconnect(SQLCHAR *target) +do_sqlbrowseconnect(const char *target) { + SQLCHAR *target_buf; + SQLSMALLINT target_len = SQL_NTS; + make_arg(target, &target_buf, &target_len); + + SQLSMALLINT n; - SQLSMALLINT target_len = SQL_NTS; - if (use_counted_strings) - fuzz_sql_nts(&target, &target_len); SQLRETURN ret = SQLBrowseConnectA( conn, - target, target_len, + target_buf, target_len, outbuf, sizeof(outbuf), &n ); ensure_ok(SQL_HANDLE_DBC, conn, "SQLBrowseConnect", ret); @@ -323,7 +339,6 @@ do_sqlbrowseconnect(SQLCHAR *target) if (ret != SQL_NEED_DATA) exitcode = do_execute_stmt(); - // Do not call SQLDisconnect, SQLBrowseConnect is intended to // be invoked multiple times without disconnecting inbetween @@ -387,14 +402,16 @@ do_listdsns(const char *prefix, SQLSMALL static int do_execute_stmt(void) { + SQLCHAR *query_buf; + SQLSMALLINT query_len = SQL_NTS; + if (query == NULL) return 0; if (verbose) printf("Statement: %s\n", query); - if (use_counted_strings) - fuzz_sql_nts(&query, &query_len); + make_arg(query, &query_buf, &query_len); ensure_ok( SQL_HANDLE_ENV, conn, "allocate stmt handle", @@ -402,7 +419,7 @@ do_execute_stmt(void) ensure_ok( SQL_HANDLE_STMT, stmt, "SQLExecDirect", - SQLExecDirectA(stmt, query, query_len)); + SQLExecDirectA(stmt, query_buf, query_len)); do { SQLLEN rowcount = -1; @@ -442,26 +459,30 @@ do_execute_stmt(void) } -static SQLCHAR* -sqldup_with_margin(const char *str) +static void +make_arg(const char *arg, SQLCHAR**bufp, SQLSMALLINT *buflen) { - size_t len = strlen(str); - char *buf = malloc(len + MARGIN); - memmove(buf, str, len); - memset(buf + len, 0, MARGIN); - return (SQLCHAR*)buf; -} + if (arg == NULL) { + *bufp = NULL; + *buflen = SQL_NTS; + return; + } -static void -fuzz_sql_nts(SQLCHAR **str, SQLSMALLINT *len) -{ - if (*str != NULL && *len == SQL_NTS) { - // append garbage so it's no longer properly NUL terminated, - // indicate original length through 'len' - size_t n = strlen((char*)*str); - const char *garbage = "GARBAGE"; - size_t garblen = strlen(garbage); - memmove(*str + n, garbage, garblen + 1); // include the trailing NUL - *len = (SQLSMALLINT)n; + size_t len = strlen(arg); + if (!use_counted_strings) { _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org