andrey Wed Apr 27 13:53:19 2005 EDT
Modified files:
/php-src/ext/mysqli mysqli_api.c
Log:
fix bug #32013(MySQLi bind_result causes fatal error: memory limit reached)
#this is a partial fix but it cannot be better. the user has to call
#$stmt->store_result() and for a BLOB/MEDIUTEXT (and larger) space will be
#allocated as big as the biggest column value.
http://cvs.php.net/diff.php/php-src/ext/mysqli/mysqli_api.c?r1=1.106&r2=1.107&ty=u
Index: php-src/ext/mysqli/mysqli_api.c
diff -u php-src/ext/mysqli/mysqli_api.c:1.106
php-src/ext/mysqli/mysqli_api.c:1.107
--- php-src/ext/mysqli/mysqli_api.c:1.106 Wed Apr 20 09:24:08 2005
+++ php-src/ext/mysqli/mysqli_api.c Wed Apr 27 13:53:15 2005
@@ -15,7 +15,7 @@
| Author: Georg Richter <[EMAIL PROTECTED]> |
+----------------------------------------------------------------------+
- $Id: mysqli_api.c,v 1.106 2005/04/20 13:24:08 georg Exp $
+ $Id: mysqli_api.c,v 1.107 2005/04/27 17:53:15 andrey Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -313,9 +313,21 @@
#ifdef FIELD_TYPE_NEWDECIMAL
case MYSQL_TYPE_NEWDECIMAL:
#endif
- stmt->result.buf[ofs].type = IS_STRING;
- stmt->result.buf[ofs].buflen =
- (stmt->stmt->fields) ?
(stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
+ stmt->result.buf[ofs].type = IS_STRING;
+ /*
+ If the user has called
$stmt->store_result() then we have asked
+ max_length to be updated. this is done
only for BLOBS because we don't want to allocate
+ big chunkgs of memory 2^16 or 2^24
+ */
+ if (stmt->stmt->fields[ofs].max_length == 0) {
+ stmt->result.buf[ofs].buflen =
+ (stmt->stmt->fields) ?
(stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256;
+ } else {
+ /*
+ the user has called
store_result(). if he does not there is no way to determine the
+ */
+ stmt->result.buf[ofs].buflen =
stmt->stmt->fields[ofs].max_length;
+ }
stmt->result.buf[ofs].val = (char
*)emalloc(stmt->result.buf[ofs].buflen);
bind[ofs].buffer_type = MYSQL_TYPE_STRING;
bind[ofs].buffer = stmt->result.buf[ofs].val;
@@ -1858,12 +1870,28 @@
{
MY_STMT *stmt;
zval *mysql_stmt;
+ int i=0;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
"O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt");
+ /*
+ If the user wants to store the data and we have BLOBs/TEXTs we try to
allocate
+ not the maximal length of the type (which is 16MB even for LONGBLOB)
but
+ the maximal length of the field in the result set. If he/she has
quite big
+ BLOB/TEXT columns after calling store_result() the memory usage of
PHP will
+ double - but this is a known problem of the simple MySQL API ;)
+ */
+ for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
+ if (stmt->stmt->fields && stmt->stmt->fields[i].type ==
MYSQL_TYPE_BLOB) {
+ my_bool tmp=1;
+ mysql_stmt_attr_set(stmt->stmt,
STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
+ break;
+ }
+ }
+
if (mysql_stmt_store_result(stmt->stmt)){
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
RETURN_FALSE;
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php