From: Andrey Hristov Date: Mon, 14 Jun 2010 17:16:20 +0000 (+0000) Subject: Fixed bug #52082 (character_set_client & character_set_connection reset after X-Git-Tag: php-5.3.3RC1~28 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d9c49bb3c222c93544a7bcf1898d592c6dbac18;p=php Fixed bug #52082 (character_set_client & character_set_connection reset after mysqli_change_user()) libmysql >= 5.1.23 will PASS, older library versions will fail --- diff --git a/NEWS b/NEWS index 32c4be8ebd..f9c9839d8f 100644 --- a/NEWS +++ b/NEWS @@ -71,6 +71,8 @@ PHP NEWS requests (Fixes CVE-2010-0397, bug #51288). (Raphael Geissert) - Fixed 64-bit integer overflow in mhash_keygen_s2k(). (Clément LECIGNE, Stas) +- Fixed bug #52082 (character_set_client & character_set_connection reset after + mysqli_change_user()). (Andrey) - Fixed bug #52043 (GD doesn't recognize latest libJPEG versions). (php at group dot apple dot com, Pierre) - Fixed bug #52060 (Memory leak when passing a closure to method_exists()). 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-- + +--FILE-- +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);