diff --git a/.travis.yml b/.travis.yml index e4e28079..ac3624aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,16 +4,33 @@ cache: apt: true ccache: true services: docker + +env: + global: + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "Pk5DUyHtal064Yc4bx0S2Zo4C3NqOURLOqYxW/tQJ73XDTRhyJqD5PFLhsFN+nqvZqx8b1LLtQuVoxP7sW12Qpys7Qs39QavSsa2GWAVf9Kf4PRRsUy5as72/Vh19XbQ1w8fFdPax6KPgnWMb97XZSDJP+2Tyuk8R5pk+/T2t2QsQeml5bJwD0diffLZi27APc0mcNSdaLpPYN4SlEKFmD2CxUAR5IxaBjGKoiuo0f6FSSB1tqlirAnAc5s28tGVkXf42o13oooNYwLgNatc4JRDMofbCVxo9OzqsVbVaN2OwOD3uQ+RxB7X1FydFQm2nfiDNt+D/dBlAz0LkUw1NRrDxl+r6+9xtzVZgHTNUOqG9W5JGJ7j99dUzwSJl6RS4QxeetlrRHGx9S2TTBa6JSkDxiRTQR2XfZxyMtARuHZkY7SAq6sHNKYoyAERuUoeq5e8UOa3dLj4gBwsB/J4y0eLWMxtfDKZj2vGI2BRJewBCBeouPAVIlmWGDyNg6f6X/o07N2IeWJOoj9ZF27Kbp7QxK/D0pQp4AONxtl15ZCfRs5lthKYIHQo0qzlukcir8e7zi5J0bUlOlTT4DtXAeaeIP9oUrLn9kCv7EyvLZMR4dPvREDThqQovF03jqwMDggVa3iGmxu/zrm+S11PwDmzq45+WLcYwyikvsqBFSE=" + + addons: hosts: - mariadb.example.com + coverity_scan: + project: + name: "MariaDB/mariadb-connector-c" + description: "MariaDB Connector/C" + notification_email: georg@mariadb.com + build_command_prepend: "cmake ." + build_command: "make" + branch_pattern: coverity_scan + before_script: # Disable services enabled by default - sudo /etc/init.d/mysql stop - before_install: + - echo -n | openssl s_client -connect https://scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- - chmod -R +x .travis/* - chmod 777 .travis/build/ - export PROJ_PATH=`pwd` diff --git a/include/errmsg.h b/include/errmsg.h index f4af5288..481b0a62 100644 --- a/include/errmsg.h +++ b/include/errmsg.h @@ -85,6 +85,9 @@ extern const char *mariadb_client_errors[]; /* Error messages */ #define CR_AUTH_PLUGIN_CANNOT_LOAD 2059 #define CR_DUPLICATE_CONNECTION_ATTR 2060 #define CR_AUTH_PLUGIN_ERR 2061 +/* Always last, if you add new error codes please update the + value for CR_MYSQL_LAST_ERROR */ +#define CR_MYSQL_LAST_ERROR CR_AUTH_PLUGIN_ERR /* * MariaDB Connector/C errors: @@ -96,5 +99,8 @@ extern const char *mariadb_client_errors[]; /* Error messages */ #define CR_FILE_NOT_FOUND 5004 #define CR_FILE_READ 5005 #define CR_BULK_WITHOUT_PARAMETERS 5006 - +#define CR_INVALID_STMT 5007 +/* Always last, if you add new error codes please update the + value for CR_MARIADB_LAST_ERROR */ +#define CR_MARIADB_LAST_ERROR CR_INVALID_STMT #endif diff --git a/include/mariadb_stmt.h b/include/mariadb_stmt.h index 5e1c7110..8d676450 100644 --- a/include/mariadb_stmt.h +++ b/include/mariadb_stmt.h @@ -37,8 +37,8 @@ #define SET_CLIENT_STMT_ERROR(a, b, c, d) \ { \ (a)->last_errno= (b);\ - strncpy((a)->sqlstate, (c), sizeof((a)->sqlstate));\ - strncpy((a)->last_error, (d) ? (d) : ER((b)), sizeof((a)->last_error));\ + strncpy((a)->sqlstate, (c), SQLSTATE_LENGTH);\ + strncpy((a)->last_error, (d) ? (d) : ER((b)), MYSQL_ERRMSG_SIZE - 1);\ } #define CLEAR_CLIENT_STMT_ERROR(a) \ diff --git a/include/mysql.h b/include/mysql.h index 5d75ee68..08525e82 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -124,8 +124,8 @@ extern unsigned int mariadb_deinitialize_ssl; #define SET_CLIENT_ERROR(a, b, c, d) \ { \ (a)->net.last_errno= (b);\ - strncpy((a)->net.sqlstate, (c), sizeof((a)->net.sqlstate));\ - strncpy((a)->net.last_error, (d) ? (d) : ER((b)), sizeof((a)->net.last_error));\ + strncpy((a)->net.sqlstate, (c), SQLSTATE_LENGTH);\ + strncpy((a)->net.last_error, (d) ? (d) : ER((b)), MYSQL_ERRMSG_SIZE - 1);\ } /* For mysql_async.c */ diff --git a/libmariadb/ma_charset.c b/libmariadb/ma_charset.c index 49a50abe..c6fbe0d1 100644 --- a/libmariadb/ma_charset.c +++ b/libmariadb/ma_charset.c @@ -1408,7 +1408,7 @@ static void map_charset_name(const char *cs_name, my_bool target_cs, char *buffe if (target_cs) { - strncat(buffer, "//TRANSLIT", buff_len); + strncat(buffer, "//TRANSLIT", buff_len - strlen(buffer)); } } /* }}} */ diff --git a/libmariadb/ma_client_plugin.c.in b/libmariadb/ma_client_plugin.c.in index 8d61d317..ebf311ae 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"); - /* no plugins to load */ - if (!s) - return; + if ((s= getenv("LIBMYSQL_PLUGINS"))) + { + s= strdup(s); + free_env= plugs= s; - free_env= plugs= strdup(s); + do { + if ((s= strchr(plugs, ';'))) + *s= '\0'; + mysql_load_plugin(mysql, plugs, -1, 0); + plugs= s + 1; + } while (s); - do { - if ((s= strchr(plugs, ';'))) - *s= '\0'; - mysql_load_plugin(mysql, plugs, -1, 0); - plugs= s + 1; - } while (s); - - free(free_env); + free(free_env); + } } /********** extern functions to be used by libmariadb *********************/ @@ -365,7 +365,7 @@ mysql_load_plugin_v(MYSQL *mysql, const char *name, int type, char errbuf[1024]; #endif char dlpath[FN_REFLEN+1]; - void *sym, *dlhandle; + void *sym, *dlhandle = NULL; struct st_mysql_client_plugin *plugin; char *env_plugin_dir= getenv("MARIADB_PLUGIN_DIR"); @@ -448,6 +448,8 @@ mysql_load_plugin_v(MYSQL *mysql, const char *name, int type, return plugin; err: + if (dlhandle) + dlclose(dlhandle); pthread_mutex_unlock(&LOCK_load_client_plugin); my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN, ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, errmsg); diff --git a/libmariadb/ma_default.c b/libmariadb/ma_default.c index 17670e8d..a9ffdfcb 100644 --- a/libmariadb/ma_default.c +++ b/libmariadb/ma_default.c @@ -231,12 +231,7 @@ static my_bool _mariadb_read_options_from_file(MYSQL *mysql, key= ptr; for ( ; isspace(end[-1]) ; end--) ; *end= 0; - if (!value) - { - if (!key) - key= ptr; - } - else + if (value) { /* Remove pre- and end space */ char *value_end; diff --git a/libmariadb/ma_dtoa.c b/libmariadb/ma_dtoa.c index 5d67f7b5..9ba0387b 100644 --- a/libmariadb/ma_dtoa.c +++ b/libmariadb/ma_dtoa.c @@ -1333,7 +1333,9 @@ static char *dtoa(double dd, int mode, int ndigits, int *decpt, int *sign, *sign= 0; /* If infinity, set decpt to DTOA_OVERFLOW, if 0 set it to 1 */ + /* coverity[assign_where_compare_meant] */ if (((word0(&u) & Exp_mask) == Exp_mask && (*decpt= DTOA_OVERFLOW)) || + /* coverity[assign_where_compare_meant] */ (!dval(&u) && (*decpt= 1))) { /* Infinity, NaN, 0 */ diff --git a/libmariadb/ma_errmsg.c b/libmariadb/ma_errmsg.c index d668c779..ab0a8a38 100644 --- a/libmariadb/ma_errmsg.c +++ b/libmariadb/ma_errmsg.c @@ -142,7 +142,7 @@ const char *client_errors[]= /* 2057 */ "The number of parameters in bound buffers differs from number of columns in resultset", /* 2059 */ "Can't connect twice. Already connected", /* 2058 */ "Plugin %s could not be loaded: %s", -/* 2059 */ "An attribute with same name already exists" +/* 2059 */ "An attribute with same name already exists", /* 2060 */ "Plugin doesn't support this function", "" }; @@ -157,6 +157,7 @@ const char *mariadb_client_errors[] = /* 5004 */ "File '%s' not found (Errcode: %d)", /* 5005 */ "Error reading file '%s' (Errcode: %d)", /* 5006 */ "Bulk operation without parameters is not supported", + /* 5007 */ "Invalid statement handle", "" }; diff --git a/libmariadb/ma_io.c b/libmariadb/ma_io.c index 7ce34adb..178ffe9f 100644 --- a/libmariadb/ma_io.c +++ b/libmariadb/ma_io.c @@ -108,6 +108,7 @@ MA_FILE *ma_open(const char *location, const char *mode, MYSQL *mysql) ma_file= (MA_FILE *)malloc(sizeof(MA_FILE)); if (!ma_file) { + fclose(fp); my_set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); return NULL; } diff --git a/libmariadb/ma_net.c b/libmariadb/ma_net.c index 07460eb8..15be4fce 100644 --- a/libmariadb/ma_net.c +++ b/libmariadb/ma_net.c @@ -549,7 +549,6 @@ ulong ma_net_read(NET *net) return packet_error; if (_mariadb_uncompress((unsigned char*) net->buff + net->where_b, &packet_length, &complen)) { - len= packet_error; net->error=2; /* caller will close socket */ net->last_errno=ER_NET_UNCOMPRESS_ERROR; break; diff --git a/libmariadb/ma_pvio.c b/libmariadb/ma_pvio.c index dc263fe2..400108dd 100644 --- a/libmariadb/ma_pvio.c +++ b/libmariadb/ma_pvio.c @@ -102,7 +102,7 @@ MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo) return NULL; } - +/* 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); @@ -399,20 +399,23 @@ end: void ma_pvio_close(MARIADB_PVIO *pvio) { /* free internal structures and close connection */ -#ifdef HAVE_TLS - if (pvio && pvio->ctls) + if (pvio) { - ma_pvio_tls_close(pvio->ctls); - free(pvio->ctls); - } +#ifdef HAVE_TLS + if (pvio->ctls) + { + ma_pvio_tls_close(pvio->ctls); + free(pvio->ctls); + } #endif - if (pvio && pvio->methods->close) - pvio->methods->close(pvio); + if (pvio && pvio->methods->close) + pvio->methods->close(pvio); - if (pvio->cache) - free(pvio->cache); + if (pvio->cache) + free(pvio->cache); - free(pvio); + free(pvio); + } } /* }}} */ @@ -460,13 +463,16 @@ ma_pvio_wait_async(struct mysql_async_context *b, enum enum_pvio_io_event event, /* {{{ ma_pvio_wait_io_or_timeout */ int ma_pvio_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout) { - if (IS_PVIO_ASYNC_ACTIVE(pvio)) - return ma_pvio_wait_async(pvio->mysql->options.extension->async_context, - (is_read) ? VIO_IO_EVENT_READ : VIO_IO_EVENT_WRITE, - timeout); + if (pvio) + { + if (IS_PVIO_ASYNC_ACTIVE(pvio)) + return ma_pvio_wait_async(pvio->mysql->options.extension->async_context, + (is_read) ? VIO_IO_EVENT_READ : VIO_IO_EVENT_WRITE, + timeout); - if (pvio && pvio->methods->wait_io_or_timeout) - return pvio->methods->wait_io_or_timeout(pvio, is_read, timeout); + if (pvio && pvio->methods->wait_io_or_timeout) + return pvio->methods->wait_io_or_timeout(pvio, is_read, timeout); + } return 1; } /* }}} */ diff --git a/libmariadb/ma_time.c b/libmariadb/ma_time.c index 5b4087b0..460c32d4 100644 --- a/libmariadb/ma_time.c +++ b/libmariadb/ma_time.c @@ -34,7 +34,7 @@ size_t mariadb_time_to_string(const MYSQL_TIME *tm, char *time_str, size_t len, return 0; if (digits == AUTO_SEC_PART_DIGITS) - digits= MIN((tm->second_part) ? SEC_PART_DIGITS : 0, 15); + digits= (tm->second_part) ? SEC_PART_DIGITS : 0; switch(tm->time_type) { case MYSQL_TIMESTAMP_DATE: diff --git a/libmariadb/mariadb_dyncol.c b/libmariadb/mariadb_dyncol.c index 80bb7235..220dd63a 100644 --- a/libmariadb/mariadb_dyncol.c +++ b/libmariadb/mariadb_dyncol.c @@ -1681,7 +1681,10 @@ dynamic_new_column_store(DYNAMIC_COLUMN *str, goto err; } if (!column_count) + { + free(columns_order); return ER_DYNCOL_OK; + } memset(str->str, 0, fmt->fixed_hdr); str->length= fmt->fixed_hdr; @@ -2755,7 +2758,7 @@ dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan, new_hdr->header_size + new_hdr->nmpool_size; for (i= 0, j= 0; i < add_column_count || j < hdr->column_count; i++) { - size_t UNINIT_VAR(first_offset); + size_t first_offset= 0; uint start= j, end; /* diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index e05d3eea..e35938c3 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -230,7 +230,7 @@ restart: } else { - strcpy(net->sqlstate, SQLSTATE_UNKNOWN); + strncpy(net->sqlstate, SQLSTATE_UNKNOWN, SQLSTATE_LENGTH); } ma_strmake(net->last_error,(char*) pos, min(len,sizeof(net->last_error)-1)); @@ -948,7 +948,8 @@ int mthd_my_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) if (len > (ulong) (end_pos - pos) || pos > end_pos) { mysql->net.last_errno=CR_UNKNOWN_ERROR; - strcpy(mysql->net.last_error,ER(mysql->net.last_errno)); + strncpy(mysql->net.last_error,ER(mysql->net.last_errno), + MYSQL_ERRMSG_SIZE - 1); return -1; } row[field] = (char*) pos; @@ -985,6 +986,7 @@ mysql_init(MYSQL *mysql) { memset((char*) (mysql), 0, sizeof(*(mysql))); mysql->net.pvio= 0; + mysql->free_me= 0; mysql->net.extension= 0; } @@ -1190,8 +1192,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user, uint port, const char *unix_socket, unsigned long client_flag) { char buff[NAME_LEN+USERNAME_LENGTH+100]; - char *end, *end_pkt, *host_info, - *charset_name= NULL; + char *end, *end_pkt, *host_info; MA_PVIO_CINFO cinfo= {NULL, NULL, 0, -1, NULL}; MARIADB_PVIO *pvio= NULL; char *scramble_data; @@ -1386,9 +1387,8 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user, } /* Save connection information */ if (!user) user=""; - if (!passwd) passwd=""; - if (!(mysql->host_info= strdup(host_info ? host_info : "")) || + if (!(mysql->host_info= strdup(host_info)) || !(mysql->host= strdup(cinfo.host ? cinfo.host : "")) || !(mysql->user=strdup(user)) || !(mysql->passwd=strdup(passwd))) @@ -1490,7 +1490,8 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user, { net->last_errno=CR_CANT_READ_CHARSET; sprintf(net->last_error,ER(net->last_errno), - charset_name ? charset_name : "unknown", + mysql->options.charset_name ? mysql->options.charset_name : + MARIADB_DEFAULT_CHARSET, "compiled_in"); goto error; } @@ -1607,6 +1608,7 @@ my_bool STDCALL mariadb_reconnect(MYSQL *mysql) } mysql_init(&tmp_mysql); + tmp_mysql.free_me= 0; tmp_mysql.options=mysql->options; if (mysql->extension->conn_hdlr) { @@ -1722,13 +1724,6 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, *s_db= mysql->db; int rc; - if (!user) - user=""; - if (!passwd) - passwd=""; - if (!db) - db=""; - if (mysql->options.charset_name) mysql->charset= mysql_find_charset_name(mysql->options.charset_name); else @@ -1779,8 +1774,11 @@ mysql_select_db(MYSQL *mysql, const char *db) { int error; + if (!db) + return 1; + if ((error=ma_simple_command(mysql, COM_INIT_DB, db, - db ? (uint) strlen(db) : 0,0,0))) + (uint) strlen(db),0,0))) return(error); free(mysql->db); mysql->db=strdup(db); @@ -2293,12 +2291,14 @@ mysql_fetch_row(MYSQL_RES *res) if (!res) return 0; if (res->handle) + { if (res->handle->status != MYSQL_STATUS_USE_RESULT && res->handle->status != MYSQL_STATUS_GET_RESULT) return 0; + } if (!res->data) { /* Unbufferred fetch */ - if (!res->eof) + if (!res->eof && res->handle) { if (!(res->handle->methods->db_read_one_row(res->handle,res->field_count,res->row, res->lengths))) { @@ -2746,6 +2746,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...) if(!(mysql->options.extension= (struct st_mysql_options_extension *) calloc(1, sizeof(struct st_mysql_options_extension)))) { + free(ctxt); SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); goto end; } @@ -3146,9 +3147,6 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...) if (!(elements= va_arg(ap, unsigned int *))) goto error; - if (!elements) - goto error; - *elements= 0; if (!mysql->options.extension || diff --git a/libmariadb/mariadb_stmt.c b/libmariadb/mariadb_stmt.c index 5ed9e2c5..f5ca3818 100644 --- a/libmariadb/mariadb_stmt.c +++ b/libmariadb/mariadb_stmt.c @@ -88,12 +88,18 @@ void stmt_set_error(MYSQL_STMT *stmt, ...) { va_list ap; + const char *error= NULL; + + if (error_nr >= CR_MIN_ERROR && error_nr <= CR_MYSQL_LAST_ERROR) + error= ER(error_nr); + else if (error_nr >= CER_MIN_ERROR && error_nr <= CR_MARIADB_LAST_ERROR) + error= CER(error_nr); stmt->last_errno= error_nr; ma_strmake(stmt->sqlstate, sqlstate, SQLSTATE_LENGTH); va_start(ap, format); vsnprintf(stmt->last_error, MYSQL_ERRMSG_SIZE, - format ? format : ER(error_nr), ap); + format ? format : error ? error : "", ap); va_end(ap); return; } @@ -869,7 +875,7 @@ unsigned char* mysql_stmt_execute_generate_bulk_request(MYSQL_STMT *stmt, size_t if (!stmt->param_count) { stmt_set_error(stmt, CR_BULK_WITHOUT_PARAMETERS, "IM001", - CER(CR_BULK_WITHOUT_PARAMETERS), "Bulk operation"); + CER(CR_BULK_WITHOUT_PARAMETERS)); return NULL; } @@ -1328,15 +1334,18 @@ static my_bool net_stmt_close(MYSQL_STMT *stmt, my_bool remove) my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt) { - my_bool rc; - if (stmt && stmt->mysql && stmt->mysql->net.pvio) - mysql_stmt_internal_reset(stmt, 1); + my_bool rc= 1; - rc= net_stmt_close(stmt, 1); + if (stmt) + { + if (stmt->mysql && stmt->mysql->net.pvio) + mysql_stmt_internal_reset(stmt, 1); - free(stmt->extension); - free(stmt); + rc= net_stmt_close(stmt, 1); + free(stmt->extension); + free(stmt); + } return(rc); } @@ -1898,7 +1907,8 @@ int stmt_read_execute_response(MYSQL_STMT *stmt) */ /* preferred is buffered read */ - mysql_stmt_store_result(stmt); + if (mysql_stmt_store_result(stmt)) + return 1; stmt->mysql->status= MYSQL_STATUS_STMT_RESULT; } else { @@ -2313,17 +2323,23 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt, const char *stmt_str, size_t length) { - MYSQL *mysql= stmt->mysql; - my_bool emulate_cmd= !(!(stmt->mysql->server_capabilities & CLIENT_MYSQL) && - (stmt->mysql->extension->mariadb_server_capabilities & - (MARIADB_CLIENT_STMT_BULK_OPERATIONS >> 32))) || mysql->net.compress; + MYSQL *mysql; + my_bool emulate_cmd; + if (!stmt) + return 1; + + mysql= stmt->mysql; if (!mysql) { SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0); - goto fail; + return 1; } + emulate_cmd= !(!(stmt->mysql->server_capabilities & CLIENT_MYSQL) && + (stmt->mysql->extension->mariadb_server_capabilities & + (MARIADB_CLIENT_STMT_BULK_OPERATIONS >> 32))) || mysql->net.compress; + /* Server versions < 10.2 don't support execute_direct, so we need to emulate it */ if (emulate_cmd) @@ -2331,7 +2347,6 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt, int rc; /* avoid sending close + prepare in 2 packets */ - if ((rc= mysql_stmt_prepare(stmt, stmt_str, (unsigned long)length))) return rc; return mysql_stmt_execute(stmt); @@ -2340,13 +2355,7 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt, if (ma_multi_command(mysql, COM_MULTI_ENABLED)) { SET_CLIENT_STMT_ERROR(stmt, CR_COMMANDS_OUT_OF_SYNC, SQLSTATE_UNKNOWN, 0); - goto fail; - } - - if (!stmt->mysql) - { - SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0); - return(1); + return 1; } if (length == (size_t) -1) @@ -2430,8 +2439,10 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt, /* read execute response packet */ return stmt_read_execute_response(stmt); fail: - SET_CLIENT_STMT_ERROR(stmt, mysql->net.last_errno, mysql->net.sqlstate, - mysql->net.last_error); + /* check if we need to set error message */ + if (!mysql_stmt_errno(stmt)) + SET_CLIENT_STMT_ERROR(stmt, mysql->net.last_errno, mysql->net.sqlstate, + mysql->net.last_error); do { stmt->mysql->methods->db_stmt_flush_unbuffered(stmt); } while(mysql_stmt_more_results(stmt)); diff --git a/plugins/auth/old_password.c b/plugins/auth/old_password.c index b5a120da..6cc47074 100644 --- a/plugins/auth/old_password.c +++ b/plugins/auth/old_password.c @@ -96,8 +96,8 @@ static int auth_old_password(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) return CR_SERVER_HANDSHAKE_ERR; /* save it in MYSQL */ - memmove(mysql->scramble_buff, pkt, pkt_len); - mysql->scramble_buff[pkt_len] = 0; + memmove(mysql->scramble_buff, pkt, pkt_len - 1); + mysql->scramble_buff[pkt_len - 1] = 0; } if (mysql && mysql->passwd[0]) diff --git a/plugins/auth/sha256_pw.c b/plugins/auth/sha256_pw.c index 522307f1..6648ef11 100644 --- a/plugins/auth/sha256_pw.c +++ b/plugins/auth/sha256_pw.c @@ -117,6 +117,7 @@ char *load_pub_key_file(const char *filename, int *pub_key_size) FILE *fp= NULL; char *buffer= NULL; unsigned char error= 1; + size_t bytes_read= 0; if (!pub_key_size) return NULL; @@ -133,7 +134,8 @@ char *load_pub_key_file(const char *filename, int *pub_key_size) if (!(buffer= malloc(*pub_key_size + 1))) goto end; - if (!fread(buffer, *pub_key_size, 1, fp)) + bytes_read= fread(buffer, (size_t)*pub_key_size, 1, fp); + if (bytes_read < (size_t)*pub_key_size) goto end; error= 0; diff --git a/plugins/pvio/pvio_socket.c b/plugins/pvio/pvio_socket.c index 7c06e559..5910bc30 100644 --- a/plugins/pvio/pvio_socket.c +++ b/plugins/pvio/pvio_socket.c @@ -178,6 +178,7 @@ static int pvio_socket_end(void) my_bool pvio_socket_change_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout) { struct timeval tm; + int rc= 0; struct st_pvio_socket *csock= NULL; if (!pvio) return 1; @@ -189,22 +190,22 @@ my_bool pvio_socket_change_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout ty { case PVIO_WRITE_TIMEOUT: #ifndef _WIN32 - setsockopt(csock->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tm, sizeof(tm)); + rc= setsockopt(csock->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tm, sizeof(tm)); #else - setsockopt(csock->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(int)); + rc= setsockopt(csock->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(int)); #endif break; case PVIO_READ_TIMEOUT: #ifndef _WIN32 - setsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tm, sizeof(tm)); + rc= setsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tm, sizeof(tm)); #else - setsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(int)); + src= etsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(int)); #endif break; default: break; } - return 0; + return rc; } /* {{{ pvio_socket_set_timeout */ @@ -887,6 +888,7 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) if (rc) { closesocket(csock->socket); + csock->socket= INVALID_SOCKET; continue; } } @@ -901,6 +903,7 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) if (pvio_socket_blocking(pvio, 0, 0) == SOCKET_ERROR) { closesocket(csock->socket); + csock->socket= INVALID_SOCKET; continue; } break; /* success! */ @@ -936,21 +939,27 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) /* apply timeouts */ if (pvio->timeout[PVIO_CONNECT_TIMEOUT] > 0) { - pvio_socket_change_timeout(pvio, PVIO_READ_TIMEOUT, pvio->timeout[PVIO_CONNECT_TIMEOUT]); - pvio_socket_change_timeout(pvio, PVIO_WRITE_TIMEOUT, pvio->timeout[PVIO_CONNECT_TIMEOUT]); + if (pvio_socket_change_timeout(pvio, PVIO_READ_TIMEOUT, pvio->timeout[PVIO_CONNECT_TIMEOUT]) || + pvio_socket_change_timeout(pvio, PVIO_WRITE_TIMEOUT, pvio->timeout[PVIO_CONNECT_TIMEOUT])) + goto error; } else { if (pvio->timeout[PVIO_WRITE_TIMEOUT] > 0) - pvio_socket_change_timeout(pvio, PVIO_WRITE_TIMEOUT, pvio->timeout[PVIO_WRITE_TIMEOUT]); + if (pvio_socket_change_timeout(pvio, PVIO_WRITE_TIMEOUT, pvio->timeout[PVIO_WRITE_TIMEOUT])) + goto error; if (pvio->timeout[PVIO_READ_TIMEOUT] > 0) - pvio_socket_change_timeout(pvio, PVIO_READ_TIMEOUT, pvio->timeout[PVIO_READ_TIMEOUT]); + if (pvio_socket_change_timeout(pvio, PVIO_READ_TIMEOUT, pvio->timeout[PVIO_READ_TIMEOUT])) + goto error; } return 0; error: /* close socket: MDEV-10891 */ if (csock->socket != INVALID_SOCKET) + { closesocket(csock->socket); + csock->socket= INVALID_SOCKET; + } if (pvio->data) { free((gptr)pvio->data);