From b170111d3ef6154d8bd02da1cb0701a99b660682 Mon Sep 17 00:00:00 2001 From: Jun Aruga Date: Mon, 7 May 2018 20:30:02 +0200 Subject: [PATCH 01/37] Fix certificate request error on OpenSSL. --- .travis/gen-ssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/gen-ssl.sh b/.travis/gen-ssl.sh index bacacc34..c7e333fb 100644 --- a/.travis/gen-ssl.sh +++ b/.travis/gen-ssl.sh @@ -17,7 +17,7 @@ print_usage () { gen_cert_subject () { local fqdn="$1" [[ "${fqdn}" != "" ]] || print_error "FQDN cannot be blank" - echo "/C=/ST=/O=/localityName=/CN=${fqdn}/organizationalUnitName=/emailAddress=/" + echo "/C=XX/ST=X/O=X/localityName=X/CN=${fqdn}/organizationalUnitName=X/emailAddress=X/" } main () { From 884895975ae518e6bf9e29f7269f50a730d949c4 Mon Sep 17 00:00:00 2001 From: FaramosCZ Date: Thu, 24 May 2018 07:06:12 +0200 Subject: [PATCH 02/37] Add conversion to the types expected by the memset() --- libmariadb/ma_stmt_codec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libmariadb/ma_stmt_codec.c b/libmariadb/ma_stmt_codec.c index 1260e494..0a824ccc 100644 --- a/libmariadb/ma_stmt_codec.c +++ b/libmariadb/ma_stmt_codec.c @@ -394,7 +394,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); - memset((char*) buffer, '0', field->length - len); + memset((void*) buffer, (int) '0', field->length - len); len= field->length; } convert_froma_string(r_param, buffer, len); @@ -612,7 +612,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); - memset((char*) buff, '0', field->length - length); + memset((void*) buff, (int) '0', field->length - length); length= field->length; } @@ -711,7 +711,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); - memset((char*) buff, '0', field->length - length); + memset((void*) buff, (int) '0', field->length - length); length= field->length; } convert_froma_string(r_param, buff, length); From 9bed6bf5e98203e2b8630d3034712015b87b7751 Mon Sep 17 00:00:00 2001 From: FaramosCZ Date: Thu, 24 May 2018 07:25:45 +0200 Subject: [PATCH 03/37] Fix: double free() --- libmariadb/mariadb_dyncol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libmariadb/mariadb_dyncol.c b/libmariadb/mariadb_dyncol.c index 63be7772..80bb7235 100644 --- a/libmariadb/mariadb_dyncol.c +++ b/libmariadb/mariadb_dyncol.c @@ -3612,7 +3612,6 @@ end: create_new_string: /* There is no columns from before, so let's just add the new ones */ rc= ER_DYNCOL_OK; - free(alloc_plan); if (not_null != 0) rc= dynamic_column_create_many_internal_fmt(str, add_column_count, (uint*)column_keys, values, From cd91dc8b2e5d42eba54dc495a397d1a27ee9adf4 Mon Sep 17 00:00:00 2001 From: FaramosCZ Date: Thu, 24 May 2018 07:35:20 +0200 Subject: [PATCH 04/37] Fix: use after free() --- unittest/libmariadb/ps.c | 1 - 1 file changed, 1 deletion(-) diff --git a/unittest/libmariadb/ps.c b/unittest/libmariadb/ps.c index ffba4918..6965bc00 100644 --- a/unittest/libmariadb/ps.c +++ b/unittest/libmariadb/ps.c @@ -4637,7 +4637,6 @@ static int test_stmt_close(MYSQL *mysql) FAIL_IF(mysql_stmt_param_count(stmt2) != 1, "param_count != 1"); rc= mysql_stmt_close(stmt1); - check_stmt_rc(rc, stmt1); /* Originally we were going to close all statements automatically in From 8455b6e1c9d318e5785110648d133d9939ed36da Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Thu, 24 May 2018 12:10:02 +0200 Subject: [PATCH 05/37] Changed default character set from utf8 (see fix for CONC-315) to latin1, which is also default behavior in MariaDB 10.1 To use another default character set, MariaDB Connector/C has to be build with CMake parameter -DDEFAUT_CHARSET=name. --- CMakeLists.txt | 5 +++++ include/ma_config.h.in | 2 ++ libmariadb/mariadb_charset.c | 2 +- libmariadb/mariadb_lib.c | 18 ++++++++++-------- unittest/libmariadb/connection.c | 7 ++++--- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0cf187a..c3bba33c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,6 +256,11 @@ INCLUDE(${CC_SOURCE_DIR}/cmake/CheckFunctions.cmake) # check for various types INCLUDE(${CC_SOURCE_DIR}/cmake/CheckTypes.cmake) +IF(NOT DEFAULT_CHARSET) + SET(DEFAULT_CHARSET "latin1") +ENDIF() + + # convert SSL options to uppercase IF(WITH_SSL) STRING(TOUPPER ${WITH_SSL} WITH_SSL) diff --git a/include/ma_config.h.in b/include/ma_config.h.in index c25662fa..31ff0b87 100644 --- a/include/ma_config.h.in +++ b/include/ma_config.h.in @@ -265,3 +265,5 @@ #cmakedefine SOCKET_SIZE_TYPE @SOCKET_SIZE_TYPE@ +#define MARIADB_DEFAULT_CHARSET "@DEFAULT_CHARSET@" + diff --git a/libmariadb/mariadb_charset.c b/libmariadb/mariadb_charset.c index b249bf34..a406af2f 100644 --- a/libmariadb/mariadb_charset.c +++ b/libmariadb/mariadb_charset.c @@ -22,7 +22,7 @@ #include #include -MARIADB_CHARSET_INFO *ma_default_charset_info = (MARIADB_CHARSET_INFO *)&mariadb_compiled_charsets[21]; +MARIADB_CHARSET_INFO *ma_default_charset_info; /* will be set in mysql_server_init */ MARIADB_CHARSET_INFO *ma_charset_bin= (MARIADB_CHARSET_INFO *)&mariadb_compiled_charsets[32]; MARIADB_CHARSET_INFO *ma_charset_latin1= (MARIADB_CHARSET_INFO *)&mariadb_compiled_charsets[5]; MARIADB_CHARSET_INFO *ma_charset_utf8_general_ci= (MARIADB_CHARSET_INFO *)&mariadb_compiled_charsets[21]; diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 4a41ec00..0bba6132 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -90,6 +90,7 @@ extern my_bool mysql_ps_subsystem_initialized; extern my_bool mysql_handle_local_infile(MYSQL *mysql, const char *filename); extern const MARIADB_CHARSET_INFO * mysql_find_charset_nr(uint charsetnr); extern const MARIADB_CHARSET_INFO * mysql_find_charset_name(const char * const name); +extern my_bool set_default_charset_by_name(const char *cs_name, myf flags __attribute__((unused))); extern int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, const char *data_plugin, const char *db); extern int net_add_multi_command(NET *net, uchar command, const uchar *packet, @@ -994,7 +995,7 @@ mysql_init(MYSQL *mysql) goto error; mysql->options.report_data_truncation= 1; mysql->options.connect_timeout=CONNECT_TIMEOUT; - mysql->charset= ma_default_charset_info; + mysql->charset= mysql_find_charset_name(MARIADB_DEFAULT_CHARSET); mysql->methods= &MARIADB_DEFAULT_METHODS; strcpy(mysql->net.sqlstate, "00000"); mysql->net.last_error[0]= mysql->net.last_errno= 0; @@ -1483,7 +1484,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user, if (mysql->options.charset_name) mysql->charset= mysql_find_charset_name(mysql->options.charset_name); else - mysql->charset=ma_default_charset_info; + mysql->charset=mysql_find_charset_name(MARIADB_DEFAULT_CHARSET); if (!mysql->charset) { @@ -1729,9 +1730,9 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, db=""; if (mysql->options.charset_name) - mysql->charset =mysql_find_charset_name(mysql->options.charset_name); + mysql->charset= mysql_find_charset_name(mysql->options.charset_name); else - mysql->charset=ma_default_charset_info; + mysql->charset=mysql_find_charset_name(MARIADB_DEFAULT_CHARSET); mysql->user= strdup(user ? user : ""); mysql->passwd= strdup(passwd ? passwd : ""); @@ -2909,16 +2910,16 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...) { uchar *buffer; void *arg2= va_arg(ap, void *); - size_t key_len= arg1 ? strlen((char *)arg1) : 0, + size_t storage_len, key_len= arg1 ? strlen((char *)arg1) : 0, value_len= arg2 ? strlen((char *)arg2) : 0; if (!key_len || !value_len) { SET_CLIENT_ERROR(mysql, CR_INVALID_PARAMETER_NO, SQLSTATE_UNKNOWN, 0); goto end; } - size_t storage_len= key_len + value_len + - get_store_length(key_len) + - get_store_length(value_len); + storage_len= key_len + value_len + + get_store_length(key_len) + + get_store_length(value_len); /* since we store terminating zero character in hash, we need * to increase lengths */ @@ -3486,6 +3487,7 @@ static void mysql_once_init() ma_init(); /* Will init threads */ init_client_errs(); get_default_configuration_dirs(); + set_default_charset_by_name(MARIADB_DEFAULT_CHARSET, 0); if (mysql_client_plugin_init()) { #ifdef _WIN32 diff --git a/unittest/libmariadb/connection.c b/unittest/libmariadb/connection.c index a2108270..fd5dac43 100644 --- a/unittest/libmariadb/connection.c +++ b/unittest/libmariadb/connection.c @@ -1365,12 +1365,13 @@ static int test_conc315(MYSQL *mysql) return SKIP; mysql_get_optionv(mysql, MYSQL_SET_CHARSET_NAME, (void *)&csname); - FAIL_UNLESS(strcmp(csname, "utf8") == 0, "Wrong default character set"); + diag("csname=%s", csname); + FAIL_UNLESS(strcmp(csname, MARIADB_DEFAULT_CHARSET) == 0, "Wrong default character set"); rc= mysql_change_user(mysql, username, password, schema); check_mysql_rc(rc, mysql); mysql_get_optionv(mysql, MYSQL_SET_CHARSET_NAME, (void *)&csname); - FAIL_UNLESS(strcmp(csname, "utf8") == 0, "Wrong default character set"); + FAIL_UNLESS(strcmp(csname, MARIADB_DEFAULT_CHARSET) == 0, "Wrong default character set"); return OK; } #ifndef WIN32 @@ -1491,7 +1492,7 @@ struct my_tests_st my_tests[] = { {"test_conc327", test_conc327, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc317", test_conc317, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, #endif - {"test_conc315", test_conc315, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, + {"test_conc315", test_conc315, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_expired_pw", test_expired_pw, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc276", test_conc276, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"test_mdev13100", test_mdev13100, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, From 26893755091670c9b4a05d9f8ddf2a0dea948956 Mon Sep 17 00:00:00 2001 From: rusher Date: Mon, 28 May 2018 16:33:49 +0200 Subject: [PATCH 06/37] [test] removing plugins from server test build. server test build can be build with plugins according to build options. This patch permit will not install those plugins (particulary mariadb-plugin-cracklib-password-check) --- .travis/build/build.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis/build/build.sh b/.travis/build/build.sh index db1dbe24..3f27ae0b 100644 --- a/.travis/build/build.sh +++ b/.travis/build/build.sh @@ -14,8 +14,13 @@ grep -o ">build-[0-9]*" index.html | grep -o "[0-9]*" | tac | while read -r line echo "**************************************************************************" wget -q -o /dev/null -O $line.html http://hasky.askmonty.org/archive/10.3/build-$line/kvm-deb-jessie-amd64/debs/binary/ grep -o ">[^\"]*\.deb" $line.html | grep -o "[^>]*\.deb" | while read -r file ; do - echo "download file: $file" - wget -q -o /dev/null -O .travis/build/$file http://hasky.askmonty.org/archive/10.3/build-$line/kvm-deb-jessie-amd64/debs/binary/$file + if [[ "$file" =~ ^mariadb-plugin.* ]] ; + then + echo "skipped file: $file" + else + echo "download file: $file" + wget -q -o /dev/null -O .travis/build/$file http://hasky.askmonty.org/archive/10.3/build-$line/kvm-deb-jessie-amd64/debs/binary/$file + fi done exit From 53c40f5aaab7262c2329863e0ac4fa52091167a0 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 29 May 2018 09:49:35 +0200 Subject: [PATCH 07/37] Fix for CONC334: Copy all members of MYSQL_FIELD from mysql->fields to stmt->fields. --- libmariadb/mariadb_stmt.c | 9 ++++++++- unittest/libmariadb/ps_bugs.c | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/libmariadb/mariadb_stmt.c b/libmariadb/mariadb_stmt.c index d0ce3c29..9630387e 100644 --- a/libmariadb/mariadb_stmt.c +++ b/libmariadb/mariadb_stmt.c @@ -1854,6 +1854,12 @@ int stmt_read_execute_response(MYSQL_STMT *stmt) for (i=0; i < stmt->field_count; i++) { + memcpy(&stmt->fields[i], &mysql->fields[i], sizeof(MYSQL_FIELD)); + + /* since all pointers will be incorrect if another statement will + be executed, so we need to allocate memory and copy the + information */ + stmt->fields[i].extension= 0; /* not in use yet */ if (mysql->fields[i].db) stmt->fields[i].db= ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].db); if (mysql->fields[i].table) @@ -1866,7 +1872,8 @@ int stmt_read_execute_response(MYSQL_STMT *stmt) stmt->fields[i].org_name= ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].org_name); if (mysql->fields[i].catalog) stmt->fields[i].catalog= ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].catalog); - stmt->fields[i].def= mysql->fields[i].def ? ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].def) : NULL; + if (mysql->fields[i].def) + stmt->fields[i].def= ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].def); } } diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index 5fa72b74..5ad5345a 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4690,7 +4690,43 @@ static int test_codbc138(MYSQL *mysql) return OK; } +static int test_conc334(MYSQL *mysql) +{ + MYSQL_STMT *stmt= mysql_stmt_init(mysql); + MYSQL_RES *result; + MYSQL_FIELD *field; + int rc; + + rc= mysql_stmt_prepare(stmt, SL("SHOW ENGINES")); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + + result= mysql_stmt_result_metadata(stmt); + if (!result) + { + diag("Coudn't retrieve result set"); + mysql_stmt_close(stmt); + return FAIL; + } + + mysql_field_seek(result, 0); + + while ((field= mysql_fetch_field(result))) + { + FAIL_IF(field->name_length == 0, "Invalid name length (0)"); + FAIL_IF(field->table_length == 0, "Invalid name length (0)"); + } + mysql_free_result(result); + mysql_stmt_close(stmt); + + return OK; +} + + struct my_tests_st my_tests[] = { + {"test_conc334", test_conc334, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_compress", test_compress, TEST_CONNECTION_NEW, CLIENT_COMPRESS, NULL, NULL}, {"test_codbc138", test_codbc138, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc208", test_conc208, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, From 407ca36f24ad1225ea59237e8434687f17a16131 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Mon, 28 May 2018 15:51:58 +0200 Subject: [PATCH 08/37] Fixed string conversion to MYSQL_TIME_TYPE: - added support for negative time values - invalid strings (and/or conversion) and invalid values will result in MYSQL_TIMESTAMP_ERROR time type - added support for 2digit year representation: values < 69 will be converted to 20YY values >= 69 will be converted to 19YY --- libmariadb/ma_stmt_codec.c | 102 +++++++++++++++++++++++++--------- unittest/libmariadb/ps_bugs.c | 82 ++++++++++++++++++--------- 2 files changed, 130 insertions(+), 54 deletions(-) diff --git a/libmariadb/ma_stmt_codec.c b/libmariadb/ma_stmt_codec.c index 1260e494..10684408 100644 --- a/libmariadb/ma_stmt_codec.c +++ b/libmariadb/ma_stmt_codec.c @@ -198,42 +198,90 @@ double my_atod(const char *number, const char *end, int *error) my_bool str_to_TIME(const char *str, size_t length, MYSQL_TIME *tm) { - my_bool is_time=0, is_date=0, has_time_frac=0; - char *p= (char *)str; + char *start= alloca(length + 1); + my_bool is_date= 0, is_time= 0; - if ((p= strchr(str, '-')) && p <= str + length) - is_date= 1; - if ((p= strchr(str, ':')) && p <= str + length) - is_time= 1; - if ((p= strchr(str, '.')) && p <= str + length) - has_time_frac= 1; - - p= (char *)str; - memset(tm, 0, sizeof(MYSQL_TIME)); + if (!start) + goto error; + tm->time_type= MYSQL_TIMESTAMP_NONE; + + memcpy(start, str, length); + start[length]= '\0'; + + while (length && isspace(*start)) start++, length--; + + if (!length) + goto error; + + /* negativ value? */ + if (*start == '-') + { + tm->neg= 1; + start++; + length--; + } + + if (!length) + return 1; + + /* Determine time type: + MYSQL_TIMESTAMP_DATE: [-]YY[YY].MM.DD + MYSQL_TIMESTAMP_DATETIME: [-]YY[YY].MM.DD hh:mm:ss.mmmmmm + MYSQL_TIMESTAMP_TIME: [-]hh:mm:ss.mmmmmm + */ + if (strchr(start, '-')) + { + if (tm->neg) + goto error; + tm->time_type= MYSQL_TIMESTAMP_DATE; + if (sscanf(start, "%d-%d-%d", &tm->year, &tm->month, &tm->day) < 3) + goto error; + is_date= 1; + if (!(start= strchr(start, ' '))) + goto check; + } + if (!strchr(start, ':')) + goto check; + + is_time= 1; + if (tm->time_type== MYSQL_TIMESTAMP_DATE) + tm->time_type= MYSQL_TIMESTAMP_DATETIME; + else + tm->time_type= MYSQL_TIMESTAMP_TIME; + + if (strchr(start, '.')) /* fractional seconds */ + { + if (sscanf(start, "%d:%d:%d.%ld", &tm->hour, &tm->minute, + &tm->second,&tm->second_part) < 4) + goto error; + } else { + if (sscanf(start, "%d:%d:%d", &tm->hour, &tm->minute, + &tm->second) < 3) + goto error; + } + +check: + if (tm->time_type == MYSQL_TIMESTAMP_NONE) + goto error; if (is_date) { - sscanf(str, "%d-%d-%d", &tm->year, &tm->month, &tm->day); - p= strchr(str, ' '); - if (!p) - { - tm->time_type= MYSQL_TIMESTAMP_DATE; - return 0; - } - } - if (has_time_frac) - { - sscanf(p, "%d:%d:%d.%ld", &tm->hour, &tm->minute, &tm->second, &tm->second_part); - tm->time_type= (is_date) ? MYSQL_TIMESTAMP_DATETIME : MYSQL_TIMESTAMP_TIME; - return 0; + if (tm->year < 69) + tm->year+= 2000; + else if (tm->year < 100) + tm->year+= 1900; + if (tm->day > 31 || tm->month > 12) + goto error; } if (is_time) { - sscanf(p, "%d:%d:%d", &tm->hour, &tm->minute, &tm->second); - tm->time_type= (is_date) ? MYSQL_TIMESTAMP_DATETIME : MYSQL_TIMESTAMP_TIME; - return 0; + if (tm->minute > 59 || tm->second > 59) + goto error; } + return 0; +error: + tm->time_type= MYSQL_TIMESTAMP_ERROR; return 1; } diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index 5fa72b74..b9437bb8 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4654,39 +4654,68 @@ static int test_compress(MYSQL *mysql) static int test_codbc138(MYSQL *mysql) { int rc; - MYSQL_STMT *stmt= mysql_stmt_init(mysql); + MYSQL_STMT *stmt; MYSQL_BIND bind[1]; MYSQL_TIME tm; + int i= 0; - rc= mysql_stmt_prepare(stmt, SL("SELECT DATE_ADD('2018-02-01', INTERVAL -188 DAY)")); - check_stmt_rc(rc, stmt); + struct st_time_test { + char *statement; + MYSQL_TIME tm; + } time_test[]= { + {"SELECT DATE_ADD('2018-02-01', INTERVAL -188 DAY)", + {2017,7,28,0,0,0,0L,0, MYSQL_TIMESTAMP_DATE} + }, + {"SELECT '2001-02-03 11:12:13.123456'", + {2001,2,3,11,12,13,123456L,0, MYSQL_TIMESTAMP_DATETIME} + }, + {"SELECT '-11:12:13'", + {0,0,0,11,12,13,0,1, MYSQL_TIMESTAMP_TIME} + }, + {"SELECT ' '", + {0,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_ERROR} + }, + {"SELECT '1--'", + {1,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_ERROR} + }, + {"SELECT '-2001-01-01'", + {1,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_ERROR} + }, + {"SELECT '-11:00'", + {1,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_ERROR} + }, + {NULL, {0}} + }; - rc= mysql_stmt_execute(stmt); - check_stmt_rc(rc, stmt); - - memset(bind, 0, sizeof(MYSQL_BIND)); - bind[0].buffer_type= MYSQL_TYPE_DATETIME; - bind[0].buffer= &tm; - bind[0].buffer_length= sizeof(MYSQL_TIME); - - rc= mysql_stmt_bind_result(stmt, bind); - check_stmt_rc(rc, stmt); - - rc= mysql_stmt_fetch(stmt); - check_stmt_rc(rc, stmt); - - if (tm.year != 2017 && tm.day != 28 && tm.month != 7) + while (time_test[i].statement) { - diag("Error: Expected 2017-07-02"); - return FAIL; - } - if (tm.minute | tm.second || tm.second_part) - { - diag("Error: minute, second or second_part is not zero"); - return FAIL; + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, SL(time_test[i].statement)); + check_stmt_rc(rc, stmt); + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + rc= mysql_stmt_store_result(stmt); + + memset(bind, 0, sizeof(MYSQL_BIND)); + bind[0].buffer_type= MYSQL_TYPE_DATETIME; + bind[0].buffer= &tm; + bind[0].buffer_length= sizeof(MYSQL_TIME); + + rc= mysql_stmt_bind_result(stmt, bind); + check_stmt_rc(rc, stmt); + rc= mysql_stmt_fetch(stmt); + check_stmt_rc(rc, stmt); + diag("test: %s %d %d", time_test[i].statement, tm.time_type, time_test[i].tm.time_type); + if (time_test[i].tm.time_type == MYSQL_TIMESTAMP_ERROR) + { + FAIL_UNLESS(tm.time_type == MYSQL_TIMESTAMP_ERROR, "MYSQL_TIMESTAMP_ERROR expected"); + } + else + FAIL_UNLESS(memcmp(&tm, &time_test[i].tm, sizeof(MYSQL_TIME)) == 0, "time_in != time_out"); + mysql_stmt_close(stmt); + i++; } - mysql_stmt_close(stmt); return OK; } @@ -4776,4 +4805,3 @@ int main(int argc, char **argv) return(exit_status()); } - From 6b16eb778f60c03bd1ea956fbc9e732c32651c46 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 29 May 2018 17:46:47 +0200 Subject: [PATCH 09/37] Fix for CONC-336: Allow multiple initialization of the client library (mysql_server_init( mysql_server_end). Note: This was already fixed by commit for CONC-277, unfortunately the fix was overwritten by a bad merge. --- libmariadb/mariadb_lib.c | 10 ++++++++-- unittest/libmariadb/CMakeLists.txt | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 0bba6132..758a8c68 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -3532,6 +3532,7 @@ static void mysql_once_init() } #ifdef _WIN32 +static INIT_ONCE init_once = (INIT_ONCE)INIT_ONCE_STATIC_INIT; BOOL CALLBACK win_init_once( PINIT_ONCE InitOnce, PVOID Parameter, @@ -3540,6 +3541,8 @@ BOOL CALLBACK win_init_once( return !mysql_once_init(); return TRUE; } +#else +static pthread_once_t init_once = PTHREAD_ONCE_INIT; #endif int STDCALL mysql_server_init(int argc __attribute__((unused)), @@ -3547,11 +3550,9 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)), char **groups __attribute__((unused))) { #ifdef _WIN32 - static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; BOOL ret = InitOnceExecuteOnce(&init_once, win_init_once, NULL, NULL); return ret? 0: 1; #else - static pthread_once_t init_once = PTHREAD_ONCE_INIT; return pthread_once(&init_once, mysql_once_init); #endif } @@ -3572,6 +3573,11 @@ void STDCALL mysql_server_end(void) #endif mysql_client_init= 0; ma_init_done= 0; +#ifdef WIN32 + init_once = (INIT_ONCE)INIT_ONCE_STATIC_INIT; +#else + init_once = (pthread_once_t)PTHREAD_ONCE_INIT; +#endif } my_bool STDCALL mysql_thread_init(void) diff --git a/unittest/libmariadb/CMakeLists.txt b/unittest/libmariadb/CMakeLists.txt index eba3cb53..9cea9163 100644 --- a/unittest/libmariadb/CMakeLists.txt +++ b/unittest/libmariadb/CMakeLists.txt @@ -26,7 +26,7 @@ INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/include ${CC_SOURCE_DIR}/unittest/libmariadb) ADD_DEFINITIONS(-DLIBMARIADB) -SET(API_TESTS "bulk1" "performance" "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs" "sp" "result" "connection" "misc" "ps_new" "thread" "features-10_2" "bulk1") +SET(API_TESTS "conc336" "bulk1" "performance" "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs" "sp" "result" "connection" "misc" "ps_new" "thread" "features-10_2" "bulk1") IF(WITH_DYNCOL) SET(API_TESTS ${API_TESTS} "dyncol") ENDIF() From 8f168c4d513e2e08334f77ca6e44efcd01ac3306 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 30 May 2018 07:04:38 +0200 Subject: [PATCH 10/37] Added test case for conc336 --- unittest/libmariadb/conc336.c | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 unittest/libmariadb/conc336.c diff --git a/unittest/libmariadb/conc336.c b/unittest/libmariadb/conc336.c new file mode 100644 index 00000000..3b0f5608 --- /dev/null +++ b/unittest/libmariadb/conc336.c @@ -0,0 +1,45 @@ +#include "my_test.h" + +#define MAX_COUNT 4000 + +int main(int argc, char *argv[]) { + + MYSQL *mysql; + int i; + + if (argc > 1) + get_options(argc, argv); + + get_envvars(); + + for (i = 0; i < MAX_COUNT; ++i) { + + if (mysql_library_init(-1, NULL, NULL) != 0) { + diag("mysql_library_init failed"); + return 1; + } + + mysql = mysql_init(NULL); + if (!mysql) { + diag("mysql_init failed"); + return 1; + } + + if (!mysql_real_connect(mysql, hostname, username, password, NULL, port, NULL, 0)) { + diag("mysql_real_connect failed: %s", mysql_error(mysql)); + return 1; + } + + if (mysql_query(mysql, "SELECT NULL LIMIT 0") != 0) { + diag("mysql_query failed: %s", mysql_error(mysql)); + return 1; + } + + mysql_close(mysql); + mysql_library_end(); + + } + + return 0; + +} From e8aea63d9fcf7289d5f5b55be8d2a7661f392be5 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 30 May 2018 16:31:17 +0200 Subject: [PATCH 11/37] Windows build fix --- libmariadb/mariadb_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 758a8c68..1065f30e 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -3532,7 +3532,7 @@ static void mysql_once_init() } #ifdef _WIN32 -static INIT_ONCE init_once = (INIT_ONCE)INIT_ONCE_STATIC_INIT; +static INIT_ONCE init_once= INIT_ONCE_STATIC_INIT; BOOL CALLBACK win_init_once( PINIT_ONCE InitOnce, PVOID Parameter, From ff5aac525c71f76dc32fea74c5b7b1bf2a9331ba Mon Sep 17 00:00:00 2001 From: Rasmus Johansson Date: Mon, 28 May 2018 11:17:28 +0000 Subject: [PATCH 12/37] CONC-335 Test latest Connector/C code as libmariadb in the latest versions of the server for 10.3 and 10.4 Added MTR testing with 10.3 and 10.4 branch --- .travis.yml | 18 +++++++++++++----- .travis/build/build.sh | 9 +++++++-- .travis/server-replace-submodule.sh | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 .travis/server-replace-submodule.sh diff --git a/.travis.yml b/.travis.yml index f4054de1..e4e28079 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ sudo: true language: c +cache: + apt: true + ccache: true services: docker addons: hosts: @@ -11,10 +14,7 @@ before_script: before_install: - - chmod +x .travis/script.sh - - chmod +x .travis/gen-ssl.sh - - chmod +x .travis/build/build.sh - - chmod +x .travis/build/docker-entrypoint.sh + - chmod -R +x .travis/* - chmod 777 .travis/build/ - export PROJ_PATH=`pwd` - export ENTRYPOINT=$PROJ_PATH/.travis/sql @@ -24,6 +24,8 @@ before_install: matrix: allow_failures: - env: DB=build + - env: SERVER_BRANCH=10.4 + - env: SERVER_BRANCH=10.4 TEST_OPTION=--ps-protocol include: - env: DB=build - env: DB=mysql:5.7 @@ -32,8 +34,14 @@ matrix: - env: DB=mariadb:10.1 - env: DB=mariadb:10.2 - env: DB=mariadb:10.3 + - env: SERVER_BRANCH=10.3 + - env: SERVER_BRANCH=10.3 TEST_OPTION=--ps-protocol + - env: SERVER_BRANCH=10.4 + - env: SERVER_BRANCH=10.4 TEST_OPTION=--ps-protocol script: - if [ "$DB" = "build" ] ; then .travis/build/build.sh; fi - if [ "$DB" = "build" ] ; then docker build -t build:latest --label build .travis/build/; fi - - .travis/script.sh + - if [ -z "$DB" ] ; then .travis/server-replace-submodule.sh; fi + - if [ -n "$DB" ] ; then .travis/script.sh; fi + diff --git a/.travis/build/build.sh b/.travis/build/build.sh index db1dbe24..3f27ae0b 100644 --- a/.travis/build/build.sh +++ b/.travis/build/build.sh @@ -14,8 +14,13 @@ grep -o ">build-[0-9]*" index.html | grep -o "[0-9]*" | tac | while read -r line echo "**************************************************************************" wget -q -o /dev/null -O $line.html http://hasky.askmonty.org/archive/10.3/build-$line/kvm-deb-jessie-amd64/debs/binary/ grep -o ">[^\"]*\.deb" $line.html | grep -o "[^>]*\.deb" | while read -r file ; do - echo "download file: $file" - wget -q -o /dev/null -O .travis/build/$file http://hasky.askmonty.org/archive/10.3/build-$line/kvm-deb-jessie-amd64/debs/binary/$file + if [[ "$file" =~ ^mariadb-plugin.* ]] ; + then + echo "skipped file: $file" + else + echo "download file: $file" + wget -q -o /dev/null -O .travis/build/$file http://hasky.askmonty.org/archive/10.3/build-$line/kvm-deb-jessie-amd64/debs/binary/$file + fi done exit diff --git a/.travis/server-replace-submodule.sh b/.travis/server-replace-submodule.sh new file mode 100644 index 00000000..11538db0 --- /dev/null +++ b/.travis/server-replace-submodule.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# get latest server +git clone -b ${SERVER_BRANCH} https://github.com/mariadb/server ../workdir-server + +# copy C/C into libmariadb in server +ls -l ../workdir-server/libmariadb +cp -r . ../workdir-server/libmariadb + +cd ../workdir-server +# don't pull in submodules. We want the latest C/C as libmariadb +git config cmake.update-submodules no +# build latest server with latest C/C as libmariadb +# skip to build some storage engines to speed up the build +cmake -DPLUGIN_MROONGA=NO -DPLUGIN_ROCKSDB=NO -DPLUGIN_SPIDER=NO -DPLUGIN_TOKUDB=NO +make -j9 + +cd mysql-test/ +./mysql-test-run.pl --suite=main ${TEST_OPTION} --parallel=auto From 32246542a33768571556a124fb015b643a9d2e5a Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 6 Jun 2018 08:10:25 +0200 Subject: [PATCH 13/37] Bumped version number --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c3bba33c..4b837ee4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ SET(CC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) SET(CPACK_PACKAGE_VERSION_MAJOR 3) SET(CPACK_PACKAGE_VERSION_MINOR 0) -SET(CPACK_PACKAGE_VERSION_PATCH 5) +SET(CPACK_PACKAGE_VERSION_PATCH 6) SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") MATH(EXPR MARIADB_PACKAGE_VERSION_ID "${CPACK_PACKAGE_VERSION_MAJOR} * 10000 + ${CPACK_PACKAGE_VERSION_MINOR} * 100 + From 5b01cd608a19b885d34ecff84c648d9b38f9708c Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 13 Jun 2018 17:28:50 +0200 Subject: [PATCH 14/37] Fix crash in mysql_select_db if db is null --- libmariadb/mariadb_lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 1065f30e..e05d3eea 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -1779,7 +1779,8 @@ mysql_select_db(MYSQL *mysql, const char *db) { int error; - if ((error=ma_simple_command(mysql, COM_INIT_DB,db,(uint) strlen(db),0,0))) + if ((error=ma_simple_command(mysql, COM_INIT_DB, db, + db ? (uint) strlen(db) : 0,0,0))) return(error); free(mysql->db); mysql->db=strdup(db); From b937b75f6e077fd830cddc9f377c12ba992f7453 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Thu, 14 Jun 2018 06:51:50 +0200 Subject: [PATCH 15/37] Fix IS_NUM macro (MDEV-15263) --- include/mysql.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mysql.h b/include/mysql.h index 85ccc467..727eddea 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -88,7 +88,7 @@ extern unsigned int mariadb_deinitialize_ssl; #define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG) #define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG) #define IS_BLOB(n) ((n) & BLOB_FLAG) -#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR) +#define IS_NUM(t) (((t) <= MYSQL_TYPE_INT24 && (t) != MYSQL_TYPE_TIMESTAMP) || (t) == MYSQL_TYPE_YEAR || (t) == MYSQL_TYPE_NEWDECIMAL) #define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG) #define INTERNAL_NUM_FIELD(f) (((f)->type <= MYSQL_TYPE_INT24 && ((f)->type != MYSQL_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == MYSQL_TYPE_YEAR || (f)->type == MYSQL_TYPE_NEWDECIMAL || (f)->type == MYSQL_TYPE_DECIMAL) From dd54e6fa28a1e387af503c016aedb91dc2e23d90 Mon Sep 17 00:00:00 2001 From: Lawrin Novitsky Date: Wed, 20 Jun 2018 16:34:03 +0200 Subject: [PATCH 16/37] Typo in CMakeLists.txt WITH_UNITTEST instead of WITH_UNIT_TESTS --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b837ee4..452b5399 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY) # do not inherit include directories from the parent project SET_PROPERTY(DIRECTORY PROPERTY INCLUDE_DIRECTORIES) -FOREACH(V WITH_MYSQLCOMPAT WITH_MSI WITH_SIGNCODE WITH_RTC WITH_UNITTEST +FOREACH(V WITH_MYSQLCOMPAT WITH_MSI WITH_SIGNCODE WITH_RTC WITH_UNIT_TESTS WITH_DYNCOL WITH_EXTERNAL_ZLIB WITH_CURL WITH_SQLITE WITH_SSL INSTALL_LAYOUT WITH_TEST_SRCPKG) SET(${V} ${${OPT}${V}}) From 9e1fef0bf2c47b6f75b68fc6ce3ed15495222da9 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Thu, 28 Jun 2018 17:22:08 +0200 Subject: [PATCH 17/37] Fix for CONC-344: reset internal row counter before executing prepared statement --- libmariadb/mariadb_stmt.c | 3 ++- unittest/libmariadb/ps_bugs.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/libmariadb/mariadb_stmt.c b/libmariadb/mariadb_stmt.c index 9630387e..5ed9e2c5 100644 --- a/libmariadb/mariadb_stmt.c +++ b/libmariadb/mariadb_stmt.c @@ -1977,8 +1977,9 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt) { ma_free_root(&stmt->result.alloc, MYF(MY_KEEP_PREALLOC)); stmt->result_cursor= stmt->result.data= 0; - stmt->result.rows= 0; } + /* CONC-344: set row count to zero */ + stmt->result.rows= 0; if (stmt->array_size > 0) request= (char *)mysql_stmt_execute_generate_bulk_request(stmt, &request_len); else diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index 9eed9a0f..c25e2ff6 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4660,7 +4660,7 @@ static int test_codbc138(MYSQL *mysql) int i= 0; struct st_time_test { - char *statement; + const char *statement; MYSQL_TIME tm; } time_test[]= { {"SELECT DATE_ADD('2018-02-01', INTERVAL -188 DAY)", @@ -4752,9 +4752,36 @@ static int test_conc334(MYSQL *mysql) return OK; } +static int test_conc344(MYSQL *mysql) +{ + MYSQL_STMT *stmt= mysql_stmt_init(mysql); + int rc; + rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (a int, b int)"); + check_mysql_rc(rc, mysql); + rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1,1), (2,2),(3,3),(4,4),(5,5)"); + check_mysql_rc(rc, mysql); + + rc= mysql_stmt_prepare(stmt, SL("SELECT * FROM t1 ORDER BY a")); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + + while (!mysql_stmt_fetch(stmt)); + FAIL_IF(mysql_stmt_num_rows(stmt) != 5, "expected 5 rows"); + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + rc= mysql_stmt_fetch(stmt); + diag("num_rows: %lld", mysql_stmt_num_rows(stmt)); + FAIL_IF(mysql_stmt_num_rows(stmt) != 1, "expected 1 row"); + + mysql_stmt_close(stmt); + return OK; +} struct my_tests_st my_tests[] = { + {"test_conc344", test_conc344, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_conc334", test_conc334, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_compress", test_compress, TEST_CONNECTION_NEW, CLIENT_COMPRESS, NULL, NULL}, {"test_codbc138", test_codbc138, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, From a0d4b422bd3bcb9db6cec0c9c36004952ed5b924 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 3 Jul 2018 11:17:46 +0200 Subject: [PATCH 18/37] Fix for CONC-345: heap-use-after free in client_mpvio_read_packet We need to check if pkt_len is > 0 before the buffer content will be checked. --- plugins/auth/my_auth.c | 2 +- unittest/libmariadb/bulk1.c | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/plugins/auth/my_auth.c b/plugins/auth/my_auth.c index 8db6e04e..9010a6f5 100644 --- a/plugins/auth/my_auth.c +++ b/plugins/auth/my_auth.c @@ -357,7 +357,7 @@ static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf) *buf= mysql->net.read_pos; /* was it a request to change plugins ? */ - if (**buf == 254) + if (pkt_len && **buf == 254) return (int)packet_error; /* if yes, this plugin shan't continue */ /* diff --git a/unittest/libmariadb/bulk1.c b/unittest/libmariadb/bulk1.c index 6f3a9458..d060add6 100644 --- a/unittest/libmariadb/bulk1.c +++ b/unittest/libmariadb/bulk1.c @@ -43,6 +43,49 @@ static int check_bulk(MYSQL *mysql) return OK; } +static int bulk_insert_id(MYSQL *mysql) +{ + int i; + int rc; + MYSQL_BIND bind[1]; + unsigned int array_size= 2; + int val_a[2]= {0,1}; + MYSQL_STMT *stmt= mysql_stmt_init(mysql); + + rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (a int not null auto_increment primary key)"); + check_mysql_rc(rc, mysql); + + rc= mysql_query(mysql, "INSERT INTO t1 VALUES(0),(1)"); + check_mysql_rc(rc, mysql); + + diag("Insert via mysql_query ok"); + + rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (a int not null auto_increment primary key)"); + check_mysql_rc(rc, mysql); + + memset(&bind, 0, sizeof(MYSQL_BIND)); + bind[0].buffer_type= MYSQL_TYPE_LONG; + bind[0].buffer= val_a; + + rc= mysql_stmt_prepare(stmt, SL("insert into t1 values(?)")); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_bind_param(stmt, bind); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + + diag("Insert via bulk insert (binary protocol) ok"); + + mysql_stmt_close(stmt); +exit(1); + return OK; +} + static int bulk1(MYSQL *mysql) { MYSQL_STMT *stmt= mysql_stmt_init(mysql); @@ -998,6 +1041,7 @@ static int bulk_null_null(MYSQL *mysql) struct my_tests_st my_tests[] = { {"check_bulk", check_bulk, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, + {"bulk_insert_id", bulk_insert_id, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"bulk_null_null", bulk_null_null, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_char_conv1", test_char_conv1, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_char_conv2", test_char_conv2, TEST_CONNECTION_NEW, 0, NULL, NULL}, From dc50976e36c067c465cfbadc90288f934a80388f Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 3 Jul 2018 11:22:31 +0200 Subject: [PATCH 19/37] Fix for travis tests: Older server versions don't support CREATE or REPLACE syntax. --- unittest/libmariadb/ps_bugs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index c25e2ff6..fd931ed5 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4757,7 +4757,10 @@ static int test_conc344(MYSQL *mysql) MYSQL_STMT *stmt= mysql_stmt_init(mysql); int rc; - rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (a int, b int)"); + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + check_mysql_rc(rc, mysql); + + rc= mysql_query(mysql, "CREATE TABLE t1 (a int, b int)"); check_mysql_rc(rc, mysql); rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1,1), (2,2),(3,3),(4,4),(5,5)"); check_mysql_rc(rc, mysql); From 66586051595c8a43e63dd821f1a5cc36cfbd608e Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 3 Jul 2018 12:45:55 +0200 Subject: [PATCH 20/37] Skip test for MDEV-16593 (not fixed yet) --- unittest/libmariadb/bulk1.c | 116 ++++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 44 deletions(-) diff --git a/unittest/libmariadb/bulk1.c b/unittest/libmariadb/bulk1.c index d060add6..7d5fb146 100644 --- a/unittest/libmariadb/bulk1.c +++ b/unittest/libmariadb/bulk1.c @@ -43,49 +43,6 @@ static int check_bulk(MYSQL *mysql) return OK; } -static int bulk_insert_id(MYSQL *mysql) -{ - int i; - int rc; - MYSQL_BIND bind[1]; - unsigned int array_size= 2; - int val_a[2]= {0,1}; - MYSQL_STMT *stmt= mysql_stmt_init(mysql); - - rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (a int not null auto_increment primary key)"); - check_mysql_rc(rc, mysql); - - rc= mysql_query(mysql, "INSERT INTO t1 VALUES(0),(1)"); - check_mysql_rc(rc, mysql); - - diag("Insert via mysql_query ok"); - - rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (a int not null auto_increment primary key)"); - check_mysql_rc(rc, mysql); - - memset(&bind, 0, sizeof(MYSQL_BIND)); - bind[0].buffer_type= MYSQL_TYPE_LONG; - bind[0].buffer= val_a; - - rc= mysql_stmt_prepare(stmt, SL("insert into t1 values(?)")); - check_stmt_rc(rc, stmt); - - rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size); - check_stmt_rc(rc, stmt); - - rc= mysql_stmt_bind_param(stmt, bind); - check_stmt_rc(rc, stmt); - - rc= mysql_stmt_execute(stmt); - check_stmt_rc(rc, stmt); - - diag("Insert via bulk insert (binary protocol) ok"); - - mysql_stmt_close(stmt); -exit(1); - return OK; -} - static int bulk1(MYSQL *mysql) { MYSQL_STMT *stmt= mysql_stmt_init(mysql); @@ -1039,9 +996,80 @@ static int bulk_null_null(MYSQL *mysql) return OK; } +static int test_mdev16593(MYSQL *mysql) +{ + int i; + int rc; + MYSQL_BIND bind[2]; + unsigned int array_size= 2; + int val_a[2]= {1,2}; + int val_b[2]= {3,4}; + char indicators[2]= {STMT_INDICATOR_NULL, STMT_INDICATOR_NULL}; + char *testcase[]= {"MYSQL_TYPE_LONG", "MYSQL_TYPE_NULL", "STMT_INDICATOR_NULL"}; + + diag("waiting for server fix"); + return SKIP; + + for (i=0; i < 3; i++) + { + MYSQL_RES *res; + MYSQL_ROW row; + MYSQL_STMT *stmt= mysql_stmt_init(mysql); + rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (a int not null auto_increment primary key, b int)"); + check_mysql_rc(rc, mysql); + + memset(&bind, 0, sizeof(MYSQL_BIND)); + switch (i) { + case 0: + bind[0].buffer_type= MYSQL_TYPE_LONG; + break; + case 1: + bind[0].buffer_type= MYSQL_TYPE_NULL; + break; + case 2: + bind[0].buffer_type= MYSQL_TYPE_LONG; + bind[0].u.indicator= indicators; + break; + } + bind[0].buffer= val_a; + bind[1].buffer_type= MYSQL_TYPE_LONG; + bind[1].buffer= val_a; + + rc= mysql_stmt_prepare(stmt, SL("insert into t1 values(?,?)")); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_bind_param(stmt, bind); + check_stmt_rc(rc, stmt); + + rc= mysql_stmt_execute(stmt); + check_stmt_rc(rc, stmt); + + rc= mysql_query(mysql, "COMMIT"); + check_mysql_rc(rc, mysql); + + diag("Insert id with buffer_type %s: %lld", + testcase[i], + mysql_stmt_insert_id(stmt)); + + rc= mysql_query(mysql, "SELECT max(a) FROM t1"); + check_mysql_rc(rc, mysql); + + res= mysql_store_result(mysql); + row= mysql_fetch_row(res); + diag("Max value for t1.a=%s", row[0]); + mysql_free_result(res); + + mysql_stmt_close(stmt); + } + return OK; +} + struct my_tests_st my_tests[] = { {"check_bulk", check_bulk, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, - {"bulk_insert_id", bulk_insert_id, TEST_CONNECTION_NEW, 0, NULL, NULL}, + {"test_mdev16593", test_mdev16593, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"bulk_null_null", bulk_null_null, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_char_conv1", test_char_conv1, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_char_conv2", test_char_conv2, TEST_CONNECTION_NEW, 0, NULL, NULL}, From eda04fe6159107fd0c128b9f0e591d273985409c Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 4 Jul 2018 07:25:24 +0200 Subject: [PATCH 21/37] Fixed warning --- unittest/libmariadb/bulk1.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/unittest/libmariadb/bulk1.c b/unittest/libmariadb/bulk1.c index 7d5fb146..9531658a 100644 --- a/unittest/libmariadb/bulk1.c +++ b/unittest/libmariadb/bulk1.c @@ -1003,9 +1003,8 @@ static int test_mdev16593(MYSQL *mysql) MYSQL_BIND bind[2]; unsigned int array_size= 2; int val_a[2]= {1,2}; - int val_b[2]= {3,4}; char indicators[2]= {STMT_INDICATOR_NULL, STMT_INDICATOR_NULL}; - char *testcase[]= {"MYSQL_TYPE_LONG", "MYSQL_TYPE_NULL", "STMT_INDICATOR_NULL"}; + const char *testcase[]= {"MYSQL_TYPE_LONG", "MYSQL_TYPE_NULL", "STMT_INDICATOR_NULL"}; diag("waiting for server fix"); return SKIP; From 41cc847c314f4568455229400fb182db1463dfaa Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 4 Jul 2018 07:37:03 +0200 Subject: [PATCH 22/37] Fix for CONC-346: Removed all OLD cmake policies - Symlink macro now uses cmake generator expression $ - Since all plugins are built in the same directory, the location detection was removed for windows packaging - Installation of the windows *.pdb for libmariadb now also uses a static path. --- CMakeLists.txt | 1 - cmake/symlink.cmake | 22 ++++++---------------- libmariadb/CMakeLists.txt | 15 ++++++--------- win/packaging/CMakeLists.txt | 2 +- 4 files changed, 13 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 452b5399..9762018d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) INCLUDE(CheckFunctionExists) IF(COMMAND CMAKE_POLICY) - SET(OLD_POLICIES CMP0026 CMP0042 CMP0045) SET(NEW_POLICIES CMP0003 CMP0022 CMP0023) FOREACH(TYPE OLD NEW) FOREACH(P ${${TYPE}_POLICIES}) diff --git a/cmake/symlink.cmake b/cmake/symlink.cmake index eed83a17..0a558318 100644 --- a/cmake/symlink.cmake +++ b/cmake/symlink.cmake @@ -8,24 +8,14 @@ MACRO(create_symlink symlink_name target install_path) # According to cmake documentation symlinks work on unix systems only IF(UNIX) - # Get target components - GET_TARGET_PROPERTY(target_location ${target} LOCATION) - GET_FILENAME_COMPONENT(target_path ${target_location} PATH) - GET_FILENAME_COMPONENT(target_name ${target_location} NAME) + # Set target components + SET(target_lib $/${symlink_name}) ADD_CUSTOM_COMMAND( - OUTPUT ${target_path}/${symlink_name} - COMMAND ${CMAKE_COMMAND} ARGS -E remove -f ${target_path}/${symlink_name} - COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink ${target_name} ${symlink_name} - WORKING_DIRECTORY ${target_path} - DEPENDS ${target} - ) + TARGET ${target} POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E remove -f ${target_lib} + COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink $ ${symlink_name}) - ADD_CUSTOM_TARGET(SYM_${symlink_name} - ALL - DEPENDS ${target_path}/${symlink_name}) - SET_TARGET_PROPERTIES(SYM_${symlink_name} PROPERTIES CLEAN_DIRECT_OUTPUT 1) - IF(CMAKE_GENERATOR MATCHES "Xcode") # For Xcode, replace project config with install config STRING(REPLACE "${CMAKE_CFG_INTDIR}" @@ -33,7 +23,7 @@ IF(UNIX) ENDIF() # presumably this will be used for libmysql*.so symlinks - INSTALL(FILES ${target_path}/${symlink_name} DESTINATION ${install_path} + INSTALL(FILES ${target_lib} DESTINATION ${install_path} COMPONENT SharedLibraries) ENDIF() ENDMACRO() diff --git a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt index 430020bb..5301c06b 100644 --- a/libmariadb/CMakeLists.txt +++ b/libmariadb/CMakeLists.txt @@ -443,14 +443,11 @@ INSTALL(TARGETS libmariadb COMPONENT SharedLibraries DESTINATION ${INSTALL_LIBDIR}) + IF(WIN32) - # On Windows, install PDB - GET_TARGET_PROPERTY(location libmariadb LOCATION) - STRING(REPLACE ".dll" ".pdb" pdb_location ${location}) - IF (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") - STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CMAKE_INSTALL_CONFIG_NAME}" - pdb_location ${pdb_location}) - ENDIF() - INSTALL(FILES ${pdb_location} DESTINATION "${INSTALL_LIBDIR}" + IF(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") + SET(PDB_LOCATION ${CC_BINARY_DIR}/libmariadb/RelWIthDebInfo/libmariadb.pdb) + INSTALL(FILES ${PDB_LOCATION} DESTINATION "${INSTALL_LIBDIR}" COMPONENT Development) -ENDIF() + ENDIF() +ENDIF() \ No newline at end of file diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt index 454dfe1a..439ec205 100644 --- a/win/packaging/CMakeLists.txt +++ b/win/packaging/CMakeLists.txt @@ -30,7 +30,7 @@ FOREACH(plugin ${PLUGINS_DYNAMIC}) SET(TARGET ${plugin}) # Get dependencies SET(DYNAMIC_TARGETS ${DYNAMIC_TARGETS} ${TARGET}) - GET_PROPERTY(FILE TARGET ${TARGET} PROPERTY LOCATION) + SET(FILE ${CC_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${TARGET}.dll) MESSAGE(STATUS "Location for ${TARGET}: ${FILE}") # build file list STRING(REPLACE "$(Configuration)" "RelWithDebInfo" FILE ${FILE}) From ffd908406307ce76b5eb93506c14cf01f74e1262 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 4 Jul 2018 07:56:17 +0200 Subject: [PATCH 23/37] Fixed comment for MY_CHARSET_INFO: csname is the name of the character set, while name is the name of the collation --- include/mysql.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mysql.h b/include/mysql.h index 727eddea..5d75ee68 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -409,8 +409,8 @@ typedef struct character_set { unsigned int number; /* character set number */ unsigned int state; /* character set state */ - const char *csname; /* collation name */ - const char *name; /* character set name */ + const char *csname; /* character set name */ + const char *name; /* collation name */ const char *comment; /* comment */ const char *dir; /* character set directory */ unsigned int mbminlen; /* min. length for multibyte strings */ From c14a06f1c0a3d71ade689ba293231cd3d6d60d42 Mon Sep 17 00:00:00 2001 From: Lawrin Novitsky Date: Wed, 4 Jul 2018 17:50:32 +0200 Subject: [PATCH 24/37] Fix required for ODBC-154 It changes TARGET_LINK_LIBRARIES in versionin script configuration in cmake for SET_TARGET_PROPERTIES. In this way, if C/C is a sub-project in other project, version script want go into parent project. --- libmariadb/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt index 5301c06b..995dc28b 100644 --- a/libmariadb/CMakeLists.txt +++ b/libmariadb/CMakeLists.txt @@ -387,7 +387,7 @@ ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE}) TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS}) IF(UNIX) - ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def) + ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE}) SET_TARGET_PROPERTIES(libmariadb PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}") ELSE() ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} mariadbclient.def) @@ -407,7 +407,7 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") IF (NOT WITH_ASAN) TARGET_LINK_LIBRARIES (libmariadb "-Wl,--no-undefined") ENDIF() - TARGET_LINK_LIBRARIES (libmariadb "${CC_BINARY_DIR}/libmariadb/mariadbclient.def") + SET_TARGET_PROPERTIES(libmariadb PROPERTIES LINK_FLAGS "${CC_BINARY_DIR}/libmariadb/mariadbclient.def") ENDIF() SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}") @@ -450,4 +450,4 @@ IF(WIN32) INSTALL(FILES ${PDB_LOCATION} DESTINATION "${INSTALL_LIBDIR}" COMPONENT Development) ENDIF() -ENDIF() \ No newline at end of file +ENDIF() From b0f2e4e72fbf086f34b0b1401c5964c3da8359d7 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 6 Jul 2018 09:28:24 +0200 Subject: [PATCH 25/37] Coverity fixes and travis integration --- .travis.yml | 19 +++++++++- include/errmsg.h | 8 ++++- include/mariadb_stmt.h | 4 +-- include/mysql.h | 4 +-- libmariadb/ma_charset.c | 2 +- libmariadb/ma_client_plugin.c.in | 28 ++++++++------- libmariadb/ma_default.c | 7 +--- libmariadb/ma_dtoa.c | 2 ++ libmariadb/ma_errmsg.c | 3 +- libmariadb/ma_io.c | 1 + libmariadb/ma_net.c | 1 - libmariadb/ma_pvio.c | 40 +++++++++++++--------- libmariadb/ma_time.c | 2 +- libmariadb/mariadb_dyncol.c | 5 ++- libmariadb/mariadb_lib.c | 36 +++++++++---------- libmariadb/mariadb_stmt.c | 59 +++++++++++++++++++------------- plugins/auth/old_password.c | 4 +-- plugins/auth/sha256_pw.c | 4 ++- plugins/pvio/pvio_socket.c | 27 ++++++++++----- 19 files changed, 154 insertions(+), 102 deletions(-) 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); From 3169da36b494ffaeb78c8a0c5312acb1a0cd5cee Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 6 Jul 2018 12:36:41 +0200 Subject: [PATCH 26/37] .travis.yml fixes --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac3624aa..186f5d8d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,22 +15,20 @@ env: addons: hosts: - mariadb.example.com - coverity_scan: + 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 - + branch_pattern: master 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` From 77fc17b7aacb7e9e538f40123bc9dc994a39daf2 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 6 Jul 2018 17:39:07 +0200 Subject: [PATCH 27/37] remove coverity-scan, we do that in a separate branch coverity_scan --- .travis.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 186f5d8d..5d836f1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,24 +5,9 @@ cache: 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: master before_script: # Disable services enabled by default From c95f86e88289ca84d881af6680e56c25aeb8e3b6 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 13 Jul 2018 12:30:13 +0200 Subject: [PATCH 28/37] 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"); From d3e06bc1616588fe01920f86e5a28fce65824655 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 13 Jul 2018 14:48:42 +0200 Subject: [PATCH 29/37] Added test for nested dynamic column --- libmariadb/mariadb_dyncol.c | 2 +- unittest/libmariadb/dyncol.c | 78 +++++++++++++++++++----------------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/libmariadb/mariadb_dyncol.c b/libmariadb/mariadb_dyncol.c index 01e0ba15..96f9a0fa 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) & (~0xf)) == 0); /* fit in 4 bits */ + DBUG_ASSERT(((type - 1) & (~7)) == 0); /* fit in 3 bits */ DBUG_ASSERT(offset_size >= 1 && offset_size <= 4); /* Index entry starts with column number; jump over it */ diff --git a/unittest/libmariadb/dyncol.c b/unittest/libmariadb/dyncol.c index 47ce313b..8fe0acb9 100644 --- a/unittest/libmariadb/dyncol.c +++ b/unittest/libmariadb/dyncol.c @@ -56,42 +56,6 @@ 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"); @@ -289,12 +253,54 @@ static int dyncol_column_count(MYSQL *unused __attribute__((unused))) return OK; } +static int dyncol_nested(MYSQL *mysql __attribute__((unused))) +{ + DYNAMIC_COLUMN col1, col2; + DYNAMIC_COLUMN_VALUE value[2]; + MYSQL_LEX_STRING cols[2]= {{(char *)"0",1},{(char *)"1",1}}; + DYNAMIC_STRING s; + + mariadb_dyncol_init(&col1); + mariadb_dyncol_init(&col2); + + memset(&value, 0, sizeof(DYNAMIC_COLUMN_VALUE)); + + value[0].type= DYN_COL_UINT; + value[0].x.ulong_value = 17; + + mariadb_dyncol_create_many_named(&col1, 1, cols, value, 0); + if (mariadb_dyncol_check(&col1) != ER_DYNCOL_OK) + { + diag("Error while creating col1"); + return FAIL; + } + + value[1].type= DYN_COL_DYNCOL; + value[1].x.string.value.str= col1.str; + value[1].x.string.value.length= col1.length; + + mariadb_dyncol_create_many_named(&col2, 2, cols, value, 0); + if (mariadb_dyncol_check(&col2) != ER_DYNCOL_OK) + { + diag("Error while creating col1"); + return FAIL; + } + mariadb_dyncol_json(&col2, &s); + if (strcmp(s.str, "{\"0\":17,\"1\":{\"0\":17}}") != 0) + { + diag("%s != %s", s.str, "{\"0\":17,\"1\":{\"0\":17}}"); + return FAIL; + } + return OK; +} + struct my_tests_st my_tests[] = { {"mdev_x1", mdev_x1, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"mdev_4994", mdev_4994, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"create_dyncol_named", create_dyncol_named, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"create_dyncol_num", create_dyncol_num, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"dyncol_column_count", dyncol_column_count, TEST_CONNECTION_NEW, 0, NULL, NULL}, + {"dyncol_nested", dyncol_nested, TEST_CONNECTION_NEW, 0, NULL, NULL}, {NULL, NULL, 0, 0, NULL, 0} }; From b19f6a475b2865b067e70b50ae47ce7ed03f5698 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 18 Jul 2018 09:28:05 +1000 Subject: [PATCH 30/37] CONC-329: change pvio_*_blocking to return int to accomidate SOCKET_ERROR(-1) POWER and other architectures that define char(as my_bool) to be unsigned (as the C standard leaves this undefined). This resulted in error branches being unreachabe as indicated by the below compile warnings. plugins/pvio/pvio_socket.c:763:42: warning: comparison of constant -1 with expression of type 'my_bool' (aka 'char') is always false [-Wtautological-constant-out-of-range-compare] if (pvio_socket_blocking(pvio, 1, 0) == SOCKET_ERROR) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~ plugins/pvio/pvio_socket.c:875:46: warning: comparison of constant -1 with expression of type 'my_bool' (aka 'char') is always false [-Wtautological-constant-out-of-range-compare] if (pvio_socket_blocking(pvio, 0, 0) == SOCKET_ERROR) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~ plugins/pvio/pvio_socket.c:907:42: warning: comparison of constant -1 with expression of type 'my_bool' (aka 'char') is always false [-Wtautological-constant-out-of-range-compare] if (pvio_socket_blocking(pvio, 1, 0) == SOCKET_ERROR) ma_hext2int: signed char - prevent compiler errors when char is unsigned. libmariadb/ma_tls.c:169:31: warning: comparison of constant -1 with expression of type 'char' is always false [-Wtautological-constant-out-of-range-compare] if ((d1 = ma_hex2int(*p)) == - 1 || ~~~~~~~~~~~~~~~~~~~~~ ^ ~~~ libmariadb/ma_tls.c:170:35: warning: comparison of constant -1 with expression of type 'char' is always false [-Wtautological-constant-out-of-range-compare] (d2 = ma_hex2int(*(p+1))) == -1 || ~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~ To fix this all the pvio_*_blocking functions have been changed to use int as a return value. Other my_bool/char differences fixed: mariadb_dyncol_val_str: fix prototype to use char - like implemented function. unittest: bind.is_null is my_bool* so we use a my_bool. --- include/ma_pvio.h | 2 +- include/mariadb_dyncol.h | 2 +- libmariadb/ma_pvio.c | 2 +- libmariadb/ma_tls.c | 4 ++-- plugins/pvio/pvio_npipe.c | 4 ++-- plugins/pvio/pvio_shmem.c | 4 ++-- plugins/pvio/pvio_socket.c | 4 ++-- unittest/libmariadb/ps.c | 8 ++++---- unittest/libmariadb/view.c | 8 ++++---- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/ma_pvio.h b/include/ma_pvio.h index 38e68ebf..7e300fee 100644 --- a/include/ma_pvio.h +++ b/include/ma_pvio.h @@ -98,7 +98,7 @@ struct st_ma_pvio_methods ssize_t (*write)(MARIADB_PVIO *pvio, const uchar *buffer, size_t length); ssize_t (*async_write)(MARIADB_PVIO *pvio, const uchar *buffer, size_t length); int (*wait_io_or_timeout)(MARIADB_PVIO *pvio, my_bool is_read, int timeout); - my_bool (*blocking)(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value); + int (*blocking)(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value); my_bool (*connect)(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo); my_bool (*close)(MARIADB_PVIO *pvio); int (*fast_send)(MARIADB_PVIO *pvio); diff --git a/include/mariadb_dyncol.h b/include/mariadb_dyncol.h index f2c13aa3..a6084fd9 100644 --- a/include/mariadb_dyncol.h +++ b/include/mariadb_dyncol.h @@ -225,7 +225,7 @@ void mariadb_dyncol_free(DYNAMIC_COLUMN *str); /* conversion of values to 3 base types */ enum enum_dyncol_func_result mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, - MARIADB_CHARSET_INFO *cs, my_bool quote); + MARIADB_CHARSET_INFO *cs, char quote); enum enum_dyncol_func_result mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val); enum enum_dyncol_func_result diff --git a/libmariadb/ma_pvio.c b/libmariadb/ma_pvio.c index f00484de..8f9afc7b 100644 --- a/libmariadb/ma_pvio.c +++ b/libmariadb/ma_pvio.c @@ -490,7 +490,7 @@ my_bool ma_pvio_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) my_bool ma_pvio_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode) { if (pvio && pvio->methods->blocking) - return pvio->methods->blocking(pvio, block, previous_mode); + return pvio->methods->blocking(pvio, block, previous_mode) != 0; return 1; } /* }}} */ diff --git a/libmariadb/ma_tls.c b/libmariadb/ma_tls.c index 7629bcaa..3090d49e 100644 --- a/libmariadb/ma_tls.c +++ b/libmariadb/ma_tls.c @@ -130,7 +130,7 @@ const char *ma_pvio_tls_get_protocol_version(MARIADB_TLS *ctls) return tls_protocol_version[version]; } -static char ma_hex2int(char c) +static signed char ma_hex2int(char c) { if (c >= '0' && c <= '9') return c - '0'; @@ -161,7 +161,7 @@ static my_bool ma_pvio_tls_compare_fp(const char *cert_fp, for(c= (char *)cert_fp; c < cert_fp + cert_fp_len; c++) { - char d1, d2; + signed char d1, d2; if (*p == ':') p++; if (p - fp > (int)fp_len -1) diff --git a/plugins/pvio/pvio_npipe.c b/plugins/pvio/pvio_npipe.c index e3900ddf..cf95ede8 100644 --- a/plugins/pvio/pvio_npipe.c +++ b/plugins/pvio/pvio_npipe.c @@ -38,7 +38,7 @@ ssize_t pvio_npipe_async_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length); ssize_t pvio_npipe_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length); ssize_t pvio_npipe_async_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length); int pvio_npipe_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout); -my_bool pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value); +int pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value); my_bool pvio_npipe_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo); my_bool pvio_npipe_close(MARIADB_PVIO *pvio); int pvio_npipe_fast_send(MARIADB_PVIO *pvio); @@ -187,7 +187,7 @@ int pvio_npipe_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeo return -1; } -my_bool pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode) +int pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode) { /* not supported */ DWORD flags= 0; diff --git a/plugins/pvio/pvio_shmem.c b/plugins/pvio/pvio_shmem.c index 8e7efa7d..ba217b72 100644 --- a/plugins/pvio/pvio_shmem.c +++ b/plugins/pvio/pvio_shmem.c @@ -36,7 +36,7 @@ int pvio_shm_get_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type); ssize_t pvio_shm_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length); ssize_t pvio_shm_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length); int pvio_shm_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout); -my_bool pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value); +int pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value); my_bool pvio_shm_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo); my_bool pvio_shm_close(MARIADB_PVIO *pvio); int pvio_shm_shutdown(MARIADB_PVIO *pvio); @@ -218,7 +218,7 @@ int pvio_shm_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout return 0; } -my_bool pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode) +int pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode) { /* not supported */ return 0; diff --git a/plugins/pvio/pvio_socket.c b/plugins/pvio/pvio_socket.c index 85026803..0905d708 100644 --- a/plugins/pvio/pvio_socket.c +++ b/plugins/pvio/pvio_socket.c @@ -92,7 +92,7 @@ ssize_t pvio_socket_async_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length) ssize_t pvio_socket_async_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length); ssize_t pvio_socket_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length); int pvio_socket_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout); -my_bool pvio_socket_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value); +int pvio_socket_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value); my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo); my_bool pvio_socket_close(MARIADB_PVIO *pvio); int pvio_socket_fast_send(MARIADB_PVIO *pvio); @@ -565,7 +565,7 @@ int pvio_socket_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int time return rc; } -my_bool pvio_socket_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode) +int pvio_socket_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode) { my_bool is_blocking; struct st_pvio_socket *csock; diff --git a/unittest/libmariadb/ps.c b/unittest/libmariadb/ps.c index 6965bc00..df2af5c3 100644 --- a/unittest/libmariadb/ps.c +++ b/unittest/libmariadb/ps.c @@ -2209,7 +2209,7 @@ static int test_bind_negative(MYSQL *mysql) my_bind[0].buffer_type= MYSQL_TYPE_LONG; my_bind[0].buffer= (void *)&my_val; my_bind[0].length= &my_length; - my_bind[0].is_null= (char*)&my_null; + my_bind[0].is_null= &my_null; rc= mysql_stmt_bind_param(stmt, my_bind); check_stmt_rc(rc, stmt); @@ -2400,12 +2400,12 @@ static int test_union_param(MYSQL *mysql) my_bind[0].buffer= (char*) &my_val; my_bind[0].buffer_length= 4; my_bind[0].length= &my_length; - my_bind[0].is_null= (char*)&my_null; + my_bind[0].is_null= &my_null; my_bind[1].buffer_type= MYSQL_TYPE_STRING; my_bind[1].buffer= (char*) &my_val; my_bind[1].buffer_length= 4; my_bind[1].length= &my_length; - my_bind[1].is_null= (char*)&my_null; + my_bind[1].is_null= &my_null; rc= mysql_stmt_bind_param(stmt, my_bind); check_stmt_rc(rc, stmt); @@ -3313,7 +3313,7 @@ ENGINE=InnoDB DEFAULT CHARSET=utf8"); my_bind[0].buffer_type= MYSQL_TYPE_LONG; my_bind[0].buffer= (void *)&my_val; my_bind[0].length= &my_length; - my_bind[0].is_null= (char*)&my_null; + my_bind[0].is_null= &my_null; my_val= 1; rc= mysql_stmt_bind_param(stmt, my_bind); check_stmt_rc(rc, stmt); diff --git a/unittest/libmariadb/view.c b/unittest/libmariadb/view.c index ea1aa352..9aeeecde 100644 --- a/unittest/libmariadb/view.c +++ b/unittest/libmariadb/view.c @@ -30,7 +30,7 @@ static int test_view(MYSQL *mysql) MYSQL_BIND my_bind[1]; char str_data[50]; ulong length = 0L; - long is_null = 0L; + my_bool is_null = 0; const char *query= "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?"; @@ -84,7 +84,7 @@ static int test_view(MYSQL *mysql) my_bind[0].buffer_length= 50; my_bind[0].length= &length; length= 4; - my_bind[0].is_null= (char*)&is_null; + my_bind[0].is_null= &is_null; rc= mysql_stmt_bind_param(stmt, my_bind); check_stmt_rc(rc, stmt); @@ -301,7 +301,7 @@ static int test_view_insert(MYSQL *mysql) MYSQL_BIND my_bind[1]; int my_val = 0; ulong my_length = 0L; - long my_null = 0L; + my_bool my_null = 0; const char *query= "insert into v1 values (?)"; @@ -328,7 +328,7 @@ static int test_view_insert(MYSQL *mysql) my_bind[0].buffer_type = MYSQL_TYPE_LONG; my_bind[0].buffer = (char *)&my_val; my_bind[0].length = &my_length; - my_bind[0].is_null = (char*)&my_null; + my_bind[0].is_null = &my_null; rc= mysql_stmt_bind_param(insert_stmt, my_bind); check_stmt_rc(rc, select_stmt); From eb64582b68eb627d70dffad8808c7b6d4cf11b27 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 25 Jul 2018 09:33:53 +0200 Subject: [PATCH 31/37] Debian layout changes/fixes --- cmake/install.cmake | 29 +++++++++++++++++++++++------ libmariadb/CMakeLists.txt | 4 ++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/cmake/install.cmake b/cmake/install.cmake index 04834d91..5352677d 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -31,13 +31,13 @@ IF(NOT INSTALL_LAYOUT) ENDIF() SET(INSTALL_LAYOUT ${INSTALL_LAYOUT} CACHE - STRING "Installation layout. Currently supported options are DEFAULT (tar.gz and zip) and RPM") + STRING "Installation layout. Currently supported options are DEFAULT (tar.gz and zip), RPM and DEB") # On Windows we only provide zip and .msi. Latter one uses a different packager. IF(UNIX) IF(INSTALL_LAYOUT MATCHES "RPM") SET(libmariadb_prefix "/usr") - ELSEIF(INSTALL_LAYOUT MATCHES "DEFAULT") + ELSEIF(INSTALL_LAYOUT MATCHES "DEFAULT|DEB") SET(libmariadb_prefix ${CMAKE_INSTALL_PREFIX}) ENDIF() ENDIF() @@ -47,7 +47,7 @@ IF(CMAKE_DEFAULT_PREFIX_INITIALIZED_BY_DEFAULT) ENDIF() # check if the specified installation layout is valid -SET(VALID_INSTALL_LAYOUTS "DEFAULT" "RPM") +SET(VALID_INSTALL_LAYOUTS "DEFAULT" "RPM" "DEB") LIST(FIND VALID_INSTALL_LAYOUTS "${INSTALL_LAYOUT}" layout_no) IF(layout_no EQUAL -1) MESSAGE(FATAL_ERROR "Invalid installation layout ${INSTALL_LAYOUT}. Please specify one of the following layouts: ${VALID_INSTALL_LAYOUTS}") @@ -64,14 +64,12 @@ ENDIF() # DEFAULT layout # - - SET(INSTALL_BINDIR_DEFAULT "bin") SET(INSTALL_LIBDIR_DEFAULT "lib/mariadb") SET(INSTALL_INCLUDEDIR_DEFAULT "include/mariadb") SET(INSTALL_DOCDIR_DEFAULT "docs") SET(INSTALL_PLUGINDIR_DEFAULT "lib/mariadb/plugin") - +SET(LIBMARIADB_STATIC_DEFAULT "mariadbclient") # # RPM layout # @@ -85,6 +83,22 @@ ELSE() ENDIF() SET(INSTALL_INCLUDEDIR_RPM "include") SET(INSTALL_DOCDIR_RPM "docs") +SET(LIBMARIADB_STATIC_RPM "mariadbclient") + +# +# DEB layout +# +SET(INSTALL_BINDIR_DEB "bin") +SET(INSTALL_LIBDIR_DEB "lib/${CMAKE_LIBRARY_ARCHITECTURE}") +IF(PLUGINDIR_DEB) + SET(INSTALL_PLUGINDIR_DEB "${INSTALL_LIBDIR_DEB}/${PLUGINDIR_DEB}/plugin") +ELSE() + SET(INSTALL_PLUGINDIR_DEB "${INSTALL_LIBDIR_DEB}/mariadb/plugin") +ENDIF() +SET(INSTALL_INCLUDEDIR_DEB "include/mariadb") +SET(LIBMARIADB_STATIC_DEB "mariadb") + + # # Overwrite defaults @@ -119,3 +133,6 @@ FOREACH(dir "BIN" "LIB" "INCLUDE" "DOCS" "PLUGIN") SET(INSTALL_${dir}DIR ${INSTALL_${dir}DIR_${INSTALL_LAYOUT}}) MARK_AS_ADVANCED(INSTALL_${dir}DIR) ENDFOREACH() + +SET(LIBMARIADB_STATIC_NAME ${LIBMARIADB_STATIC_${INSTALL_LAYOUT}}) +MARK_AS_ADVANCED(LIBMARIADB_STATIC_NAME) diff --git a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt index 995dc28b..9b37d6db 100644 --- a/libmariadb/CMakeLists.txt +++ b/libmariadb/CMakeLists.txt @@ -436,6 +436,10 @@ SET_TARGET_PROPERTIES(libmariadb PROPERTIES VERSION ${CPACK_PACKAGE_VERSION_MAJOR} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR}) +IF(NOT WIN32) + SET_TARGET_PROPERTIES(mariadbclient PROPERTIES OUTPUT_NAME "${LIBMARIADB_STATIC_NAME}") +ENDIF() + INSTALL(TARGETS mariadbclient COMPONENT Development DESTINATION ${INSTALL_LIBDIR}) From 1788e000d210a05322ccebfad1a16de5d0fca68d Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 27 Jul 2018 07:17:27 +0200 Subject: [PATCH 32/37] Fix for CONC-332: mysql_change_user doesn't reset server status Fixed my_auth.c, after successful connect the server status package information (including session change information) must be updated. --- libmariadb/mariadb_lib.c | 215 ++++++++++++++++--------------- plugins/auth/my_auth.c | 6 +- unittest/libmariadb/connection.c | 40 ++++++ 3 files changed, 153 insertions(+), 108 deletions(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index e35938c3..2dbbdb8a 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -1977,67 +1977,84 @@ mysql_send_query(MYSQL* mysql, const char* query, unsigned long length) return ma_simple_command(mysql, COM_QUERY, query, length, 1,0); } -int mthd_my_read_query_result(MYSQL *mysql) +int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length) { - uchar *pos; - ulong field_count; - MYSQL_DATA *fields; - ulong length; + size_t item_len; + mysql->affected_rows= net_field_length_ll(&pos); + mysql->insert_id= net_field_length_ll(&pos); + mysql->server_status=uint2korr(pos); + pos+=2; + mysql->warning_count=uint2korr(pos); + pos+=2; + if (pos < mysql->net.read_pos+length) + { + if ((item_len= net_field_length(&pos))) + mysql->info=(char*) pos; - if (!mysql || (length = ma_net_safe_read(mysql)) == packet_error) - { - return(1); - } - free_old_query(mysql); /* Free old result */ -get_info: - pos=(uchar*) mysql->net.read_pos; - if ((field_count= net_field_length(&pos)) == 0) - { - size_t item_len; - mysql->affected_rows= net_field_length_ll(&pos); - mysql->insert_id= net_field_length_ll(&pos); - mysql->server_status=uint2korr(pos); - pos+=2; - mysql->warning_count=uint2korr(pos); - pos+=2; - if (pos < mysql->net.read_pos+length) + /* check if server supports session tracking */ + if (mysql->server_capabilities & CLIENT_SESSION_TRACKING) { - if ((item_len= net_field_length(&pos))) - mysql->info=(char*) pos; + ma_clear_session_state(mysql); + pos+= item_len; - /* check if server supports session tracking */ - if (mysql->server_capabilities & CLIENT_SESSION_TRACKING) + if (mysql->server_status & SERVER_SESSION_STATE_CHANGED) { - ma_clear_session_state(mysql); - pos+= item_len; - - if (mysql->server_status & SERVER_SESSION_STATE_CHANGED) + int i; + if (pos < mysql->net.read_pos + length) { - int i; - if (pos < mysql->net.read_pos + length) + LIST *session_item; + MYSQL_LEX_STRING *str= NULL; + enum enum_session_state_type si_type; + uchar *old_pos= pos; + size_t item_len= net_field_length(&pos); /* length for all items */ + + /* length was already set, so make sure that info will be zero terminated */ + if (mysql->info) + *old_pos= 0; + + while (item_len > 0) { - LIST *session_item; - MYSQL_LEX_STRING *str= NULL; - enum enum_session_state_type si_type; - uchar *old_pos= pos; - size_t item_len= net_field_length(&pos); /* length for all items */ + size_t plen; + char *data; + old_pos= pos; + si_type= (enum enum_session_state_type)net_field_length(&pos); + switch(si_type) { + case SESSION_TRACK_SCHEMA: + case SESSION_TRACK_STATE_CHANGE: + case SESSION_TRACK_TRANSACTION_CHARACTERISTICS: + case SESSION_TRACK_SYSTEM_VARIABLES: + net_field_length(&pos); /* ignore total length, item length will follow next */ + plen= net_field_length(&pos); + if (!ma_multi_malloc(0, + &session_item, sizeof(LIST), + &str, sizeof(MYSQL_LEX_STRING), + &data, plen, + NULL)) + { + SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); + return -1; + } + str->length= plen; + str->str= data; + memcpy(str->str, (char *)pos, plen); + pos+= plen; + session_item->data= str; + mysql->extension->session_state[si_type].list= list_add(mysql->extension->session_state[si_type].list, session_item); - /* length was already set, so make sure that info will be zero terminated */ - if (mysql->info) - *old_pos= 0; - - while (item_len > 0) - { - size_t plen; - char *data; - old_pos= pos; - si_type= (enum enum_session_state_type)net_field_length(&pos); - switch(si_type) { - case SESSION_TRACK_SCHEMA: - case SESSION_TRACK_STATE_CHANGE: - case SESSION_TRACK_TRANSACTION_CHARACTERISTICS: - case SESSION_TRACK_SYSTEM_VARIABLES: - net_field_length(&pos); /* ignore total length, item length will follow next */ + /* in case schema has changed, we have to update mysql->db */ + if (si_type == SESSION_TRACK_SCHEMA) + { + free(mysql->db); + mysql->db= malloc(plen + 1); + memcpy(mysql->db, str->str, plen); + mysql->db[plen]= 0; + } + else if (si_type == SESSION_TRACK_SYSTEM_VARIABLES) + { + my_bool set_charset= 0; + /* make sure that we update charset in case it has changed */ + if (!strncmp(str->str, "character_set_client", str->length)) + set_charset= 1; plen= net_field_length(&pos); if (!ma_multi_malloc(0, &session_item, sizeof(LIST), @@ -2054,68 +2071,54 @@ get_info: pos+= plen; session_item->data= str; mysql->extension->session_state[si_type].list= list_add(mysql->extension->session_state[si_type].list, session_item); - - /* in case schema has changed, we have to update mysql->db */ - if (si_type == SESSION_TRACK_SCHEMA) + if (set_charset && + strncmp(mysql->charset->csname, str->str, str->length) != 0) { - free(mysql->db); - mysql->db= malloc(plen + 1); - memcpy(mysql->db, str->str, plen); - mysql->db[plen]= 0; + char cs_name[64]; + MARIADB_CHARSET_INFO *cs_info; + memcpy(cs_name, str->str, str->length); + cs_name[str->length]= 0; + if ((cs_info = (MARIADB_CHARSET_INFO *)mysql_find_charset_name(cs_name))) + mysql->charset= cs_info; } - else if (si_type == SESSION_TRACK_SYSTEM_VARIABLES) - { - my_bool set_charset= 0; - /* make sure that we update charset in case it has changed */ - if (!strncmp(str->str, "character_set_client", str->length)) - set_charset= 1; - plen= net_field_length(&pos); - if (!ma_multi_malloc(0, - &session_item, sizeof(LIST), - &str, sizeof(MYSQL_LEX_STRING), - &data, plen, - NULL)) - { - SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); - return -1; - } - str->length= plen; - str->str= data; - memcpy(str->str, (char *)pos, plen); - pos+= plen; - session_item->data= str; - mysql->extension->session_state[si_type].list= list_add(mysql->extension->session_state[si_type].list, session_item); - if (set_charset && - strncmp(mysql->charset->csname, str->str, str->length) != 0) - { - char cs_name[64]; - MARIADB_CHARSET_INFO *cs_info; - memcpy(cs_name, str->str, str->length); - cs_name[str->length]= 0; - if ((cs_info = (MARIADB_CHARSET_INFO *)mysql_find_charset_name(cs_name))) - mysql->charset= cs_info; - } - } - break; - default: - /* not supported yet */ - plen= net_field_length(&pos); - pos+= plen; - break; } - item_len-= (pos - old_pos); + break; + default: + /* not supported yet */ + plen= net_field_length(&pos); + pos+= plen; + break; } + item_len-= (pos - old_pos); } - for (i= SESSION_TRACK_BEGIN; i <= SESSION_TRACK_END; i++) - { - mysql->extension->session_state[i].list= list_reverse(mysql->extension->session_state[i].list); - mysql->extension->session_state[i].current= mysql->extension->session_state[i].list; - } + } + for (i= SESSION_TRACK_BEGIN; i <= SESSION_TRACK_END; i++) + { + mysql->extension->session_state[i].list= list_reverse(mysql->extension->session_state[i].list); + mysql->extension->session_state[i].current= mysql->extension->session_state[i].list; } } } - return(0); } + return(0); +} + +int mthd_my_read_query_result(MYSQL *mysql) +{ + uchar *pos; + ulong field_count; + MYSQL_DATA *fields; + ulong length; + + if (!mysql || (length = ma_net_safe_read(mysql)) == packet_error) + { + return(1); + } + free_old_query(mysql); /* Free old result */ +get_info: + pos=(uchar*) mysql->net.read_pos; + if ((field_count= net_field_length(&pos)) == 0) + return ma_read_ok_packet(mysql, pos, length); if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */ { int error=mysql_handle_local_infile(mysql, (char *)pos); diff --git a/plugins/auth/my_auth.c b/plugins/auth/my_auth.c index 9010a6f5..7c84c784 100644 --- a/plugins/auth/my_auth.c +++ b/plugins/auth/my_auth.c @@ -10,6 +10,7 @@ static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, size_t static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql); extern void read_user_name(char *name); extern char *ma_send_connect_attr(MYSQL *mysql, unsigned char *buffer); +extern int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length); typedef struct { int (*read_packet)(struct st_plugin_vio *vio, uchar **buf); @@ -577,7 +578,6 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, errno); return 1; } - if (mysql->net.read_pos[0] == 254) { /* The server asked to use a different authentication plugin */ @@ -632,6 +632,8 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, net->read_pos[0] should always be 0 here if the server implements the protocol correctly */ - return mysql->net.read_pos[0] != 0; + if (mysql->net.read_pos[0] == 0) + return ma_read_ok_packet(mysql, mysql->net.read_pos + 1, pkt_length); + return 1; } diff --git a/unittest/libmariadb/connection.c b/unittest/libmariadb/connection.c index fd5dac43..5ebcc44d 100644 --- a/unittest/libmariadb/connection.c +++ b/unittest/libmariadb/connection.c @@ -1487,7 +1487,47 @@ static int test_conc327(MYSQL *unused __attribute__((unused))) } #endif +static int test_conc332(MYSQL *unused __attribute__((unused))) +{ + int rc; + MYSQL *mysql= mysql_init(NULL); + int server_status1, server_status2; + + mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4"); + + my_test_connect(mysql, hostname, username, password, schema, + port, socketname, 0); + + FAIL_IF(mysql_errno(mysql), "Error during connect"); + + mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status1); + diag("server_status: %d", server_status1); + + if (server_status1 & SERVER_STATUS_AUTOCOMMIT) + rc= mysql_query(mysql, "SET autocommit= 0"); + else + rc= mysql_query(mysql, "SET autocommit= 1"); + check_mysql_rc(rc, mysql); + mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status2); + diag("server_status after changing autocommit: %d", server_status2); + + rc= mysql_change_user(mysql, username, password, schema); + check_mysql_rc(rc, mysql); + + mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status2); + diag("server_status after mysql_change_user: %d", server_status2); + if (server_status1 != server_status2) + { + diag("Expected server_status %d instead of %d", server_status1, server_status2); + mysql_close(mysql); + return FAIL; + } + mysql_close(mysql); + return OK; +} + struct my_tests_st my_tests[] = { + {"test_conc332", test_conc332, TEST_CONNECTION_NONE, 0, NULL, NULL}, #ifndef WIN32 {"test_conc327", test_conc327, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc317", test_conc317, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, From d2ee129f8c757634ec243804010f7025c3e95778 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 27 Jul 2018 07:32:08 +0200 Subject: [PATCH 33/37] CONC-297: Fixed regression bug (which happend due to a bad merge) --- libmariadb/mariadb_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 2dbbdb8a..28e2cbbc 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -2661,7 +2661,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...) mysql->options.named_pipe=1; /* Force named pipe */ break; case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/ - if (!arg1 || test(*(my_bool*) arg1)) + if (!arg1 || test(*(unsigned int*) arg1)) mysql->options.client_flag|= CLIENT_LOCAL_FILES; else mysql->options.client_flag&= ~CLIENT_LOCAL_FILES; From 5cb4d8d77c9e63ca04c18c5caae49eea8287b92e Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 27 Jul 2018 07:46:05 +0200 Subject: [PATCH 34/37] Fixed typo which broke windows build --- plugins/pvio/pvio_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/pvio/pvio_socket.c b/plugins/pvio/pvio_socket.c index 0905d708..888264c9 100644 --- a/plugins/pvio/pvio_socket.c +++ b/plugins/pvio/pvio_socket.c @@ -199,7 +199,7 @@ my_bool pvio_socket_change_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout ty #ifndef _WIN32 rc= setsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tm, sizeof(tm)); #else - src= etsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(int)); + rc= setsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(int)); #endif break; default: From f69eaf04dd58dd2167fcb5be33597b506a3d2321 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 31 Jul 2018 06:44:13 +0200 Subject: [PATCH 35/37] Bumped version number to 3.0.7 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9762018d..735c6372 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ SET(CC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) SET(CPACK_PACKAGE_VERSION_MAJOR 3) SET(CPACK_PACKAGE_VERSION_MINOR 0) -SET(CPACK_PACKAGE_VERSION_PATCH 6) +SET(CPACK_PACKAGE_VERSION_PATCH 7) SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") MATH(EXPR MARIADB_PACKAGE_VERSION_ID "${CPACK_PACKAGE_VERSION_MAJOR} * 10000 + ${CPACK_PACKAGE_VERSION_MINOR} * 100 + From f1fd014a15a1cb14b9f583d1a21929e22362f35c Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 31 Jul 2018 09:39:03 +0200 Subject: [PATCH 36/37] Fixed leak in ma_tls_read/write --- libmariadb/mariadb_lib.c | 2 +- libmariadb/secure/openssl.c | 10 ++++------ unittest/libmariadb/connection.c | 2 ++ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 28e2cbbc..b7316b21 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -1745,7 +1745,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, free(s_passwd); free(s_db); - if (db && !(mysql->db= strdup(db))) + if (!mysql->db && db && !(mysql->db= strdup(db))) { SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); rc= 1; diff --git a/libmariadb/secure/openssl.c b/libmariadb/secure/openssl.c index 4208828b..2d8fc696 100644 --- a/libmariadb/secure/openssl.c +++ b/libmariadb/secure/openssl.c @@ -719,15 +719,14 @@ ssize_t ma_tls_write_async(MARIADB_PVIO *pvio, ssize_t ma_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length) { ssize_t rc; - MYSQL *mysql= (MYSQL *)SSL_get_app_data(ctls->ssl); - MARIADB_PVIO *pvio= mysql->net.pvio; + MARIADB_PVIO *pvio= ctls->pvio; while ((rc= SSL_read((SSL *)ctls->ssl, (void *)buffer, (int)length)) < 0) { int error= SSL_get_error((SSL *)ctls->ssl, rc); if (error != SSL_ERROR_WANT_READ) return rc; - if (pvio->methods->wait_io_or_timeout(pvio, TRUE, mysql->options.read_timeout) < 1) + if (pvio->methods->wait_io_or_timeout(pvio, TRUE, pvio->mysql->options.read_timeout) < 1) return rc; } return rc; @@ -736,15 +735,14 @@ ssize_t ma_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length) ssize_t ma_tls_write(MARIADB_TLS *ctls, const uchar* buffer, size_t length) { ssize_t rc; - MYSQL *mysql= (MYSQL *)SSL_get_app_data(ctls->ssl); - MARIADB_PVIO *pvio= mysql->net.pvio; + MARIADB_PVIO *pvio= ctls->pvio; while ((rc= SSL_write((SSL *)ctls->ssl, (void *)buffer, (int)length)) <= 0) { int error= SSL_get_error((SSL *)ctls->ssl, rc); if (error != SSL_ERROR_WANT_WRITE) return rc; - if (pvio->methods->wait_io_or_timeout(pvio, TRUE, mysql->options.write_timeout) < 1) + if (pvio->methods->wait_io_or_timeout(pvio, TRUE, pvio->mysql->options.write_timeout) < 1) return rc; } return rc; diff --git a/unittest/libmariadb/connection.c b/unittest/libmariadb/connection.c index 5ebcc44d..bcdf2bca 100644 --- a/unittest/libmariadb/connection.c +++ b/unittest/libmariadb/connection.c @@ -1084,6 +1084,7 @@ static int test_auth256(MYSQL *my) if (!mysql_client_find_plugin(mysql, "sha256_password", 3)) { diag("sha256_password plugin not available"); + mysql_close(mysql); return SKIP; } @@ -1097,6 +1098,7 @@ static int test_auth256(MYSQL *my) if (!num_rows) { diag("server doesn't support sha256 authentication"); + mysql_close(mysql); return SKIP; } From a0fd36cc5a5313414a5a2ebe9322577a29b4782a Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 31 Jul 2018 09:44:20 +0200 Subject: [PATCH 37/37] Revert "Bumped version number to 3.0.7" This reverts commit f69eaf04dd58dd2167fcb5be33597b506a3d2321. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 735c6372..9762018d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ SET(CC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) SET(CPACK_PACKAGE_VERSION_MAJOR 3) SET(CPACK_PACKAGE_VERSION_MINOR 0) -SET(CPACK_PACKAGE_VERSION_PATCH 7) +SET(CPACK_PACKAGE_VERSION_PATCH 6) SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") MATH(EXPR MARIADB_PACKAGE_VERSION_ID "${CPACK_PACKAGE_VERSION_MAJOR} * 10000 + ${CPACK_PACKAGE_VERSION_MINOR} * 100 +