]> granicus.if.org Git - php/commitdiff
Make it coupled - what is allocated with mnd_ should be freed
authorAndrey Hristov <andrey@php.net>
Mon, 29 Mar 2010 17:04:16 +0000 (17:04 +0000)
committerAndrey Hristov <andrey@php.net>
Mon, 29 Mar 2010 17:04:16 +0000 (17:04 +0000)
with mnd_ and vice versa.
Added mnd_pestrndup and mnd_pestrdup, which wrap the normal
calls to be able to track this calls.
Fixed some failing tests.

ext/mysqli/tests/mysqli_constants.phpt
ext/mysqli/tests/mysqli_get_client_stats.phpt
ext/mysqli/tests/mysqli_options.phpt
ext/mysqli/tests/mysqli_set_opt_numeric_and_datetime_as_unicode.phpt [deleted file]
ext/mysqlnd/mysqlnd.c
ext/mysqlnd/mysqlnd_debug.c
ext/mysqlnd/mysqlnd_debug.h
ext/mysqlnd/mysqlnd_enum_n_def.h
ext/mysqlnd/mysqlnd_statistics.c
ext/mysqlnd/mysqlnd_wireprotocol.c
ext/mysqlnd/mysqlnd_wireprotocol.h

index 32a259350adab40589d526775556cc4ca748d934..418eb070e5f80b0e842776d0928942371b67d290 100644 (file)
@@ -154,10 +154,7 @@ require_once('skipifconnectfailure.inc');
        if (defined('MYSQLI_DATA_TRUNCATED'))
                $expected_constants["MYSQLI_DATA_TRUNCATED"] = true;
 
-       if ($IS_MYSQLND && $php_version >= 600) {
-               /* mysqlnd only */
-               $expected_constants["MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE"] = true;
-       } else if (!$IS_MYSQLND) {
+       if (!$IS_MYSQLND) {
                /* libmysql only */
 
                /* are they available in all versions of ext/mysqli ?
index 74c0cc800b196acd9d9b1e55f2dbebfbe3508853..9446d072e9f497332a6cb17ab712d5cb31d00fc5 100644 (file)
@@ -887,7 +887,7 @@ if (!mysqli_query($link, "DROP SERVER IF EXISTS myself"))
 mysqli_close($link);
 ?>
 --EXPECTF--
-array(152) {
+array(156) {
   [%u|b%"bytes_sent"]=>
   %unicode|string%(1) "0"
   [%u|b%"bytes_received"]=>
@@ -1046,6 +1046,14 @@ array(152) {
   %unicode|string%(1) "0"
   [%u|b%"mem_free_count"]=>
   %unicode|string%(1) "0"
+  [%u|b%"mem_estrndup_count"]=>
+  %unicode|string%(1) "0"
+  [%u|b%"mem_strndup_count"]=>
+  %unicode|string%(1) "0"
+  [%u|b%"mem_estndup_count"]=>
+  %unicode|string%(1) "0"
+  [%u|b%"mem_strdup_count"]=>
+  %unicode|string%(1) "0"
   [%u|b%"proto_text_fetched_null"]=>
   %unicode|string%(1) "0"
   [%u|b%"proto_text_fetched_bit"]=>
index 1da140b3973ebc71fc13b743a4b08e9fcc9f663d..1d5955b55e33c217bb751eb26c575bdbbdb23ba0 100644 (file)
@@ -41,8 +41,6 @@ already through other measures.
                $valid_options[] = constant('MYSQLI_OPT_NET_READ_BUFFER_SIZE');
        if ($IS_MYSQLND && defined('MYSQLI_OPT_INT_AND_FLOAT_NATIVE'))
                $valid_options[] = constant('MYSQLI_OPT_INT_AND_FLOAT_NATIVE');
-       if (defined('MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE'))
-               $valid_options[] = constant('MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE');
 
        $tmp    = NULL;
        $link   = NULL;
@@ -81,10 +79,6 @@ already through other measures.
                !($tmp = mysqli_options($link, constant('MYSQLI_OPT_INT_AND_YEARS_AS_INT'), true)))
                printf("[006] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp);
 
-       if (defined('MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE') &&
-               !($tmp = mysqli_options($link, constant('MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE'), true)))
-               printf("[006] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp);
-
        if ($IS_MYSQLND) {
                /* Don't do this with libmysql. You may hit options not exported to PHP and cause false positives */
                for ($flag = -10000; $flag < 10000; $flag++) {
diff --git a/ext/mysqli/tests/mysqli_set_opt_numeric_and_datetime_as_unicode.phpt b/ext/mysqli/tests/mysqli_set_opt_numeric_and_datetime_as_unicode.phpt
deleted file mode 100644 (file)
index 7e0593c..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
---TEST--
-mysqli_set_opt() - MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-if (version_compare(PHP_VERSION, '5.9.9', '<') == 1) {
-       die('skip Needs PHP 6 and Unicode');
-}
-
-if (!stristr(mysqli_get_client_info(), "mysqlnd"))
-       die("skip works only with mysqlnd");
-?>
---FILE--
-<?php
-       require_once("table.inc");
-
-       if (true !== ($tmp = mysqli_set_opt($link, MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE, 1)))
-               printf("[001] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
-
-       if (!mysqli_query($link, 'ALTER TABLE test ADD col_date DATE,
-               ADD col_time TIME,
-               ADD col_timestamp TIMESTAMP,
-               ADD col_datetime DATETIME'))
-               printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       if (!mysqli_query($link, 'UPDATE test SET col_date = NOW(),
-               col_time = NOW(),
-               col_timestamp = NOW(),
-               col_datetime = NOW()'))
-               printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       if (!$res = mysqli_query($link, 'SELECT * FROM test'))
-               printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       if (!$row = mysqli_fetch_assoc($res))
-               printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       if (!is_unicode($row['col_time']) || '' == $row['col_time'])
-               printf("[006] Expecting unicode/any, got %s/%s\n", gettype($row['col_time']), $row['col_time']);
-
-       if (!is_unicode($row['col_timestamp']) || '' == $row['col_timestamp'])
-               printf("[007] Expecting unicode/any, got %s/%s\n", gettype($row['col_timestamp']), $row['col_timestamp']);
-
-       if (!is_unicode($row['col_datetime']) || '' == $row['col_datetime'])
-               printf("[008] Expecting unicode/any, got %s/%s\n", gettype($row['col_datetime']), $row['col_datetime']);
-
-       if (!is_unicode($row['col_date']) || '' == $row['col_date'])
-               printf("[009] Expecting unicode/any, got %s/%s\n", gettype($row['col_date']), $row['col_date']);
-
-       mysqli_free_result($res);
-
-       if (true !== ($tmp = mysqli_set_opt($link, MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE, 0)))
-               printf("[010] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
-
-       if (!$res = mysqli_query($link, 'SELECT * FROM test'))
-               printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       if (!$row = mysqli_fetch_assoc($res))
-               printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       if (is_unicode($row['col_time']) || '' == $row['col_time'])
-               printf("[013] Expecting (binary) string/any, got %s/%s\n", gettype($row['col_time']), $row['col_time']);
-
-       if (is_unicode($row['col_timestamp']) || '' == $row['col_timestamp'])
-               printf("[014] Expecting (binary) string/any, got %s/%s\n", gettype($row['col_timestamp']), $row['col_timestamp']);
-
-       if (is_unicode($row['col_datetime']) || '' == $row['col_datetime'])
-               printf("[015] Expecting (binary) string/any, got %s/%s\n", gettype($row['col_datetime']), $row['col_datetime']);
-
-       if (is_unicode($row['col_date']) || '' == $row['col_date'])
-               printf("[016] Expecting (binary) string/any, got %s/%s\n", gettype($row['col_date']), $row['col_date']);
-
-       mysqli_free_result($res);
-
-       if (true !== ($tmp = mysqli_set_opt($link, MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE, 1)))
-               printf("[017] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
-
-       if (!$res = mysqli_query($link, 'SELECT * FROM test'))
-               printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       if (!$row = mysqli_fetch_assoc($res))
-               printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       if (!is_unicode($row['col_time']) || '' == $row['col_time'])
-               printf("[020] Expecting unicode/any, got %s/%s\n", gettype($row['col_time']), $row['col_time']);
-
-       mysqli_free_result($res);
-
-       if (!$stmt = mysqli_stmt_init($link))
-               printf("[021] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       $col_date = $col_time = $col_datetime = $col_timestamp = null;
-       if (!mysqli_stmt_prepare($stmt, 'SELECT col_date, col_time, col_datetime, col_timestamp FROM test') ||
-               !mysqli_stmt_execute($stmt) ||
-               !mysqli_stmt_bind_result($stmt, $col_date, $col_time, $col_datetime, $col_timestamp) ||
-               !mysqli_stmt_fetch($stmt))
-               printf("[022] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
-
-       if (!is_unicode($col_date) || '' == $col_date)
-               printf("[023] Expecting unicode/any, got %s/%s\n", gettype($col_date), $col_date);
-
-       if (!is_unicode($col_time) || '' == $col_time)
-               printf("[024] Expecting unicode/any, got %s/%s\n", gettype($col_time), $col_time);
-
-       if (!is_unicode($col_datetime) || '' == $col_datetime)
-               printf("[025] Expecting unicode/any, got %s/%s\n", gettype($col_datetime), $col_datetime);
-
-       if (!is_unicode($col_timestamp) || '' == $col_timestamp)
-               printf("[026] Expecting unicode/any, got %s/%s\n", gettype($col_timestamp), $col_timestamp);
-
-       mysqli_stmt_close($stmt);
-
-       if (true !== ($tmp = mysqli_set_opt($link, MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE, 0)))
-               printf("[027] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
-
-       if (!$stmt = mysqli_stmt_init($link))
-               printf("[028] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
-       $col_date = $col_time = $col_datetime = $col_timestamp = null;
-       if (!mysqli_stmt_prepare($stmt, 'SELECT col_date, col_time, col_datetime, col_timestamp FROM test') ||
-               !mysqli_stmt_execute($stmt) ||
-               !mysqli_stmt_bind_result($stmt, $col_date, $col_time, $col_datetime, $col_timestamp) ||
-               !mysqli_stmt_fetch($stmt))
-               printf("[029] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
-
-       if (is_unicode($col_date) || '' == $col_date)
-               printf("[030] Expecting (binary) string/any, got %s/%s\n", gettype($col_date), $col_date);
-
-       if (is_unicode($col_time) || '' == $col_time)
-               printf("[031] Expecting (binary) string/any, got %s/%s\n", gettype($col_time), $col_time);
-
-       if (is_unicode($col_datetime) || '' == $col_datetime)
-               printf("[032] Expecting (binary) string/any, got %s/%s\n", gettype($col_datetime), $col_datetime);
-
-       if (is_unicode($col_timestamp) || '' == $col_timestamp)
-               printf("[033] Expecting (binary) string/any, got %s/%s\n", gettype($col_timestamp), $col_timestamp);
-
-       mysqli_stmt_close($stmt);
-
-       mysqli_close($link);
-       print "done!";
-?>
---CLEAN--
-<?php
-       require_once("clean_table.inc");
-?>
---EXPECTF--
-done!
\ No newline at end of file
index 4f89b8c57e0e50727247b3eb5b9fae8cbe1550db..6d313c161b64c6b96a130c267ece7a6d745d01cc 100644 (file)
@@ -143,7 +143,6 @@ MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND *conn TSRMLS_DC)
        mysqlnd_local_infile_default(conn);
        if (conn->current_result) {
                conn->current_result->m.free_result(conn->current_result, TRUE TSRMLS_CC);
-//             mnd_pefree(conn->current_result, conn->current_result->persistent);
                conn->current_result = NULL;
        }
 
@@ -468,8 +467,8 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
                                                 unsigned int mysql_flags
                                                 TSRMLS_DC)
 {
-       char *transport = NULL, *errstr = NULL;
-       int transport_len, errcode = 0, host_len;
+       char *errstr = NULL;
+       int errcode = 0, host_len;
        zend_bool self_alloced = FALSE;
        zend_bool unix_socket = FALSE;
        const MYSQLND_CHARSET * charset;
@@ -531,39 +530,38 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
                db_len = 0;
        }
        host_len = strlen(host);
+       {
+               char * transport = NULL;
+               int transport_len;
 #ifndef PHP_WIN32
-       if (host_len == sizeof("localhost") - 1 && !strncasecmp(host, "localhost", host_len)) {
-               DBG_INF_FMT("socket=%s", socket? socket:"n/a");
-               if (!socket) {
-                       socket = "/tmp/mysql.sock";
-               }
-               transport_len = spprintf(&transport, 0, "unix://%s", socket);
-               unix_socket = TRUE;
-       } else
+               if (host_len == sizeof("localhost") - 1 && !strncasecmp(host, "localhost", host_len)) {
+                       DBG_INF_FMT("socket=%s", socket? socket:"n/a");
+                       if (!socket) {
+                               socket = "/tmp/mysql.sock";
+                       }
+                       transport_len = spprintf(&transport, 0, "unix://%s", socket);
+                       unix_socket = TRUE;
+               } else
 #endif
-       {
-               if (!port) {
-                       port = 3306;
-               }
+               {
+                       if (!port) {
+                               port = 3306;
+                       }
 
-               transport_len = spprintf(&transport, 0, "tcp://%s:%d", host, port);
+                       transport_len = spprintf(&transport, 0, "tcp://%s:%d", host, port);
+               }
+               DBG_INF_FMT("transport=%s", transport);
+               conn->scheme = mnd_pestrndup(transport, transport_len, conn->persistent);
+               conn->scheme_len = transport_len;
+               efree(transport);
+               transport = NULL;
        }
-       DBG_INF_FMT("transport=%s", transport);
-
 
        greet_packet = conn->protocol->m.get_greet_packet(conn->protocol, FALSE TSRMLS_CC);
        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 (conn->persistent) {
-               conn->scheme = pestrndup(transport, transport_len, 1);
-               mnd_efree(transport);
-       } else {
-               conn->scheme = transport;
-       }
-       conn->scheme_len = transport_len;
-       DBG_INF(conn->scheme);
-       if (FAIL == conn->net->m.connect(conn->net, conn->scheme, transport_len, conn->persistent, &errstr, &errcode TSRMLS_CC)) {
+       if (FAIL == conn->net->m.connect(conn->net, conn->scheme, conn->scheme_len, conn->persistent, &errstr, &errcode TSRMLS_CC)) {
                goto err;       
        }
 
@@ -588,7 +586,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
 
        conn->thread_id                 = greet_packet->thread_id;
        conn->protocol_version  = greet_packet->protocol_version;
-       conn->server_version    = pestrdup(greet_packet->server_version, conn->persistent);
+       conn->server_version    = mnd_pestrdup(greet_packet->server_version, conn->persistent);
 
        conn->greet_charset = mysqlnd_find_charset_nr(greet_packet->charset_no);
        /* we allow load data local infile by default */
@@ -655,30 +653,30 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
                */
                conn->net->compressed = mysql_flags & CLIENT_COMPRESS? TRUE:FALSE;
 
-               conn->user                              = pestrdup(user, conn->persistent);
+               conn->user                              = mnd_pestrdup(user, conn->persistent);
                conn->user_len                  = strlen(conn->user);
-               conn->passwd                    = pestrndup(passwd, passwd_len, conn->persistent);
+               conn->passwd                    = mnd_pestrndup(passwd, passwd_len, conn->persistent);
                conn->passwd_len                = passwd_len;
                conn->port                              = port;
-               conn->connect_or_select_db = pestrndup(db, db_len, conn->persistent);
+               conn->connect_or_select_db = mnd_pestrndup(db, db_len, conn->persistent);
                conn->connect_or_select_db_len = db_len;
 
                if (!unix_socket) {
                        char *p;
 
-                       conn->host = pestrdup(host, conn->persistent);
+                       conn->host = mnd_pestrdup(host, conn->persistent);
                        conn->host_len = strlen(conn->host);
                        spprintf(&p, 0, "%s via TCP/IP", conn->host);
                        if (conn->persistent) {
-                               conn->host_info = pestrdup(p, 1);
+                               conn->host_info = mnd_pestrdup(p, 1);
                                mnd_efree(p);
                        } else {
                                conn->host_info = p;
                        }
                } else {
-                       conn->unix_socket       = pestrdup(socket, conn->persistent);
+                       conn->unix_socket       = mnd_pestrdup(socket, conn->persistent);
                        conn->unix_socket_len = strlen(conn->unix_socket);
-                       conn->host_info         = pestrdup("Localhost via UNIX socket", conn->persistent);
+                       conn->host_info         = mnd_pestrdup("Localhost via UNIX socket", conn->persistent);
                }
                conn->client_flag               = auth_packet->client_flags;
                conn->max_packet_size   = auth_packet->max_packet_size;
@@ -754,7 +752,7 @@ err:
        }
        if (conn->scheme) {
                /* no mnd_ since we don't allocate it */
-               pefree(conn->scheme, conn->persistent);
+               mnd_pefree(conn->scheme, conn->persistent);
                conn->scheme = NULL;
        }
 
@@ -1229,7 +1227,7 @@ MYSQLND_METHOD(mysqlnd_conn, select_db)(MYSQLND * const conn, const char * const
                if (conn->connect_or_select_db) {
                        pefree(conn->connect_or_select_db, conn->persistent);
                }
-               conn->connect_or_select_db = pestrndup(db, db_len, conn->persistent);
+               conn->connect_or_select_db = mnd_pestrndup(db, db_len, conn->persistent);
                conn->connect_or_select_db_len = db_len;
        }
        DBG_RETURN(ret);
@@ -1842,9 +1840,9 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
        }
        if (ret == PASS) {
                mnd_pefree(conn->user, conn->persistent);
-               conn->user = pestrndup(user, user_len, conn->persistent);
+               conn->user = mnd_pestrndup(user, user_len, conn->persistent);
                mnd_pefree(conn->passwd, conn->persistent);
-               conn->passwd = pestrdup(passwd, conn->persistent);
+               conn->passwd = mnd_pestrdup(passwd, conn->persistent);
                if (conn->last_message) {
                        mnd_pefree(conn->last_message, conn->persistent);
                        conn->last_message = NULL;
@@ -1912,7 +1910,7 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
                        /* when num_commands is 0, then realloc will be effectively a malloc call, internally */
                        conn->options.init_commands = mnd_perealloc(conn->options.init_commands, sizeof(char *) * (conn->options.num_commands + 1),
                                                                                                                conn->persistent);
-                       conn->options.init_commands[conn->options.num_commands] = pestrdup(value, conn->persistent);
+                       conn->options.init_commands[conn->options.num_commands] = mnd_pestrdup(value, conn->persistent);
                        ++conn->options.num_commands;
                        break;
                case MYSQL_READ_DEFAULT_FILE:
@@ -1926,7 +1924,7 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,
                        break;
                case MYSQL_SET_CHARSET_NAME:
                        DBG_INF("MYSQL_SET_CHARSET_NAME");
-                       conn->options.charset_name = pestrdup(value, conn->persistent);
+                       conn->options.charset_name = mnd_pestrdup(value, conn->persistent);
                        DBG_INF_FMT("charset=%s", conn->options.charset_name);
                        break;
 #ifdef WHEN_SUPPORTED_BY_MYSQLI
index 4ede83663fbf5f9f984b4ab832548b2e096dc0ce..1eedbdf00b52d2aa3603279e6de684ee83a2854d 100644 (file)
@@ -59,6 +59,8 @@ static const char mysqlnd_malloc_name[]               = "_mysqlnd_malloc";
 static const char mysqlnd_calloc_name[]                = "_mysqlnd_calloc";
 static const char mysqlnd_realloc_name[]       = "_mysqlnd_realloc";
 static const char mysqlnd_free_name[]          = "_mysqlnd_free";
+static const char mysqlnd_pestrndup_name[]     = "_mysqlnd_pestrndup";
+static const char mysqlnd_pestrdup_name[]      = "_mysqlnd_pestrdup";
 
 const char * mysqlnd_debug_std_no_trace_funcs[] =
 {
@@ -74,6 +76,7 @@ const char * mysqlnd_debug_std_no_trace_funcs[] =
        mysqlnd_calloc_name,
        mysqlnd_realloc_name,
        mysqlnd_free_name,
+       mysqlnd_pestrndup_name,
        mysqlnd_read_header_name,
        mysqlnd_read_body_name,
        NULL /* must be always last */
@@ -916,6 +919,43 @@ void _mysqlnd_free(void *ptr MYSQLND_MEM_D)
 /* }}} */
 
 
+/* {{{ _mysqlnd_pestrndup */
+char * _mysqlnd_pestrndup(const char * const ptr, size_t length, zend_bool persistent MYSQLND_MEM_D)
+{
+       char * ret;
+       DBG_ENTER(mysqlnd_pestrndup_name);
+       DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+       DBG_INF_FMT("ptr=%p", ptr); 
+
+       ret = pestrndup(ptr, length, persistent);
+
+       if (MYSQLND_G(collect_memory_statistics)) {
+               MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRNDUP_COUNT : STAT_MEM_ESTRNDUP_COUNT);
+       }
+
+       DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ _mysqlnd_pestrdup */
+char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D)
+{
+       char * ret;
+       DBG_ENTER(mysqlnd_pestrdup_name);
+       DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+       DBG_INF_FMT("ptr=%p", ptr); 
+
+       ret = pestrdup(ptr, persistent);
+
+       if (MYSQLND_G(collect_memory_statistics)) {
+               MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRDUP_COUNT : STAT_MEM_ESTRDUP_COUNT);
+       }
+
+       DBG_RETURN(ret);
+}
+/* }}} */
+
 
 
 /* Follows code borrowed from zend_builtin_functions.c because the functions there are static */
index 96c953c24dc4b21be6741e06fd57b911d9bd8ac8..dc9d0a7dfb3f1b2bfbffe9e7de3cd15b6d48c003 100644 (file)
@@ -63,7 +63,7 @@ PHPAPI extern const char * mysqlnd_debug_std_no_trace_funcs[];
 PHPAPI MYSQLND_DEBUG * mysqlnd_debug_init(const char * skip_functions[] TSRMLS_DC);
 
 #define MYSQLND_MEM_D  TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC
-
+#define MYSQLND_MEM_C  TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC
 
 PHPAPI void *  _mysqlnd_emalloc(size_t size MYSQLND_MEM_D);
 PHPAPI void *  _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D);
@@ -76,7 +76,9 @@ PHPAPI void   _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D);
 PHPAPI void *  _mysqlnd_malloc(size_t size MYSQLND_MEM_D);
 PHPAPI void *  _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D);
 PHPAPI void *  _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D);
-PHPAPI void    _mysqlnd_free(void *ptr MYSQLND_MEM_D);
+PHPAPI void            _mysqlnd_free(void *ptr MYSQLND_MEM_D);
+PHPAPI char *  _mysqlnd_pestrndup(const char * const ptr, size_t size, zend_bool persistent MYSQLND_MEM_D);
+PHPAPI char *  _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_MEM_D);
 
 PHPAPI char *  mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC);
 
@@ -129,18 +131,20 @@ static inline void DBG_ENTER(const char * const func_name) {}
 
 #if MYSQLND_DEBUG_MEMORY
 
-#define mnd_emalloc(size)                              _mysqlnd_emalloc((size) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_pemalloc(size, pers)               _mysqlnd_pemalloc((size), (pers) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_ecalloc(nmemb, size)               _mysqlnd_ecalloc((nmemb), (size) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_pecalloc(nmemb, size, p)   _mysqlnd_pecalloc((nmemb), (size), (p) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_erealloc(ptr, new_size)            _mysqlnd_erealloc((ptr), (new_size) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_perealloc(ptr, new_size, p)        _mysqlnd_perealloc((ptr), (new_size), (p) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_efree(ptr)                                 _mysqlnd_efree((ptr) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_pefree(ptr, pers)                  _mysqlnd_pefree((ptr), (pers) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_malloc(size)                               _mysqlnd_malloc((size) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_calloc(nmemb, size)                        _mysqlnd_calloc((nmemb), (size) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_realloc(ptr, new_size)             _mysqlnd_realloc((ptr), (new_size) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-#define mnd_free(ptr)                                  _mysqlnd_free((ptr) TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
+#define mnd_emalloc(size)                              _mysqlnd_emalloc((size) MYSQLND_MEM_C)
+#define mnd_pemalloc(size, pers)               _mysqlnd_pemalloc((size), (pers) MYSQLND_MEM_C)
+#define mnd_ecalloc(nmemb, size)               _mysqlnd_ecalloc((nmemb), (size) MYSQLND_MEM_C)
+#define mnd_pecalloc(nmemb, size, p)   _mysqlnd_pecalloc((nmemb), (size), (p) MYSQLND_MEM_C)
+#define mnd_erealloc(ptr, new_size)            _mysqlnd_erealloc((ptr), (new_size) MYSQLND_MEM_C)
+#define mnd_perealloc(ptr, new_size, p)        _mysqlnd_perealloc((ptr), (new_size), (p) MYSQLND_MEM_C)
+#define mnd_efree(ptr)                                 _mysqlnd_efree((ptr) MYSQLND_MEM_C)
+#define mnd_pefree(ptr, pers)                  _mysqlnd_pefree((ptr), (pers) MYSQLND_MEM_C)
+#define mnd_malloc(size)                               _mysqlnd_malloc((size) MYSQLND_MEM_C)
+#define mnd_calloc(nmemb, size)                        _mysqlnd_calloc((nmemb), (size) MYSQLND_MEM_C)
+#define mnd_realloc(ptr, new_size)             _mysqlnd_realloc((ptr), (new_size) MYSQLND_MEM_C)
+#define mnd_free(ptr)                                  _mysqlnd_free((ptr) MYSQLND_MEM_C)
+#define mnd_pestrndup(ptr, size, pers) _mysqlnd_pestrndup((ptr), (size), (pers) MYSQLND_MEM_C)
+#define mnd_pestrdup(ptr, pers)                        _mysqlnd_pestrdup((ptr), (pers) MYSQLND_MEM_C)
 
 #else
 
@@ -156,6 +160,8 @@ static inline void DBG_ENTER(const char * const func_name) {}
 #define mnd_calloc(nmemb, size)                        calloc((nmemb), (size))
 #define mnd_realloc(ptr, new_size)             realloc((ptr), (new_size))
 #define mnd_free(ptr)                                  free((ptr))
+#define mnd_pestrndup(ptr, size, pers) pestrndup((ptr), (size), (pers))
+#define mnd_pestrndup(ptr, size, pers) pestrdup((ptr), (pers))
 
 #endif
 
index 8404fbeb6e2a8bccb666f7679e41dae71968b8ab..9b17f60fe6124a7b364c6dcf95c85960fad9fc74 100644 (file)
@@ -401,6 +401,10 @@ typedef enum mysqlnd_collected_stats
        STAT_MEM_REALLOC_COUNT,
        STAT_MEM_REALLOC_AMMOUNT,
        STAT_MEM_FREE_COUNT,
+       STAT_MEM_ESTRNDUP_COUNT,
+       STAT_MEM_STRNDUP_COUNT,
+       STAT_MEM_ESTRDUP_COUNT,
+       STAT_MEM_STRDUP_COUNT,
        STAT_TEXT_TYPE_FETCHED_NULL,
        STAT_TEXT_TYPE_FETCHED_BIT,
        STAT_TEXT_TYPE_FETCHED_INT8,
index e52414b3e8c66ce183c9ce97e725befa928c7256..2e7665d8a761351ddc24cb0b9eef827803d3d4ab 100644 (file)
@@ -112,6 +112,10 @@ const MYSQLND_STRING mysqlnd_stats_values_names[STAT_LAST] =
        { STR_W_LEN("mem_realloc_count") },
        { STR_W_LEN("mem_realloc_ammount") },
        { STR_W_LEN("mem_free_count") },
+       { STR_W_LEN("mem_estrndup_count") },
+       { STR_W_LEN("mem_strndup_count") },
+       { STR_W_LEN("mem_estndup_count") },
+       { STR_W_LEN("mem_strdup_count") },
        { STR_W_LEN("proto_text_fetched_null") },
        { STR_W_LEN("proto_text_fetched_bit") },
        { STR_W_LEN("proto_text_fetched_tinyint") },
index 09666835654c63edad4affd795452daaf6e6793f..03f8550b28b89cc762b2327d33af837838771723 100644 (file)
@@ -367,11 +367,11 @@ void php_mysqlnd_greet_free_mem(void *_packet, zend_bool alloca TSRMLS_DC)
 {
        MYSQLND_PACKET_GREET *p= (MYSQLND_PACKET_GREET *) _packet;
        if (p->server_version) {
-               mnd_efree(p->server_version);
+               efree(p->server_version);
                p->server_version = NULL;
        }
        if (!alloca) {
-               mnd_efree(p);
+               mnd_pefree(p, p->header.persistent);
        }
 }
 /* }}} */
@@ -494,7 +494,8 @@ static
 void php_mysqlnd_auth_free_mem(void *_packet, zend_bool alloca TSRMLS_DC)
 {
        if (!alloca) {
-               mnd_pefree((MYSQLND_PACKET_AUTH *) _packet, ((MYSQLND_PACKET_AUTH *)_packet)->header.persistent);
+               MYSQLND_PACKET_AUTH * p = (MYSQLND_PACKET_AUTH *) _packet;
+               mnd_pefree(p, p->header.persistent);
        }
 }
 /* }}} */
@@ -716,7 +717,8 @@ static
 void php_mysqlnd_cmd_free_mem(void *_packet, zend_bool alloca TSRMLS_DC)
 {
        if (!alloca) {
-               mnd_pefree(_packet, ((MYSQLND_PACKET_COMMAND *)_packet)->header.persistent);
+               MYSQLND_PACKET_COMMAND * p = (MYSQLND_PACKET_COMMAND *) _packet;
+               mnd_pefree(p, p->header.persistent);
        }
 }
 /* }}} */
@@ -1799,7 +1801,7 @@ mysqlnd_packet_methods packet_methods[PROT_LAST] =
 static struct st_mysqlnd_packet_greet *
 MYSQLND_METHOD(mysqlnd_protocol, get_greet_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_greet * packet = pecalloc(1, packet_methods[PROT_GREET_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_greet * packet = mnd_pecalloc(1, packet_methods[PROT_GREET_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_greet_packet");
        packet->header.m = &packet_methods[PROT_GREET_PACKET];
        packet->header.persistent = persistent;
@@ -1812,7 +1814,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_greet_packet)(MYSQLND_PROTOCOL * const prot
 static struct st_mysqlnd_packet_auth *
 MYSQLND_METHOD(mysqlnd_protocol, get_auth_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_auth * packet = pecalloc(1, packet_methods[PROT_AUTH_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_auth * packet = mnd_pecalloc(1, packet_methods[PROT_AUTH_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_auth_packet");
        packet->header.m = &packet_methods[PROT_AUTH_PACKET];
        packet->header.persistent = persistent;
@@ -1825,7 +1827,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_auth_packet)(MYSQLND_PROTOCOL * const proto
 static struct st_mysqlnd_packet_ok *
 MYSQLND_METHOD(mysqlnd_protocol, get_ok_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_ok * packet = pecalloc(1, packet_methods[PROT_OK_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_ok * packet = mnd_pecalloc(1, packet_methods[PROT_OK_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_ok_packet");
        packet->header.m = &packet_methods[PROT_OK_PACKET];
        packet->header.persistent = persistent;
@@ -1838,7 +1840,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_ok_packet)(MYSQLND_PROTOCOL * const protoco
 static struct st_mysqlnd_packet_eof *
 MYSQLND_METHOD(mysqlnd_protocol, get_eof_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_eof * packet = pecalloc(1, packet_methods[PROT_EOF_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_eof * packet = mnd_pecalloc(1, packet_methods[PROT_EOF_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_eof_packet");
        packet->header.m = &packet_methods[PROT_EOF_PACKET];
        packet->header.persistent = persistent;
@@ -1851,7 +1853,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_eof_packet)(MYSQLND_PROTOCOL * const protoc
 static struct st_mysqlnd_packet_command *
 MYSQLND_METHOD(mysqlnd_protocol, get_command_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_command * packet = pecalloc(1, packet_methods[PROT_CMD_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_command * packet = mnd_pecalloc(1, packet_methods[PROT_CMD_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_command_packet");
        packet->header.m = &packet_methods[PROT_CMD_PACKET];
        packet->header.persistent = persistent;
@@ -1864,7 +1866,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_command_packet)(MYSQLND_PROTOCOL * const pr
 static struct st_mysqlnd_packet_rset_header *
 MYSQLND_METHOD(mysqlnd_protocol, get_rset_header_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_rset_header * packet = pecalloc(1, packet_methods[PROT_RSET_HEADER_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_rset_header * packet = mnd_pecalloc(1, packet_methods[PROT_RSET_HEADER_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_rset_header_packet");
        packet->header.m = &packet_methods[PROT_RSET_HEADER_PACKET];
        packet->header.persistent = persistent;
@@ -1877,7 +1879,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_rset_header_packet)(MYSQLND_PROTOCOL * cons
 static struct st_mysqlnd_packet_res_field *
 MYSQLND_METHOD(mysqlnd_protocol, get_result_field_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_res_field * packet = pecalloc(1, packet_methods[PROT_RSET_FLD_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_res_field * packet = mnd_pecalloc(1, packet_methods[PROT_RSET_FLD_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_result_field_packet");
        packet->header.m = &packet_methods[PROT_RSET_FLD_PACKET];
        packet->header.persistent = persistent;
@@ -1890,7 +1892,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_result_field_packet)(MYSQLND_PROTOCOL * con
 static struct st_mysqlnd_packet_row *
 MYSQLND_METHOD(mysqlnd_protocol, get_row_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_row * packet = pecalloc(1, packet_methods[PROT_ROW_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_row * packet = mnd_pecalloc(1, packet_methods[PROT_ROW_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_row_packet");
        packet->header.m = &packet_methods[PROT_ROW_PACKET];
        packet->header.persistent = persistent;
@@ -1903,7 +1905,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_row_packet)(MYSQLND_PROTOCOL * const protoc
 static struct st_mysqlnd_packet_stats *
 MYSQLND_METHOD(mysqlnd_protocol, get_stats_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_stats * packet = pecalloc(1, packet_methods[PROT_STATS_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_stats * packet = mnd_pecalloc(1, packet_methods[PROT_STATS_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_stats_packet");
        packet->header.m = &packet_methods[PROT_STATS_PACKET];
        packet->header.persistent = persistent;
@@ -1916,7 +1918,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_stats_packet)(MYSQLND_PROTOCOL * const prot
 static struct st_mysqlnd_packet_prepare_response *
 MYSQLND_METHOD(mysqlnd_protocol, get_prepare_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_prepare_response * packet = pecalloc(1, packet_methods[PROT_PREPARE_RESP_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_prepare_response * packet = mnd_pecalloc(1, packet_methods[PROT_PREPARE_RESP_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_prepare_response_packet");
        packet->header.m = &packet_methods[PROT_PREPARE_RESP_PACKET];
        packet->header.persistent = persistent;
@@ -1929,7 +1931,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_prepare_response_packet)(MYSQLND_PROTOCOL *
 static struct st_mysqlnd_packet_chg_user_resp*
 MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
 {
-       struct st_mysqlnd_packet_chg_user_resp * packet = pecalloc(1, packet_methods[PROT_CHG_USER_RESP_PACKET].struct_size, persistent);
+       struct st_mysqlnd_packet_chg_user_resp * packet = mnd_pecalloc(1, packet_methods[PROT_CHG_USER_RESP_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_change_user_response_packet");
        packet->header.m = &packet_methods[PROT_CHG_USER_RESP_PACKET];
        packet->header.persistent = persistent;
index 8e36b1fac9a11d6cdbac9621f3b975a15e7c0eb3..82f0465df34e80a292be68a88b1d628daf639467 100644 (file)
@@ -41,7 +41,9 @@ PHPAPI extern const char mysqlnd_read_body_name[];
 #define PACKET_FREE(packet) \
        do { \
                DBG_INF_FMT("PACKET_FREE(%p)", packet); \
-               ((packet)->header.m->free_mem((packet), FALSE TSRMLS_CC)); \
+               if ((packet)) { \
+                       ((packet)->header.m->free_mem((packet), FALSE TSRMLS_CC)); \
+               } \
        } while (0);
 
 PHPAPI extern const char * const mysqlnd_command_to_text[COM_END];