]> granicus.if.org Git - php/commitdiff
Various bug fixed
authorXinchen Hui <laruence@php.net>
Sun, 11 May 2014 08:05:14 +0000 (16:05 +0800)
committerXinchen Hui <laruence@php.net>
Sun, 11 May 2014 08:05:14 +0000 (16:05 +0800)
ext/mysqli/mysqli.c
ext/mysqli/mysqli_api.c
ext/mysqli/php_mysqli_structs.h

index 54e490d73b3b2b76c230e9594c394ec32f1ec435..09fafd3eea8dc54aceef707e5732d9cc7e48b3aa 100644 (file)
@@ -81,6 +81,9 @@ typedef struct _mysqli_prop_handler {
 
 static int le_pmysqli;
 
+static void free_prop_handler(zval *el) {
+       pefree(Z_PTR_P(el), 1);
+}
 
 /* Destructor for mysqli entries in free_links/used_links */
 void php_mysqli_dtor_p_elements(void *data)
@@ -424,7 +427,6 @@ HashTable *mysqli_object_get_debug_info(zval *object, int *is_temp TSRMLS_DC)
 {
        mysqli_object *obj = Z_MYSQLI_P(object);
        HashTable *retval, *props = obj->prop_handler;
-       HashPosition pos;
        mysqli_prop_handler *entry;
 
        ALLOC_HASHTABLE(retval);
@@ -618,7 +620,7 @@ PHP_MINIT_FUNCTION(mysqli)
 
        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_driver", mysqli_driver_class_entry, mysqli_driver_methods);
        ce = mysqli_driver_class_entry;
-       zend_hash_init(&mysqli_driver_properties, 0, NULL, NULL, 1);
+       zend_hash_init(&mysqli_driver_properties, 0, NULL, free_prop_handler, 1);
        MYSQLI_ADD_PROPERTIES(&mysqli_driver_properties, mysqli_driver_property_entries);
        zend_declare_property_null(ce, "client_info",           sizeof("client_info") - 1, ZEND_ACC_PUBLIC TSRMLS_CC);
        zend_declare_property_null(ce, "client_version",        sizeof("client_version") - 1, ZEND_ACC_PUBLIC TSRMLS_CC);
@@ -631,7 +633,7 @@ PHP_MINIT_FUNCTION(mysqli)
 
        REGISTER_MYSQLI_CLASS_ENTRY("mysqli", mysqli_link_class_entry, mysqli_link_methods);
        ce = mysqli_link_class_entry;
-       zend_hash_init(&mysqli_link_properties, 0, NULL, NULL, 1);
+       zend_hash_init(&mysqli_link_properties, 0, NULL, free_prop_handler, 1);
        MYSQLI_ADD_PROPERTIES(&mysqli_link_properties, mysqli_link_property_entries);
        zend_declare_property_null(ce, "affected_rows",         sizeof("affected_rows") - 1, ZEND_ACC_PUBLIC TSRMLS_CC);
        zend_declare_property_null(ce, "client_info",           sizeof("client_info") - 1, ZEND_ACC_PUBLIC TSRMLS_CC);
@@ -657,7 +659,7 @@ PHP_MINIT_FUNCTION(mysqli)
        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;
-       zend_hash_init(&mysqli_warning_properties, 0, NULL, NULL, 1);
+       zend_hash_init(&mysqli_warning_properties, 0, NULL, free_prop_handler, 1);
        MYSQLI_ADD_PROPERTIES(&mysqli_warning_properties, mysqli_warning_property_entries);
        zend_declare_property_null(ce, "message",       sizeof("message") - 1, ZEND_ACC_PUBLIC TSRMLS_CC);
        zend_declare_property_null(ce, "sqlstate",      sizeof("sqlstate") - 1, ZEND_ACC_PUBLIC TSRMLS_CC);
@@ -666,7 +668,7 @@ PHP_MINIT_FUNCTION(mysqli)
 
        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_result", mysqli_result_class_entry, mysqli_result_methods);
        ce = mysqli_result_class_entry;
-       zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1);
+       zend_hash_init(&mysqli_result_properties, 0, NULL, free_prop_handler, 1);
        MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries);
        zend_declare_property_null(ce, "current_field", sizeof("current_field") - 1,ZEND_ACC_PUBLIC TSRMLS_CC);
        zend_declare_property_null(ce, "field_count",   sizeof("field_count") - 1, ZEND_ACC_PUBLIC TSRMLS_CC);
@@ -680,7 +682,7 @@ PHP_MINIT_FUNCTION(mysqli)
 
        REGISTER_MYSQLI_CLASS_ENTRY("mysqli_stmt", mysqli_stmt_class_entry, mysqli_stmt_methods);
        ce = mysqli_stmt_class_entry;
-       zend_hash_init(&mysqli_stmt_properties, 0, NULL, NULL, 1);
+       zend_hash_init(&mysqli_stmt_properties, 0, NULL, free_prop_handler, 1);
        MYSQLI_ADD_PROPERTIES(&mysqli_stmt_properties, mysqli_stmt_property_entries);
        zend_declare_property_null(ce, "affected_rows", sizeof("affected_rows") - 1, ZEND_ACC_PUBLIC TSRMLS_CC);
        zend_declare_property_null(ce, "insert_id",             sizeof("insert_id") - 1, ZEND_ACC_PUBLIC TSRMLS_CC);
@@ -1248,13 +1250,13 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
                if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|Sz", &mysql_result, mysqli_result_class_entry, &class_name, &ctor_params) == FAILURE) {
                        return;
                }
-               if (class_name) {
+               if (class_name == NULL) {
                        ce = zend_standard_class_def;
                } else {
                        ce = zend_fetch_class(class_name, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
                }
                if (!ce) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name->val);
                        return;
                }
                fetchtype = MYSQLI_ASSOC;
@@ -1288,7 +1290,8 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
                ZVAL_COPY_VALUE(&dataset, return_value);
 
                object_and_properties_init(return_value, ce, NULL);
-               zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
+               zend_merge_properties(return_value, Z_ARRVAL(dataset), 0 TSRMLS_CC);
+               zval_ptr_dtor(&dataset);
 
                if (ce->constructor) {
                        fci.size = sizeof(fci);
index d1767082f9c4f48edbf731b9025ccbf447dff89e..59d03e65798bf8d6731b157a75956a378580845b 100644 (file)
@@ -198,12 +198,17 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in
 
        ofs = 0;
        for (i = start; i < argc; i++) {
-
+               zval *param;
+               if (Z_ISREF(args[i])) {
+                       param = Z_REFVAL(args[i]);
+               } else {
+                       param = &args[i];
+               }
                /* set specified type */
                switch (types[ofs]) {
                        case 'd': /* Double */
                                bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
-                               bind[ofs].buffer = &Z_DVAL(args[i]);
+                               bind[ofs].buffer = &Z_DVAL_P(param);
                                bind[ofs].is_null = &stmt->param.is_null[ofs];
                                break;
 
@@ -213,7 +218,7 @@ int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned in
 #elif SIZEOF_LONG==4
                                bind[ofs].buffer_type = MYSQL_TYPE_LONG;
 #endif
-                               bind[ofs].buffer = &Z_LVAL(args[i]);
+                               bind[ofs].buffer = &Z_LVAL_P(param);
                                bind[ofs].is_null = &stmt->param.is_null[ofs];
                                break;
 
@@ -397,7 +402,7 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc, un
        bind = (MYSQL_BIND *)ecalloc(var_cnt, sizeof(MYSQL_BIND));
        {
                int size;
-               char *p= emalloc(size= var_cnt * (sizeof(char) + sizeof(VAR_BUFFER)));
+               char *p = emalloc(size= var_cnt * (sizeof(char) + sizeof(VAR_BUFFER)));
                stmt->result.buf = (VAR_BUFFER *) p;
                stmt->result.is_null = p + var_cnt * sizeof(VAR_BUFFER);
                memset(p, 0, size);
@@ -410,7 +415,6 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc, un
                switch (col_type) {
                        case MYSQL_TYPE_DOUBLE:
                        case MYSQL_TYPE_FLOAT:
-                               convert_to_double_ex(&args[i]);
                                stmt->result.buf[ofs].type = IS_DOUBLE;
                                stmt->result.buf[ofs].buflen = sizeof(double);
 
@@ -439,7 +443,6 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc, un
                        case MYSQL_TYPE_LONG:
                        case MYSQL_TYPE_INT24:
                        case MYSQL_TYPE_YEAR:
-                               convert_to_long_ex(&args[i]);
                                stmt->result.buf[ofs].type = IS_LONG;
                                /* don't set stmt->result.buf[ofs].buflen to 0, we used ecalloc */
                                stmt->result.buf[ofs].val = (char *)emalloc(sizeof(int));
@@ -863,10 +866,11 @@ PHP_FUNCTION(mysqli_error)
 }
 /* }}} */
 
+#if 0
 #ifndef MYSQLI_USE_MYSQLND
 /* {{{ php_mysqli_stmt_copy_it */
 static void
-php_mysqli_stmt_copy_it(zval *** copies, zval *original, uint param_count, uint current)
+php_mysqli_stmt_copy_it(zval *copies, zval *original, uint param_count, uint current)
 {
        if (!*copies) {
                *copies = ecalloc(param_count, sizeof(zval *));
@@ -878,6 +882,7 @@ php_mysqli_stmt_copy_it(zval *** copies, zval *original, uint param_count, uint
 }
 /* }}} */
 #endif
+#endif
 
 /* {{{ proto bool mysqli_stmt_execute(object stmt)
    Execute a prepared statement */
@@ -897,22 +902,27 @@ PHP_FUNCTION(mysqli_stmt_execute)
 #ifndef MYSQLI_USE_MYSQLND
        for (i = 0; i < stmt->param.var_cnt; i++) {
                if (!Z_ISUNDEF(stmt->param.vars[i])) {
-                       if (!(stmt->param.is_null[i] = (Z_ISNULL(stmt->param.vars[i])))) {
-                               zval *the_var = &stmt->param.vars[i];
+                       zval *param;
+                       if (Z_ISREF(stmt->param.vars[i])) {
+                               param = Z_REFVAL(stmt->param.vars[i]);
+                       } else {
+                               param = &stmt->param.vars[i];
+                       }
+                       if (!(stmt->param.is_null[i] = (Z_ISNULL_P(param)))) {
                                switch (stmt->stmt->params[i].buffer_type) {
                                        case MYSQL_TYPE_VAR_STRING:
-                                               convert_to_string_ex(the_var);
-                                               stmt->stmt->params[i].buffer = Z_STRVAL_P(the_var);
-                                               stmt->stmt->params[i].buffer_length = Z_STRLEN_P(the_var);
+                                               convert_to_string_ex(param);
+                                               stmt->stmt->params[i].buffer = Z_STRVAL_P(param);
+                                               stmt->stmt->params[i].buffer_length = Z_STRLEN_P(param);
                                                break;
                                        case MYSQL_TYPE_DOUBLE:
-                                               convert_to_double_ex(the_var);
-                                               stmt->stmt->params[i].buffer = &Z_DVAL_P(the_var);
+                                               convert_to_double_ex(param);
+                                               stmt->stmt->params[i].buffer = &Z_DVAL_P(param);
                                                break;
                                        case MYSQL_TYPE_LONGLONG:
                                        case MYSQL_TYPE_LONG:
-                                               convert_to_long_ex(the_var);
-                                               stmt->stmt->params[i].buffer = &Z_LVAL_P(the_var);
+                                               convert_to_long_ex(param);
+                                               stmt->stmt->params[i].buffer = &Z_LVAL_P(param);
                                                break;
                                        default:
                                                break;
@@ -966,15 +976,20 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
        if (!ret) {
 #endif
                for (i = 0; i < stmt->result.var_cnt; i++) {
+                       zval *result;
+                       /* it must be a reference, isn't it? */
+                       if (Z_ISREF(stmt->result.vars[i])) {
+                               result = Z_REFVAL(stmt->result.vars[i]);
+                       } else {
+                               result = &stmt->result.vars[i];
+                       }
                        /*
                          QQ: Isn't it quite better to call zval_dtor(). What if the user has
                          assigned a resource, or an array to the bound variable? We are going
                          to leak probably. zval_dtor() will handle also Unicode/Non-unicode mode.
                        */
                        /* Even if the string is of length zero there is one byte alloced so efree() in all cases */
-                       if (Z_TYPE(stmt->result.vars[i]) == IS_STRING) {
-                               zval_ptr_dtor(&stmt->result.vars[i]);
-                       }
+                       zval_ptr_dtor(result);
                        if (!stmt->result.is_null[i]) {
                                switch (stmt->result.buf[i].type) {
                                        case IS_LONG:
@@ -986,7 +1001,7 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
 #if SIZEOF_LONG==4
                                                        if (uval > INT_MAX) {
                                                                char *tmp, *p;
-                                                               int j=10;
+                                                               int j = 10;
                                                                tmp = emalloc(11);
                                                                p= &tmp[9];
                                                                do {
@@ -995,20 +1010,20 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
                                                                } while (--j > 0);
                                                                tmp[10]= '\0';
                                                                /* unsigned int > INT_MAX is 10 digits - ALWAYS */
-                                                               ZVAL_STRINGL(&stmt->result.vars[i], tmp, 10);
+                                                               ZVAL_STRINGL(result, tmp, 10);
                                                                efree(tmp);
                                                                break;
                                                        }
 #endif
                                                }
                                                if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) {
-                                                       ZVAL_LONG(&stmt->result.vars[i], *(unsigned int *)stmt->result.buf[i].val);
+                                                       ZVAL_LONG(result, *(unsigned int *)stmt->result.buf[i].val);
                                                } else {
-                                                       ZVAL_LONG(&stmt->result.vars[i], *(int *)stmt->result.buf[i].val);
+                                                       ZVAL_LONG(result, *(int *)stmt->result.buf[i].val);
                                                }
                                                break;
                                        case IS_DOUBLE:
-                                               ZVAL_DOUBLE(&stmt->result.vars[i], *(double *)stmt->result.buf[i].val);
+                                               ZVAL_DOUBLE(result, *(double *)stmt->result.buf[i].val);
                                                break;
                                        case IS_STRING:
                                                if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG
@@ -1016,7 +1031,7 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
                                                 || stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT
 #endif
                                                 ) {
-                                                       my_bool uns= (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0;
+                                                       my_bool uns = (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0;
 #if MYSQL_VERSION_ID > 50002
                                                        if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) {
                                                                switch (stmt->result.buf[i].output_len) {
@@ -1048,22 +1063,20 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
                                                                 * use MYSQLI_LL_SPEC.
                                                                 */
                                                                snprintf(tmp, sizeof(tmp), (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
-                                                               ZVAL_STRING(&stmt->result.vars[i], tmp);
+                                                               ZVAL_STRING(result, tmp);
                                                        } else {
-                                                               ZVAL_LONG(&stmt->result.vars[i], llval);
+                                                               ZVAL_LONG(result, llval);
                                                        }
                                                } else {
 #if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002
                                                        if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {
                                                                /* result was truncated */
-                                                               ZVAL_STRINGL(&stmt->result.vars[i], stmt->result.buf[i].val,
-                                                                                        stmt->stmt->bind[i].buffer_length);
+                                                               ZVAL_STRINGL(result, stmt->result.buf[i].val, stmt->stmt->bind[i].buffer_length);
                                                        } else {
 #else
                                                        {
 #endif
-                                                               ZVAL_STRINGL(&stmt->result.vars[i], stmt->result.buf[i].val,
-                                                                                        stmt->result.buf[i].output_len);
+                                                               ZVAL_STRINGL(result, stmt->result.buf[i].val, stmt->result.buf[i].output_len);
                                                        }
                                                }
                                                break;
@@ -1071,7 +1084,7 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
                                                break;
                                }
                        } else {
-                               ZVAL_NULL(&stmt->result.vars[i]);
+                               ZVAL_NULL(result);
                        }
                }
        } else {
index 8fea060f0806699b6795a55c052deba38d00e2a6..8b0bf1faf92b4a7e400428da419884e77150a15c 100644 (file)
@@ -259,7 +259,7 @@ extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
        MYSQLI_RESOURCE *my_res; \
        mysqli_object *intern = Z_MYSQLI_P(__id); \
        if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {\
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);\
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name->val);\
                RETURN_NULL();\
        }\
        __ptr = (__type)my_res->ptr; \
@@ -298,7 +298,7 @@ extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
        MYSQLI_FETCH_RESOURCE((__ptr), MY_STMT *, (__id), "mysqli_stmt", (__check)); \
        if (!(__ptr)->stmt) { \
                mysqli_object *intern = Z_MYSQLI_P(__id); \
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name); \
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name->val); \
                RETURN_NULL();\
        } \
 }