Changeset: 55b7f9555245 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/55b7f9555245
Modified Files:
clients/odbc/tests/odbcconnect.c
sql/odbc/tests/Tests/ODBCconnect.py
Branch: Aug2024
Log Message:
Test non-NUL-terminated arguments
diffs (172 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
@@ -17,6 +17,7 @@
#endif
#include <assert.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -33,6 +34,7 @@ static const char *USAGE =
" -l List registered drivers and data sources\n"
" -u USER\n"
" -p PASSWORD\n"
+ " -0 use counted strings rather than nul-terminated
arguments\n"
" -v Be verbose\n"
" TARGET DSN or with -d and -b, Connection String\n";
@@ -49,10 +51,16 @@ static int do_listdsns(const char *prefi
static void ensure_ok(SQLSMALLINT type, SQLHANDLE handle, const char *message,
SQLRETURN ret);
+#define MARGIN 100
+static SQLCHAR* sqldup_with_margin(const char *str);
+static void fuzz_sql_nts(SQLCHAR **str, SQLSMALLINT *len);
int verbose = 0;
SQLCHAR *user = NULL;
+SQLSMALLINT user_len = SQL_NTS;
SQLCHAR *password = NULL;
+SQLSMALLINT password_len = SQL_NTS;
+bool use_counted_strings = false;
SQLHANDLE env = NULL;
SQLHANDLE conn = NULL;
@@ -89,13 +97,15 @@ main(int argc, char **argv)
else if (strcmp(arg, "-l") == 0)
action = NULL;
else if (strcmp(arg, "-u") == 0 && i + 1 < argc)
- user = (SQLCHAR*)argv[++i];
+ user = sqldup_with_margin(argv[++i]);
else if (strcmp(arg, "-p") == 0 && i + 1 < argc)
- password = (SQLCHAR*)argv[++i];
+ password = sqldup_with_margin(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++] = (SQLCHAR*)arg;
+ targets[ntargets++] = sqldup_with_margin(arg);
else {
fprintf(stderr, "\nERROR: invalid argument: %s\n%s",
arg, USAGE);
ret = 1;
@@ -111,6 +121,11 @@ 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);
@@ -130,6 +145,10 @@ main(int argc, char **argv)
}
end:
+ free(user);
+ free(password);
+ for (int i = 0; i < ntargets; i++)
+ free(targets[i]);
free(targets);
cleanup();
@@ -207,9 +226,13 @@ do_actions(action_t action, int ntargets
static int
do_sqlconnect(SQLCHAR *target)
{
+ SQLSMALLINT target_len = SQL_NTS;
+ if (use_counted_strings)
+ fuzz_sql_nts(&target, &target_len);
+
ensure_ok(
SQL_HANDLE_DBC, conn, "SQLConnect",
- SQLConnect(conn, target, SQL_NTS, user, SQL_NTS, password,
SQL_NTS));
+ SQLConnect(conn, target, target_len, user, user_len, password,
password_len));
printf("OK\n");
return 0;
@@ -219,11 +242,15 @@ static int
do_sqldriverconnect(SQLCHAR *target)
{
SQLSMALLINT n;
+ SQLSMALLINT target_len = SQL_NTS;
+ if (use_counted_strings)
+ fuzz_sql_nts(&target, &target_len);
+
ensure_ok(
SQL_HANDLE_DBC, conn, "SQLDriverConnect",
SQLDriverConnect(
conn, NULL,
- target, SQL_NTS,
+ target, target_len,
outbuf, sizeof(outbuf), &n,
SQL_DRIVER_NOPROMPT
));
@@ -236,9 +263,13 @@ static int
do_sqlbrowseconnect(SQLCHAR *target)
{
SQLSMALLINT n;
+ SQLSMALLINT target_len = SQL_NTS;
+ if (use_counted_strings)
+ fuzz_sql_nts(&target, &target_len);
+
SQLRETURN ret = SQLBrowseConnect(
conn,
- target, SQL_NTS,
+ target, target_len,
outbuf, sizeof(outbuf), &n
);
ensure_ok(SQL_HANDLE_DBC, conn, "SQLBrowseConnect", ret);
@@ -302,3 +333,27 @@ do_listdsns(const char *prefix, SQLSMALL
return 0;
}
+
+static SQLCHAR*
+sqldup_with_margin(const char *str)
+{
+ size_t len = strlen(str);
+ char *buf = malloc(len + MARGIN);
+ memmove(buf, str, len);
+ memset(buf + len, 0, MARGIN);
+ return (SQLCHAR*)buf;
+}
+
+static void
+fuzz_sql_nts(SQLCHAR **str, SQLSMALLINT *len)
+{
+ if (*str != NULL) {
+ // 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;
+ }
+}
diff --git a/sql/odbc/tests/Tests/ODBCconnect.py
b/sql/odbc/tests/Tests/ODBCconnect.py
--- a/sql/odbc/tests/Tests/ODBCconnect.py
+++ b/sql/odbc/tests/Tests/ODBCconnect.py
@@ -134,4 +134,15 @@ ex.expect('Error')
ex.expect('28000:') # 28000 bad credentials
ex.end()
+# test non-NUL terminated strings
+
+ex = Execution(dbname, '-0')
+ex.expect('OK')
+ex.end()
+
+ex = Execution(dbname, '-0', '-u', 'monetdb', '-p', 'monetdb')
+ex.expect('OK')
+ex.end()
+
+
ex = None
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]