summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorAndrey Hristov <andrey@php.net>2010-03-29 17:04:16 +0000
committerAndrey Hristov <andrey@php.net>2010-03-29 17:04:16 +0000
commit94cd357f5b4a2533510e382e08861269f57602e0 (patch)
tree65d0d2b969cd8f31eb6af1fbe908c9db965224f1 /ext
parente99039d69269445ea7a786cff6086a314d301da0 (diff)
downloadphp-git-94cd357f5b4a2533510e382e08861269f57602e0.tar.gz
Make it coupled - what is allocated with mnd_ should be freed
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.
Diffstat (limited to 'ext')
-rw-r--r--ext/mysqli/tests/mysqli_constants.phpt5
-rw-r--r--ext/mysqli/tests/mysqli_get_client_stats.phpt10
-rw-r--r--ext/mysqli/tests/mysqli_options.phpt6
-rw-r--r--ext/mysqli/tests/mysqli_set_opt_numeric_and_datetime_as_unicode.phpt150
-rw-r--r--ext/mysqlnd/mysqlnd.c80
-rw-r--r--ext/mysqlnd/mysqlnd_debug.c40
-rw-r--r--ext/mysqlnd/mysqlnd_debug.h34
-rw-r--r--ext/mysqlnd/mysqlnd_enum_n_def.h4
-rw-r--r--ext/mysqlnd/mysqlnd_statistics.c4
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.c32
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.h4
11 files changed, 137 insertions, 232 deletions
diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt
index 32a259350a..418eb070e5 100644
--- a/ext/mysqli/tests/mysqli_constants.phpt
+++ b/ext/mysqli/tests/mysqli_constants.phpt
@@ -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 ?
diff --git a/ext/mysqli/tests/mysqli_get_client_stats.phpt b/ext/mysqli/tests/mysqli_get_client_stats.phpt
index 74c0cc800b..9446d072e9 100644
--- a/ext/mysqli/tests/mysqli_get_client_stats.phpt
+++ b/ext/mysqli/tests/mysqli_get_client_stats.phpt
@@ -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"]=>
diff --git a/ext/mysqli/tests/mysqli_options.phpt b/ext/mysqli/tests/mysqli_options.phpt
index 1da140b397..1d5955b55e 100644
--- a/ext/mysqli/tests/mysqli_options.phpt
+++ b/ext/mysqli/tests/mysqli_options.phpt
@@ -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
index 7e0593cb50..0000000000
--- a/ext/mysqli/tests/mysqli_set_opt_numeric_and_datetime_as_unicode.phpt
+++ /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
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index 4f89b8c57e..6d313c161b 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -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
diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c
index 4ede83663f..1eedbdf00b 100644
--- a/ext/mysqlnd/mysqlnd_debug.c
+++ b/ext/mysqlnd/mysqlnd_debug.c
@@ -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 */
diff --git a/ext/mysqlnd/mysqlnd_debug.h b/ext/mysqlnd/mysqlnd_debug.h
index 96c953c24d..dc9d0a7dfb 100644
--- a/ext/mysqlnd/mysqlnd_debug.h
+++ b/ext/mysqlnd/mysqlnd_debug.h
@@ -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
diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h
index 8404fbeb6e..9b17f60fe6 100644
--- a/ext/mysqlnd/mysqlnd_enum_n_def.h
+++ b/ext/mysqlnd/mysqlnd_enum_n_def.h
@@ -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,
diff --git a/ext/mysqlnd/mysqlnd_statistics.c b/ext/mysqlnd/mysqlnd_statistics.c
index e52414b3e8..2e7665d8a7 100644
--- a/ext/mysqlnd/mysqlnd_statistics.c
+++ b/ext/mysqlnd/mysqlnd_statistics.c
@@ -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") },
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index 0966683565..03f8550b28 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -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;
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h
index 8e36b1fac9..82f0465df3 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.h
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.h
@@ -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];