andrey                                   Wed, 06 Oct 2010 11:11:02 +0000

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

Log:
Fix for Bug #52686      mysql_stmt_attr_[gs]et arg. points to incorrect type

Bug: http://bugs.php.net/52686 (Assigned) mysql_stmt_attr_[gs]et arg. points to 
incorrect type
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_api.c
    U   php/php-src/branches/PHP_5_3/ext/mysqli/tests/mysqli_stmt_attr_set.phpt
    U   php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c
    U   php/php-src/trunk/ext/mysqli/mysqli_api.c
    U   php/php-src/trunk/ext/mysqli/tests/mysqli_stmt_attr_set.phpt
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c

Modified: php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_api.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_api.c	2010-10-06 11:07:15 UTC (rev 304145)
+++ php/php-src/branches/PHP_5_3/ext/mysqli/mysqli_api.c	2010-10-06 11:11:02 UTC (rev 304146)
@@ -380,11 +380,11 @@
 			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 @@
 	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 @@
 		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 @@
 {
 	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 @@
 	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 @@
 				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;
 			}

Modified: php/php-src/branches/PHP_5_3/ext/mysqli/tests/mysqli_stmt_attr_set.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqli/tests/mysqli_stmt_attr_set.phpt	2010-10-06 11:07:15 UTC (rev 304145)
+++ php/php-src/branches/PHP_5_3/ext/mysqli/tests/mysqli_stmt_attr_set.phpt	2010-10-06 11:11:02 UTC (rev 304146)
@@ -92,6 +92,9 @@
 	$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 @@
 	$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();

Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c	2010-10-06 11:07:15 UTC (rev 304145)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c	2010-10-06 11:11:02 UTC (rev 304146)
@@ -1827,39 +1827,42 @@
 									   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:

Modified: php/php-src/trunk/ext/mysqli/mysqli_api.c
===================================================================
--- php/php-src/trunk/ext/mysqli/mysqli_api.c	2010-10-06 11:07:15 UTC (rev 304145)
+++ php/php-src/trunk/ext/mysqli/mysqli_api.c	2010-10-06 11:11:02 UTC (rev 304146)
@@ -380,11 +380,11 @@
 			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 @@
 	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 @@
 		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 @@
 {
 	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 @@
 	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 @@
 				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;
 			}

Modified: php/php-src/trunk/ext/mysqli/tests/mysqli_stmt_attr_set.phpt
===================================================================
--- php/php-src/trunk/ext/mysqli/tests/mysqli_stmt_attr_set.phpt	2010-10-06 11:07:15 UTC (rev 304145)
+++ php/php-src/trunk/ext/mysqli/tests/mysqli_stmt_attr_set.phpt	2010-10-06 11:11:02 UTC (rev 304146)
@@ -92,6 +92,9 @@
 	$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 @@
 	$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();

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c	2010-10-06 11:07:15 UTC (rev 304145)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c	2010-10-06 11:11:02 UTC (rev 304146)
@@ -1827,39 +1827,42 @@
 									   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:
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to