From c75061c90b41233217ca2db763cee9d7b16335d5 Mon Sep 17 00:00:00 2001 From: Dharman Date: Wed, 16 Sep 2020 14:20:03 +0100 Subject: [PATCH 1/4] mysqli_set_charset now throws an mysqli_sql_exception when incorrect charset is provided --- ext/mysqli/mysqli_nonapi.c | 1 + ext/mysqlnd/mysqlnd_connection.c | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 394afc7ccc993..76b02d4a50beb 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -1039,6 +1039,7 @@ PHP_FUNCTION(mysqli_set_charset) MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); if (mysql_set_character_set(mysql->mysql, cs_name)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } RETURN_TRUE; diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index 252c05f676dd2..9f34c0407004b 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -1152,8 +1152,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_charset)(MYSQLND_CONN_DATA * const conn, c DBG_INF_FMT("conn=%llu cs=%s", conn->thread_id, csname); if (!charset) { - SET_CLIENT_ERROR(conn->error_info, CR_CANT_FIND_CHARSET, UNKNOWN_SQLSTATE, - "Invalid characterset or character set not supported"); + SET_CLIENT_ERROR(conn->error_info, CR_CANT_FIND_CHARSET, UNKNOWN_SQLSTATE, "Invalid character set was provided"); DBG_RETURN(ret); } @@ -1161,9 +1160,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_charset)(MYSQLND_CONN_DATA * const conn, c char * query; size_t query_len = mnd_sprintf(&query, 0, "SET NAMES %s", csname); - if (FAIL == (ret = conn->m->query(conn, query, query_len))) { - php_error_docref(NULL, E_WARNING, "Error executing query"); - } else if (conn->error_info->error_no) { + if (FAIL == (ret = conn->m->query(conn, query, query_len)) || conn->error_info->error_no) { ret = FAIL; } else { conn->charset = charset; From 598e0b699e1ec7b8735f3748381a067a402e0e71 Mon Sep 17 00:00:00 2001 From: Dharman Date: Wed, 16 Sep 2020 20:52:12 +0100 Subject: [PATCH 2/4] Update test case for mysqli_set_charset() --- ext/mysqli/tests/mysqli_set_charset.phpt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt index 43b8be3f0017c..13fbdf3f82377 100644 --- a/ext/mysqli/tests/mysqli_set_charset.phpt +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -102,6 +102,14 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR } mysqli_free_result($res); + // Make sure that set_charset throws an exception in exception mode + mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); + try { + $link->set_charset('invalid'); + } catch (\mysqli_sql_exception $exception) { + echo $exception->getMessage() . "\n"; + } + mysqli_close($link); try { @@ -117,5 +125,6 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR require_once("clean_table.inc"); ?> --EXPECT-- +Invalid character set was provided mysqli object is already closed done! From 434f8f1cc567faa4529da4cbb9e2dc2ed3fb9761 Mon Sep 17 00:00:00 2001 From: Dharman Date: Thu, 17 Sep 2020 13:02:37 +0100 Subject: [PATCH 3/4] Test for error: ucs2 is not a supported charset in MySQL nor in MariaDB It's unclear if the support for ucs2 will be added in the future but at the moment it looks like this is impossible. An exception should be thrown if you try to set charset to ucs2 --- ext/mysqli/tests/mysqli_set_charset.phpt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt index 13fbdf3f82377..f106006b0f359 100644 --- a/ext/mysqli/tests/mysqli_set_charset.phpt +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -106,6 +106,12 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); try { $link->set_charset('invalid'); + } catch (\mysqli_sql_exception $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $link->set_charset('ucs2'); } catch (\mysqli_sql_exception $exception) { echo $exception->getMessage() . "\n"; } @@ -126,5 +132,6 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR ?> --EXPECT-- Invalid character set was provided +Variable 'character_set_client' can't be set to the value of 'ucs2' mysqli object is already closed done! From 8ec514cefc483d17e5076c432073e1052137105c Mon Sep 17 00:00:00 2001 From: Dharman Date: Fri, 18 Sep 2020 11:02:59 +0100 Subject: [PATCH 4/4] Indentation --- ext/mysqli/tests/mysqli_set_charset.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt index f106006b0f359..9c66116081e35 100644 --- a/ext/mysqli/tests/mysqli_set_charset.phpt +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -108,8 +108,8 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR $link->set_charset('invalid'); } catch (\mysqli_sql_exception $exception) { echo $exception->getMessage() . "\n"; - } - + } + try { $link->set_charset('ucs2'); } catch (\mysqli_sql_exception $exception) {