andrey                                   Mon, 14 Jun 2010 17:16:20 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=300435

Log:
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

Bug: http://bugs.php.net/52082 (Verified) character_set_client & 
character_set_connection reset after mysqli_change_user
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    A   php/php-src/branches/PHP_5_3/ext/mysqli/tests/bug52082.phpt
    U   php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c
    A   php/php-src/trunk/ext/mysqli/tests/bug52082.phpt
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd.c

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS   2010-06-14 17:11:50 UTC (rev 300434)
+++ php/php-src/branches/PHP_5_3/NEWS   2010-06-14 17:16:20 UTC (rev 300435)
@@ -71,6 +71,8 @@
   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()).

Added: php/php-src/branches/PHP_5_3/ext/mysqli/tests/bug52082.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqli/tests/bug52082.phpt                 
        (rev 0)
+++ php/php-src/branches/PHP_5_3/ext/mysqli/tests/bug52082.phpt 2010-06-14 
17:16:20 UTC (rev 300435)
@@ -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

Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c  2010-06-14 17:11:50 UTC 
(rev 300434)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c  2010-06-14 17:16:20 UTC 
(rev 300435)
@@ -1860,8 +1860,9 @@
        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 @@
        }
        *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 @@
                }
                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);

Added: php/php-src/trunk/ext/mysqli/tests/bug52082.phpt
===================================================================
--- php/php-src/trunk/ext/mysqli/tests/bug52082.phpt                            
(rev 0)
+++ php/php-src/trunk/ext/mysqli/tests/bug52082.phpt    2010-06-14 17:16:20 UTC 
(rev 300435)
@@ -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

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd.c     2010-06-14 17:11:50 UTC (rev 
300434)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd.c     2010-06-14 17:16:20 UTC (rev 
300435)
@@ -1860,8 +1860,9 @@
        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 @@
        }
        *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 @@
                }
                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);

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to