MY_STMT *stmt = (MY_STMT *)my_res->ptr;
php_clear_stmt_bind(stmt);
}
- } else if (instanceof_function(intern->zo.ce, mysqli_result_class_entry TSRMLS_CC)) { /* stmt object */
+ } else if (instanceof_function(intern->zo.ce, mysqli_result_class_entry TSRMLS_CC)) { /* result object */
if (my_res && my_res->ptr) {
mysql_free_result(my_res->ptr);
}
- } else if (instanceof_function(intern->zo.ce, mysqli_warning_class_entry TSRMLS_CC)) { /* stmt object */
+ } else if (instanceof_function(intern->zo.ce, mysqli_warning_class_entry TSRMLS_CC)) { /* warning object */
if (my_res && my_res->ptr) {
php_clear_warnings((MYSQLI_WARNING *)my_res->info);
}
zend_hash_init(&mysqli_driver_properties, 0, NULL, NULL, 1);
MYSQLI_ADD_PROPERTIES(&mysqli_driver_properties, mysqli_driver_property_entries);
zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_driver_properties, sizeof(mysqli_driver_properties), NULL);
- ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
+ ce->ce_flags |= ZEND_ACC_FINAL_CLASS;
REGISTER_MYSQLI_CLASS_ENTRY("mysqli", mysqli_link_class_entry, mysqli_link_methods);
ce = mysqli_link_class_entry;
REGISTER_MYSQLI_CLASS_ENTRY("mysqli_warning", mysqli_warning_class_entry, mysqli_warning_methods);
ce = mysqli_warning_class_entry;
- ce->ce_flags |= ZEND_ACC_FINAL_CLASS | ZEND_ACC_PROTECTED;
+ ce->ce_flags |= ZEND_ACC_FINAL_CLASS | ZEND_ACC_PROTECTED;
zend_hash_init(&mysqli_warning_properties, 0, NULL, NULL, 1);
MYSQLI_ADD_PROPERTIES(&mysqli_warning_properties, mysqli_warning_property_entries);
zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_warning_properties, sizeof(mysqli_warning_properties), NULL);
#ifdef FIELD_TYPE_NEWDECIMAL
case MYSQL_TYPE_NEWDECIMAL:
#endif
+ {
+ ulong tmp;
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) {
+ if (stmt->stmt->fields[ofs].max_length == 0 &&
+ !mysql_stmt_attr_get(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp) && !tmp)
+ {
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
+ libmysql does not allow us to allocate 0 bytes for a buffer so we try 1
*/
- stmt->result.buf[ofs].buflen = stmt->stmt->fields[ofs].max_length;
+ if (!(stmt->result.buf[ofs].buflen = stmt->stmt->fields[ofs].max_length))
+ ++stmt->result.buf[ofs].buflen;
}
stmt->result.buf[ofs].val = (char *)emalloc(stmt->result.buf[ofs].buflen);
bind[ofs].buffer_type = MYSQL_TYPE_STRING;
bind[ofs].buffer_length = stmt->result.buf[ofs].buflen;
bind[ofs].length = &stmt->result.buf[ofs].buflen;
break;
+ }
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Server returned unknown type %ld. Probably your client library is incompatible with the server version you use!", col_type);
break;
--- /dev/null
+--TEST--
+bug #35759 : mysqli_stmt_bind_result() makes huge allocation when column empty
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$sql=<<<EOSQL
+CREATE TABLE blobby (
+ a1 MEDIUMBLOB NOT NULL,
+
+
+EOSQL;
+ include "connect.inc";
+ $col_num= 1000;
+
+ $mysql = new mysqli($host, $user, $passwd, "test");
+ $mysql->query("DROP TABLE IF EXISTS blobby");
+ $create = "CREATE TABLE blobby (a0 MEDIUMBLOB NOT NULL DEFAULT ''";
+ $i= 0;
+ while (++$i < $col_num) {
+ $create .= ", a$i MEDIUMBLOB NOT NULL DEFAULT ''";
+ }
+ $create .= ")";
+
+ $mysql->query($create);
+ $mysql->query("INSERT INTO blobby (a0) VALUES ('')");
+
+ $stmt = $mysql->prepare("SELECT * FROM blobby");
+ $stmt->execute();
+ $stmt->store_result();
+ $params= array_pad(array(), $col_num, "");
+ call_user_func_array(array($stmt, "bind_result"), $params);
+ $stmt->fetch();
+
+ $stmt->close();
+
+ $mysql->query("DROP TABLE blobby");
+
+ $mysql->close();
+ echo "OK\n";
+?>
+--EXPECT--
+OK