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

Reply via email to