]> granicus.if.org Git - php/commitdiff
Fix for Bug #52686 mysql_stmt_attr_[gs]et arg. points to incorrect type
authorAndrey Hristov <andrey@php.net>
Wed, 6 Oct 2010 11:11:02 +0000 (11:11 +0000)
committerAndrey Hristov <andrey@php.net>
Wed, 6 Oct 2010 11:11:02 +0000 (11:11 +0000)
ext/mysqli/mysqli_api.c
ext/mysqli/tests/mysqli_stmt_attr_set.phpt
ext/mysqlnd/mysqlnd_ps.c

index 6ce166713e9db48ac1d5d9a60dd4ec7e9f481ec0..8557a1ba89d7652fecc8b371a3fc96acee4354a0 100644 (file)
@@ -380,11 +380,11 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc,
                        case MYSQL_TYPE_NEWDECIMAL:
 #endif
                        {
-#if MYSQL_VERSION_ID > 50099
+#if MYSQL_VERSION_ID >= 50107
                                /* Changed to my_bool in MySQL 5.1. See MySQL Bug #16144 */
                                my_bool tmp;
 #else
-                               ulong tmp = 0;
+                               uint tmp = 0;
 #endif
                                stmt->result.buf[ofs].type = IS_STRING;
                                /*
@@ -2231,8 +2231,10 @@ PHP_FUNCTION(mysqli_stmt_attr_set)
        MY_STMT *stmt;
        zval    *mysql_stmt;
        long    mode_in;
+       my_bool mode_b;
        ulong   mode;
        ulong   attr;
+       void    *mode_p;
 
        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) {
                return;
@@ -2244,11 +2246,22 @@ PHP_FUNCTION(mysqli_stmt_attr_set)
                RETURN_FALSE;
        }
 
-       mode = mode_in;
+       switch (attr) {
+#if MYSQL_VERSION_ID >= 50107
+       case STMT_ATTR_UPDATE_MAX_LENGTH:
+               mode_b = (my_bool) mode_in;
+               mode_p = &mode_b;
+               break;
+#endif
+       default:
+               mode = mode_in;
+               mode_p = &mode;
+               break;
+       }
 #if !defined(MYSQLI_USE_MYSQLND)
-       if (mysql_stmt_attr_set(stmt->stmt, attr, (void *)&mode)) {
+       if (mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
 #else
-       if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, (void *)&mode)) {
+       if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
 #endif
                RETURN_FALSE;
        }
@@ -2262,11 +2275,7 @@ PHP_FUNCTION(mysqli_stmt_attr_get)
 {
        MY_STMT *stmt;
        zval    *mysql_stmt;
-#if !defined(MYSQLI_USE_MYSQLND) && MYSQL_VERSION_ID > 50099
-       my_bool value;
-#else
        ulong   value = 0;
-#endif
        ulong   attr;
        int             rc;
 
@@ -2278,6 +2287,11 @@ PHP_FUNCTION(mysqli_stmt_attr_get)
        if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) {
                RETURN_FALSE;
        }
+
+#if MYSQL_VERSION_ID >= 50107
+       if (attr == STMT_ATTR_UPDATE_MAX_LENGTH)
+               value = *((my_bool *)&value);
+#endif
        RETURN_LONG((long)value);
 }
 /* }}} */
@@ -2423,7 +2437,11 @@ PHP_FUNCTION(mysqli_stmt_store_result)
                                stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB ||
                                stmt->stmt->fields[i].type == MYSQL_TYPE_GEOMETRY))
                        {
+#if MYSQL_VERSION_ID >= 50107
                                my_bool tmp=1;
+#else
+                               uint tmp=1;
+#endif
                                mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
                                break;
                        }
index 82e0121a3cdedf900f7cb5809b0288de0e533e3a..c2ddd211984f96e3712ecfd3b006741acca2ccfc 100644 (file)
@@ -92,6 +92,9 @@ require_once('skipifconnectfailure.inc');
        $stmt = mysqli_stmt_init($link);
        $stmt->prepare("SELECT label FROM test");
        $stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 1);
+       $res = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
+       if ($res !== 1)
+               printf("[007.1] max_length should be 1, got %s\n", $res);
        $stmt->execute();
        $stmt->store_result();
        $res = $stmt->result_metadata();
@@ -109,6 +112,9 @@ require_once('skipifconnectfailure.inc');
        $stmt = mysqli_stmt_init($link);
        $stmt->prepare("SELECT label FROM test");
        $stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 0);
+       $res = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
+       if ($res !== 0)
+               printf("[008.1] max_length should be 0, got %s\n", $res);
        $stmt->execute();
        $stmt->store_result();
        $res = $stmt->result_metadata();
index 70bcef9e383d047d3e84bd7ef4278ad4330771a4..cecce5ec439181e0f2a0c79703703e0be37d94fb 100644 (file)
@@ -1827,39 +1827,42 @@ MYSQLND_METHOD(mysqlnd_stmt, attr_set)(MYSQLND_STMT * const s,
                                                                           const void * const value TSRMLS_DC)
 {
        MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
-       unsigned long val = *(unsigned long *) value;
        DBG_ENTER("mysqlnd_stmt::attr_set");
        if (!stmt) {
                DBG_RETURN(FAIL);
        }
-       DBG_INF_FMT("stmt=%lu attr_type=%u value=%lu", stmt->stmt_id, attr_type, val);
+       DBG_INF_FMT("stmt=%lu attr_type=%u", stmt->stmt_id, attr_type);
 
        switch (attr_type) {
-               case STMT_ATTR_UPDATE_MAX_LENGTH:
+               case STMT_ATTR_UPDATE_MAX_LENGTH:{
+                       zend_uchar bval = *(zend_uchar *) value;
                        /*
                          XXX : libmysql uses my_bool, but mysqli uses ulong as storage on the stack
                          and mysqlnd won't be used out of the scope of PHP -> use ulong.
                        */
-                       stmt->update_max_length = val? TRUE:FALSE;
+                       stmt->update_max_length = bval? TRUE:FALSE;
                        break;
+               }
                case STMT_ATTR_CURSOR_TYPE: {
-                       if (val > (unsigned long) CURSOR_TYPE_READ_ONLY) {
+                       unsigned int ival = *(unsigned int *) value;
+                       if (ival > (unsigned long) CURSOR_TYPE_READ_ONLY) {
                                SET_STMT_ERROR(stmt, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented");
                                DBG_INF("FAIL");
                                DBG_RETURN(FAIL);
                        }
-                       stmt->flags = val;
+                       stmt->flags = ival;
                        break;
                }
                case STMT_ATTR_PREFETCH_ROWS: {
-                       if (val == 0) {
-                               val = MYSQLND_DEFAULT_PREFETCH_ROWS;
-                       } else if (val > 1) {
+                       unsigned int ival = *(unsigned int *) value;
+                       if (ival == 0) {
+                               ival = MYSQLND_DEFAULT_PREFETCH_ROWS;
+                       } else if (ival > 1) {
                                SET_STMT_ERROR(stmt, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented");
                                DBG_INF("FAIL");
                                DBG_RETURN(FAIL);
                        }
-                       stmt->prefetch_rows = val;
+                       stmt->prefetch_rows = ival;
                        break;
                }
                default: