Changeset: 666b3fcab133 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=666b3fcab133 Modified Files: tools/monetdbe/monetdbe.c Branch: default Log Message:
Merged with Oct2020. Don't forget to escape SQL identifiers when building SQL queries! diffs (155 lines): diff --git a/common/utils/msabaoth.c b/common/utils/msabaoth.c --- a/common/utils/msabaoth.c +++ b/common/utils/msabaoth.c @@ -611,6 +611,7 @@ msab_pickSecret(char **generated_secret) if (generated_secret) // do not return an error, just continue without a secret *generated_secret = NULL; + free(secret); return NULL; #endif #endif @@ -629,6 +630,7 @@ msab_pickSecret(char **generated_secret) char err[512]; snprintf(err, sizeof(err), "unable to open '%s': %s", pathbuf, strerror(errno)); + free(secret); return strdup(err); } if ((f = fdopen(fd, "w")) == NULL) { @@ -637,6 +639,7 @@ msab_pickSecret(char **generated_secret) pathbuf, strerror(errno)); close(fd); (void)remove(pathbuf); + free(secret); return strdup(err); } if (fwrite(secret, 1, SECRET_LENGTH, f) < SECRET_LENGTH || fclose(f) < 0) { @@ -645,11 +648,14 @@ msab_pickSecret(char **generated_secret) strerror(errno)); fclose(f); (void)remove(pathbuf); + free(secret); return strdup(err); } if (generated_secret) *generated_secret = (char*)secret; + else + free(secret); return NULL; #endif } diff --git a/tools/monetdbe/monetdbe.c b/tools/monetdbe/monetdbe.c --- a/tools/monetdbe/monetdbe.c +++ b/tools/monetdbe/monetdbe.c @@ -1443,12 +1443,53 @@ cleanup_get_columns_result(size_t column column_types = NULL; } +static char * +escape_identifier(const char *s) /* Escapes a SQL identifier string, ie the " and \ characters */ +{ + char *ret = NULL, *q; + const char *p = s; + + /* At most we will need 2*strlen(s) + 1 characters */ + if (!(ret = (char *)GDKmalloc(2*strlen(s) + 1))) + return NULL; + + for (q = ret; *p; p++, q++) { + *q = *p; + if (*p == '"') + *(++q) = '"'; + else if (*p == '\\') + *(++q) = '\\'; + } + + *q = '\0'; + return ret; +} + static char* monetdbe_get_columns_remote(monetdbe_database_internal *mdbe, const char* schema_name, const char *table_name, size_t *column_count, char ***column_names, int **column_types) { - char buf[140]; - snprintf(buf, 140, "SELECT * FROM %s.%s WHERE FALSE;", schema_name, table_name); + char buf[1024], *escaped_schema_name = NULL, *escaped_table_name = NULL; + + if (schema_name && !(escaped_schema_name = escape_identifier(schema_name))) { + mdbe->msg = createException(MAL, "monetdbe.monetdbe_get_columns", MAL_MALLOC_FAIL); + return mdbe->msg; + } + if (!(escaped_table_name = escape_identifier(table_name))) { + GDKfree(escaped_schema_name); + mdbe->msg = createException(MAL, "monetdbe.monetdbe_get_columns", MAL_MALLOC_FAIL); + return mdbe->msg; + } + + int len = snprintf(buf, 1024, "SELECT * FROM %s%s%s\"%s\" WHERE FALSE;", + escaped_schema_name ? "\"" : "", escaped_schema_name ? escaped_schema_name : "", + escaped_schema_name ? escaped_schema_name : "\".", escaped_table_name); + GDKfree(escaped_schema_name); + GDKfree(escaped_table_name); + if (len == -1 || len >= 1024) { + mdbe->msg = createException(MAL, "monetdbe.monetdbe_get_columns", "Schema and table path is too large"); + return mdbe->msg; + } monetdbe_result* result = NULL; @@ -1538,14 +1579,14 @@ monetdbe_get_columns(monetdbe_database d return mdbe->msg; if (schema_name) { if (!(s = mvc_bind_schema(m, schema_name))) { - mdbe->msg = createException(MAL, "monetdbe.monetdbe_get_columns", "Could not find schema %s", schema_name); + mdbe->msg = createException(SQL, "monetdbe.monetdbe_get_columns", "Could not find schema '%s'", schema_name); goto cleanup; } } else { s = cur_schema(m); } if (!(t = mvc_bind_table(m, s, table_name))) { - mdbe->msg = createException(MAL, "monetdbe.monetdbe_get_columns", "Could not find table %s", table_name); + mdbe->msg = createException(SQL, "monetdbe.monetdbe_get_columns", "No such table '%s' in schema '%s'", table_name, s->base.name); goto cleanup; } @@ -1731,7 +1772,7 @@ append_create_remote_append_mal_program( a = newFcnCall(mb, sqlRef, appendRef); setArgType(mb, a, 0, TYPE_int); a = pushArgument(mb, a, mvc_id); - a = pushStr(mb, a, schema); + a = pushStr(mb, a, schema ? schema : "sys"); /* TODO this should be better */ a = pushStr(mb, a, table); a = pushStr(mb, a, cnames[i]); a = pushArgument(mb, a, idx); @@ -1783,10 +1824,6 @@ monetdbe_append(monetdbe_database dbhdl, if ((mdbe->msg = getSQLContext(mdbe->c, NULL, &m, NULL)) != MAL_SUCCEED) goto cleanup; - if (schema == NULL) { - mdbe->msg = createException(MAL, "monetdbe.monetdbe_append", "schema parameter is NULL"); - goto cleanup; - } if (table == NULL) { mdbe->msg = createException(MAL, "monetdbe.monetdbe_append", "table parameter is NULL"); goto cleanup; @@ -1853,14 +1890,14 @@ remote_cleanup: if (schema) { if (!(s = mvc_bind_schema(m, schema))) { - mdbe->msg = createException(MAL, "monetdbe.monetdbe_append", "Schema missing %s", schema); + mdbe->msg = createException(SQL, "monetdbe.monetdbe_append", "Could not find schema '%s'", schema); goto cleanup; } } else { s = cur_schema(m); } if (!(t = mvc_bind_table(m, s, table))) { - mdbe->msg = createException(SQL, "monetdbe.monetdbe_append", "Table missing %s.%s", schema, table); + mdbe->msg = createException(SQL, "monetdbe.monetdbe_append", "No such table '%s' in schema '%s'", table, s->base.name); goto cleanup; } } _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list