andrey                                   Mon, 03 May 2010 18:50:47 +0000

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

Log:
Handle OOM stemming from mysqlnd_result_init in the same
function and up the stack.

Changed paths:
    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/trunk/ext/mysqlnd/mysqlnd_ps.c
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c

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-03 17:47:58 UTC (rev 298919)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_ps.c	2010-05-03 18:50:47 UTC (rev 298920)
@@ -156,20 +156,35 @@
 	SET_EMPTY_ERROR(stmt->conn->error_info);
 	MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS);

-	result = mysqlnd_result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
+	do {
+		result = mysqlnd_result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
+		if (!result) {
+			SET_OOM_ERROR(stmt->conn->error_info);
+			break;
+		}

-	result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+		result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+		if (!result->meta) {
+			SET_OOM_ERROR(stmt->conn->error_info);
+			break;
+		}

-	if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
-		stmt->upsert_status.affected_rows = result->stored_data->row_count;
-		stmt->state = MYSQLND_STMT_PREPARED;
-		result->type = MYSQLND_RES_PS_BUF;
-	} else {
-		stmt->error_info = conn->error_info;
-		stmt->state = MYSQLND_STMT_PREPARED;
+		if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
+			stmt->upsert_status.affected_rows = result->stored_data->row_count;
+			stmt->state = MYSQLND_STMT_PREPARED;
+			result->type = MYSQLND_RES_PS_BUF;
+		} else {
+			stmt->error_info = conn->error_info;
+			stmt->state = MYSQLND_STMT_PREPARED;
+			break;
+		}
+		DBG_RETURN(result);
+	} while (0);
+
+	if (result) {
+		result->m.free_result(result, TRUE TSRMLS_CC);
 	}
-
-	DBG_RETURN(result);
+	DBG_RETURN(NULL);
 }
 /* }}} */

@@ -366,6 +381,10 @@
 	*/
 	if (stmt_to_prepare->field_count) {
 		MYSQLND_RES * result = mysqlnd_result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent TSRMLS_CC);
+		if (!result) {
+			SET_OOM_ERROR(stmt->conn->error_info);
+			goto fail;
+		}
 		/* Allocate the result now as it is needed for the reading of metadata */
 		stmt_to_prepare->result = result;

@@ -374,7 +393,8 @@
 		result->type = MYSQLND_RES_PS_BUF;

 		if (FAIL == result->m.read_result_metadata(result, stmt_to_prepare->conn TSRMLS_CC) ||
-			FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC)) {
+			FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC))
+		{
 			goto fail;
 		}
 	}
@@ -1655,15 +1675,32 @@
 	  In the meantime we don't need a zval cache reference for this fake
 	  result set, so we don't get one.
 	*/
-	result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
-	result->type = MYSQLND_RES_NORMAL;
-	result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
-	result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
-	result->unbuf->eof_reached = TRUE;
-	result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+	do {
+		result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
+		if (!result) {
+			break;
+		}
+		result->type = MYSQLND_RES_NORMAL;
+		result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
+		result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
+		if (!result->unbuf) {
+			break;
+		}
+		result->unbuf->eof_reached = TRUE;
+		result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+		if (!result->meta) {
+			break;
+		}

-	DBG_INF_FMT("result=%p", result);
-	DBG_RETURN(result);
+		DBG_INF_FMT("result=%p", result);
+		DBG_RETURN(result);
+	} while (0);
+
+	SET_OOM_ERROR(stmt->conn->error_info);
+	if (result) {
+		result->m.free_result(result, TRUE TSRMLS_CC);
+	}
+	DBG_RETURN(NULL);
 }
 /* }}} */


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-03 17:47:58 UTC (rev 298919)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c	2010-05-03 18:50:47 UTC (rev 298920)
@@ -353,6 +353,7 @@
 	MYSQLND_STMT_DATA * stmt = s ? s->data:NULL;
 	enum_func_status ret;
 	MYSQLND_PACKET_RSET_HEADER * rset_header;
+	MYSQLND_PACKET_EOF * fields_eof;

 	DBG_ENTER("mysqlnd_query_read_result_set_header");
 	DBG_INF_FMT("stmt=%d", stmt? stmt->stmt_id:0);
@@ -420,8 +421,7 @@
 				ret = PASS;
 				MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_NON_RSET_QUERY);
 				break;
-			default:{			/* Result set */
-				MYSQLND_PACKET_EOF * fields_eof;
+			default: do {			/* Result set */
 				MYSQLND_RES * result;
 				enum_mysqlnd_collected_stats stat = STAT_LAST;

@@ -464,7 +464,12 @@
 					}
 					result = stmt->result;
 				}
-
+				if (!result) {
+					SET_OOM_ERROR(conn->error_info);
+					ret = FAIL;
+					break;
+				}
+
 				if (FAIL == (ret = result->m.read_result_metadata(result, conn TSRMLS_CC))) {
 					/* For PS, we leave them in Prepared state */
 					if (!stmt && conn->current_result) {
@@ -517,11 +522,9 @@
 					}
 					MYSQLND_INC_CONN_STATISTIC(conn->stats, stat);
 				}
-
-				PACKET_FREE(fields_eof);
-
-				break;
-			}
+			} while (0);
+			PACKET_FREE(fields_eof);
+			break; /* switch break */
 		}
 	} while (0);
 	PACKET_FREE(rset_header);
@@ -1546,6 +1549,10 @@

 	DBG_ENTER("mysqlnd_result_init");
 	DBG_INF_FMT("field_count=%u", field_count);
+
+	if (!ret) {
+		DBG_RETURN(NULL);
+	}

 	ret->persistent		= persistent;
 	ret->field_count	= field_count;

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c	2010-05-03 17:47:58 UTC (rev 298919)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_ps.c	2010-05-03 18:50:47 UTC (rev 298920)
@@ -156,20 +156,35 @@
 	SET_EMPTY_ERROR(stmt->conn->error_info);
 	MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS);

-	result = mysqlnd_result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
+	do {
+		result = mysqlnd_result_init(stmt->result->field_count, stmt->persistent TSRMLS_CC);
+		if (!result) {
+			SET_OOM_ERROR(stmt->conn->error_info);
+			break;
+		}

-	result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+		result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+		if (!result->meta) {
+			SET_OOM_ERROR(stmt->conn->error_info);
+			break;
+		}

-	if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
-		stmt->upsert_status.affected_rows = result->stored_data->row_count;
-		stmt->state = MYSQLND_STMT_PREPARED;
-		result->type = MYSQLND_RES_PS_BUF;
-	} else {
-		stmt->error_info = conn->error_info;
-		stmt->state = MYSQLND_STMT_PREPARED;
+		if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
+			stmt->upsert_status.affected_rows = result->stored_data->row_count;
+			stmt->state = MYSQLND_STMT_PREPARED;
+			result->type = MYSQLND_RES_PS_BUF;
+		} else {
+			stmt->error_info = conn->error_info;
+			stmt->state = MYSQLND_STMT_PREPARED;
+			break;
+		}
+		DBG_RETURN(result);
+	} while (0);
+
+	if (result) {
+		result->m.free_result(result, TRUE TSRMLS_CC);
 	}
-
-	DBG_RETURN(result);
+	DBG_RETURN(NULL);
 }
 /* }}} */

@@ -366,6 +381,10 @@
 	*/
 	if (stmt_to_prepare->field_count) {
 		MYSQLND_RES * result = mysqlnd_result_init(stmt_to_prepare->field_count, stmt_to_prepare->persistent TSRMLS_CC);
+		if (!result) {
+			SET_OOM_ERROR(stmt->conn->error_info);
+			goto fail;
+		}
 		/* Allocate the result now as it is needed for the reading of metadata */
 		stmt_to_prepare->result = result;

@@ -374,7 +393,8 @@
 		result->type = MYSQLND_RES_PS_BUF;

 		if (FAIL == result->m.read_result_metadata(result, stmt_to_prepare->conn TSRMLS_CC) ||
-			FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC)) {
+			FAIL == mysqlnd_stmt_prepare_read_eof(s_to_prepare TSRMLS_CC))
+		{
 			goto fail;
 		}
 	}
@@ -1655,15 +1675,32 @@
 	  In the meantime we don't need a zval cache reference for this fake
 	  result set, so we don't get one.
 	*/
-	result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
-	result->type = MYSQLND_RES_NORMAL;
-	result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
-	result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
-	result->unbuf->eof_reached = TRUE;
-	result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+	do {
+		result = mysqlnd_result_init(stmt->field_count, stmt->persistent TSRMLS_CC);
+		if (!result) {
+			break;
+		}
+		result->type = MYSQLND_RES_NORMAL;
+		result->m.fetch_row = result->m.fetch_row_normal_unbuffered;
+		result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));
+		if (!result->unbuf) {
+			break;
+		}
+		result->unbuf->eof_reached = TRUE;
+		result->meta = stmt->result->meta->m->clone_metadata(stmt->result->meta, FALSE TSRMLS_CC);
+		if (!result->meta) {
+			break;
+		}

-	DBG_INF_FMT("result=%p", result);
-	DBG_RETURN(result);
+		DBG_INF_FMT("result=%p", result);
+		DBG_RETURN(result);
+	} while (0);
+
+	SET_OOM_ERROR(stmt->conn->error_info);
+	if (result) {
+		result->m.free_result(result, TRUE TSRMLS_CC);
+	}
+	DBG_RETURN(NULL);
 }
 /* }}} */


Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c	2010-05-03 17:47:58 UTC (rev 298919)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c	2010-05-03 18:50:47 UTC (rev 298920)
@@ -353,6 +353,7 @@
 	MYSQLND_STMT_DATA * stmt = s ? s->data:NULL;
 	enum_func_status ret;
 	MYSQLND_PACKET_RSET_HEADER * rset_header;
+	MYSQLND_PACKET_EOF * fields_eof;

 	DBG_ENTER("mysqlnd_query_read_result_set_header");
 	DBG_INF_FMT("stmt=%d", stmt? stmt->stmt_id:0);
@@ -420,8 +421,7 @@
 				ret = PASS;
 				MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_NON_RSET_QUERY);
 				break;
-			default:{			/* Result set */
-				MYSQLND_PACKET_EOF * fields_eof;
+			default: do {			/* Result set */
 				MYSQLND_RES * result;
 				enum_mysqlnd_collected_stats stat = STAT_LAST;

@@ -464,7 +464,12 @@
 					}
 					result = stmt->result;
 				}
-
+				if (!result) {
+					SET_OOM_ERROR(conn->error_info);
+					ret = FAIL;
+					break;
+				}
+
 				if (FAIL == (ret = result->m.read_result_metadata(result, conn TSRMLS_CC))) {
 					/* For PS, we leave them in Prepared state */
 					if (!stmt && conn->current_result) {
@@ -517,11 +522,9 @@
 					}
 					MYSQLND_INC_CONN_STATISTIC(conn->stats, stat);
 				}
-
-				PACKET_FREE(fields_eof);
-
-				break;
-			}
+			} while (0);
+			PACKET_FREE(fields_eof);
+			break; /* switch break */
 		}
 	} while (0);
 	PACKET_FREE(rset_header);
@@ -1546,6 +1549,10 @@

 	DBG_ENTER("mysqlnd_result_init");
 	DBG_INF_FMT("field_count=%u", field_count);
+
+	if (!ret) {
+		DBG_RETURN(NULL);
+	}

 	ret->persistent		= persistent;
 	ret->field_count	= field_count;
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to