andrey                                   Tue, 25 May 2010 23:18:13 +0000

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

Log:
Handle the situation when MYSQLND_PROTOCOL's methods return NULL.
mysqlnd should not crash but gracefully return with an error.

Changed paths:
    U   php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c
    U   php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c
    U   php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c
    U   php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result_meta.c
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd.c
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd_result_meta.c

Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c	2010-05-25 22:55:10 UTC (rev 299764)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd.c	2010-05-25 23:18:13 UTC (rev 299765)
@@ -225,7 +225,7 @@
 															 zend_bool silent, enum php_mysqlnd_server_command command,
 															 zend_bool ignore_upsert_status TSRMLS_DC)
 {
-	enum_func_status ret;
+	enum_func_status ret = FAIL;

 	DBG_ENTER("mysqlnd_conn::simple_command_handle_response");
 	DBG_INF_FMT("silent=%d packet=%d command=%s", silent, ok_packet, mysqlnd_command_to_text[command]);
@@ -233,6 +233,10 @@
 	switch (ok_packet) {
 		case PROT_OK_PACKET:{
 			MYSQLND_PACKET_OK * ok_response = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
+			if (!ok_response) {
+				SET_OOM_ERROR(conn->error_info);
+				break;
+			}
 			if (FAIL == (ret = PACKET_READ(ok_response, conn))) {
 				if (!silent) {
 					DBG_ERR_FMT("Error while reading %s's OK packet", mysqlnd_command_to_text[command]);
@@ -274,6 +278,10 @@
 		}
 		case PROT_EOF_PACKET:{
 			MYSQLND_PACKET_EOF * ok_response = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC);
+			if (!ok_response) {
+				SET_OOM_ERROR(conn->error_info);
+				break;
+			}
 			if (FAIL == (ret = PACKET_READ(ok_response, conn))) {
 				SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE,
 								 "Malformed packet");
@@ -300,7 +308,6 @@
 			break;
 		}
 		default:
-			ret = FAIL;
 			SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
 			php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong response packet %d passed to the function", ok_packet);
 			break;
@@ -344,6 +351,11 @@
 	SET_EMPTY_ERROR(conn->error_info);

 	cmd_packet = conn->protocol->m.get_command_packet(conn->protocol, FALSE TSRMLS_CC);
+	if (!cmd_packet) {
+		SET_OOM_ERROR(conn->error_info);
+		DBG_RETURN(FAIL);
+	}
+
 	cmd_packet->command = command;
 	if (arg && arg_len) {
 		cmd_packet->argument = arg;
@@ -526,6 +538,7 @@
 			transport_len = spprintf(&transport, 0, "tcp://%s:%d", host, port);
 		}
 		if (!transport) {
+			SET_OOM_ERROR(conn->error_info);
 			goto err; /* OOM */
 		}
 		DBG_INF_FMT("transport=%s", transport);
@@ -542,6 +555,7 @@
 	auth_packet = conn->protocol->m.get_auth_packet(conn->protocol, FALSE TSRMLS_CC);
 	ok_packet = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
 	if (!greet_packet || !auth_packet || !ok_packet) {
+		SET_OOM_ERROR(conn->error_info);
 		goto err; /* OOM */
 	}

@@ -613,6 +627,7 @@

 	conn->scramble = auth_packet->server_scramble_buf = mnd_pemalloc(SCRAMBLE_LENGTH, conn->persistent);
 	if (!conn->scramble) {
+		SET_OOM_ERROR(conn->error_info);
 		goto err; /* OOM */
 	}
 	memcpy(auth_packet->server_scramble_buf, greet_packet->scramble_buf, SCRAMBLE_LENGTH);
@@ -682,12 +697,14 @@
 		conn->connect_or_select_db_len = db_len;

 		if (!conn->user || !conn->passwd || !conn->connect_or_select_db) {
+			SET_OOM_ERROR(conn->error_info);
 			goto err; /* OOM */
 		}

 		if (!unix_socket) {
 			conn->host = mnd_pestrdup(host, conn->persistent);
 			if (!conn->host) {
+				SET_OOM_ERROR(conn->error_info);
 				goto err; /* OOM */
 			}
 			conn->host_len = strlen(conn->host);
@@ -695,11 +712,13 @@
 				char *p;
 				spprintf(&p, 0, "%s via TCP/IP", conn->host);
 				if (!p) {
+					SET_OOM_ERROR(conn->error_info);
 					goto err; /* OOM */
 				}
 				conn->host_info =  mnd_pestrdup(p, conn->persistent);
 				efree(p); /* allocated by spprintf */
 				if (!conn->host_info) {
+					SET_OOM_ERROR(conn->error_info);
 					goto err; /* OOM */
 				}
 			}
@@ -707,6 +726,7 @@
 			conn->unix_socket	= mnd_pestrdup(socket, conn->persistent);
 			conn->host_info		= mnd_pestrdup("Localhost via UNIX socket", conn->persistent);
 			if (!conn->unix_socket || !conn->host_info) {
+				SET_OOM_ERROR(conn->error_info);
 				goto err; /* OOM */
 			}
 			conn->unix_socket_len = strlen(conn->unix_socket);
@@ -1333,6 +1353,11 @@
 		DBG_RETURN(FAIL);
 	}
 	stats_header = conn->protocol->m.get_stats_packet(conn->protocol, FALSE TSRMLS_CC);
+	if (!stats_header) {
+		SET_OOM_ERROR(conn->error_info);
+		DBG_RETURN(FAIL);
+	}
+
 	if (FAIL == (ret = PACKET_READ(stats_header, conn))) {
 		DBG_RETURN(FAIL);
 	}
@@ -1829,7 +1854,7 @@
 	  buffer overflows.
 	*/
 	size_t user_len;
-	enum_func_status ret;
+	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 *p = buffer;
@@ -1838,6 +1863,8 @@
 	DBG_INF_FMT("conn=%llu user=%s passwd=%s db=%s silent=%d",
 				conn->thread_id, user?user:"", passwd?"***":"null", db?db:"", (silent == TRUE)?1:0 );

+	SET_ERROR_AFF_ROWS(conn);
+
 	if (!user) {
 		user = "";
 	}
@@ -1878,6 +1905,10 @@
 	}

 	chg_user_resp = conn->protocol->m.get_change_user_response_packet(conn->protocol, FALSE TSRMLS_CC);
+	if (!chg_user_resp) {
+		SET_OOM_ERROR(conn->error_info);
+		goto end;
+	}
 	ret = PACKET_READ(chg_user_resp, conn);
 	conn->error_info = chg_user_resp->error_info;

@@ -1888,13 +1919,15 @@
 		  bug#25371 mysql_change_user() triggers "packets out of sync"
 		  When it gets fixed, there should be one more check here
 		*/
-		if (mysqlnd_get_server_version(conn) > 50113L &&
-			mysqlnd_get_server_version(conn) < 50118L)
-		{
+		if (mysqlnd_get_server_version(conn) > 50113L && mysqlnd_get_server_version(conn) < 50118L) {
 			MYSQLND_PACKET_OK * redundant_error_packet = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
-			PACKET_READ(redundant_error_packet, conn);
-			PACKET_FREE(redundant_error_packet);
-			DBG_INF_FMT("Server is %d, buggy, sends two ERR messages", mysqlnd_get_server_version(conn));
+			if (redundant_error_packet) {
+				PACKET_READ(redundant_error_packet, conn);
+				PACKET_FREE(redundant_error_packet);
+				DBG_INF_FMT("Server is %d, buggy, sends two ERR messages", mysqlnd_get_server_version(conn));
+			} else {
+				SET_OOM_ERROR(conn->error_info);
+			}
 		}
 	}
 	if (ret == PASS) {
@@ -1919,10 +1952,9 @@
 		DBG_ERR(mysqlnd_old_passwd);
 		SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
 	}
+end:
 	PACKET_FREE(chg_user_resp);

-	SET_ERROR_AFF_ROWS(conn);
-
 	/*
 	  Here we should close all statements. Unbuffered queries should not be a
 	  problem as we won't allow sending COM_CHANGE_USER.

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-05-25 22:55:10 UTC (rev 299764)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c	2010-05-25 23:18:13 UTC (rev 299765)
@@ -243,7 +243,10 @@
 	DBG_INF_FMT("stmt=%lu", stmt->stmt_id);

 	field_packet = stmt->conn->protocol->m.get_result_field_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
-	if (field_packet) {
+	if (!field_packet) {
+		SET_OOM_ERROR(stmt->error_info);
+		SET_OOM_ERROR(stmt->conn->error_info);
+	} else {
 		ret = PASS;
 		field_packet->skip_parsing = TRUE;
 		for (;i < stmt->param_count; i++) {
@@ -266,23 +269,27 @@
 {
 	MYSQLND_STMT_DATA * stmt = s->data;
 	MYSQLND_PACKET_PREPARE_RESPONSE * prepare_resp;
-	enum_func_status ret = PASS;
+	enum_func_status ret = FAIL;

 	DBG_ENTER("mysqlnd_stmt_read_prepare_response");
 	DBG_INF_FMT("stmt=%lu", stmt->stmt_id);

 	prepare_resp = stmt->conn->protocol->m.get_prepare_response_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
+	if (!prepare_resp) {
+		SET_OOM_ERROR(stmt->error_info);
+		SET_OOM_ERROR(stmt->conn->error_info);
+		goto done;
+	}
+
 	if (FAIL == PACKET_READ(prepare_resp, stmt->conn)) {
-		ret = FAIL;
 		goto done;
 	}

 	if (0xFF == prepare_resp->error_code) {
 		stmt->error_info = stmt->conn->error_info = prepare_resp->error_info;
-		ret = FAIL;
 		goto done;
 	}
-
+	ret = PASS;
 	stmt->stmt_id = prepare_resp->stmt_id;
 	stmt->warning_count = stmt->conn->upsert_status.warning_count = prepare_resp->warning_count;
 	stmt->field_count = stmt->conn->field_count = prepare_resp->field_count;
@@ -307,19 +314,24 @@
 	DBG_INF_FMT("stmt=%lu", stmt->stmt_id);

 	fields_eof = stmt->conn->protocol->m.get_eof_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
-	if (FAIL == (ret = PACKET_READ(fields_eof, stmt->conn))) {
-		if (stmt->result) {
-			stmt->result->m.free_result_contents(stmt->result TSRMLS_CC);
-			mnd_efree(stmt->result);
-			memset(stmt, 0, sizeof(MYSQLND_STMT_DATA));
-			stmt->state = MYSQLND_STMT_INITTED;
+	if (!fields_eof) {
+		SET_OOM_ERROR(stmt->error_info);
+		SET_OOM_ERROR(stmt->conn->error_info);
+	} else {
+		if (FAIL == (ret = PACKET_READ(fields_eof, stmt->conn))) {
+			if (stmt->result) {
+				stmt->result->m.free_result_contents(stmt->result TSRMLS_CC);
+				mnd_efree(stmt->result);
+				memset(stmt, 0, sizeof(MYSQLND_STMT_DATA));
+				stmt->state = MYSQLND_STMT_INITTED;
+			}
+		} else {
+			stmt->upsert_status.server_status = fields_eof->server_status;
+			stmt->upsert_status.warning_count = fields_eof->warning_count;
+			stmt->state = MYSQLND_STMT_PREPARED;
 		}
-	} else {
-		stmt->upsert_status.server_status = fields_eof->server_status;
-		stmt->upsert_status.warning_count = fields_eof->warning_count;
-		stmt->state = MYSQLND_STMT_PREPARED;
+		PACKET_FREE(fields_eof);
 	}
-	PACKET_FREE(fields_eof);

 	DBG_RETURN(ret);
 }

Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c	2010-05-25 22:55:10 UTC (rev 299764)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c	2010-05-25 23:18:13 UTC (rev 299765)
@@ -493,6 +493,11 @@

 				/* Check for SERVER_STATUS_MORE_RESULTS if needed */
 				fields_eof = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC);
+				if (!fields_eof) {
+					SET_OOM_ERROR(conn->error_info);
+					ret = FAIL;
+					break;
+				}
 				if (FAIL == (ret = PACKET_READ(fields_eof, conn))) {
 					DBG_ERR("Error ocurred while reading the EOF packet");
 					result->m.free_result_contents(result TSRMLS_CC);

Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result_meta.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result_meta.c	2010-05-25 22:55:10 UTC (rev 299764)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result_meta.c	2010-05-25 23:18:13 UTC (rev 299765)
@@ -151,6 +151,7 @@

 	field_packet = conn->protocol->m.get_result_field_packet(conn->protocol, FALSE TSRMLS_CC);
 	if (!field_packet) {
+		SET_OOM_ERROR(conn->error_info);
 		DBG_RETURN(FAIL);
 	}
 	field_packet->persistent_alloc = meta->persistent;

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd.c	2010-05-25 22:55:10 UTC (rev 299764)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd.c	2010-05-25 23:18:13 UTC (rev 299765)
@@ -225,7 +225,7 @@
 															 zend_bool silent, enum php_mysqlnd_server_command command,
 															 zend_bool ignore_upsert_status TSRMLS_DC)
 {
-	enum_func_status ret;
+	enum_func_status ret = FAIL;

 	DBG_ENTER("mysqlnd_conn::simple_command_handle_response");
 	DBG_INF_FMT("silent=%d packet=%d command=%s", silent, ok_packet, mysqlnd_command_to_text[command]);
@@ -233,6 +233,10 @@
 	switch (ok_packet) {
 		case PROT_OK_PACKET:{
 			MYSQLND_PACKET_OK * ok_response = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
+			if (!ok_response) {
+				SET_OOM_ERROR(conn->error_info);
+				break;
+			}
 			if (FAIL == (ret = PACKET_READ(ok_response, conn))) {
 				if (!silent) {
 					DBG_ERR_FMT("Error while reading %s's OK packet", mysqlnd_command_to_text[command]);
@@ -274,6 +278,10 @@
 		}
 		case PROT_EOF_PACKET:{
 			MYSQLND_PACKET_EOF * ok_response = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC);
+			if (!ok_response) {
+				SET_OOM_ERROR(conn->error_info);
+				break;
+			}
 			if (FAIL == (ret = PACKET_READ(ok_response, conn))) {
 				SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE,
 								 "Malformed packet");
@@ -300,7 +308,6 @@
 			break;
 		}
 		default:
-			ret = FAIL;
 			SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
 			php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong response packet %d passed to the function", ok_packet);
 			break;
@@ -344,6 +351,11 @@
 	SET_EMPTY_ERROR(conn->error_info);

 	cmd_packet = conn->protocol->m.get_command_packet(conn->protocol, FALSE TSRMLS_CC);
+	if (!cmd_packet) {
+		SET_OOM_ERROR(conn->error_info);
+		DBG_RETURN(FAIL);
+	}
+
 	cmd_packet->command = command;
 	if (arg && arg_len) {
 		cmd_packet->argument = arg;
@@ -526,6 +538,7 @@
 			transport_len = spprintf(&transport, 0, "tcp://%s:%d", host, port);
 		}
 		if (!transport) {
+			SET_OOM_ERROR(conn->error_info);
 			goto err; /* OOM */
 		}
 		DBG_INF_FMT("transport=%s", transport);
@@ -542,6 +555,7 @@
 	auth_packet = conn->protocol->m.get_auth_packet(conn->protocol, FALSE TSRMLS_CC);
 	ok_packet = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
 	if (!greet_packet || !auth_packet || !ok_packet) {
+		SET_OOM_ERROR(conn->error_info);
 		goto err; /* OOM */
 	}

@@ -613,6 +627,7 @@

 	conn->scramble = auth_packet->server_scramble_buf = mnd_pemalloc(SCRAMBLE_LENGTH, conn->persistent);
 	if (!conn->scramble) {
+		SET_OOM_ERROR(conn->error_info);
 		goto err; /* OOM */
 	}
 	memcpy(auth_packet->server_scramble_buf, greet_packet->scramble_buf, SCRAMBLE_LENGTH);
@@ -682,12 +697,14 @@
 		conn->connect_or_select_db_len = db_len;

 		if (!conn->user || !conn->passwd || !conn->connect_or_select_db) {
+			SET_OOM_ERROR(conn->error_info);
 			goto err; /* OOM */
 		}

 		if (!unix_socket) {
 			conn->host = mnd_pestrdup(host, conn->persistent);
 			if (!conn->host) {
+				SET_OOM_ERROR(conn->error_info);
 				goto err; /* OOM */
 			}
 			conn->host_len = strlen(conn->host);
@@ -695,11 +712,13 @@
 				char *p;
 				spprintf(&p, 0, "%s via TCP/IP", conn->host);
 				if (!p) {
+					SET_OOM_ERROR(conn->error_info);
 					goto err; /* OOM */
 				}
 				conn->host_info =  mnd_pestrdup(p, conn->persistent);
 				efree(p); /* allocated by spprintf */
 				if (!conn->host_info) {
+					SET_OOM_ERROR(conn->error_info);
 					goto err; /* OOM */
 				}
 			}
@@ -707,6 +726,7 @@
 			conn->unix_socket	= mnd_pestrdup(socket, conn->persistent);
 			conn->host_info		= mnd_pestrdup("Localhost via UNIX socket", conn->persistent);
 			if (!conn->unix_socket || !conn->host_info) {
+				SET_OOM_ERROR(conn->error_info);
 				goto err; /* OOM */
 			}
 			conn->unix_socket_len = strlen(conn->unix_socket);
@@ -1333,6 +1353,11 @@
 		DBG_RETURN(FAIL);
 	}
 	stats_header = conn->protocol->m.get_stats_packet(conn->protocol, FALSE TSRMLS_CC);
+	if (!stats_header) {
+		SET_OOM_ERROR(conn->error_info);
+		DBG_RETURN(FAIL);
+	}
+
 	if (FAIL == (ret = PACKET_READ(stats_header, conn))) {
 		DBG_RETURN(FAIL);
 	}
@@ -1829,7 +1854,7 @@
 	  buffer overflows.
 	*/
 	size_t user_len;
-	enum_func_status ret;
+	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 *p = buffer;
@@ -1838,6 +1863,8 @@
 	DBG_INF_FMT("conn=%llu user=%s passwd=%s db=%s silent=%d",
 				conn->thread_id, user?user:"", passwd?"***":"null", db?db:"", (silent == TRUE)?1:0 );

+	SET_ERROR_AFF_ROWS(conn);
+
 	if (!user) {
 		user = "";
 	}
@@ -1878,6 +1905,10 @@
 	}

 	chg_user_resp = conn->protocol->m.get_change_user_response_packet(conn->protocol, FALSE TSRMLS_CC);
+	if (!chg_user_resp) {
+		SET_OOM_ERROR(conn->error_info);
+		goto end;
+	}
 	ret = PACKET_READ(chg_user_resp, conn);
 	conn->error_info = chg_user_resp->error_info;

@@ -1888,13 +1919,15 @@
 		  bug#25371 mysql_change_user() triggers "packets out of sync"
 		  When it gets fixed, there should be one more check here
 		*/
-		if (mysqlnd_get_server_version(conn) > 50113L &&
-			mysqlnd_get_server_version(conn) < 50118L)
-		{
+		if (mysqlnd_get_server_version(conn) > 50113L && mysqlnd_get_server_version(conn) < 50118L) {
 			MYSQLND_PACKET_OK * redundant_error_packet = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
-			PACKET_READ(redundant_error_packet, conn);
-			PACKET_FREE(redundant_error_packet);
-			DBG_INF_FMT("Server is %d, buggy, sends two ERR messages", mysqlnd_get_server_version(conn));
+			if (redundant_error_packet) {
+				PACKET_READ(redundant_error_packet, conn);
+				PACKET_FREE(redundant_error_packet);
+				DBG_INF_FMT("Server is %d, buggy, sends two ERR messages", mysqlnd_get_server_version(conn));
+			} else {
+				SET_OOM_ERROR(conn->error_info);
+			}
 		}
 	}
 	if (ret == PASS) {
@@ -1919,10 +1952,9 @@
 		DBG_ERR(mysqlnd_old_passwd);
 		SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
 	}
+end:
 	PACKET_FREE(chg_user_resp);

-	SET_ERROR_AFF_ROWS(conn);
-
 	/*
 	  Here we should close all statements. Unbuffered queries should not be a
 	  problem as we won't allow sending COM_CHANGE_USER.

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c	2010-05-25 22:55:10 UTC (rev 299764)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c	2010-05-25 23:18:13 UTC (rev 299765)
@@ -243,7 +243,10 @@
 	DBG_INF_FMT("stmt=%lu", stmt->stmt_id);

 	field_packet = stmt->conn->protocol->m.get_result_field_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
-	if (field_packet) {
+	if (!field_packet) {
+		SET_OOM_ERROR(stmt->error_info);
+		SET_OOM_ERROR(stmt->conn->error_info);
+	} else {
 		ret = PASS;
 		field_packet->skip_parsing = TRUE;
 		for (;i < stmt->param_count; i++) {
@@ -266,23 +269,27 @@
 {
 	MYSQLND_STMT_DATA * stmt = s->data;
 	MYSQLND_PACKET_PREPARE_RESPONSE * prepare_resp;
-	enum_func_status ret = PASS;
+	enum_func_status ret = FAIL;

 	DBG_ENTER("mysqlnd_stmt_read_prepare_response");
 	DBG_INF_FMT("stmt=%lu", stmt->stmt_id);

 	prepare_resp = stmt->conn->protocol->m.get_prepare_response_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
+	if (!prepare_resp) {
+		SET_OOM_ERROR(stmt->error_info);
+		SET_OOM_ERROR(stmt->conn->error_info);
+		goto done;
+	}
+
 	if (FAIL == PACKET_READ(prepare_resp, stmt->conn)) {
-		ret = FAIL;
 		goto done;
 	}

 	if (0xFF == prepare_resp->error_code) {
 		stmt->error_info = stmt->conn->error_info = prepare_resp->error_info;
-		ret = FAIL;
 		goto done;
 	}
-
+	ret = PASS;
 	stmt->stmt_id = prepare_resp->stmt_id;
 	stmt->warning_count = stmt->conn->upsert_status.warning_count = prepare_resp->warning_count;
 	stmt->field_count = stmt->conn->field_count = prepare_resp->field_count;
@@ -307,19 +314,24 @@
 	DBG_INF_FMT("stmt=%lu", stmt->stmt_id);

 	fields_eof = stmt->conn->protocol->m.get_eof_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
-	if (FAIL == (ret = PACKET_READ(fields_eof, stmt->conn))) {
-		if (stmt->result) {
-			stmt->result->m.free_result_contents(stmt->result TSRMLS_CC);
-			mnd_efree(stmt->result);
-			memset(stmt, 0, sizeof(MYSQLND_STMT_DATA));
-			stmt->state = MYSQLND_STMT_INITTED;
+	if (!fields_eof) {
+		SET_OOM_ERROR(stmt->error_info);
+		SET_OOM_ERROR(stmt->conn->error_info);
+	} else {
+		if (FAIL == (ret = PACKET_READ(fields_eof, stmt->conn))) {
+			if (stmt->result) {
+				stmt->result->m.free_result_contents(stmt->result TSRMLS_CC);
+				mnd_efree(stmt->result);
+				memset(stmt, 0, sizeof(MYSQLND_STMT_DATA));
+				stmt->state = MYSQLND_STMT_INITTED;
+			}
+		} else {
+			stmt->upsert_status.server_status = fields_eof->server_status;
+			stmt->upsert_status.warning_count = fields_eof->warning_count;
+			stmt->state = MYSQLND_STMT_PREPARED;
 		}
-	} else {
-		stmt->upsert_status.server_status = fields_eof->server_status;
-		stmt->upsert_status.warning_count = fields_eof->warning_count;
-		stmt->state = MYSQLND_STMT_PREPARED;
+		PACKET_FREE(fields_eof);
 	}
-	PACKET_FREE(fields_eof);

 	DBG_RETURN(ret);
 }

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c	2010-05-25 22:55:10 UTC (rev 299764)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c	2010-05-25 23:18:13 UTC (rev 299765)
@@ -493,6 +493,11 @@

 				/* Check for SERVER_STATUS_MORE_RESULTS if needed */
 				fields_eof = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC);
+				if (!fields_eof) {
+					SET_OOM_ERROR(conn->error_info);
+					ret = FAIL;
+					break;
+				}
 				if (FAIL == (ret = PACKET_READ(fields_eof, conn))) {
 					DBG_ERR("Error ocurred while reading the EOF packet");
 					result->m.free_result_contents(result TSRMLS_CC);

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_result_meta.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_result_meta.c	2010-05-25 22:55:10 UTC (rev 299764)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_result_meta.c	2010-05-25 23:18:13 UTC (rev 299765)
@@ -151,6 +151,7 @@

 	field_packet = conn->protocol->m.get_result_field_packet(conn->protocol, FALSE TSRMLS_CC);
 	if (!field_packet) {
+		SET_OOM_ERROR(conn->error_info);
 		DBG_RETURN(FAIL);
 	}
 	field_packet->persistent_alloc = meta->persistent;
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to