From c95f86e88289ca84d881af6680e56c25aeb8e3b6 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 13 Jul 2018 12:30:13 +0200 Subject: [PATCH] More coverity fixes --- include/ma_string.h | 19 +++++++++++++++++ include/ma_sys.h | 3 +++ libmariadb/get_password.c | 2 +- libmariadb/ma_client_plugin.c.in | 24 ++++++++++----------- libmariadb/ma_pvio.c | 2 +- libmariadb/ma_stmt_codec.c | 3 +++ libmariadb/ma_string.c | 30 ++++++++++++++++++++++++++ libmariadb/mariadb_dyncol.c | 11 +++++----- plugins/auth/sha256_pw.c | 14 +++++++++---- plugins/pvio/pvio_socket.c | 2 +- unittest/libmariadb/dyncol.c | 36 ++++++++++++++++++++++++++++++++ 11 files changed, 121 insertions(+), 25 deletions(-) diff --git a/include/ma_string.h b/include/ma_string.h index f00f4805..10325387 100644 --- a/include/ma_string.h +++ b/include/ma_string.h @@ -33,4 +33,23 @@ size_t ma_gcvt(double x, my_gcvt_arg_type type, int width, char *to, my_bool *error); char *ma_ll2str(long long val,char *dst, int radix); +#define MAX_ENV_SIZE 1024 + +static inline my_bool ma_check_env_str(const char *env) +{ + unsigned int i; + + if (!env) + return 1; + + for (i=0; i < MAX_ENV_SIZE; i++) + { + if (env[i] == 0) + break; + } + if (i >= MAX_ENV_SIZE) + return 1; + return 0; +} + #endif diff --git a/include/ma_sys.h b/include/ma_sys.h index e0515dd6..431c758f 100644 --- a/include/ma_sys.h +++ b/include/ma_sys.h @@ -524,6 +524,9 @@ extern const char *ma_get_type(TYPELIB *typelib,uint nr); extern my_bool ma_init_dynamic_string(DYNAMIC_STRING *str, const char *init_str, size_t init_alloc, size_t alloc_increment); extern my_bool ma_dynstr_append(DYNAMIC_STRING *str, const char *append); +extern my_bool ma_dynstr_append_quoted(DYNAMIC_STRING *str, + const char *append, size_t len, + char quote); my_bool ma_dynstr_append_mem(DYNAMIC_STRING *str, const char *append, size_t length); extern my_bool ma_dynstr_set(DYNAMIC_STRING *str, const char *init_str); diff --git a/libmariadb/get_password.c b/libmariadb/get_password.c index d5d17bb1..4a93a738 100644 --- a/libmariadb/get_password.c +++ b/libmariadb/get_password.c @@ -65,7 +65,7 @@ static char *get_password(FILE *file, char *buffer, int length) !CharsProcessed) break; #else - inChar= fgetc(file); + inChar= (char)fgetc(file); #endif switch(inChar) { diff --git a/libmariadb/ma_client_plugin.c.in b/libmariadb/ma_client_plugin.c.in index ebf311ae..1b18c0bb 100644 --- a/libmariadb/ma_client_plugin.c.in +++ b/libmariadb/ma_client_plugin.c.in @@ -237,20 +237,20 @@ static void load_env_plugins(MYSQL *mysql) { char *plugs, *free_env, *s= getenv("LIBMYSQL_PLUGINS"); - if ((s= getenv("LIBMYSQL_PLUGINS"))) - { - s= strdup(s); - free_env= plugs= s; + if (ma_check_env_str(s)) + return; - do { - if ((s= strchr(plugs, ';'))) - *s= '\0'; - mysql_load_plugin(mysql, plugs, -1, 0); - plugs= s + 1; - } while (s); + free_env= strdup(s); + plugs= s= free_env; - free(free_env); - } + do { + if ((s= strchr(plugs, ';'))) + *s= '\0'; + mysql_load_plugin(mysql, plugs, -1, 0); + plugs= s + 1; + } while (s); + + free(free_env); } /********** extern functions to be used by libmariadb *********************/ diff --git a/libmariadb/ma_pvio.c b/libmariadb/ma_pvio.c index 400108dd..f00484de 100644 --- a/libmariadb/ma_pvio.c +++ b/libmariadb/ma_pvio.c @@ -105,7 +105,7 @@ MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo) /* coverity[var_deref_op] */ if (!(pvio= (MARIADB_PVIO *)calloc(1, sizeof(MARIADB_PVIO)))) { - PVIO_SET_ERROR(cinfo->mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0); + my_set_error(cinfo->mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0); return NULL; } diff --git a/libmariadb/ma_stmt_codec.c b/libmariadb/ma_stmt_codec.c index f6afaf58..d2b51544 100644 --- a/libmariadb/ma_stmt_codec.c +++ b/libmariadb/ma_stmt_codec.c @@ -442,6 +442,7 @@ static void convert_from_long(MYSQL_BIND *r_param, const MYSQL_FIELD *field, lon len < field->length && len < r_param->buffer_length) { ma_bmove_upp(buffer + field->length, buffer + len, len); + /* coverity [bad_memset] */ memset((void*) buffer, (int) '0', field->length - len); len= field->length; } @@ -660,6 +661,7 @@ static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, fl if (field->length < length || field->length > MAX_DOUBLE_STRING_REP_LENGTH - 1) break; ma_bmove_upp(buff + field->length, buff + length, length); + /* coverity [bad_memset] */ memset((void*) buff, (int) '0', field->length - length); length= field->length; } @@ -759,6 +761,7 @@ static void convert_from_double(MYSQL_BIND *r_param, const MYSQL_FIELD *field, d if (field->length < length || field->length > MAX_DOUBLE_STRING_REP_LENGTH - 1) break; ma_bmove_upp(buff + field->length, buff + length, length); + /* coverity [bad_memset] */ memset((void*) buff, (int) '0', field->length - length); length= field->length; } diff --git a/libmariadb/ma_string.c b/libmariadb/ma_string.c index 9e8773eb..7eb95554 100644 --- a/libmariadb/ma_string.c +++ b/libmariadb/ma_string.c @@ -92,6 +92,36 @@ my_bool ma_dynstr_append(DYNAMIC_STRING *str, const char *append) return ma_dynstr_append_mem(str,append,strlen(append)); } +my_bool ma_dynstr_append_quoted(DYNAMIC_STRING *str, + const char *append, size_t len, + char quote) +{ + uint additional= str->alloc_increment; + uint lim= additional; + uint i; + + if (ma_dynstr_realloc(str, len + additional + 2)) + return TRUE; + str->str[str->length++]= quote; + for (i= 0; i < len; i++) + { + register char c= append[i]; + if (c == quote || c == '\\') + { + if (!lim) + { + if (ma_dynstr_realloc(str, additional)) + return TRUE; + lim= additional; + } + lim--; + str->str[str->length++]= '\\'; + } + str->str[str->length++]= c; + } + str->str[str->length++]= quote; + return FALSE; +} my_bool ma_dynstr_append_mem(DYNAMIC_STRING *str, const char *append, size_t length) diff --git a/libmariadb/mariadb_dyncol.c b/libmariadb/mariadb_dyncol.c index 220dd63a..01e0ba15 100644 --- a/libmariadb/mariadb_dyncol.c +++ b/libmariadb/mariadb_dyncol.c @@ -332,7 +332,7 @@ static my_bool type_and_offset_store_num(uchar *place, size_t offset_size, { ulong val = (((ulong) offset) << 3) | (type - 1); DBUG_ASSERT(type != DYN_COL_NULL); - DBUG_ASSERT(((type - 1) & (~7)) == 0); /* fit in 3 bits */ + DBUG_ASSERT(((type - 1) & (~0xf)) == 0); /* fit in 4 bits */ DBUG_ASSERT(offset_size >= 1 && offset_size <= 4); /* Index entry starts with column number; jump over it */ @@ -3889,10 +3889,9 @@ mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, return ER_DYNCOL_RESOURCE; } if (quote) - rc= ma_dynstr_append_mem(str, "e, 1); - rc= ma_dynstr_append_mem(str, from, len); - if (quote) - rc= ma_dynstr_append_mem(str, "e, 1); + rc= ma_dynstr_append_quoted(str, from, len, quote); + else + rc= ma_dynstr_append_mem(str, from, len); if (alloc) free(alloc); if (rc) @@ -3948,7 +3947,7 @@ mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val) break; case DYN_COL_UINT: *ll= (longlong)val->x.ulong_value; - if (val->x.ulong_value > ULONGLONG_MAX) + if (*ll > (longlong)ULONGLONG_MAX) rc= ER_DYNCOL_TRUNCATED; break; case DYN_COL_DOUBLE: diff --git a/plugins/auth/sha256_pw.c b/plugins/auth/sha256_pw.c index 6648ef11..162c9349 100644 --- a/plugins/auth/sha256_pw.c +++ b/plugins/auth/sha256_pw.c @@ -118,6 +118,7 @@ char *load_pub_key_file(const char *filename, int *pub_key_size) char *buffer= NULL; unsigned char error= 1; size_t bytes_read= 0; + long fsize= 0; if (!pub_key_size) return NULL; @@ -128,16 +129,21 @@ char *load_pub_key_file(const char *filename, int *pub_key_size) if (fseek(fp, 0, SEEK_END)) goto end; - *pub_key_size= ftell(fp); + fsize= ftell(fp); + if (fsize < 0) + goto end; + rewind(fp); - if (!(buffer= malloc(*pub_key_size + 1))) + if (!(buffer= malloc(fsize + 1))) goto end; - bytes_read= fread(buffer, (size_t)*pub_key_size, 1, fp); - if (bytes_read < (size_t)*pub_key_size) + bytes_read= fread(buffer, 1, (size_t)fsize, fp); + if (bytes_read < (size_t)fsize) goto end; + *pub_key_size= bytes_read; + error= 0; end: diff --git a/plugins/pvio/pvio_socket.c b/plugins/pvio/pvio_socket.c index 5910bc30..85026803 100644 --- a/plugins/pvio/pvio_socket.c +++ b/plugins/pvio/pvio_socket.c @@ -772,7 +772,7 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) /* Abstract socket */ if (cinfo->unix_socket[0] == '@') { - strcpy(UNIXaddr.sun_path + 1, cinfo->unix_socket + 1); + strncpy(UNIXaddr.sun_path + 1, cinfo->unix_socket + 1, 107); port_length+= offsetof(struct sockaddr_un, sun_path); } else diff --git a/unittest/libmariadb/dyncol.c b/unittest/libmariadb/dyncol.c index 6e7e9913..47ce313b 100644 --- a/unittest/libmariadb/dyncol.c +++ b/unittest/libmariadb/dyncol.c @@ -56,6 +56,42 @@ static int create_dyncol_named(MYSQL *mysql) mariadb_dyncol_init(&dyncol); rc= mariadb_dyncol_create_many_named(&dyncol, column_count, keys1, vals, 0); FAIL_IF(mariadb_dyncol_create_many_named(&dyncol, column_count, keys1, vals, 1) < 0, "Error"); + if (1) { + DYNAMIC_COLUMN foo, bar; + MYSQL_BIND bind; + MYSQL_STMT *stmt= mysql_stmt_init(mysql); + DYNAMIC_COLUMN_VALUE val; + MYSQL_LEX_STRING keys[]= {{(char *)"TEST", 4}}; + MYSQL_LEX_STRING keys2[]= {{(char *)"PyTuple", 7}}; + rc= mysql_query(mysql, "CREATE OR REPLACE TABLE dyn1 (a blob)"); + check_mysql_rc(rc, mysql); + rc= mysql_stmt_prepare(stmt, SL("INSERT INTO dyn1 VALUES (?)")); + check_stmt_rc(rc, stmt); + memset(&bind, 0, sizeof(MYSQL_BIND)); + mariadb_dyncol_init(&foo); + mariadb_dyncol_init(&bar); + memset(&val, 0, sizeof(DYNAMIC_COLUMN_VALUE)); + val.type= DYN_COL_DYNCOL; + val.x.string.value.str= dyncol.str; + val.x.string.value.length= dyncol.length; + if (mariadb_dyncol_create_many_named(&bar, 1, keys2, &val, 0) != ER_DYNCOL_OK) + val.type= DYN_COL_DYNCOL; + val.x.string.value.str= bar.str; + val.x.string.value.length= bar.length; + diag("l1: %lld\n", bar.length); + if (mariadb_dyncol_create_many_named(&foo, 1, keys2, &val, 0) != ER_DYNCOL_OK) + printf("Error\n"); + diag("l2: %lld\n", foo.length); + bind.buffer_type= MYSQL_TYPE_BLOB; + bind.buffer= (void *)foo.str; + bind.buffer_length= foo.length; + mysql_stmt_bind_param(stmt, &bind); + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + diag("check: %d %d", ER_DYNCOL_OK, mariadb_dyncol_check(&dyncol)); + exit(1); + } + column_count= 0; FAIL_IF(mariadb_dyncol_column_count(&dyncol, &column_count) < 0, "Error");