From 9f6b9f26f07ed2dbcebe434cee1f2d66c91f189f Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 29 May 2018 09:49:35 +0200 Subject: [PATCH 01/40] 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 | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 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 c5cd53cd..77331822 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4651,7 +4651,42 @@ static int test_compress(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_conc208", test_conc208, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_mdev14165", test_mdev14165, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, From e06960d7a6f791fb4907d4d26de85bd715c80432 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 29 May 2018 17:46:47 +0200 Subject: [PATCH 02/40] 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 68b6f9c6..be7bacdd 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -3521,6 +3521,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, @@ -3529,6 +3530,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)), @@ -3536,11 +3539,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 } @@ -3561,6 +3562,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 a1ac1b832d28eefedb396f9a472ee37fe443d420 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 30 May 2018 07:04:38 +0200 Subject: [PATCH 03/40] 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 8ec62e2f323a9fb253fc9b80e65627dfc53e5087 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 30 May 2018 16:31:17 +0200 Subject: [PATCH 04/40] 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 be7bacdd..bdd965f8 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -3521,7 +3521,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 2693f4c83058f4671ba990aef73a2c23ac6f0026 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 13 Jun 2018 17:28:50 +0200 Subject: [PATCH 05/40] 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 bdd965f8..f5227afb 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -1774,7 +1774,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 f91518d510b06908cd412f03165071562a89b4b7 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Thu, 14 Jun 2018 06:51:50 +0200 Subject: [PATCH 06/40] 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 f76dae7879f8e4685336e09063282d7eaa59e6bf Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Thu, 14 Jun 2018 06:51:50 +0200 Subject: [PATCH 07/40] 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 ca0786082bd829599592f4fae5c59dc1a72e4f1a Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 13 Jun 2018 17:28:50 +0200 Subject: [PATCH 08/40] 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 4a41ec00..306852f1 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -1778,7 +1778,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 ebf5db6cd0c7d10b0632a1389faa9731e3c09cf3 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 20 Jun 2018 09:01:59 +0200 Subject: [PATCH 09/40] Fix gcc warning --- libmariadb/mariadb_lib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 306852f1..53212e67 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -2910,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 */ From 74fbbaefeb54a485786a7180e15c3995eeaeac0a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 24 Jun 2018 20:37:01 +0200 Subject: [PATCH 10/40] fix unit test conc336 to pass in mtr --- unittest/libmariadb/conc336.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unittest/libmariadb/conc336.c b/unittest/libmariadb/conc336.c index 3b0f5608..b155c160 100644 --- a/unittest/libmariadb/conc336.c +++ b/unittest/libmariadb/conc336.c @@ -1,6 +1,6 @@ #include "my_test.h" -#define MAX_COUNT 4000 +#define MAX_COUNT 2000 int main(int argc, char *argv[]) { @@ -25,7 +25,7 @@ int main(int argc, char *argv[]) { return 1; } - if (!mysql_real_connect(mysql, hostname, username, password, NULL, port, NULL, 0)) { + if (!mysql_real_connect(mysql, hostname, username, password, schema, port, socketname, 0)) { diag("mysql_real_connect failed: %s", mysql_error(mysql)); return 1; } From ed5921ed4f26407ff1ff0596f2c74c8d7098632d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 30 Jun 2018 22:42:38 +0200 Subject: [PATCH 11/40] CONC-346 CMake warnings CMP0026 OLD CMP0042 OLD CMP0045 OLD --- CMakeLists.txt | 2 +- cmake/symlink.cmake | 18 +++++++----------- libmariadb/CMakeLists.txt | 8 +------- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0cf187a..404821f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) INCLUDE(CheckFunctionExists) IF(COMMAND CMAKE_POLICY) - SET(OLD_POLICIES CMP0026 CMP0042 CMP0045) + SET(OLD_POLICIES ) 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..117c1647 100644 --- a/cmake/symlink.cmake +++ b/cmake/symlink.cmake @@ -9,31 +9,27 @@ 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) - 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} + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${symlink_name} + COMMAND ${CMAKE_COMMAND} ARGS -E remove -f ${symlink_name} + COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink $ ${symlink_name} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${target} ) ADD_CUSTOM_TARGET(SYM_${symlink_name} ALL - DEPENDS ${target_path}/${symlink_name}) + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${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}" - "\${CMAKE_INSTALL_CONFIG_NAME}" output ${target_path}/${symlink_name}) + "\${CMAKE_INSTALL_CONFIG_NAME}" output ${CMAKE_CURRENT_BINARY_DIR}/${symlink_name}) ENDIF() # presumably this will be used for libmysql*.so symlinks - INSTALL(FILES ${target_path}/${symlink_name} DESTINATION ${install_path} + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${symlink_name} DESTINATION ${install_path} COMPONENT SharedLibraries) ENDIF() ENDMACRO() diff --git a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt index 430020bb..0fa86243 100644 --- a/libmariadb/CMakeLists.txt +++ b/libmariadb/CMakeLists.txt @@ -445,12 +445,6 @@ INSTALL(TARGETS libmariadb 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}" + INSTALL(FILES $ DESTINATION "${INSTALL_LIBDIR}" COMPONENT Development) ENDIF() From 463211f4a9e68eb7a2fd7a8a3466e5bf3a13e361 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 4 Jul 2018 19:49:10 +0200 Subject: [PATCH 12/40] cmake .git warning only run git if .git exists, don't do it for source tarballs --- CMakeLists.txt | 10 +++++----- cmake/version_info.cmake | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 404821f5..67545750 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,7 +152,7 @@ ENDIF() # various defines for generating include/mysql_version.h INCLUDE(FindGit) -IF(GIT_EXECUTABLE) +IF(GIT_EXECUTABLE AND EXISTS ${CC_SOURCE_DIR}/.git) EXECUTE_PROCESS( COMMAND ${GIT_EXECUTABLE} rev-parse HEAD WORKING_DIRECTORY ${CC_SOURCE_DIR} @@ -410,15 +410,15 @@ ENDIF() # Build source packages IF(GIT_BUILD_SRCPKG) # get branch name - EXECUTE_PROCESS(COMMAND git show-branch OUTPUT_VARIABLE git_branch) + EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} show-branch OUTPUT_VARIABLE git_branch) STRING(REGEX MATCH "\\[([^]]+)\\]" git_branch ${git_branch}) STRING(REGEX REPLACE "\\[|\\]" "" GIT_BRANCH ${git_branch}) MESSAGE1(GIT_BRANCH "${GIT_BRANCH}") IF(WIN32) - EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip) + EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} archive ${GIT_BRANCH} --format=zip --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip) ELSE() - EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip) - EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=tar --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar) + EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} archive ${GIT_BRANCH} --format=zip --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip) + EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} archive ${GIT_BRANCH} --format=tar --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar) EXECUTE_PROCESS(COMMAND gzip -9 -f ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar) ENDIF() ENDIF() diff --git a/cmake/version_info.cmake b/cmake/version_info.cmake index 4b2324a7..1c05de03 100644 --- a/cmake/version_info.cmake +++ b/cmake/version_info.cmake @@ -9,8 +9,8 @@ FUNCTION(GET_FILE_VERSION FILE_NAME FILE_VERSION) # if we build from a git repository, we calculate the file version: # Patch number is numer of commits for given file - IF(EXISTS ${CC_SOURCE_DIR}/.git) - EXECUTE_PROCESS(COMMAND git --git-dir=${CC_SOURCE_DIR}/.git --work-tree=${CC_SOURCE_DIR} rev-list HEAD --count -- ${FILE_NAME} + IF(GIT_EXECUTABLE AND EXISTS ${CC_SOURCE_DIR}/.git) + EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} --git-dir=${CC_SOURCE_DIR}/.git --work-tree=${CC_SOURCE_DIR} rev-list HEAD --count -- ${FILE_NAME} OUTPUT_VARIABLE FV) STRING(REPLACE "\n" "" FV ${FV}) SET(${FILE_VERSION} ${FV} PARENT_SCOPE) From ade0d67b0a79cf5e96305b6c312a5b26e9469dd0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 5 Jul 2018 14:24:05 +0200 Subject: [PATCH 13/40] less re-cmake messages --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 67545750..4dd13987 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -392,7 +392,7 @@ ENDIF() IF(WIN32 AND WITH_MSI AND CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") ADD_SUBDIRECTORY(win/packaging) ENDIF() -MESSAGE("SYSTEM processor: ${CMAKE_SYSTEM_PROCESSOR}") +MESSAGE1(SYSTEM_PROCESSOR "SYSTEM processor: ${CMAKE_SYSTEM_PROCESSOR}") SET(CPACK_PACKAGE_VENDOR "MariaDB Corporation Ab") SET(CPACK_PACKAGE_DESCRIPTION "MariaDB Connector/C. A library for connecting to MariaDB and MySQL servers") SET(CPACK_PACKAGE_NAME "mariadb_connector_c") From e5a7852f42474b80f627c7ae3ca17ffbc6874123 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 2 May 2018 11:40:42 +0200 Subject: [PATCH 14/40] CONC-327: Add support for !include an !includedir in configuration files --- libmariadb/ma_default.c | 54 ++++++++++++++++++++--- libmariadb/mariadb_lib.c | 7 ++- unittest/libmariadb/connection.c | 75 ++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 10 deletions(-) diff --git a/libmariadb/ma_default.c b/libmariadb/ma_default.c index 064d1c03..17670e8d 100644 --- a/libmariadb/ma_default.c +++ b/libmariadb/ma_default.c @@ -39,6 +39,12 @@ static const char *ini_exts[]= {"cnf", 0}; char **configuration_dirs= NULL; #define MAX_CONFIG_DIRS 6 +my_bool _mariadb_read_options(MYSQL *mysql, + const char *config_dir, + const char *config_file, + const char *group, + unsigned int recursion); + static int add_cfg_dir(char **cfg_dirs, const char *directory) { int i; @@ -139,7 +145,8 @@ static my_bool is_group(char *ptr, const char **groups) static my_bool _mariadb_read_options_from_file(MYSQL *mysql, const char *config_file, - const char *group) + const char *group, + unsigned int recursion) { uint line=0; my_bool read_values= 0, found_group= 0, is_escaped= 0, is_quoted= 0; @@ -175,6 +182,23 @@ static my_bool _mariadb_read_options_from_file(MYSQL *mysql, is_quoted= !is_quoted; continue; } + /* CONC- 327: !includedir and !include */ + if (*ptr == '!') + { + char *val; + ptr++; + if (!(val= strchr(ptr, ' '))) + continue; + *val++= 0; + end= strchr(val, 0); + for ( ; isspace(end[-1]) ; end--) ; /* Remove end space */ + *end= 0; + if (!strcmp(ptr, "includedir")) + _mariadb_read_options(mysql, (const char *)val, NULL, group, recursion + 1); + else if (!strcmp(ptr, "include")) + _mariadb_read_options(mysql, NULL, (const char *)val, group, recursion + 1); + continue; + } if (*ptr == '#' || *ptr == ';' || !*ptr) continue; is_escaped= (*ptr == '\\'); @@ -286,19 +310,37 @@ err: my_bool _mariadb_read_options(MYSQL *mysql, + const char *config_dir, const char *config_file, - const char *group) + const char *group, + unsigned int recursion) { int i= 0, exts, errors= 0; char filename[FN_REFLEN + 1]; + unsigned int recursion_stop= 64; #ifndef _WIN32 char *env; #endif - if (config_file) - return _mariadb_read_options_from_file(mysql, config_file, group); + if (recursion >= recursion_stop) + return 1; + + if (config_file && config_file[0]) + return _mariadb_read_options_from_file(mysql, config_file, group, recursion); + + if (config_dir && config_dir[0]) + { + for (exts= 0; ini_exts[exts]; exts++) + { + snprintf(filename, FN_REFLEN, + "%s%cmy.%s", config_dir, FN_LIBCHAR, ini_exts[exts]); + if (!access(filename, R_OK)) + errors+= _mariadb_read_options_from_file(mysql, filename, group, recursion); + } + return errors; + } for (i=0; i < MAX_CONFIG_DIRS && configuration_dirs[i]; i++) { @@ -307,7 +349,7 @@ my_bool _mariadb_read_options(MYSQL *mysql, snprintf(filename, FN_REFLEN, "%s%cmy.%s", configuration_dirs[i], FN_LIBCHAR, ini_exts[exts]); if (!access(filename, R_OK)) - errors+= _mariadb_read_options_from_file(mysql, filename, group); + errors+= _mariadb_read_options_from_file(mysql, filename, group, recursion); } } #ifndef _WIN32 @@ -319,7 +361,7 @@ my_bool _mariadb_read_options(MYSQL *mysql, snprintf(filename, FN_REFLEN, "%s%c.my.%s", env, FN_LIBCHAR, ini_exts[exts]); if (!access(filename, R_OK)) - errors+= _mariadb_read_options_from_file(mysql, filename, group); + errors+= _mariadb_read_options_from_file(mysql, filename, group, recursion); } } #endif diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index f5227afb..000e18ef 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -106,8 +106,7 @@ extern int mthd_stmt_fetch_row(MYSQL_STMT *stmt, unsigned char **row); extern int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row); extern int mthd_stmt_read_all_rows(MYSQL_STMT *stmt); extern void mthd_stmt_flush_unbuffered(MYSQL_STMT *stmt); -extern my_bool _mariadb_read_options(MYSQL *mysql, const char *config_file, - char *group); +extern my_bool _mariadb_read_options(MYSQL *mysql, const char *dir, const char *config_file, char *group, unsigned int recursion); extern unsigned char *mysql_net_store_length(unsigned char *packet, size_t length); extern void @@ -1210,10 +1209,10 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user, /* use default options */ if (mysql->options.my_cnf_file || mysql->options.my_cnf_group) { - _mariadb_read_options(mysql, + _mariadb_read_options(mysql, NULL, (mysql->options.my_cnf_file ? mysql->options.my_cnf_file : NULL), - mysql->options.my_cnf_group); + mysql->options.my_cnf_group, 0); free(mysql->options.my_cnf_file); free(mysql->options.my_cnf_group); mysql->options.my_cnf_file=mysql->options.my_cnf_group=0; diff --git a/unittest/libmariadb/connection.c b/unittest/libmariadb/connection.c index 8f1daa92..c24c7254 100644 --- a/unittest/libmariadb/connection.c +++ b/unittest/libmariadb/connection.c @@ -1026,6 +1026,9 @@ static int test_reset(MYSQL *mysql) if (mysql_get_server_version(mysql) < 100200) return SKIP; + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + check_mysql_rc(rc, mysql); + rc= mysql_query(mysql, "CREATE TABLE t1 (a int)"); check_mysql_rc(rc, mysql); @@ -1415,10 +1418,82 @@ static int test_conc317(MYSQL *unused __attribute__((unused))) mysql_close(mysql); return OK; } + +static int test_conc327(MYSQL *unused __attribute__((unused))) +{ + MYSQL *mysql; + my_bool reconnect = 0; + FILE *fp1= NULL, *fp2= NULL; + const char *env= getenv("MYSQL_TMP_DIR"); + char cnf_file1[FN_REFLEN + 1]; + char cnf_file2[FN_REFLEN + 1]; + + if (travis_test) + return SKIP; + + if (!env) + env= "/tmp"; + + setenv("HOME", env, 1); + + snprintf(cnf_file1, FN_REFLEN, "%s%c.my.cnf", env, FN_LIBCHAR); + snprintf(cnf_file2, FN_REFLEN, "%s%c.my.tmp", env, FN_LIBCHAR); + + FAIL_IF(!access(cnf_file1, R_OK), "access"); + + fp1= fopen(cnf_file1, "w"); + fp2= fopen(cnf_file2, "w"); + FAIL_IF(!fp1 || !fp2, "fopen failed"); + + fprintf(fp1, "!include %s\n", cnf_file2); + + fprintf(fp2, "[client]\ndefault-character-set = latin2\nreconnect= 1\n"); + fclose(fp1); + fclose(fp2); + + mysql= mysql_init(NULL); + mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, ""); + my_test_connect(mysql, hostname, username, password, + schema, 0, socketname, 0); + + remove(cnf_file1); + remove(cnf_file2); + + FAIL_IF(strcmp(mysql_character_set_name(mysql), "latin2"), "expected charset latin2"); + mysql_get_optionv(mysql, MYSQL_OPT_RECONNECT, &reconnect); + FAIL_IF(reconnect != 1, "expected reconnect=1"); + mysql_close(mysql); + + snprintf(cnf_file1, FN_REFLEN, "%s%cmy.cnf", env, FN_LIBCHAR); + fp1= fopen(cnf_file1, "w"); + fp2= fopen(cnf_file2, "w"); + FAIL_IF(!fp1 || !fp2, "fopen failed"); + + fprintf(fp2, "!includedir %s\n", env); + + fprintf(fp1, "[client]\ndefault-character-set = latin2\nreconnect= 1\n"); + fclose(fp1); + fclose(fp2); + mysql= mysql_init(NULL); + mysql_options(mysql, MYSQL_READ_DEFAULT_FILE, cnf_file2); + my_test_connect(mysql, hostname, username, password, + schema, 0, socketname, 0); + + remove(cnf_file1); + remove(cnf_file2); + + FAIL_IF(strcmp(mysql_character_set_name(mysql), "latin2"), "expected charset latin2"); + mysql_get_optionv(mysql, MYSQL_OPT_RECONNECT, &reconnect); + FAIL_IF(reconnect != 1, "expected reconnect=1"); + mysql_close(mysql); + + return OK; +} #endif struct my_tests_st my_tests[] = { #ifndef WIN32 + {"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}, From 7d28557c8d6b6cc5c1ab59b771524dfeb6fe4238 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Mon, 28 May 2018 15:51:58 +0200 Subject: [PATCH 15/40] 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 | 70 ++++++++++++++++++++++- 2 files changed, 144 insertions(+), 28 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 77331822..8b2c30ce 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4685,9 +4685,78 @@ static int test_conc334(MYSQL *mysql) return OK; } +static int test_codbc138(MYSQL *mysql) +{ + int rc; + MYSQL_STMT *stmt; + MYSQL_BIND bind[1]; + MYSQL_TIME tm; + int i= 0; + + 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}} + }; + + while (time_test[i].statement) + { + 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++; + } + + 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}, {"test_mdev14165", test_mdev14165, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc208", test_conc208, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, @@ -4771,4 +4840,3 @@ int main(int argc, char **argv) return(exit_status()); } - From 768f50ebe332271281406279e1f9d67acf00ecce Mon Sep 17 00:00:00 2001 From: FaramosCZ Date: Thu, 24 May 2018 07:35:20 +0200 Subject: [PATCH 16/40] 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 91e8858139d1e7c987bec6cb9fbf03a324bb7ce3 Mon Sep 17 00:00:00 2001 From: FaramosCZ Date: Thu, 24 May 2018 07:25:45 +0200 Subject: [PATCH 17/40] 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 edc4caacf34e3292145d2f2a969d14f5b4c20ca2 Mon Sep 17 00:00:00 2001 From: FaramosCZ Date: Thu, 24 May 2018 07:06:12 +0200 Subject: [PATCH 18/40] 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 10684408..f6afaf58 100644 --- a/libmariadb/ma_stmt_codec.c +++ b/libmariadb/ma_stmt_codec.c @@ -442,7 +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); - 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); @@ -660,7 +660,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; } @@ -759,7 +759,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 32096f3bedef999a661d74b3235db38bf2091499 Mon Sep 17 00:00:00 2001 From: Lawrin Novitsky Date: Wed, 20 Jun 2018 16:34:03 +0200 Subject: [PATCH 19/40] 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 da6da028..f4f48d6e 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 010124ca127ca5c588d2f678fc84f8d3482ec643 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 8 Aug 2018 11:54:32 +0200 Subject: [PATCH 20/40] compilation warning --- unittest/libmariadb/ps_bugs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index 8b2c30ce..d250835d 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4694,7 +4694,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)", From 4700c3fcec3f04f5063a79fd07c8245480b2d4b9 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Thu, 28 Jun 2018 17:22:08 +0200 Subject: [PATCH 21/40] Fix for CONC-344: reset internal row counter before executing prepared statement --- libmariadb/mariadb_stmt.c | 3 +- unittest/libmariadb/ps_bugs.c | 97 +++++++++++++++++++++++------------ 2 files changed, 65 insertions(+), 35 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 d250835d..0ee6d365 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4651,40 +4651,6 @@ static int test_compress(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; -} - static int test_codbc138(MYSQL *mysql) { int rc; @@ -4753,7 +4719,70 @@ 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; +} + +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 ea79ee6e7d4abf1656b0fa3d1b47bba4f47a633d Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 3 Jul 2018 11:17:46 +0200 Subject: [PATCH 22/40] 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 8b33faca..50101ce5 100644 --- a/plugins/auth/my_auth.c +++ b/plugins/auth/my_auth.c @@ -359,7 +359,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 c3e9aab76d1271fc6793eaba528c899f4b099d55 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Tue, 3 Jul 2018 12:45:55 +0200 Subject: [PATCH 23/40] 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 3a4b088f4b9b4d7ff726f367d9bef1a789691410 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 4 Jul 2018 07:25:24 +0200 Subject: [PATCH 24/40] 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 29b319a230a46a39b6601a2ed1fd02bd92038af5 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 4 Jul 2018 07:56:17 +0200 Subject: [PATCH 25/40] 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 00b35605e05ab6e6fb96a32a50dfd2553c32f717 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 6 Jul 2018 09:28:24 +0200 Subject: [PATCH 26/40] Coverity fixes and travis integration --- .travis.yml | 56 ++++++++++++++++++++++++------ 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, 181 insertions(+), 112 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2787396d..ac3624aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,30 +1,64 @@ sudo: true language: c +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: - - chmod +x .travis/script.sh - - chmod +x .travis/gen-ssl.sh + - 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` - export ENTRYPOINT=$PROJ_PATH/.travis/sql - mkdir tmp - .travis/gen-ssl.sh mariadb.example.com tmp - export SSLCERT=$PROJ_PATH/tmp +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 + - env: DB=mariadb:5.5 + - env: DB=mariadb:10.0 + - 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 -env: - - DB=mysql:5.7 - - DB=mariadb:5.5 - - DB=mariadb:10.0 - - DB=mariadb:10.1 - - DB=mariadb:10.2 - - DB=mariadb:10.3 +script: + - if [ "$DB" = "build" ] ; then .travis/build/build.sh; fi + - if [ "$DB" = "build" ] ; then docker build -t build:latest --label build .travis/build/; fi + - if [ -z "$DB" ] ; then .travis/server-replace-submodule.sh; fi + - if [ -n "$DB" ] ; then .travis/script.sh; fi -script: .travis/script.sh 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 a3e09430..e1c0b231 100644 --- a/libmariadb/ma_charset.c +++ b/libmariadb/ma_charset.c @@ -1409,7 +1409,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 6c940f3a..42f32bbc 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); @@ -392,20 +392,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); + } } /* }}} */ @@ -453,13 +456,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 000e18ef..11f265a4 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -229,7 +229,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)); @@ -947,7 +947,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; @@ -984,6 +985,7 @@ mysql_init(MYSQL *mysql) { memset((char*) (mysql), 0, sizeof(*(mysql))); mysql->net.pvio= 0; + mysql->free_me= 0; mysql->net.extension= 0; } @@ -1185,8 +1187,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; @@ -1380,9 +1381,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))) @@ -1484,7 +1484,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 : + "unknown", "compiled_in"); goto error; } @@ -1601,6 +1602,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) { @@ -1716,13 +1718,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 @@ -1773,8 +1768,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); @@ -2287,12 +2285,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))) { @@ -2740,6 +2740,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; } @@ -3135,9 +3136,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 543a5b1d..d45be2b5 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 c5a23356..7454fd93 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 43bb4aac..429fb3c4 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 */ @@ -874,6 +875,7 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) if (rc) { closesocket(csock->socket); + csock->socket= INVALID_SOCKET; continue; } } @@ -888,6 +890,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! */ @@ -923,21 +926,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 3630fecae6c33587b5d83315ee497de0610e83eb Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 13 Jul 2018 12:30:13 +0200 Subject: [PATCH 27/40] 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 +++++++++---- unittest/libmariadb/dyncol.c | 36 ++++++++++++++++++++++++++++++++ 10 files changed, 120 insertions(+), 24 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 42f32bbc..1feb727b 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 7454fd93..2c3afa6b 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/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 9cf39da26a4b610beb084fbf049461ee8633008a Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 13 Jul 2018 14:48:42 +0200 Subject: [PATCH 28/40] 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 6530cc161f3cb4c225356785d677e5bba000e8b4 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 27 Jul 2018 07:17:27 +0200 Subject: [PATCH 29/40] 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 11f265a4..c181e027 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -1971,67 +1971,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), @@ -2048,68 +2065,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 50101ce5..414667bb 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); @@ -579,7 +580,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 */ @@ -634,6 +634,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 c24c7254..1d5f224d 100644 --- a/unittest/libmariadb/connection.c +++ b/unittest/libmariadb/connection.c @@ -1491,7 +1491,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 e71512b949d2c6f2e573957d30fc644ae9907508 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 27 Jul 2018 07:32:08 +0200 Subject: [PATCH 30/40] 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 c181e027..b2c1ccad 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -2655,7 +2655,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 3616c977f675f7aa9923a6b2ee26281a00d64a06 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 18 Jul 2018 09:28:05 +1000 Subject: [PATCH 31/40] 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 1feb727b..8da77490 100644 --- a/libmariadb/ma_pvio.c +++ b/libmariadb/ma_pvio.c @@ -483,7 +483,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 4acc7272..4b2ebaf3 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 86cd2ba1..42f68977 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 429fb3c4..061e817f 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 7ec72504161c9ffe4b8d8de27bfde5834388faae Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Fri, 27 Jul 2018 07:46:05 +0200 Subject: [PATCH 32/40] 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 061e817f..2ec67b72 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 31eb49f1f4dff7841866f6eaaefe44f94e124d62 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 8 Aug 2018 22:05:46 +0200 Subject: [PATCH 33/40] compilation failure on Win64 conversion from 'size_t' to 'int', possible loss of data --- libmariadb/ma_string.c | 4 ++-- plugins/auth/sha256_pw.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libmariadb/ma_string.c b/libmariadb/ma_string.c index 7eb95554..9a62e06e 100644 --- a/libmariadb/ma_string.c +++ b/libmariadb/ma_string.c @@ -96,8 +96,8 @@ 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; + size_t additional= str->alloc_increment; + size_t lim= additional; uint i; if (ma_dynstr_realloc(str, len + additional + 2)) diff --git a/plugins/auth/sha256_pw.c b/plugins/auth/sha256_pw.c index 2c3afa6b..81b5c992 100644 --- a/plugins/auth/sha256_pw.c +++ b/plugins/auth/sha256_pw.c @@ -142,7 +142,7 @@ char *load_pub_key_file(const char *filename, int *pub_key_size) if (bytes_read < (size_t)fsize) goto end; - *pub_key_size= bytes_read; + *pub_key_size= (int)bytes_read; error= 0; From d0f201451d062b83912525b4821d82304b32ecb1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 8 Aug 2018 17:37:35 +0200 Subject: [PATCH 34/40] SLES11 OpenSSL 0.9.8 support --- libmariadb/secure/openssl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libmariadb/secure/openssl.c b/libmariadb/secure/openssl.c index 6b41a34d..0a1ec78c 100644 --- a/libmariadb/secure/openssl.c +++ b/libmariadb/secure/openssl.c @@ -39,6 +39,13 @@ #define HAVE_OPENSSL_1_1_API #endif +#if OPENSSL_VERSION_NUMBER < 0x10000000L +#define SSL_OP_NO_TLSv1_1 0L +#define SSL_OP_NO_TLSv1_2 0L +#define CRYPTO_THREADID_set_callback CRYPTO_set_id_callback +#define CRYPTO_THREADID_get_callback CRYPTO_get_id_callback +#endif + #ifdef HAVE_TLS_SESSION_CACHE #undef HAVE_TLS_SESSION_CACHE #endif From d0582ea02f772cb30dc848589a251cb278d739e0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 12 Aug 2018 14:50:14 +0200 Subject: [PATCH 35/40] debian packaging fixes early return prevents LIBMARIADB_STATIC_NAME from being set --- cmake/install.cmake | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cmake/install.cmake b/cmake/install.cmake index 5352677d..15af5f5b 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -22,10 +22,6 @@ # INSTALL_LIBDIR location of libraries # INSTALL_PLUGINDIR location of plugins -IF(DEFINED INSTALL_BINDIR AND DEFINED INSTALL_LIBDIR AND DEFINED INSTALL_INCLUDEDIR AND DEFINED INSTALL_DOCDIR AND DEFINED INSTALL_PLUGINDIR) - RETURN() -ENDIF() - IF(NOT INSTALL_LAYOUT) SET(INSTALL_LAYOUT "DEFAULT") ENDIF() From b948553b3464d37240c4d129fae47ce147e6dabc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 12 Aug 2018 14:51:00 +0200 Subject: [PATCH 36/40] .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index eba6b53c..1044957e 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,7 @@ unittest/libmariadb/t_aurora unittest/libmariadb/t_conc173 unittest/libmariadb/thread unittest/libmariadb/view +unittest/libmariadb/conc336 #VS files/directories *.vcxproj From f45eca0a69a10fb66a7f7273285d645ea2e91d38 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 16 Aug 2018 11:43:32 +0200 Subject: [PATCH 37/40] MDEV-14977 10.2.12 libmariadb doesn't support old protocol fix the typo in the plugin name --- plugins/auth/my_auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth/my_auth.c b/plugins/auth/my_auth.c index 414667bb..4b848de2 100644 --- a/plugins/auth/my_auth.c +++ b/plugins/auth/my_auth.c @@ -521,7 +521,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, else { if (!(auth_plugin= (auth_plugin_t*)mysql_client_find_plugin(mysql, - "old_password", MYSQL_CLIENT_AUTHENTICATION_PLUGIN))) + "mysql_old_password", MYSQL_CLIENT_AUTHENTICATION_PLUGIN))) return 1; /* not found */ } auth_plugin_name= auth_plugin->name; From 17d0e5317604718fc059ee1ad4bd2ea36494226b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 8 Sep 2018 15:47:17 +0100 Subject: [PATCH 38/40] Fix broken build with Windows OpenSSL. --- libmariadb/secure/openssl.c | 12 ++++++------ plugins/auth/CMakeLists.txt | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libmariadb/secure/openssl.c b/libmariadb/secure/openssl.c index 79479ab3..943c19f4 100644 --- a/libmariadb/secure/openssl.c +++ b/libmariadb/secure/openssl.c @@ -443,7 +443,7 @@ int ma_tls_get_password(char *buf, int size, memset(buf, 0, size); if (userdata) strncpy(buf, (char *)userdata, size); - return strlen(buf); + return (int)strlen(buf); } @@ -623,7 +623,7 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls) SSL_set_bio(ssl, bio, bio); BIO_set_fd(bio, mysql_get_socket(mysql), BIO_NOCLOSE); #else - SSL_set_fd(ssl, mysql_get_socket(mysql)); + SSL_set_fd(ssl, (int)mysql_get_socket(mysql)); #endif while (try_connect && (rc= SSL_connect(ssl)) == -1) @@ -700,7 +700,7 @@ ssize_t ma_tls_read_async(MARIADB_PVIO *pvio, for (;;) { - res= SSL_read((SSL *)ctls->ssl, (void *)buffer, length); + res= SSL_read((SSL *)ctls->ssl, (void *)buffer, (int)length); if (ma_tls_async_check_result(res, b, (SSL *)ctls->ssl)) return res; } @@ -716,7 +716,7 @@ ssize_t ma_tls_write_async(MARIADB_PVIO *pvio, for (;;) { - res= SSL_write((SSL *)ctls->ssl, (void *)buffer, length); + res= SSL_write((SSL *)ctls->ssl, (void *)buffer, (int)length); if (ma_tls_async_check_result(res, b, (SSL *)ctls->ssl)) return res; } @@ -725,7 +725,7 @@ 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; + int rc; MARIADB_PVIO *pvio= ctls->pvio; while ((rc= SSL_read((SSL *)ctls->ssl, (void *)buffer, (int)length)) < 0) @@ -741,7 +741,7 @@ 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; + int rc; MARIADB_PVIO *pvio= ctls->pvio; while ((rc= SSL_write((SSL *)ctls->ssl, (void *)buffer, (int)length)) <= 0) diff --git a/plugins/auth/CMakeLists.txt b/plugins/auth/CMakeLists.txt index 1d40a34e..99548dc2 100644 --- a/plugins/auth/CMakeLists.txt +++ b/plugins/auth/CMakeLists.txt @@ -39,7 +39,7 @@ IF(GSSAPI_SOURCES) ENDIF() IF(${WITH_SSL} STREQUAL "OPENSSL" OR ${WITH_SSL} STREQUAL "SCHANNEL") - IF(WIN32) + IF(WITH_SSL STREQUAL "SCHANNEL") SET(SHA256_LIBS crypt32) ELSE() SET(SHA256_LIBS ${SSL_LIBRARIES}) From fb3bc6b171d0c5fb4829f50c03c3fe3f5919a35b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 12 Aug 2018 14:51:00 +0200 Subject: [PATCH 39/40] .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index eba6b53c..1044957e 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,7 @@ unittest/libmariadb/t_aurora unittest/libmariadb/t_conc173 unittest/libmariadb/thread unittest/libmariadb/view +unittest/libmariadb/conc336 #VS files/directories *.vcxproj From 5d5c1ba55664f23cf474ff6278e467f85ada1a0f Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 3 Oct 2018 13:19:08 +0100 Subject: [PATCH 40/40] Multiple fixes in named pipe implementation: - integer overflow in multiplication in pvio_npipe_set_timeout. - overlapped ReadFile/WriteFile should not use parameter for size and get it e.g from GetOverlappedResult(). See similar server bug MDEV-14115 - Fix incorrect implementation of connection timeout in WaitNamedPipe(). WaitNamedPipe is called in a loop, timeout it for loop, not a single iteration. - If there is a lot of connect/disconnects, client's connect loop (CreateFile() with retries if ERROR_PIPE_BUSY) is very hot. Add some small Sleep() between retries. - Do not do anything with (deprecated) PIPE_NOWAIT flag. - Also remove functions that are not used. --- plugins/pvio/pvio_npipe.c | 173 ++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 100 deletions(-) diff --git a/plugins/pvio/pvio_npipe.c b/plugins/pvio/pvio_npipe.c index 4b2ebaf3..f97c6493 100644 --- a/plugins/pvio/pvio_npipe.c +++ b/plugins/pvio/pvio_npipe.c @@ -34,11 +34,8 @@ my_bool pvio_npipe_set_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout); int pvio_npipe_get_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type); ssize_t pvio_npipe_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length); -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); -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); @@ -55,8 +52,8 @@ struct st_ma_pvio_methods pvio_npipe_methods= { NULL, pvio_npipe_write, NULL, - pvio_npipe_wait_io_or_timeout, - pvio_npipe_blocking, + NULL, + NULL, pvio_npipe_connect, pvio_npipe_close, pvio_npipe_fast_send, @@ -91,14 +88,22 @@ MARIADB_PVIO_PLUGIN _mysql_client_plugin_declaration_ = struct st_pvio_npipe { HANDLE pipe; OVERLAPPED overlapped; - size_t rw_size; MYSQL *mysql; }; my_bool pvio_npipe_set_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout) { + int timeout_ms; + if (!pvio) return 1; + if (timeout > INT_MAX/1000) + timeout_ms= -1; + else if (timeout <=0) + timeout_ms= -1; + else + timeout_ms = timeout*100; + pvio->timeout[type]= (timeout > 0) ? timeout * 1000 : -1; return 0; } @@ -110,103 +115,78 @@ int pvio_npipe_get_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type) return pvio->timeout[type] / 1000; } +static BOOL complete_io(HANDLE file, OVERLAPPED *ov, BOOL ret, DWORD timeout, DWORD *size) +{ + if (ret) + timeout = 0; /* IO completed successfully, do not WaitForSingleObject */ + else + { + assert(timeout); + if (GetLastError() != ERROR_IO_PENDING) + return FALSE; + } + + if (timeout) + { + HANDLE wait_handle= ov->hEvent; + assert(wait_handle && (wait_handle != INVALID_HANDLE_VALUE)); + + DWORD wait_ret= WaitForSingleObject(wait_handle, timeout); + switch (wait_ret) + { + case WAIT_OBJECT_0: + break; + case WAIT_TIMEOUT: + CancelIoEx(file, ov); + SetLastError(ERROR_TIMEOUT); + return FALSE; + default: + /* WAIT_ABANDONED or WAIT_FAILED unexpected. */ + assert(0); + return FALSE; + } + } + + return GetOverlappedResult(file, ov, size, FALSE); +} + ssize_t pvio_npipe_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length) { - DWORD dwRead= 0; + BOOL ret; ssize_t r= -1; struct st_pvio_npipe *cpipe= NULL; + DWORD size; if (!pvio || !pvio->data) return -1; cpipe= (struct st_pvio_npipe *)pvio->data; - if (ReadFile(cpipe->pipe, (LPVOID)buffer, (DWORD)length, &dwRead, &cpipe->overlapped)) - { - r= (ssize_t)dwRead; - goto end; - } - if (GetLastError() == ERROR_IO_PENDING) - { - if (!pvio_npipe_wait_io_or_timeout(pvio, 1, 0)) - r= cpipe->rw_size; - } -end: + ret= ReadFile(cpipe->pipe, buffer, (DWORD)length, NULL, &cpipe->overlapped); + ret= complete_io(cpipe->pipe, &cpipe->overlapped, ret, pvio->timeout[PVIO_READ_TIMEOUT], &size); + r= ret? (ssize_t) size:-1; + return r; } ssize_t pvio_npipe_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length) { - DWORD dwWrite= 0; ssize_t r= -1; struct st_pvio_npipe *cpipe= NULL; + BOOL ret; + DWORD size; if (!pvio || !pvio->data) return -1; cpipe= (struct st_pvio_npipe *)pvio->data; - if (WriteFile(cpipe->pipe, buffer, (DWORD)length, &dwWrite, &cpipe->overlapped)) - { - r= (ssize_t)dwWrite; - goto end; - } - if (GetLastError() == ERROR_IO_PENDING) - { - if (!pvio_npipe_wait_io_or_timeout(pvio, 0, 0)) - r= cpipe->rw_size; - } -end: + ret= WriteFile(cpipe->pipe, buffer, (DWORD)length, NULL , &cpipe->overlapped); + ret= complete_io(cpipe->pipe, &cpipe->overlapped, ret, pvio->timeout[PVIO_WRITE_TIMEOUT], &size); + r= ret ? (ssize_t)size : -1; return r; } -int pvio_npipe_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout) -{ - DWORD status; - int save_error; - struct st_pvio_npipe *cpipe= NULL; - - cpipe= (struct st_pvio_npipe *)pvio->data; - - if (!timeout) - timeout= (is_read) ? pvio->timeout[PVIO_READ_TIMEOUT] : pvio->timeout[PVIO_WRITE_TIMEOUT]; - if (!timeout) - timeout= INFINITE; - - status= WaitForSingleObject(cpipe->overlapped.hEvent, timeout); - if (status == WAIT_OBJECT_0) - { - if (GetOverlappedResult(cpipe->pipe, &cpipe->overlapped, (LPDWORD)&cpipe->rw_size, FALSE)) - return 0; - } - /* For other status codes (WAIT_ABANDONED, WAIT_TIMEOUT and WAIT_FAILED) - we return error */ - save_error= GetLastError(); - CancelIo(cpipe->pipe); - SetLastError(save_error); - return -1; -} - -int pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode) -{ - /* not supported */ - DWORD flags= 0; - struct st_pvio_npipe *cpipe= NULL; - - cpipe= (struct st_pvio_npipe *)pvio->data; - - if (previous_mode) - { - if (!GetNamedPipeHandleState(cpipe->pipe, &flags, NULL, NULL, NULL, NULL, 0)) - return 1; - *previous_mode= flags & PIPE_NOWAIT ? 0 : 1; - } - - flags= block ? PIPE_WAIT : PIPE_NOWAIT; - if (!SetNamedPipeHandleState(cpipe->pipe, &flags, NULL, NULL)) - return 1; - return 0; -} int pvio_npipe_keepalive(MARIADB_PVIO *pvio) { @@ -245,10 +225,10 @@ my_bool pvio_npipe_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) if (cinfo->type == PVIO_TYPE_NAMEDPIPE) { - my_bool has_timedout= 0; char szPipeName[MAX_PATH]; - DWORD dwMode; - + ULONGLONG deadline; + LONGLONG wait_ms; + DWORD backoff= 0; /* Avoid busy wait if ERROR_PIPE_BUSY.*/ if ( ! cinfo->unix_socket || (cinfo->unix_socket)[0] == 0x00) cinfo->unix_socket = MARIADB_NAMEDPIPE; if (!cinfo->host || !strcmp(cinfo->host,LOCAL_HOST)) @@ -257,6 +237,7 @@ my_bool pvio_npipe_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) szPipeName[MAX_PATH - 1]= 0; snprintf(szPipeName, MAX_PATH - 1, "\\\\%s\\pipe\\%s", cinfo->host, cinfo->unix_socket); + deadline = GetTickCount64() + pvio->timeout[PVIO_CONNECT_TIMEOUT]; while (1) { if ((cpipe->pipe = CreateFile(szPipeName, @@ -276,24 +257,23 @@ my_bool pvio_npipe_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo) goto end; } - if (has_timedout || !WaitNamedPipe(szPipeName, pvio->timeout[PVIO_CONNECT_TIMEOUT])) + Sleep(backoff); + if (!backoff) + backoff = 1; + + wait_ms = deadline - GetTickCount64(); + if (wait_ms > INFINITE) + wait_ms = INFINITE; + + if ((wait_ms <= 0) || !WaitNamedPipe(szPipeName, (DWORD)wait_ms)) { pvio->set_error(pvio->mysql, CR_NAMEDPIPEWAIT_ERROR, SQLSTATE_UNKNOWN, 0, - cinfo->host, cinfo->unix_socket, GetLastError()); + cinfo->host, cinfo->unix_socket, ERROR_TIMEOUT); goto end; } - has_timedout= 1; } - dwMode = PIPE_READMODE_BYTE | PIPE_WAIT; - if (!SetNamedPipeHandleState(cpipe->pipe, &dwMode, NULL, NULL)) - { - pvio->set_error(pvio->mysql, CR_NAMEDPIPESETSTATE_ERROR, SQLSTATE_UNKNOWN, 0, - cinfo->host, cinfo->unix_socket, (ulong) GetLastError()); - goto end; - } - /* Register event handler for overlapped IO */ if (!(cpipe->overlapped.hEvent= CreateEvent(NULL, FALSE, FALSE, NULL))) { pvio->set_error(pvio->mysql, CR_EVENT_CREATE_FAILED, SQLSTATE_UNKNOWN, 0, @@ -348,14 +328,7 @@ my_bool pvio_npipe_get_handle(MARIADB_PVIO *pvio, void *handle) my_bool pvio_npipe_is_blocking(MARIADB_PVIO *pvio) { - DWORD flags= 0; - struct st_pvio_npipe *cpipe= NULL; - - cpipe= (struct st_pvio_npipe *)pvio->data; - - if (!GetNamedPipeHandleState(cpipe->pipe, &flags, NULL, NULL, NULL, NULL, 0)) - return 1; - return (flags & PIPE_NOWAIT) ? 0 : 1; + return 1; } int pvio_npipe_shutdown(MARIADB_PVIO *pvio)