From 1ecc37f94f8223c0939b958059b5e874bab8edf5 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 7 Dec 2018 17:21:18 +0100 Subject: [PATCH 1/5] CONC-387 return MYSQL_DATA_TRUNCATED for invalid numeric strings. Fix a regression in new my_atoll()/my_atoull() to set error, if there are non-digits found in the string. Spaces at the start and end of string are ignored (however, not between the digits). --- libmariadb/ma_stmt_codec.c | 19 ++++++++++++ unittest/libmariadb/ps_bugs.c | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/libmariadb/ma_stmt_codec.c b/libmariadb/ma_stmt_codec.c index e05b37f0..45ce4c3c 100644 --- a/libmariadb/ma_stmt_codec.c +++ b/libmariadb/ma_stmt_codec.c @@ -209,6 +209,7 @@ static long long my_strtoll(const char *str, size_t len, const char **end, int * return -1LL * uval; } + static long long my_atoll(const char *str, const char *end_str, int *error) { const char *p=str; @@ -216,18 +217,36 @@ static long long my_atoll(const char *str, const char *end_str, int *error) long long ret; while (p < end_str && isspace(*p)) p++; + ret = my_strtoll(p, end_str - p, &end, error); + + while(end < end_str && isspace(*end)) + end++; + + if(end != end_str) + *error= 1; + return ret; } + static unsigned long long my_atoull(const char *str, const char *end_str, int *error) { const char *p = str; const char *end; unsigned long long ret; + while (p < end_str && isspace(*p)) p++; + ret = my_strtoull(p, end_str - p, &end, error); + + while(end < end_str && isspace(*end)) + end++; + + if(end != end_str) + *error= 1; + return ret; } diff --git a/unittest/libmariadb/ps_bugs.c b/unittest/libmariadb/ps_bugs.c index e2a595d1..10f80a91 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4658,6 +4658,62 @@ static int equal_MYSQL_TIME(MYSQL_TIME *tm1, MYSQL_TIME *tm2) tm1->second_part==tm2->second_part && tm1->time_type==tm2->time_type && tm1->year==tm2->year; } +static int test_str_to_int(MYSQL *mysql) +{ + int i; + struct st_atoi_test{ + const char *str_value; + int int_value; + int rc; + } atoi_tests[]= + { + {"0", 0, 0}, + {" 1",1, 0}, + {"123 ",123, 0}, + {"10.2",10, MYSQL_DATA_TRUNCATED}, + {"a", 0, MYSQL_DATA_TRUNCATED}, + {"1 2 3", 1, MYSQL_DATA_TRUNCATED}, + {NULL, 0, 0} + }; + + for(i=0; atoi_tests[i].str_value; i++) + { + int rc; + MYSQL_STMT *stmt; + MYSQL_BIND bind[1]; + struct st_atoi_test *test= &atoi_tests[i]; + char sql[256]; + int int_value; + + snprintf(sql, sizeof(sql), "SELECT '%s'",test->str_value); + + stmt= mysql_stmt_init(mysql); + + rc= mysql_stmt_prepare(stmt, sql, strlen(sql)); + 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_LONG; + bind[0].buffer= &int_value; + bind[0].buffer_length= sizeof(int_value); + + rc= mysql_stmt_bind_result(stmt, bind); + check_stmt_rc(rc, stmt); + rc= mysql_stmt_fetch(stmt); + + diag("test: str='%s', expected/returned value =%d/%d, expected/returned rc=%d/%d", + test->str_value, test->int_value, int_value, test->rc, rc); + FAIL_UNLESS(rc == test->rc, "unexpected return code"); + FAIL_UNLESS(int_value == test->int_value, "unexpected int value"); + mysql_stmt_close(stmt); + } + return OK; +} + + static int test_codbc138(MYSQL *mysql) { int rc; @@ -5029,6 +5085,7 @@ struct my_tests_st my_tests[] = { {"test_stiny_bug", test_stiny_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL}, {"test_bug53311", test_bug53311, TEST_CONNECTION_NEW, 0, NULL , NULL}, {"test_conc_fraction", test_conc_fraction, TEST_CONNECTION_DEFAULT, 0, NULL , NULL}, + {"test_str_to_int", test_str_to_int, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {NULL, NULL, 0, 0, NULL, NULL} }; From 5baea224783b986f559e4a1495723fef8974fc11 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 7 Dec 2018 17:39:34 +0100 Subject: [PATCH 2/5] Fix warnings on Windows --- libmariadb/secure/win_crypt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libmariadb/secure/win_crypt.c b/libmariadb/secure/win_crypt.c index c4f5058c..3c99e967 100644 --- a/libmariadb/secure/win_crypt.c +++ b/libmariadb/secure/win_crypt.c @@ -19,6 +19,7 @@ #include #include #include +#include #pragma comment(lib, "bcrypt.lib") From 2a66af1aba3f28c7f997db330cdf0e73aa99afeb Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 18 Dec 2018 15:16:16 +0100 Subject: [PATCH 3/5] support linking with external manually specified zlib one can set ZLIB_INCLUDE_DIR, ZLIB_LIBRARY, ZLIB_FOUND manually and skip automatic zlib location detection, --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe1bb46f..8cba0a1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -198,7 +198,9 @@ SET(DEFAULT_CHARSET_HOME "${CMAKE_INSTALL_PREFIX}") INCLUDE(${CC_SOURCE_DIR}/cmake/SearchLibrary.cmake) IF(WITH_EXTERNAL_ZLIB) - FIND_PACKAGE(ZLIB) + IF(NOT ZLIB_FOUND) + FIND_PACKAGE(ZLIB) + ENDIF() IF(ZLIB_FOUND) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) SET(LIBZ ${ZLIB_LIBRARY}) From 9d981de5687a0a5724f820fa4087034979a133f5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 18 Dec 2018 15:17:42 +0100 Subject: [PATCH 4/5] gnutls (esp. when static) needs zlib --- plugins/auth/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth/CMakeLists.txt b/plugins/auth/CMakeLists.txt index 4f5ed198..42f6f05e 100644 --- a/plugins/auth/CMakeLists.txt +++ b/plugins/auth/CMakeLists.txt @@ -28,7 +28,7 @@ IF(WITH_SSL) SET(CACHING_SHA2_LIBS crypt32 bcrypt) ELSEIF(${WITH_SSL} STREQUAL "GNUTLS") SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/gnutls_crypt.c) - SET(CACHING_SHA2_LIBS ${SSL_LIBRARIES}) + SET(CACHING_SHA2_LIBS ${SSL_LIBRARIES} ${LIBZ}) ENDIF() REGISTER_PLUGIN(TARGET caching_sha2_password TYPE MARIADB_CLIENT_PLUGIN_AUTH From 34f8887af03d022416dd6593de91d0706e57f46b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 18 Dec 2018 17:34:42 +0100 Subject: [PATCH 5/5] Fix warnings on Windows --- 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 10f80a91..e9079c47 100644 --- a/unittest/libmariadb/ps_bugs.c +++ b/unittest/libmariadb/ps_bugs.c @@ -4689,7 +4689,7 @@ static int test_str_to_int(MYSQL *mysql) stmt= mysql_stmt_init(mysql); - rc= mysql_stmt_prepare(stmt, sql, strlen(sql)); + rc= mysql_stmt_prepare(stmt, sql, (ulong)strlen(sql)); check_stmt_rc(rc, stmt); rc= mysql_stmt_execute(stmt); check_stmt_rc(rc, stmt);