diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/mysqli/tests/bug52082.phpt | 50 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd.c | 17 |
2 files changed, 66 insertions, 1 deletions
diff --git a/ext/mysqli/tests/bug52082.phpt b/ext/mysqli/tests/bug52082.phpt new file mode 100644 index 0000000000..8e3bd59ba5 --- /dev/null +++ b/ext/mysqli/tests/bug52082.phpt @@ -0,0 +1,50 @@ +--TEST-- +Bug #52082 (character_set_client & character_set_connection reset after mysqli_change_user) +--SKIPIF-- +<?php +require_once('skipif.inc'); +require_once('skipifemb.inc'); +require_once('skipifconnectfailure.inc'); +?> +--FILE-- +<?php + require_once("connect.inc"); + $link = mysqli_init(); + $link->options(MYSQLI_SET_CHARSET_NAME, "latin2"); + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + die("can't connect"); + } + var_dump($link->query("show variables like 'character_set_client'")->fetch_row()); + var_dump($link->query("show variables like 'character_set_connection'")->fetch_row()); + $link->change_user($user, $passwd, $db); + var_dump($link->query("show variables like 'character_set_client'")->fetch_row()); + var_dump($link->query("show variables like 'character_set_connection'")->fetch_row()); + + print "done!"; +?> +--EXPECTF-- +array(2) { + [0]=> + string(20) "character_set_client" + [1]=> + string(6) "latin2" +} +array(2) { + [0]=> + string(24) "character_set_connection" + [1]=> + string(6) "latin2" +} +array(2) { + [0]=> + string(20) "character_set_client" + [1]=> + string(6) "latin2" +} +array(2) { + [0]=> + string(24) "character_set_connection" + [1]=> + string(6) "latin2" +} +done!
\ No newline at end of file diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index 79580dcc31..46556eb46f 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -1860,8 +1860,9 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn, size_t user_len; enum_func_status ret = FAIL; MYSQLND_PACKET_CHG_USER_RESPONSE * chg_user_resp; - char buffer[MYSQLND_MAX_ALLOWED_USER_LEN + 1 + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1]; + char buffer[MYSQLND_MAX_ALLOWED_USER_LEN + 1 + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1 + 2 /* charset*/ ]; char *p = buffer; + const MYSQLND_CHARSET * old_cs = conn->charset; DBG_ENTER("mysqlnd_conn::change_user"); DBG_INF_FMT("conn=%llu user=%s passwd=%s db=%s silent=%d", @@ -1902,6 +1903,16 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn, } *p++ = '\0'; + /* + 4. request the current charset, or it will be reset to the system one. + 5.0 doesn't support it. Support added in 5.1.23 by fixing the following bug : + Bug #30472 libmysql doesn't reset charset, insert_id after succ. mysql_change_user() call + */ + if (mysqlnd_get_server_version(conn) >= 50123) { + int2store(p, conn->charset->nr); + p+=2; + } + if (PASS != conn->m->simple_command(conn, COM_CHANGE_USER, buffer, p - buffer, PROT_LAST /* we will handle the OK packet*/, silent, TRUE TSRMLS_CC)) { @@ -1951,6 +1962,10 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn, } conn->charset = conn->greet_charset; memset(&conn->upsert_status, 0, sizeof(conn->upsert_status)); + /* set charset for old servers */ + if (mysqlnd_get_server_version(conn) < 50123) { + ret = conn->m->set_charset(conn, old_cs->name TSRMLS_CC); + } } else if (ret == FAIL && chg_user_resp->server_asked_323_auth == TRUE) { /* old authentication with new server !*/ DBG_ERR(mysqlnd_old_passwd); |
