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 -- [email protected]
To unsubscribe send an email to [email protected]