summaryrefslogtreecommitdiff
path: root/ext/mysqli
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mysqli')
-rw-r--r--ext/mysqli/config.m47
-rw-r--r--ext/mysqli/mysqli.c228
-rw-r--r--ext/mysqli/mysqli_api.c203
-rw-r--r--ext/mysqli/mysqli_fe.c82
-rw-r--r--ext/mysqli/mysqli_fe.h4
-rw-r--r--ext/mysqli/mysqli_libmysql.h12
-rw-r--r--ext/mysqli/mysqli_nonapi.c167
-rw-r--r--ext/mysqli/mysqli_priv.h1
-rw-r--r--ext/mysqli/mysqli_prop.c4
-rw-r--r--ext/mysqli/mysqli_report.h64
-rw-r--r--ext/mysqli/mysqli_result_iterator.c5
-rw-r--r--ext/mysqli/package.xml1
-rw-r--r--ext/mysqli/php_mysqli_structs.h12
-rw-r--r--ext/mysqli/tests/057.phpt4
-rw-r--r--ext/mysqli/tests/connect.inc93
-rw-r--r--ext/mysqli/tests/mysqli_class_mysqli_interface.phpt49
-rw-r--r--ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt110
-rw-r--r--ext/mysqli/tests/mysqli_commit_oo.phpt6
-rw-r--r--ext/mysqli/tests/mysqli_constants.phpt19
-rw-r--r--ext/mysqli/tests/mysqli_expire_password.phpt8
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field.phpt22
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field_oo.phpt21
-rw-r--r--ext/mysqli/tests/mysqli_fetch_fields.phpt20
-rw-r--r--ext/mysqli/tests/mysqli_field_seek.phpt22
-rw-r--r--ext/mysqli/tests/mysqli_info.phpt8
-rw-r--r--ext/mysqli/tests/mysqli_pam_sha256.phpt113
-rw-r--r--ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt129
-rw-r--r--ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt132
-rw-r--r--ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt188
-rw-r--r--ext/mysqli/tests/mysqli_query_local_infile_large.phpt103
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_default.phpt132
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler.phpt196
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt82
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt60
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt61
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt70
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt62
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt61
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt58
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt107
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt71
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt70
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt115
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt78
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt101
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt64
-rw-r--r--ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt21
47 files changed, 1169 insertions, 2077 deletions
diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4
index 687b422898..f6c86e762b 100644
--- a/ext/mysqli/config.m4
+++ b/ext/mysqli/config.m4
@@ -3,13 +3,14 @@ dnl $Id$
dnl config.m4 for extension mysqli
PHP_ARG_WITH(mysqli, for MySQLi support,
-[ --with-mysqli[=FILE] Include MySQLi support. FILE is the path
+[ --with-mysqli[=FILE] Include MySQLi support. FILE is the path
to mysql_config. If no value or mysqlnd is passed
as FILE, the MySQL native driver will be used])
PHP_ARG_ENABLE(embedded_mysqli, whether to enable embedded MySQLi support,
-[ --enable-embedded-mysqli MYSQLi: Enable embedded support
- Note: Does not work with MySQL native driver!], no, no)
+[ --enable-embedded-mysqli
+ MYSQLi: Enable embedded support
+ Note: Does not work with MySQL native driver!], no, no)
if test "$PHP_MYSQLI" = "yes" || test "$PHP_MYSQLI" = "mysqlnd"; then
dnl This needs to be set in any extension which wishes to use mysqlnd
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index 2710b9de23..ad4e25c66f 100644
--- a/ext/mysqli/mysqli.c
+++ b/ext/mysqli/mysqli.c
@@ -699,6 +699,10 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
#endif
+#if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND)
+ REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PUBLIC_KEY", MYSQL_SERVER_PUBLIC_KEY, CONST_CS | CONST_PERSISTENT);
+#endif
+
/* mysqli_real_connect flags */
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT);
@@ -838,10 +842,20 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_CS | CONST_PERSISTENT);
#endif
-#if MYSQL_VERSION_ID >= 50611 || defined(MYSQLI_USE_MYSQLND)
+#if (MYSQL_VERSION_ID >= 50611 && defined(CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) || defined(MYSQLI_USE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_CS | CONST_PERSISTENT);
#endif
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT", TRANS_START_WITH_CONSISTENT_SNAPSHOT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_WRITE", TRANS_START_READ_WRITE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_ONLY", TRANS_START_READ_ONLY, CONST_CS | CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_AND_CHAIN", TRANS_COR_AND_CHAIN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_AND_NO_CHAIN", TRANS_COR_AND_NO_CHAIN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_RELEASE", TRANS_COR_RELEASE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_NO_RELEASE", TRANS_COR_NO_RELEASE, CONST_CS | CONST_PERSISTENT);
+
+
#ifdef MYSQLI_USE_MYSQLND
mysqlnd_reverse_api_register_api(&mysqli_reverse_api TSRMLS_CC);
#endif
@@ -1324,218 +1338,6 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
}
/* }}} */
-
-#if !defined(MYSQLI_USE_MYSQLND)
-
-#define ALLOC_CALLBACK_ARGS(a, b, c)\
-if (c) {\
- a = (zval ***)safe_emalloc(c, sizeof(zval **), 0);\
- for (i = b; i < c; i++) {\
- a[i] = emalloc(sizeof(zval *));\
- MAKE_STD_ZVAL(*a[i]);\
- }\
-}
-
-#define FREE_CALLBACK_ARGS(a, b, c)\
-if (a) {\
- for (i=b; i < c; i++) {\
- zval_ptr_dtor(a[i]);\
- efree(a[i]);\
- }\
- efree(a);\
-}
-
-#define LOCAL_INFILE_ERROR_MSG(source,dest)\
- memset(source, 0, LOCAL_INFILE_ERROR_LEN);\
- memcpy(source, dest, MIN(strlen(dest), LOCAL_INFILE_ERROR_LEN-1));\
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", dest);
-
-
-/* {{{ php_local_infile_init
- */
-static int php_local_infile_init(void **ptr, const char *filename, void *userdata)
-{
- mysqli_local_infile *data;
- MY_MYSQL *mysql;
- php_stream_context *context = NULL;
-
- TSRMLS_FETCH();
-
- /* save pointer to MY_MYSQL structure (userdata) */
- if (!(*ptr= data= ((mysqli_local_infile *)calloc(1, sizeof(mysqli_local_infile))))) {
- return 1;
- }
-
- if (!(mysql = (MY_MYSQL *)userdata)) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
- return 1;
- }
-
- /* check open_basedir */
- if (PG(open_basedir)) {
- if (php_check_open_basedir_ex(filename, 0 TSRMLS_CC) == -1) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "open_basedir restriction in effect. Unable to open file");
- return 1;
- }
- }
-
- mysql->li_stream = php_stream_open_wrapper_ex((char *)filename, "r", 0, NULL, context);
-
- if (mysql->li_stream == NULL) {
- snprintf((char *)data->error_msg, sizeof(data->error_msg), "Can't find file '%-.64s'.", filename);
- return 1;
- }
-
- data->userdata = mysql;
-
- return 0;
-}
-/* }}} */
-
-/* {{{ int php_local_infile_read */
-static int php_local_infile_read(void *ptr, char *buf, uint buf_len)
-{
- mysqli_local_infile *data;
- MY_MYSQL *mysql;
- zval ***callback_args;
- zval *retval;
- zval *fp;
- int argc = 4;
- int i;
- long rc;
-
- TSRMLS_FETCH();
-
- data= (mysqli_local_infile *)ptr;
- mysql = data->userdata;
-
- /* default processing */
- if (!mysql->li_read) {
- int count = (int)php_stream_read(mysql->li_stream, buf, buf_len);
-
- if (count < 0) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(2));
- }
-
- return count;
- }
-
- ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
-
- /* set parameters: filepointer, buffer, buffer_len, errormsg */
-
- MAKE_STD_ZVAL(fp);
- php_stream_to_zval(mysql->li_stream, fp);
- callback_args[0] = &fp;
- ZVAL_STRING(*callback_args[1], "", 1);
- ZVAL_LONG(*callback_args[2], buf_len);
- ZVAL_STRING(*callback_args[3], "", 1);
-
- if (call_user_function_ex(EG(function_table),
- NULL,
- mysql->li_read,
- &retval,
- argc,
- callback_args,
- 0,
- NULL TSRMLS_CC) == SUCCESS) {
-
- rc = Z_LVAL_P(retval);
- zval_ptr_dtor(&retval);
-
- if (rc > 0) {
- if (rc >= 0 && rc != Z_STRLEN_P(*callback_args[1])) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg,
- "Mismatch between the return value of the callback and the content "
- "length of the buffer.");
- rc = -1;
- } else if (rc > buf_len) {
- /* check buffer overflow */
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "Too much data returned");
- rc = -1;
- } else {
- memcpy(buf, Z_STRVAL_P(*callback_args[1]), MIN(rc, Z_STRLEN_P(*callback_args[1])));
- }
- } else if (rc < 0) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[3]));
- }
- } else {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
- rc = -1;
- }
- /*
- If the (ab)user has closed the file handle we should
- not try to use it anymore or even close it
- */
- if (!zend_rsrc_list_get_rsrc_type(Z_LVAL_P(fp) TSRMLS_CC)) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "File handle closed");
- rc = -1;
- /* Thus the end handler won't try to free already freed memory */
- mysql->li_stream = NULL;
- }
-
- FREE_CALLBACK_ARGS(callback_args, 1, argc);
- efree(fp);
- return rc;
-}
-/* }}} */
-
-/* {{{ php_local_infile_error
- */
-static int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
-{
- mysqli_local_infile *data = (mysqli_local_infile *) ptr;
-
- if (data) {
- strlcpy(error_msg, data->error_msg, error_msg_len);
- return 2000;
- }
- strlcpy(error_msg, ER(CR_OUT_OF_MEMORY), error_msg_len);
- return CR_OUT_OF_MEMORY;
-}
-/* }}} */
-
-/* {{{ php_local_infile_end
- */
-static void php_local_infile_end(void *ptr)
-{
- mysqli_local_infile *data;
- MY_MYSQL *mysql;
-
- TSRMLS_FETCH();
-
- data= (mysqli_local_infile *)ptr;
-
- if (!data || !(mysql = data->userdata)) {
- if (data) {
- free(data);
- }
- return;
- }
-
- if (mysql->li_stream) {
- php_stream_close(mysql->li_stream);
- }
- free(data);
- return;
-}
-/* }}} */
-
-
-/* {{{ void php_set_local_infile_handler_default
-*/
-void php_set_local_infile_handler_default(MY_MYSQL *mysql) {
- /* register internal callback functions */
- mysql_set_local_infile_handler(mysql->mysql, &php_local_infile_init, &php_local_infile_read,
- &php_local_infile_end, &php_local_infile_error, (void *)mysql);
- if (mysql->li_read) {
- zval_ptr_dtor(&mysql->li_read);
- mysql->li_read = NULL;
- }
-}
-/* }}} */
-#endif
-
/*
* Local variables:
* tab-width: 4
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
index 6078a5e758..e67aba8da0 100644
--- a/ext/mysqli/mysqli_api.c
+++ b/ext/mysqli/mysqli_api.c
@@ -30,6 +30,7 @@
#include "php_ini.h"
#include "php_globals.h"
#include "ext/standard/info.h"
+#include "ext/standard/php_smart_str.h"
#include "php_mysqli_structs.h"
#include "mysqli_priv.h"
@@ -566,14 +567,17 @@ PHP_FUNCTION(mysqli_character_set_name)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ const char *cs_name;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
-
- RETURN_STRING((char *)mysql_character_set_name(mysql->mysql), 1);
+ cs_name = mysql_character_set_name(mysql->mysql);
+ if (cs_name) {
+ RETURN_STRING(cs_name, 1);
+ }
}
/* }}} */
@@ -632,18 +636,86 @@ PHP_FUNCTION(mysqli_close)
}
/* }}} */
+
+#if !defined(MYSQLI_USE_MYSQLND)
+/* {{{ mysqli_tx_cor_options_to_string */
+static void mysqli_tx_cor_options_to_string(const MYSQL * const conn, smart_str * str, const unsigned int mode)
+{
+ if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1);
+ } else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & TRANS_COR_AND_CHAIN)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 1);
+ }
+
+ if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1);
+ } else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1);
+ }
+ smart_str_0(str);
+}
+/* }}} */
+
+
+/* {{{ proto bool mysqli_commit_or_rollback_libmysql */
+static int mysqli_commit_or_rollback_libmysql(MYSQL * conn, zend_bool commit, const unsigned int mode, const char * const name)
+{
+ int ret;
+ smart_str tmp_str = {0, 0, 0};
+ mysqli_tx_cor_options_to_string(conn, &tmp_str, mode);
+ smart_str_0(&tmp_str);
+
+ {
+ char * commented_name = NULL;
+ unsigned int commented_name_len = name? spprintf(&commented_name, 0, " /*%s*/", name):0;
+ char * query;
+ unsigned int query_len = spprintf(&query, 0, (commit? "COMMIT%s %s":"ROLLBACK%s %s"),
+ commented_name? commented_name:"", tmp_str.c? tmp_str.c:"");
+ smart_str_free(&tmp_str);
+
+ ret = mysql_real_query(conn, query, query_len);
+ efree(query);
+ if (commented_name) {
+ efree(commented_name);
+ }
+ }
+}
+/* }}} */
+#endif
+
+
/* {{{ proto bool mysqli_commit(object link)
Commit outstanding actions and close transaction */
PHP_FUNCTION(mysqli_commit)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ long flags = TRANS_COR_NO_OPT;
+ char * name = NULL;
+ int name_len = 0;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- if (mysql_commit(mysql->mysql)) {
+
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_commit_or_rollback_libmysql(mysql->mysql, TRUE, flags, name)) {
+#else
+ if (FAIL == mysqlnd_commit(mysql->mysql, flags, name)) {
+#endif
RETURN_FALSE;
}
RETURN_TRUE;
@@ -732,12 +804,16 @@ PHP_FUNCTION(mysqli_error)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ const char *err;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- RETURN_STRING((char *)mysql_error(mysql->mysql),1);
+ err = mysql_error(mysql->mysql);
+ if (err) {
+ RETURN_STRING(err, 1);
+ }
}
/* }}} */
@@ -1268,7 +1344,10 @@ PHP_FUNCTION(mysqli_free_result)
Get MySQL client info */
PHP_FUNCTION(mysqli_get_client_info)
{
- RETURN_STRING((char *)mysql_get_client_info(), 1);
+ const char * info = mysql_get_client_info();
+ if (info) {
+ RETURN_STRING(info, 1);
+ }
}
/* }}} */
@@ -1320,15 +1399,18 @@ PHP_FUNCTION(mysqli_get_server_info)
{
MY_MYSQL *mysql;
zval *mysql_link = NULL;
+ const char *info;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- RETURN_STRING((char *)mysql_get_server_info(mysql->mysql), 1);
+ info = mysql_get_server_info(mysql->mysql);
+ if (info) {
+ RETURN_STRING(info, 1);
+ }
}
-
/* }}} */
/* {{{ proto int mysqli_get_server_version(object link)
@@ -1361,7 +1443,9 @@ PHP_FUNCTION(mysqli_info)
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
info = mysql_info(mysql->mysql);
- RETURN_STRING((info) ? (char *)info : "", 1);
+ if (info) {
+ RETURN_STRING(info, 1);
+ }
}
/* }}} */
@@ -1456,64 +1540,6 @@ PHP_FUNCTION(mysqli_kill)
}
/* }}} */
-/* {{{ proto void mysqli_set_local_infile_default(object link)
- unsets user defined handler for load local infile command */
-#if !defined(MYSQLI_USE_MYSQLND)
-PHP_FUNCTION(mysqli_set_local_infile_default)
-{
- MY_MYSQL *mysql;
- zval *mysql_link;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
- return;
- }
-
- MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
-
- if (mysql->li_read) {
- zval_ptr_dtor(&(mysql->li_read));
- mysql->li_read = NULL;
- }
-}
-/* }}} */
-
-/* {{{ proto bool mysqli_set_local_infile_handler(object link, callback read_func)
- Set callback functions for LOAD DATA LOCAL INFILE */
-PHP_FUNCTION(mysqli_set_local_infile_handler)
-{
- MY_MYSQL *mysql;
- zval *mysql_link;
- char *callback_name;
- zval *callback_func;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &mysql_link, mysqli_link_class_entry,
- &callback_func) == FAILURE) {
- return;
- }
-
- MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
-
- /* check callback function */
- if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name);
- efree(callback_name);
- RETURN_FALSE;
- }
- efree(callback_name);
-
- /* save callback function */
- if (!mysql->li_read) {
- MAKE_STD_ZVAL(mysql->li_read);
- } else {
- zval_dtor(mysql->li_read);
- }
- ZVAL_ZVAL(mysql->li_read, callback_func, 1, 0);
-
- RETURN_TRUE;
-}
-#endif
-/* }}} */
-
/* {{{ proto bool mysqli_more_results(object link)
check if there any more query results from a multi query */
PHP_FUNCTION(mysqli_more_results)
@@ -1645,10 +1671,10 @@ static int mysqli_options_get_option_zval_type(int option)
#endif /* MYSQLI_USE_MYSQLND */
case MYSQL_OPT_CONNECT_TIMEOUT:
#ifdef MYSQL_REPORT_DATA_TRUNCATION
- case MYSQL_REPORT_DATA_TRUNCATION:
+ case MYSQL_REPORT_DATA_TRUNCATION:
#endif
- case MYSQL_OPT_LOCAL_INFILE:
- case MYSQL_OPT_NAMED_PIPE:
+ case MYSQL_OPT_LOCAL_INFILE:
+ case MYSQL_OPT_NAMED_PIPE:
#ifdef MYSQL_OPT_PROTOCOL
case MYSQL_OPT_PROTOCOL:
#endif /* MySQL 4.1.0 */
@@ -1664,7 +1690,7 @@ static int mysqli_options_get_option_zval_type(int option)
case MYSQL_OPT_RECONNECT:
#endif /* MySQL 5.0.13 */
#ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
- case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
+ case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
#endif /* MySQL 5.0.23 */
#ifdef MYSQL_OPT_COMPRESS
case MYSQL_OPT_COMPRESS:
@@ -1672,7 +1698,7 @@ static int mysqli_options_get_option_zval_type(int option)
#ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
#endif /* MySQL 5.1.1., mysqlnd @ PHP 5.3.3 */
-#if MYSQL_VERSION_ID >= 50611 || defined(MYSQLI_USE_MYSQLND)
+#if (MYSQL_VERSION_ID >= 50611 && defined(CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) || defined(MYSQLI_USE_MYSQLND)
case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
#endif
return IS_LONG;
@@ -1688,6 +1714,9 @@ static int mysqli_options_get_option_zval_type(int option)
case MYSQL_INIT_COMMAND:
case MYSQL_SET_CHARSET_NAME:
case MYSQL_SET_CHARSET_DIR:
+#if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND)
+ case MYSQL_SERVER_PUBLIC_KEY:
+#endif
return IS_STRING;
default:
@@ -1912,19 +1941,27 @@ PHP_FUNCTION(mysqli_real_escape_string) {
}
/* }}} */
+
/* {{{ proto bool mysqli_rollback(object link)
Undo actions from current transaction */
PHP_FUNCTION(mysqli_rollback)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ long flags = TRANS_COR_NO_OPT;
+ char * name = NULL;
+ int name_len = 0;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- if (mysql_rollback(mysql->mysql)) {
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_commit_or_rollback_libmysql(mysql->mysql, FALSE, flags, name)) {
+#else
+ if (FAIL == mysqlnd_rollback(mysql->mysql, flags, name)) {
+#endif
RETURN_FALSE;
}
RETURN_TRUE;
@@ -2154,12 +2191,16 @@ PHP_FUNCTION(mysqli_sqlstate)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ const char *state;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- RETURN_STRING((char *)mysql_sqlstate(mysql->mysql),1);
+ state = mysql_sqlstate(mysql->mysql);
+ if (state) {
+ RETURN_STRING(state, 1);
+ }
}
/* }}} */
@@ -2337,13 +2378,17 @@ PHP_FUNCTION(mysqli_stmt_error)
{
MY_STMT *stmt;
zval *mysql_stmt;
+ const char * err;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
- RETURN_STRING((char *)mysql_stmt_error(stmt->stmt),1);
+ err = mysql_stmt_error(stmt->stmt);
+ if (err) {
+ RETURN_STRING(err, 1);
+ }
}
/* }}} */
@@ -2482,13 +2527,17 @@ PHP_FUNCTION(mysqli_stmt_sqlstate)
{
MY_STMT *stmt;
zval *mysql_stmt;
+ const char * state;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
- RETURN_STRING((char *)mysql_stmt_sqlstate(stmt->stmt),1);
+ state = mysql_stmt_sqlstate(stmt->stmt);
+ if (state) {
+ RETURN_STRING(state, 1);
+ }
}
/* }}} */
diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c
index 8bcb02fdc5..6f2e404087 100644
--- a/ext/mysqli/mysqli_fe.c
+++ b/ext/mysqli/mysqli_fe.c
@@ -86,6 +86,56 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_autocommit, 0, 0, 1)
ZEND_ARG_INFO(0, mode)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_begin_transaction, 0, 0, 1)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_begin_transaction, 0, 0, 0)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_savepoint, 0, 0, 2)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_savepoint, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_release_savepoint, 0, 0, 2)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_release_savepoint, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_commit, 0, 0, 1)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_commit, 0, 0, 0)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_rollback, 0, 0, 1)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_rollback, 0, 0, 0)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_change_user, 0, 0, 4)
MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
@@ -200,16 +250,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_kill, 0, 0, 1)
ZEND_ARG_INFO(0, connection_id)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_set_local_infile_handler, 0, 0, 2)
- MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
- ZEND_ARG_INFO(0, read_callback)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_set_local_infile_handler, 0, 0, 1)
- MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
- ZEND_ARG_INFO(0, read_callback)
-ZEND_END_ARG_INFO()
-
ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_query, 0, 0, 2)
MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
ZEND_ARG_INFO(0, query)
@@ -336,10 +376,11 @@ ZEND_END_ARG_INFO()
const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_affected_rows, arginfo_mysqli_only_link)
PHP_FE(mysqli_autocommit, arginfo_mysqli_autocommit)
+ PHP_FE(mysqli_begin_transaction, arginfo_mysqli_begin_transaction)
PHP_FE(mysqli_change_user, arginfo_mysqli_change_user)
PHP_FE(mysqli_character_set_name, arginfo_mysqli_only_link)
PHP_FE(mysqli_close, arginfo_mysqli_only_link)
- PHP_FE(mysqli_commit, arginfo_mysqli_only_link)
+ PHP_FE(mysqli_commit, arginfo_mysqli_commit)
PHP_FE(mysqli_connect, arginfo_mysqli_connect)
PHP_FE(mysqli_connect_errno, arginfo_mysqli_no_params)
PHP_FE(mysqli_connect_error, arginfo_mysqli_no_params)
@@ -388,10 +429,6 @@ const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_info, arginfo_mysqli_only_link)
PHP_FE(mysqli_insert_id, arginfo_mysqli_only_link)
PHP_FE(mysqli_kill, arginfo_mysqli_kill)
-#if !defined(MYSQLI_USE_MYSQLND)
- PHP_FE(mysqli_set_local_infile_default, arginfo_mysqli_only_link)
- PHP_FE(mysqli_set_local_infile_handler, arginfo_mysqli_set_local_infile_handler)
-#endif
PHP_FE(mysqli_more_results, arginfo_mysqli_only_link)
PHP_FE(mysqli_multi_query, arginfo_mysqli_query)
PHP_FE(mysqli_next_result, arginfo_mysqli_only_link)
@@ -411,7 +448,9 @@ const zend_function_entry mysqli_functions[] = {
#if defined(MYSQLI_USE_MYSQLND)
PHP_FE(mysqli_reap_async_query, arginfo_mysqli_only_link)
#endif
- PHP_FE(mysqli_rollback, arginfo_mysqli_only_link)
+ PHP_FE(mysqli_release_savepoint, arginfo_mysqli_release_savepoint)
+ PHP_FE(mysqli_rollback, arginfo_mysqli_rollback)
+ PHP_FE(mysqli_savepoint, arginfo_mysqli_savepoint)
PHP_FE(mysqli_select_db, arginfo_mysqli_select_db)
#ifdef HAVE_MYSQLI_SET_CHARSET
PHP_FE(mysqli_set_charset, arginfo_mysqli_set_charset)
@@ -472,10 +511,11 @@ const zend_function_entry mysqli_functions[] = {
*/
const zend_function_entry mysqli_link_methods[] = {
PHP_FALIAS(autocommit, mysqli_autocommit, arginfo_class_mysqli_autocommit)
+ PHP_FALIAS(begin_transaction, mysqli_begin_transaction, arginfo_class_mysqli_begin_transaction)
PHP_FALIAS(change_user,mysqli_change_user, arginfo_class_mysqli_change_user)
PHP_FALIAS(character_set_name, mysqli_character_set_name, arginfo_mysqli_no_params)
PHP_FALIAS(close, mysqli_close, arginfo_mysqli_no_params)
- PHP_FALIAS(commit, mysqli_commit, arginfo_mysqli_no_params)
+ PHP_FALIAS(commit, mysqli_commit, arginfo_class_mysqli_commit)
PHP_FALIAS(connect, mysqli_connect, arginfo_mysqli_connect)
PHP_FALIAS(dump_debug_info, mysqli_dump_debug_info, arginfo_mysqli_no_params)
PHP_FALIAS(debug, mysqli_debug, arginfo_mysqli_debug)
@@ -490,10 +530,6 @@ const zend_function_entry mysqli_link_methods[] = {
PHP_FALIAS(get_warnings, mysqli_get_warnings, arginfo_mysqli_no_params)
PHP_FALIAS(init,mysqli_init, arginfo_mysqli_no_params)
PHP_FALIAS(kill,mysqli_kill, arginfo_class_mysqli_kill)
-#if !defined(MYSQLI_USE_MYSQLND)
- PHP_FALIAS(set_local_infile_default, mysqli_set_local_infile_default, arginfo_mysqli_no_params)
- PHP_FALIAS(set_local_infile_handler, mysqli_set_local_infile_handler, arginfo_class_mysqli_set_local_infile_handler)
-#endif
PHP_FALIAS(multi_query, mysqli_multi_query, arginfo_class_mysqli_query)
PHP_FALIAS(mysqli, mysqli_link_construct, arginfo_mysqli_connect)
PHP_FALIAS(more_results, mysqli_more_results, arginfo_mysqli_no_params)
@@ -512,7 +548,9 @@ const zend_function_entry mysqli_link_methods[] = {
#endif
PHP_FALIAS(escape_string, mysqli_real_escape_string, arginfo_class_mysqli_real_escape_string)
PHP_FALIAS(real_query, mysqli_real_query, arginfo_class_mysqli_query)
- PHP_FALIAS(rollback,mysqli_rollback, arginfo_mysqli_no_params)
+ PHP_FALIAS(release_savepoint, mysqli_release_savepoint, arginfo_class_mysqli_release_savepoint)
+ PHP_FALIAS(rollback, mysqli_rollback, arginfo_class_mysqli_rollback)
+ PHP_FALIAS(savepoint, mysqli_savepoint, arginfo_class_mysqli_savepoint)
PHP_FALIAS(select_db,mysqli_select_db, arginfo_class_mysqli_select_db)
#ifdef HAVE_MYSQLI_SET_CHARSET
PHP_FALIAS(set_charset, mysqli_set_charset, arginfo_class_mysqli_set_charset)
diff --git a/ext/mysqli/mysqli_fe.h b/ext/mysqli/mysqli_fe.h
index d3e900003e..7e447c63e5 100644
--- a/ext/mysqli/mysqli_fe.h
+++ b/ext/mysqli/mysqli_fe.h
@@ -25,6 +25,7 @@
PHP_FUNCTION(mysqli);
PHP_FUNCTION(mysqli_affected_rows);
PHP_FUNCTION(mysqli_autocommit);
+PHP_FUNCTION(mysqli_begin_transaction);
PHP_FUNCTION(mysqli_change_user);
PHP_FUNCTION(mysqli_character_set_name);
PHP_FUNCTION(mysqli_set_charset);
@@ -107,6 +108,8 @@ PHP_FUNCTION(mysqli_sqlstate);
PHP_FUNCTION(mysqli_ssl_set);
PHP_FUNCTION(mysqli_stat);
PHP_FUNCTION(mysqli_refresh);
+PHP_FUNCTION(mysqli_savepoint);
+PHP_FUNCTION(mysqli_release_savepoint);
PHP_FUNCTION(mysqli_stmt_affected_rows);
PHP_FUNCTION(mysqli_stmt_close);
PHP_FUNCTION(mysqli_stmt_data_seek);
@@ -136,4 +139,3 @@ PHP_METHOD(mysqli_warning,__construct);
#endif /* MYSQLI_FE_H */
-
diff --git a/ext/mysqli/mysqli_libmysql.h b/ext/mysqli/mysqli_libmysql.h
index 3a7b91b995..e10e3702ea 100644
--- a/ext/mysqli/mysqli_libmysql.h
+++ b/ext/mysqli/mysqli_libmysql.h
@@ -42,6 +42,18 @@
#define mysqli_change_user_silent(c, u, p, d, p_len) mysql_change_user((c), (u), (p), (d))
+#define TRANS_START_NO_OPT 0
+#define TRANS_START_WITH_CONSISTENT_SNAPSHOT 1
+#define TRANS_START_READ_WRITE 2
+#define TRANS_START_READ_ONLY 4
+
+#define TRANS_COR_NO_OPT 0
+#define TRANS_COR_AND_CHAIN 1
+#define TRANS_COR_AND_NO_CHAIN 2
+#define TRANS_COR_RELEASE 4
+#define TRANS_COR_NO_RELEASE 8
+
+
/*
These functions also reside in ext/mysqlnd/mysqlnd_portability.h but since it is only made
available if one wants to build mysqli against mysqlnd and they are useful for libmysql as
diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c
index 35ea163ccf..b5630c3e7f 100644
--- a/ext/mysqli/mysqli_nonapi.c
+++ b/ext/mysqli/mysqli_nonapi.c
@@ -29,6 +29,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
+#include "ext/standard/php_smart_str.h"
#include "php_mysqli_structs.h"
#include "mysqli_priv.h"
@@ -259,9 +260,6 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne
#if !defined(MYSQLI_USE_MYSQLND)
mysql->mysql->reconnect = MyG(reconnect);
-
- /* set our own local_infile handler */
- php_set_local_infile_handler_default(mysql);
#endif
mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile));
@@ -737,7 +735,7 @@ static int mysqlnd_dont_poll_zval_array_from_mysqlnd_array(MYSQLND **in_array, z
int ret = 0;
ALLOC_HASHTABLE(new_hash);
- zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(in_zval_array)), NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_init(new_hash, in_zval_array? zend_hash_num_elements(Z_ARRVAL_P(in_zval_array)):0, NULL, ZVAL_PTR_DTOR, 0);
if (in_array) {
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(in_zval_array));
zend_hash_get_current_data(Z_ARRVAL_P(in_zval_array), (void **) &elem) == SUCCESS;
@@ -1048,6 +1046,167 @@ PHP_FUNCTION(mysqli_get_charset)
/* }}} */
#endif
+
+#if !defined(MYSQLI_USE_MYSQLND)
+/* {{{ proto bool mysqli_begin_transaction_libmysql */
+static int mysqli_begin_transaction_libmysql(MYSQL * conn, const unsigned int mode, const char * const name)
+{
+ int ret;
+ smart_str tmp_str = {0, 0, 0};
+ if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
+ }
+ if (mode & TRANS_START_READ_WRITE) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
+ }
+ if (mode & TRANS_START_READ_ONLY) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
+ }
+ smart_str_0(&tmp_str);
+
+ {
+ char * commented_name = NULL;
+ unsigned int commented_name_len = name? spprintf(&commented_name, 0, " /*%s*/", name):0;
+ char * query;
+ unsigned int query_len = spprintf(&query, 0, "START TRANSACTION%s %s",
+ commented_name? commented_name:"", tmp_str.c? tmp_str.c:"");
+ smart_str_free(&tmp_str);
+
+ ret = mysql_real_query(conn, query, query_len);
+ efree(query);
+ if (commented_name) {
+ efree(commented_name);
+ }
+ }
+ return ret;
+}
+/* }}} */
+#endif
+
+/* {{{ proto bool mysqli_begin_transaction(object link, [int flags [, string name]])
+ Starts a transaction */
+PHP_FUNCTION(mysqli_begin_transaction)
+{
+ MY_MYSQL *mysql;
+ zval *mysql_link;
+ long flags = TRANS_START_NO_OPT;
+ char * name = NULL;
+ int name_len = -1;
+ zend_bool err = FALSE;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
+ if (flags < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for parameter flags (%ld)", flags);
+ err = TRUE;
+ }
+ if (!name_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Savepoint name cannot be empty");
+ err = TRUE;
+ }
+ if (TRUE == err) {
+ RETURN_FALSE;
+ }
+
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_begin_transaction_libmysql(mysql->mysql, flags, name)) {
+ RETURN_FALSE;
+ }
+#else
+ if (FAIL == mysqlnd_begin_transaction(mysql->mysql, flags, name)) {
+ RETURN_FALSE;
+ }
+#endif
+ RETURN_TRUE;
+}
+/* }}} */
+
+
+#if !defined(MYSQLI_USE_MYSQLND)
+/* {{{ proto bool mysqli_savepoint_libmysql */
+static int mysqli_savepoint_libmysql(MYSQL * conn, const char * const name, zend_bool release)
+{
+ int ret;
+ char * query;
+ unsigned int query_len = spprintf(&query, 0, release? "RELEASE SAVEPOINT `%s`":"SAVEPOINT `%s`", name);
+ ret = mysql_real_query(conn, query, query_len);
+ efree(query);
+ return ret;
+}
+/* }}} */
+#endif
+
+
+/* {{{ proto bool mysqli_savepoint(object link, string name)
+ Starts a transaction */
+PHP_FUNCTION(mysqli_savepoint)
+{
+ MY_MYSQL *mysql;
+ zval *mysql_link;
+ char * name = NULL;
+ int name_len = -1;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
+ if (!name || !name_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Savepoint name cannot be empty");
+ RETURN_FALSE;
+ }
+
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_savepoint_libmysql(mysql->mysql, name, FALSE)) {
+#else
+ if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
+#endif
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+
+/* {{{ proto bool mysqli_release_savepoint(object link, string name)
+ Starts a transaction */
+PHP_FUNCTION(mysqli_release_savepoint)
+{
+ MY_MYSQL *mysql;
+ zval *mysql_link;
+ char * name = NULL;
+ int name_len = -1;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
+ if (!name || !name_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Savepoint name cannot be empty");
+ RETURN_FALSE;
+ }
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_savepoint_libmysql(mysql->mysql, name, TRUE)) {
+#else
+ if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
+#endif
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/mysqli/mysqli_priv.h b/ext/mysqli/mysqli_priv.h
index f85f029571..d823ea89eb 100644
--- a/ext/mysqli/mysqli_priv.h
+++ b/ext/mysqli/mysqli_priv.h
@@ -76,7 +76,6 @@ extern void php_clear_warnings(MYSQLI_WARNING *w);
extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type);
extern void php_mysqli_report_error(const char *sqlstate, int errorno, const char *error TSRMLS_DC);
extern void php_mysqli_report_index(const char *query, unsigned int status TSRMLS_DC);
-extern void php_set_local_infile_handler_default(MY_MYSQL *);
extern void php_mysqli_throw_sql_exception(char *sqlstate, int errorno TSRMLS_DC, char *format, ...);
#ifdef HAVE_SPL
diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c
index f50371bf0d..bd9cee28f1 100644
--- a/ext/mysqli/mysqli_prop.c
+++ b/ext/mysqli/mysqli_prop.c
@@ -253,8 +253,8 @@ MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_M
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu")
/* {{{ property link_stat_read */
-static int link_stat_read(mysqli_object *obj, zval **retval TSRMLS_DC)\
-{\
+static int link_stat_read(mysqli_object *obj, zval **retval TSRMLS_DC)
+{
MY_MYSQL *mysql;
MAKE_STD_ZVAL(*retval);
diff --git a/ext/mysqli/mysqli_report.h b/ext/mysqli/mysqli_report.h
deleted file mode 100644
index 34d0a661ff..0000000000
--- a/ext/mysqli/mysqli_report.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2013 The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Author: Georg Richter <georg@php.net> |
- +----------------------------------------------------------------------+
-
- $Id$
-*/
-
-#ifndef __HAVE_MYSQLI_PROFILER_H__
-#define __HAVE_MYSQLI_PROFILER_H__
-
-#ifdef PHP_WIN32
-#include <process.h>
-#include <direct.h>
-#include "win32/time.h"
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/time.h>
-#endif
-
-typedef struct {
- struct timeval starttime,
- endtime; /* execution time */
-} PR_TIME_INFO;
-
-
-#define MYSQLI_PR_REPORT_STDERR 1
-#define MYSQLI_PR_REPORT_PORT 2
-
-
-
-/*** PROFILER MACROS ***/
-#define MYSQLI_PROFILER_STARTTIME(ptr) if (MyG(profiler.mode)) gettimeofday(&ptr.starttime, NULL)
-#define MYSQLI_PROFILER_ENDTIME(ptr) if (MyG(profiler.mode)) gettimeofday(&ptr.endtime, NULL)
-#define MYSQLI_PROFILER_REPORT(_type, _time, ptr) if (MyG(profiler.mode)) php_mysqli_profiler_report(_type, _time, (void *)ptr)
-
-
-
-#endif
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * indent-tabs-mode: t
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
diff --git a/ext/mysqli/mysqli_result_iterator.c b/ext/mysqli/mysqli_result_iterator.c
index 0f5ccdd63d..3ea7bafe49 100644
--- a/ext/mysqli/mysqli_result_iterator.c
+++ b/ext/mysqli/mysqli_result_iterator.c
@@ -150,12 +150,11 @@ static void php_mysqli_result_iterator_rewind(zend_object_iterator *iter TSRMLS_
/* {{{ php_mysqli_result_iterator_current_key */
-static int php_mysqli_result_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+static void php_mysqli_result_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter;
- *int_key = (ulong) iterator->row_num;
- return HASH_KEY_IS_LONG;
+ ZVAL_LONG(key, iterator->row_num);
}
/* }}} */
diff --git a/ext/mysqli/package.xml b/ext/mysqli/package.xml
index 6de81d7a93..c27316a055 100644
--- a/ext/mysqli/package.xml
+++ b/ext/mysqli/package.xml
@@ -43,7 +43,6 @@ package.xml added to support installation using pear installer
<file role="src" name="mysqli_prop.c"/>
<file role="src" name="mysqli_repl.c"/>
<file role="src" name="mysqli_report.c"/>
- <file role="src" name="mysqli_report.h"/>
<file role="src" name="php_mysqli.h"/>
<file role="doc" name="CREDITS"/>
<file role="test" name="tests/001.phpt"/>
diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h
index 1f7e761c40..8b329bb5d0 100644
--- a/ext/mysqli/php_mysqli_structs.h
+++ b/ext/mysqli/php_mysqli_structs.h
@@ -131,12 +131,6 @@ typedef struct {
} MY_MYSQL;
typedef struct {
- int mode;
- int socket;
- FILE *fp;
-} PROFILER;
-
-typedef struct {
void *ptr; /* resource: (mysql, result, stmt) */
void *info; /* additional buffer */
enum mysqli_status status; /* object status */
@@ -164,12 +158,6 @@ typedef struct _mysqli_property_entry {
int (*w_func)(mysqli_object *obj, zval *value TSRMLS_DC);
} mysqli_property_entry;
-#if !defined(MYSQLI_USE_MYSQLND)
-typedef struct {
- char error_msg[LOCAL_INFILE_ERROR_LEN];
- void *userdata;
-} mysqli_local_infile;
-#endif
typedef struct {
zend_ptr_stack free_links;
diff --git a/ext/mysqli/tests/057.phpt b/ext/mysqli/tests/057.phpt
index 2cb887506a..7c7e2b7568 100644
--- a/ext/mysqli/tests/057.phpt
+++ b/ext/mysqli/tests/057.phpt
@@ -35,8 +35,8 @@ require_once('skipifconnectfailure.inc');
var_dump(mysqli_stmt_reset($stmt));
var_dump($stmt = mysqli_prepare($link, "SELECT * FROM test_store_result"));
- if ($IS_MYSQLND && $stmt->affected_rows !== -1)
- printf("[001] Expecting -1, got %d\n", $stmt->affected_rows);
+ if ($stmt->affected_rows !== 0)
+ printf("[001] Expecting 0, got %d\n", $stmt->affected_rows);
var_dump(mysqli_stmt_execute($stmt));
var_dump($stmt = @mysqli_prepare($link, "SELECT * FROM test_store_result"), mysqli_error($link));
diff --git a/ext/mysqli/tests/connect.inc b/ext/mysqli/tests/connect.inc
index 3a9d8ec258..4acc20cb91 100644
--- a/ext/mysqli/tests/connect.inc
+++ b/ext/mysqli/tests/connect.inc
@@ -129,99 +129,6 @@
}
}
- function my_get_charsets($link) {
-
- /* Those tree are set by SET NAMES */
- $charsets = array(
- 'client' => NULL,
- 'results' => NULL,
- 'connection' => NULL,
- );
-
- if (!($res = mysqli_query($link, "SHOW VARIABLES LIKE '%character%'"))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
-
- $names = array();
- while ($row = mysqli_fetch_assoc($res)) {
- $names[$row['Variable_name']] = $row['Value'];
- }
- mysqli_free_result($res);
-
- if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $names['character_set_client']))) ||
- !($details = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
-
- $charsets['client'] = array(
- 'charset' => $details['Charset'],
- 'desc' => $details['Description'],
- 'collation' => $details['Default collation'],
- 'maxlen' => $details['Maxlen'],
- 'nr' => NULL,
- );
-
- if (!($res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $details['Default collation']))) ||
- !($collation = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
- $charsets['client']['nr'] = $collation['Id'];
-
- if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $names['character_set_results']))) ||
- !($details = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
-
- $charsets['results'] = array(
- 'charset' => $details['Charset'],
- 'desc' => $details['Description'],
- 'collation' => $details['Default collation'],
- 'maxlen' => $details['Maxlen'],
- 'nr' => NULL,
- );
-
- if (!($res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $details['Default collation']))) ||
- !($collation = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
- $charsets['results']['nr'] = $collation['Id'];
-
-
- if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $names['character_set_connection']))) ||
- !($details = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
-
- $charsets['connection'] = array(
- 'charset' => $details['Charset'],
- 'desc' => $details['Description'],
- 'collation' => $details['Default collation'],
- 'maxlen' => $details['Maxlen'],
- 'nr' => NULL,
- );
-
- if (!($res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $details['Default collation']))) ||
- !($collation = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
- $charsets['connection']['nr'] = $collation['Id'];
-
- return $charsets;
- }
-
function have_innodb($link) {
if (($res = $link->query("SHOW VARIABLES LIKE 'have_innodb'")) &&
($row = $res->fetch_row()) &&
diff --git a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt
index df7d1c6580..ea86c198e7 100644
--- a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt
+++ b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt
@@ -20,38 +20,41 @@ require_once('skipifconnectfailure.inc');
$methods = get_class_methods($mysqli);
$expected_methods = array(
'autocommit' => true,
+ 'begin_transaction' => true,
'change_user' => true,
- 'character_set_name' => true,
- 'close' => true,
- 'commit' => true,
- 'connect' => true,
+ 'character_set_name' => true,
+ 'close' => true,
+ 'commit' => true,
+ 'connect' => true,
'dump_debug_info' => true,
'escape_string' => true,
'get_charset' => true,
'get_client_info' => true,
'get_server_info' => true,
'get_warnings' => true,
- 'init' => true,
- 'kill' => true,
+ 'init' => true,
+ 'kill' => true,
'more_results' => true,
'multi_query' => true,
- 'mysqli' => true,
+ 'mysqli' => true,
'next_result' => true,
- 'options' => true,
- 'ping' => true,
- 'prepare' => true,
- 'query' => true,
+ 'options' => true,
+ 'ping' => true,
+ 'prepare' => true,
+ 'query' => true,
'real_connect' => true,
- 'real_escape_string' => true,
+ 'real_escape_string' => true,
'real_query' => true,
- 'refresh' => true,
- 'rollback' => true,
- 'select_db' => true,
+ 'refresh' => true,
+ 'rollback' => true,
+ 'release_savepoint' => true,
+ 'savepoint' => true,
+ 'select_db' => true,
'set_charset' => true,
- 'set_opt' => true,
- 'ssl_set' => true,
- 'stat' => true,
- 'stmt_init' => true,
+ 'set_opt' => true,
+ 'ssl_set' => true,
+ 'stat' => true,
+ 'stmt_init' => true,
'store_result' => true,
'thread_safe' => true,
'use_result' => true,
@@ -67,12 +70,6 @@ require_once('skipifconnectfailure.inc');
$expected_methods['get_connection_stats'] = true;
$expected_methods['reap_async_query'] = true;
$expected_methods['poll'] = true;
- } else {
- // libmysql only
- if (function_exists('mysqli_ssl_set'))
- $expected_methods['ssl_set'] = true;
- $expected_methods['set_local_infile_default'] = true;
- $expected_methods['set_local_infile_handler'] = true;
}
/* we should add ruled when to expect them */
@@ -301,7 +298,7 @@ mysqli->insert_id = '0'/integer ('0'/integer)
mysqli->sqlstate = '00000'/%unicode|string% ('00000'/%unicode|string%)
mysqli->stat = 'Uptime: %d Threads: %d Questions: %d Slow queries: %d Opens: %d Flush tables: %d Open tables: %d Queries per second avg: %d.%d'/string ('Uptime: %d Threads: %d Questions: %d Slow queries: %d Opens: %d Flush tables: %d Open tables: %d Queries per second avg: %d.%d'/string)
mysqli->host_info = '%s'/%unicode|string% ('%s'/%unicode|string%)
-mysqli->info = ''/NULL (''/%unicode|string%)
+mysqli->info = ''/NULL (''/NULL)
mysqli->thread_id = '%d'/integer ('%d'/integer)
mysqli->protocol_version = '%d'/integer ('%d'/integer)
mysqli->server_info = '%s'/%unicode|string% ('%s'/%unicode|string%)
diff --git a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt
index 5fd4b6f45c..259fcd9ae6 100644
--- a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt
+++ b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt
@@ -6,8 +6,6 @@ require_once('skipif.inc');
require_once('skipifemb.inc');
require_once('connect.inc');
-if (($tmp = substr(PHP_VERSION, 0, strpos(PHP_VERSION, '.'))) && ($tmp < 5))
- die("skip Reflection not available before PHP 5 (found PHP $tmp)");
/*
Let's not deal with cross-version issues in the EXPECTF/UEXPECTF.
Most of the things which we test are covered by mysqli_class_*_interface.phpt.
@@ -120,6 +118,36 @@ isPassedByReference: no
isOptional: no
isDefaultValueAvailable: no
+Inspecting method 'begin_transaction'
+isFinal: no
+isAbstract: no
+isPublic: yes
+isPrivate: no
+isProtected: no
+isStatic: no
+isConstructor: no
+isDestructor: no
+isInternal: yes
+isUserDefined: no
+returnsReference: no
+Modifiers: 256
+Number of Parameters: 2
+Number of Required Parameters: 0
+
+Inspecting parameter 'flags' of method 'begin_transaction'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
+Inspecting parameter 'name' of method 'begin_transaction'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
Inspecting method 'change_user'
isFinal: no
isAbstract: no
@@ -202,9 +230,23 @@ isInternal: yes
isUserDefined: no
returnsReference: no
Modifiers: 256
-Number of Parameters: 0
+Number of Parameters: 2
Number of Required Parameters: 0
+Inspecting parameter 'flags' of method 'commit'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
+Inspecting parameter 'name' of method 'commit'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
Inspecting method 'connect'
isFinal: no
isAbstract: no
@@ -850,6 +892,29 @@ isPassedByReference: no
isOptional: no
isDefaultValueAvailable: no
+Inspecting method 'release_savepoint'
+isFinal: no
+isAbstract: no
+isPublic: yes
+isPrivate: no
+isProtected: no
+isStatic: no
+isConstructor: no
+isDestructor: no
+isInternal: yes
+isUserDefined: no
+returnsReference: no
+Modifiers: 256
+Number of Parameters: 1
+Number of Required Parameters: 1
+
+Inspecting parameter 'name' of method 'release_savepoint'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: no
+isDefaultValueAvailable: no
+
Inspecting method 'rollback'
isFinal: no
isAbstract: no
@@ -863,9 +928,46 @@ isInternal: yes
isUserDefined: no
returnsReference: no
Modifiers: 256
-Number of Parameters: 0
+Number of Parameters: 2
Number of Required Parameters: 0
+Inspecting parameter 'flags' of method 'rollback'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
+Inspecting parameter 'name' of method 'rollback'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
+Inspecting method 'savepoint'
+isFinal: no
+isAbstract: no
+isPublic: yes
+isPrivate: no
+isProtected: no
+isStatic: no
+isConstructor: no
+isDestructor: no
+isInternal: yes
+isUserDefined: no
+returnsReference: no
+Modifiers: 256
+Number of Parameters: 1
+Number of Required Parameters: 1
+
+Inspecting parameter 'name' of method 'savepoint'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: no
+isDefaultValueAvailable: no
+
Inspecting method 'select_db'
isFinal: no
isAbstract: no
diff --git a/ext/mysqli/tests/mysqli_commit_oo.phpt b/ext/mysqli/tests/mysqli_commit_oo.phpt
index 34ec4bfcdc..e19f698e81 100644
--- a/ext/mysqli/tests/mysqli_commit_oo.phpt
+++ b/ext/mysqli/tests/mysqli_commit_oo.phpt
@@ -28,12 +28,8 @@ if (!have_innodb($link))
printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
$host, $user, $db, $port, $socket);
- if (!is_null($tmp = @$mysqli->commit($link)))
- printf("[002] Expecting NULL/NULL, got %s/%s, [%d] %s\n",
- gettype($tmp), $tmp, $mysqli->errno, $mysqli->error);
-
if (true !== ($tmp = $mysqli->commit()))
- printf("[014] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp);
+ printf("[002] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp);
if (true !== ($tmp = $mysqli->autocommit(false)))
printf("[003] Cannot turn off autocommit, expecting true, got %s/%s\n", gettype($tmp), $tmp);
diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt
index 8bdc849f78..7c6dacd393 100644
--- a/ext/mysqli/tests/mysqli_constants.phpt
+++ b/ext/mysqli/tests/mysqli_constants.phpt
@@ -32,7 +32,7 @@ require_once('skipifconnectfailure.inc');
"MYSQLI_ASSOC" => true,
"MYSQLI_NUM" => true,
"MYSQLI_BOTH" => true,
- "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH" => true,
+ "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH"=> true,
"MYSQLI_NOT_NULL_FLAG" => true,
"MYSQLI_PRI_KEY_FLAG" => true,
"MYSQLI_UNIQUE_KEY_FLAG" => true,
@@ -86,14 +86,21 @@ require_once('skipifconnectfailure.inc');
"MYSQLI_SET_CHARSET_NAME" => true,
"MYSQLI_SET_CHARSET_DIR" => true,
"MYSQLI_REFRESH_GRANT" => true,
- "MYSQLI_REFRESH_LOG" => true,
+ "MYSQLI_REFRESH_LOG" => true,
"MYSQLI_REFRESH_TABLES" => true,
"MYSQLI_REFRESH_HOSTS" => true,
"MYSQLI_REFRESH_STATUS" => true,
"MYSQLI_REFRESH_THREADS" => true,
"MYSQLI_REFRESH_SLAVE" => true,
"MYSQLI_REFRESH_MASTER" => true,
- "MYSQLI_DEBUG_TRACE_ENABLED" => true,
+ "MYSQLI_DEBUG_TRACE_ENABLED" => true,
+ "MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT" => true,
+ "MYSQLI_TRANS_START_READ_WRITE" => true,
+ "MYSQLI_TRANS_START_READ_ONLY" => true,
+ "MYSQLI_TRANS_COR_AND_CHAIN" => true,
+ "MYSQLI_TRANS_COR_AND_NO_CHAIN" => true,
+ "MYSQLI_TRANS_COR_RELEASE" => true,
+ "MYSQLI_TRANS_COR_NO_RELEASE" => true,
);
/* depends on the build - experimental */
@@ -125,6 +132,12 @@ require_once('skipifconnectfailure.inc');
$expected_constants['MYSQLI_SERVER_QUERY_WAS_SLOW'] = true;
}
+
+ /* First introduced in MySQL 6.0, backported to MySQL 5.5 */
+ if ($version >= 50606 || $IS_MYSQLND) {
+ $expected_constants['MYSQLI_SERVER_PUBLIC_KEY'] = true;
+ }
+
if ($version > 50002) {
$expected_constants = array_merge($expected_constants, array(
"MYSQLI_TYPE_NEWDECIMAL" => true,
diff --git a/ext/mysqli/tests/mysqli_expire_password.phpt b/ext/mysqli/tests/mysqli_expire_password.phpt
index ce89a21670..4fdf902c79 100644
--- a/ext/mysqli/tests/mysqli_expire_password.phpt
+++ b/ext/mysqli/tests/mysqli_expire_password.phpt
@@ -127,11 +127,11 @@ if (!mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO expiretest@'%
?>
--EXPECTF--
-Warning: mysqli_real_connect(): (HY000/1820): %s in %s on line %d
-[001] Cannot connect [1820] %s
+Warning: mysqli_real_connect(): (HY000/1862): %s in %s on line %d
+[001] Cannot connect [1862] %s
-Warning: mysqli_real_connect(): (HY000/1820): %s in %s on line %d
-[003] Cannot connect [1820] %s
+Warning: mysqli_real_connect(): (HY000/1862): %s in %s on line %d
+[003] Cannot connect [1862] %s
[006] Connect allowed, query fail, [1820] %s
[008] Connect allowed, pw set, [0%A
array(1) {
diff --git a/ext/mysqli/tests/mysqli_fetch_field.phpt b/ext/mysqli/tests/mysqli_fetch_field.phpt
index d1d358b342..2b9108072b 100644
--- a/ext/mysqli/tests/mysqli_fetch_field.phpt
+++ b/ext/mysqli/tests/mysqli_fetch_field.phpt
@@ -22,7 +22,13 @@ require_once('skipifconnectfailure.inc');
require('table.inc');
- $charsets = my_get_charsets($link);
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!mysqli_set_charset($link, 'utf8'))
+ printf("[%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+
+ $charsetInfo = mysqli_get_charset($link);
+
if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
}
@@ -34,19 +40,17 @@ require_once('skipifconnectfailure.inc');
/* label column, result set charset */
$tmp = mysqli_fetch_field($res);
var_dump($tmp);
- if ($tmp->charsetnr != $charsets['results']['nr']) {
+ if ($tmp->charsetnr != $charsetInfo->number) {
printf("[004] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $tmp->charsetnr);
+ $charsetInfo->charset, $charsetInfo->number, $tmp->charsetnr);
}
- if ($tmp->length != (1 * $charsets['results']['maxlen'])) {
+ if ($tmp->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
- $tmp->max_length);
+ $charsetInfo->max_length, $tmp->max_length);
}
if ($tmp->db != $db) {
printf("011] Expecting database '%s' got '%s'\n",
- $db, $tmp->db);
+ $db, $tmp->db);
}
var_dump(mysqli_fetch_field($res));
@@ -174,4 +178,4 @@ object(stdClass)#%d (13) {
[%u|b%"decimals"]=>
int(0)
}
-done! \ No newline at end of file
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt
index 2d5ad261b1..8c5609b163 100644
--- a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt
+++ b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt
@@ -27,7 +27,12 @@ require_once('skipifconnectfailure.inc');
if (!is_null($tmp = @$res->fetch_field($link)))
printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
- $charsets = my_get_charsets($link);
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!$mysqli->set_charset('utf8'))
+ printf("[%d] %s\n", $mysqli->errno, $mysqli->errno);
+
+ $charsetInfo = $mysqli->get_charset();
if (!$res = $mysqli->query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error);
@@ -37,18 +42,16 @@ require_once('skipifconnectfailure.inc');
$tmp = $res->fetch_field();
var_dump($tmp);
- if ($tmp->charsetnr != $charsets['results']['nr']) {
+ if ($tmp->charsetnr != $charsetInfo->number) {
printf("[005] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $tmp->charsetnr);
+ $charsetInfo->charset, $charsetInfo->number, $tmp->charsetnr);
}
- if ($tmp->length != (1 * $charsets['results']['maxlen'])) {
+ if ($tmp->length != $charsetInfo->max_length) {
printf("[006] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
- $tmp->max_length);
+ $charsetInfo->max_length, $tmp->max_length);
}
if ($tmp->db != $db) {
- printf("008] Expecting database '%s' got '%s'\n",
+ printf("[007] Expecting database '%s' got '%s'\n",
$db, $tmp->db);
}
@@ -126,4 +129,4 @@ object(stdClass)#%d (13) {
bool(false)
Warning: mysqli_result::fetch_field(): Couldn't fetch mysqli_result in %s on line %d
-done! \ No newline at end of file
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_fields.phpt b/ext/mysqli/tests/mysqli_fetch_fields.phpt
index 479c71cbbc..6b66d6f231 100644
--- a/ext/mysqli/tests/mysqli_fetch_fields.phpt
+++ b/ext/mysqli/tests/mysqli_fetch_fields.phpt
@@ -21,7 +21,13 @@ require_once('skipifconnectfailure.inc');
printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
require('table.inc');
- $charsets = my_get_charsets($link);
+
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!mysqli_set_charset($link, 'utf8'))
+ printf("[%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+
+ $charsetInfo = mysqli_get_charset($link);
if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
@@ -33,14 +39,14 @@ require_once('skipifconnectfailure.inc');
switch ($k) {
case 1:
/* label column, result set charset */
- if ($field->charsetnr != $charsets['results']['nr']) {
+ if ($field->charsetnr != $charsetInfo->number) {
printf("[004] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $field->charsetnr);
+ $charsetInfo->charset,
+ $charsetInfo->number, $field->charsetnr);
}
- if ($field->length != (1 * $charsets['results']['maxlen'])) {
+ if ($field->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
+ $charsetInfo->max_length,
$field->max_length);
}
break;
@@ -118,4 +124,4 @@ object(stdClass)#%d (13) {
}
Warning: mysqli_fetch_fields(): Couldn't fetch mysqli_result in %s on line %d
-done! \ No newline at end of file
+done!
diff --git a/ext/mysqli/tests/mysqli_field_seek.phpt b/ext/mysqli/tests/mysqli_field_seek.phpt
index a747bdfa01..449d2f90d4 100644
--- a/ext/mysqli/tests/mysqli_field_seek.phpt
+++ b/ext/mysqli/tests/mysqli_field_seek.phpt
@@ -66,7 +66,13 @@ require_once('skipifconnectfailure.inc');
printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
require('table.inc');
- $charsets = my_get_charsets($link);
+
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!mysqli_set_charset($link, 'utf8'))
+ printf("[%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+
+ $charsetInfo = mysqli_get_charset($link);
if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1", MYSQLI_USE_RESULT)) {
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
@@ -81,15 +87,13 @@ require_once('skipifconnectfailure.inc');
$field = mysqli_fetch_field($res);
var_dump($field);
/* label column, result set charset */
- if ($field->charsetnr != $charsets['results']['nr']) {
+ if ($field->charsetnr != $charsetInfo->number) {
printf("[004] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $field->charsetnr);
+ $charsetInfo->charset, $charsetInfo->number, $field->charsetnr);
}
- if ($field->length != (1 * $charsets['results']['maxlen'])) {
+ if ($field->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
- $field->max_length);
+ $charsetInfo->max_length, $field->max_length);
}
var_dump(mysqli_field_tell($res));
@@ -217,7 +221,7 @@ bool(false)
Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
bool(false)
bool(true)
-object(stdClass)#3 (13) {
+object(stdClass)#%d (13) {
[%u|b%"name"]=>
%unicode|string%(5) "_null"
[%u|b%"orgname"]=>
@@ -248,4 +252,4 @@ object(stdClass)#3 (13) {
Warning: mysqli_field_seek(): Couldn't fetch mysqli_result in %s on line %d
NULL
-done! \ No newline at end of file
+done!
diff --git a/ext/mysqli/tests/mysqli_info.phpt b/ext/mysqli/tests/mysqli_info.phpt
index 2d5004fe6e..6bb5d215e0 100644
--- a/ext/mysqli/tests/mysqli_info.phpt
+++ b/ext/mysqli/tests/mysqli_info.phpt
@@ -21,8 +21,8 @@ require_once('skipifconnectfailure.inc');
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
// NOTE: empty string, no multiple insert syntax
- if (!is_string($tmp = mysqli_info($link)) || ('' != $tmp))
- printf("[004] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp);
+ if (!is_null($tmp = mysqli_info($link)) || ('' != $tmp))
+ printf("[004] Expecting null, got %s/%s\n", gettype($tmp), $tmp);
if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (101, 'a'), (102, 'b')"))
printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
@@ -54,8 +54,8 @@ require_once('skipifconnectfailure.inc');
if (!$res = mysqli_query($link, "SELECT 1"))
printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
- if (!is_string($tmp = mysqli_info($link)) || ('' != $tmp))
- printf("[014] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp);
+ if (!is_null($tmp = mysqli_info($link)) || ('' != $tmp))
+ printf("[014] Expecting null, got %s/%s\n", gettype($tmp), $tmp);
mysqli_free_result($res);
// NOTE: no LOAD DATA INFILE test
diff --git a/ext/mysqli/tests/mysqli_pam_sha256.phpt b/ext/mysqli/tests/mysqli_pam_sha256.phpt
new file mode 100644
index 0000000000..3016e200d7
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_pam_sha256.phpt
@@ -0,0 +1,113 @@
+--TEST--
+PAM: SHA-256
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+ob_start();
+phpinfo(INFO_MODULES);
+$tmp = ob_get_contents();
+ob_end_clean();
+if (!stristr($tmp, "auth_plugin_sha256_password"))
+ die("skip SHA256 auth plugin not built-in to mysqlnd");
+
+require_once('connect.inc');
+if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ die(printf("skip: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
+
+if (mysqli_get_server_version($link) < 50606)
+ die("skip: SHA-256 requires MySQL 5.6.6+");
+
+if (!($res = $link->query("SHOW PLUGINS"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+$found = false;
+while ($row = $res->fetch_assoc()) {
+ if (($row['Name'] == 'sha256_password') && ($row['Status'] == 'ACTIVE')) {
+ $found = true;
+ break;
+ }
+}
+if (!$found)
+ die("skip SHA-256 server plugin unavailable");
+
+if (!($res = $link->query("SHOW STATUS LIKE 'Rsa_public_key'"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!($row = $res->fetch_assoc())) {
+ die(sprintf("skip Failed to check RSA pub key, [%d] %s\n", $link->errno, $link->error));
+}
+
+if (strlen($row['Value']) < 100) {
+ die(sprintf("skip Server misconfiguration? RSA pub key is suspicious, [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!$link->query("SET @@session.old_passwords=2")) {
+ die(sprintf("skip Cannot set @@session.old_passwords=2 [%d] %s", $link->errno, $link->error));
+}
+
+$link->query('DROP USER shatest');
+$link->query("DROP USER shatest@localhost");
+
+
+if (!$link->query('CREATE USER shatest@"%" IDENTIFIED WITH sha256_password') ||
+ !$link->query('CREATE USER shatest@"localhost" IDENTIFIED WITH sha256_password')) {
+ die(sprintf("skip CREATE USER failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query('SET PASSWORD FOR shatest@"%" = PASSWORD("shatest")') ||
+ !$link->query('SET PASSWORD FOR shatest@"localhost" = PASSWORD("shatest")')) {
+ die(sprintf("skip SET PASSWORD failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query("DROP TABLE IF EXISTS test") ||
+ !$link->query("CREATE TABLE test (id INT)") ||
+ !$link->query("INSERT INTO test(id) VALUES (1), (2), (3)"))
+ die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error));
+
+
+if (!$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'%%'", $db)) ||
+ !$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'localhost'", $db))) {
+ die(sprintf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)));
+}
+
+$link->close();
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ if (!$link = my_mysqli_connect($host, 'shatest', 'shatest', $db, $port, $socket)) {
+ printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, "shatest", $db, $port, $socket);
+ } else {
+
+ if (!$res = $link->query("SELECT id FROM test WHERE id = 1"))
+ printf("[002] [%d] %s\n", $link->errno, $link->error);
+
+ if (!$row = mysqli_fetch_assoc($res)) {
+ printf("[003] [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if ($row['id'] != 1) {
+ printf("[004] Expecting 1 got %s/'%s'", gettype($row['id']), $row['id']);
+ }
+
+ $res->close();
+ $link->close();
+ }
+
+ print "done!";
+?>
+--CLEAN--
+<?php
+ require_once("clean_table.inc");
+ $link->query('DROP USER shatest');
+ $link->query('DROP USER shatest@localhost');
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt
new file mode 100644
index 0000000000..27bbed138c
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt
@@ -0,0 +1,129 @@
+--TEST--
+PAM: SHA-256, mysqlnd.sha256_server_public_key
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+ob_start();
+phpinfo(INFO_MODULES);
+$tmp = ob_get_contents();
+ob_end_clean();
+if (!stristr($tmp, "auth_plugin_sha256_password"))
+ die("skip SHA256 auth plugin not built-in to mysqlnd");
+
+require_once('connect.inc');
+if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ die(printf("skip: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
+
+if (mysqli_get_server_version($link) < 50606)
+ die("skip: SHA-256 requires MySQL 5.6.6+");
+
+if (!($res = $link->query("SHOW PLUGINS"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+$found = false;
+while ($row = $res->fetch_assoc()) {
+ if (($row['Name'] == 'sha256_password') && ($row['Status'] == 'ACTIVE')) {
+ $found = true;
+ break;
+ }
+}
+if (!$found)
+ die("skip SHA-256 server plugin unavailable");
+
+if (!($res = $link->query("SHOW STATUS LIKE 'Rsa_public_key'"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!($row = $res->fetch_assoc())) {
+ die(sprintf("skip Failed to check RSA pub key, [%d] %s\n", $link->errno, $link->error));
+}
+
+$key = $row['Value'];
+if (strlen($key) < 100) {
+ die(sprintf("skip Server misconfiguration? RSA pub key is suspicious, [%d] %s\n", $link->errno, $link->error));
+}
+
+/* date changes may give false positive */
+$file = "test_sha256_ini";
+if ((file_exists($file) && !unlink($file)) || !($fp = @fopen($file, "w"))) {
+ die(sprintf("skip Cannot create RSA pub key file '%s'", $file));
+}
+$key = str_replace("A", "a", $key);
+$key = str_replace("M", "m", $key);
+if (strlen($key) != fwrite($fp, $key)) {
+ die(sprintf("skip Failed to create pub key file"));
+}
+
+
+if (!$link->query("SET @@session.old_passwords=2")) {
+ die(sprintf("skip Cannot set @@session.old_passwords=2 [%d] %s", $link->errno, $link->error));
+}
+
+$link->query('DROP USER shatest');
+$link->query("DROP USER shatest@localhost");
+
+
+if (!$link->query('CREATE USER shatest@"%" IDENTIFIED WITH sha256_password') ||
+ !$link->query('CREATE USER shatest@"localhost" IDENTIFIED WITH sha256_password')) {
+ die(sprintf("skip CREATE USER failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query('SET PASSWORD FOR shatest@"%" = PASSWORD("shatest")') ||
+ !$link->query('SET PASSWORD FOR shatest@"localhost" = PASSWORD("shatest")')) {
+ die(sprintf("skip SET PASSWORD failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query("DROP TABLE IF EXISTS test") ||
+ !$link->query("CREATE TABLE test (id INT)") ||
+ !$link->query("INSERT INTO test(id) VALUES (1), (2), (3)"))
+ die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error));
+
+
+if (!$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'%%'", $db)) ||
+ !$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'localhost'", $db))) {
+ die(sprintf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)));
+}
+
+$link->close();
+?>
+--INI--
+mysqlnd.sha256_server_public_key="test_sha256_ini"
+--FILE--
+<?php
+ require_once("connect.inc");
+
+
+ $link = new mysqli($host, 'shatest', 'shatest', $db, $port, $socket);
+ if ($link->connect_errno) {
+ printf("[001] [%d] %s\n", $link->connect_errno, $link->connect_error);
+ } else {
+ if (!$res = $link->query("SELECT id FROM test WHERE id = 1"))
+ printf("[002] [%d] %s\n", $link->errno, $link->error);
+
+ if (!$row = mysqli_fetch_assoc($res)) {
+ printf("[003] [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if ($row['id'] != 1) {
+ printf("[004] Expecting 1 got %s/'%s'", gettype($row['id']), $row['id']);
+ }
+ }
+ print "done!";
+?>
+--CLEAN--
+<?php
+ require_once("clean_table.inc");
+ $link->query('DROP USER shatest');
+ $link->query('DROP USER shatest@localhost');
+ $file = "test_sha256_ini";
+ @unlink($file);
+?>
+--EXPECTF--
+
+Warning: mysqli::mysqli(): (HY000/1045): %s in %s on line %d
+[001] [1045] %s
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt
new file mode 100644
index 0000000000..afed773b01
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt
@@ -0,0 +1,132 @@
+--TEST--
+PAM: SHA-256, option: MYSQLI_SERVER_PUBLIC_KEY
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+ob_start();
+phpinfo(INFO_MODULES);
+$tmp = ob_get_contents();
+ob_end_clean();
+if (!stristr($tmp, "auth_plugin_sha256_password"))
+ die("skip SHA256 auth plugin not built-in to mysqlnd");
+
+require_once('connect.inc');
+if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ die(printf("skip: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
+
+if (mysqli_get_server_version($link) < 50606)
+ die("skip: SHA-256 requires MySQL 5.6.6+");
+
+if (!($res = $link->query("SHOW PLUGINS"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+$found = false;
+while ($row = $res->fetch_assoc()) {
+ if (($row['Name'] == 'sha256_password') && ($row['Status'] == 'ACTIVE')) {
+ $found = true;
+ break;
+ }
+}
+if (!$found)
+ die("skip SHA-256 server plugin unavailable");
+
+if (!($res = $link->query("SHOW STATUS LIKE 'Rsa_public_key'"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!($row = $res->fetch_assoc())) {
+ die(sprintf("skip Failed to check RSA pub key, [%d] %s\n", $link->errno, $link->error));
+}
+
+if (strlen($row['Value']) < 100) {
+ die(sprintf("skip Server misconfiguration? RSA pub key is suspicious, [%d] %s\n", $link->errno, $link->error));
+}
+
+/* date changes may give false positive */
+$file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+if ((file_exists($file) && !unlink($file)) || !($fp = @fopen($file, "w"))) {
+ die(sprintf("skip Cannot create RSA pub key file '%s'", $file));
+}
+if (strlen($row['Value']) != fwrite($fp, $row['Value'])) {
+ die(sprintf("skip Failed to create pub key file"));
+}
+
+
+if (!$link->query("SET @@session.old_passwords=2")) {
+ die(sprintf("skip Cannot set @@session.old_passwords=2 [%d] %s", $link->errno, $link->error));
+}
+
+$link->query('DROP USER shatest');
+$link->query("DROP USER shatest@localhost");
+
+
+if (!$link->query('CREATE USER shatest@"%" IDENTIFIED WITH sha256_password') ||
+ !$link->query('CREATE USER shatest@"localhost" IDENTIFIED WITH sha256_password')) {
+ die(sprintf("skip CREATE USER failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query('SET PASSWORD FOR shatest@"%" = PASSWORD("shatest")') ||
+ !$link->query('SET PASSWORD FOR shatest@"localhost" = PASSWORD("shatest")')) {
+ die(sprintf("skip SET PASSWORD failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query("DROP TABLE IF EXISTS test") ||
+ !$link->query("CREATE TABLE test (id INT)") ||
+ !$link->query("INSERT INTO test(id) VALUES (1), (2), (3)"))
+ die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error));
+
+
+if (!$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'%%'", $db)) ||
+ !$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'localhost'", $db))) {
+ die(sprintf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)));
+}
+
+$link->close();
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+ if (file_exists($file) && is_readable($file)) {
+
+ $link = mysqli_init();
+ if (!($link->options(MYSQLI_SERVER_PUBLIC_KEY, $file))) {
+ printf("[001] mysqli_options failed, [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if (!$link->real_connect($host, 'shatest', 'shatest', $db, $port, $socket)) {
+ printf("[002] [%d] %s\n", $link->connect_errno, $link->connect_error);
+ }
+
+ if (!$res = $link->query("SELECT id FROM test WHERE id = 1"))
+ printf("[003] [%d] %s\n", $link->errno, $link->error);
+
+ if (!$row = mysqli_fetch_assoc($res)) {
+ printf("[004] [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if ($row['id'] != 1) {
+ printf("[005] Expecting 1 got %s/'%s'", gettype($row['id']), $row['id']);
+ }
+
+ $res->close();
+ $link->close();
+ }
+
+ print "done!";
+?>
+--CLEAN--
+<?php
+ require_once("clean_table.inc");
+ $link->query('DROP USER shatest');
+ $link->query('DROP USER shatest@localhost');
+ $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+ @unlink($file);
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt
new file mode 100644
index 0000000000..e2626240d8
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt
@@ -0,0 +1,188 @@
+--TEST--
+PAM: SHA-256, option: MYSQLI_SERVER_PUBLIC_KEY (invalid)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+ob_start();
+phpinfo(INFO_MODULES);
+$tmp = ob_get_contents();
+ob_end_clean();
+if (!stristr($tmp, "auth_plugin_sha256_password"))
+ die("skip SHA256 auth plugin not built-in to mysqlnd");
+
+require_once('connect.inc');
+if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+ die(printf("skip: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()));
+
+if (mysqli_get_server_version($link) < 50606)
+ die("skip: SHA-256 requires MySQL 5.6.6+");
+
+if (!($res = $link->query("SHOW PLUGINS"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+$found = false;
+while ($row = $res->fetch_assoc()) {
+ if (($row['Name'] == 'sha256_password') && ($row['Status'] == 'ACTIVE')) {
+ $found = true;
+ break;
+ }
+}
+if (!$found)
+ die("skip SHA-256 server plugin unavailable");
+
+if (!($res = $link->query("SHOW STATUS LIKE 'Rsa_public_key'"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!($row = $res->fetch_assoc())) {
+ die(sprintf("skip Failed to check RSA pub key, [%d] %s\n", $link->errno, $link->error));
+}
+
+if (strlen($row['Value']) < 100) {
+ die(sprintf("skip Server misconfiguration? RSA pub key is suspicious, [%d] %s\n", $link->errno, $link->error));
+}
+
+/* date changes may give false positive */
+$file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+if ((file_exists($file) && !unlink($file)) || !($fp = @fopen($file, "w"))) {
+ die(sprintf("skip Cannot create RSA pub key file '%s'", $file));
+}
+if (strlen($row['Value']) != fwrite($fp, $row['Value'])) {
+ die(sprintf("skip Failed to create pub key file"));
+}
+
+
+if (!$link->query("SET @@session.old_passwords=2")) {
+ die(sprintf("skip Cannot set @@session.old_passwords=2 [%d] %s", $link->errno, $link->error));
+}
+
+$link->query('DROP USER shatest');
+$link->query("DROP USER shatest@localhost");
+
+
+if (!$link->query('CREATE USER shatest@"%" IDENTIFIED WITH sha256_password') ||
+ !$link->query('CREATE USER shatest@"localhost" IDENTIFIED WITH sha256_password')) {
+ die(sprintf("skip CREATE USER failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query('SET PASSWORD FOR shatest@"%" = PASSWORD("shatest")') ||
+ !$link->query('SET PASSWORD FOR shatest@"localhost" = PASSWORD("shatest")')) {
+ die(sprintf("skip SET PASSWORD failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query("DROP TABLE IF EXISTS test") ||
+ !$link->query("CREATE TABLE test (id INT)") ||
+ !$link->query("INSERT INTO test(id) VALUES (1), (2), (3)"))
+ die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error));
+
+
+if (!$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'%%'", $db)) ||
+ !$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'localhost'", $db))) {
+ die(sprintf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)));
+}
+
+$link->close();
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ function sha_connect($offset, $host, $db, $port, $socket, $file) {
+
+ $link = mysqli_init();
+ if (!($link->options(MYSQLI_SERVER_PUBLIC_KEY, $file))) {
+ printf("[%03d + 001] mysqli_options failed, [%d] %s\n", $offset, $link->errno, $link->error);
+ return false;
+ }
+
+ if (!$link->real_connect($host, 'shatest', 'shatest', $db, $port, $socket)) {
+ printf("[%03d + 002] [%d] %s\n", $offset, $link->connect_errno, $link->connect_error);
+ return false;
+ }
+
+ if (!$res = $link->query("SELECT id FROM test WHERE id = 1"))
+ printf("[%03d + 003] [%d] %s\n", $offset, $link->errno, $link->error);
+ return false;
+
+ if (!$row = mysqli_fetch_assoc($res)) {
+ printf("[%03d + 004] [%d] %s\n", $offset, $link->errno, $link->error);
+ return false;
+ }
+
+ if ($row['id'] != 1) {
+ printf("[%03d + 005] Expecting 1 got %s/'%s'", $offset, gettype($row['id']), $row['id']);
+ return false;
+ }
+
+ $res->close();
+ $link->close();
+ return true;
+ }
+
+ $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+ if (file_exists($file) && is_readable($file)) {
+
+ /* valid key */
+ sha_connect(100, $host, $db, $port, $socket, $file);
+
+ /* invalid key */
+ $file_wrong = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_wrong" , @date("Ymd"));
+
+ $key = file_get_contents($file);
+ $key = str_replace("A", "a", $key);
+ $key = str_replace("M", "m", $key);
+ @unlink($file_wrong);
+ if (!($fp = fopen($file_wrong, "w"))) {
+ printf("[002] Can't write public key file.");
+ } else {
+ fwrite($fp, $key);
+ fclose($fp);
+ sha_connect(200, $host, $db, $port, $socket, $file_wrong);
+ }
+
+ /* empty file */
+ @unlink($file_wrong);
+ if (!($fp = fopen($file_wrong, "w"))) {
+ printf("[003] Can't write public key file.");
+ } else {
+ fwrite($fp, "");
+ fclose($fp);
+ sha_connect(300, $host, $db, $port, $socket, $file_wrong);
+ }
+
+ /* file does not exist */
+ @unlink($file_wrong);
+ sha_connect(400, $host, $db, $port, $socket, $file_wrong);
+
+ } else {
+ printf("[001] Cannot read public key file.");
+ }
+
+ print "done!";
+?>
+--CLEAN--
+<?php
+ require_once("clean_table.inc");
+ $link->query('DROP USER shatest');
+ $link->query('DROP USER shatest@localhost');
+ $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+ @unlink($file);
+ $file_wrong = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_wrong" , @date("Ymd"));
+ @unlink($file_wrong);
+?>
+--EXPECTF--
+Warning: mysqli::real_connect(): (HY000/1045): %s in %s on line %d
+[200 + 002] [1045] %s
+
+Warning: mysqli::real_connect(): (HY000/1045): %s in %s on line %d
+[300 + 002] [1045] %s
+
+Warning: mysqli::real_connect(%sest_sha256_wrong_%d): failed to open stream: No such file or directory in %s on line %d
+
+Warning: mysqli::real_connect(): (HY000/1045): %s in %s on line %d
+[400 + 002] [1045] %s
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_query_local_infile_large.phpt b/ext/mysqli/tests/mysqli_query_local_infile_large.phpt
deleted file mode 100644
index 76bc415d8b..0000000000
--- a/ext/mysqli/tests/mysqli_query_local_infile_large.phpt
+++ /dev/null
@@ -1,103 +0,0 @@
---TEST--
-mysql_query(LOAD DATA LOCAL INFILE) with large data set (10MB)
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifconnectfailure.inc');
-
-$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
-if (!$link)
- die(sprintf("skip Can't connect [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- // Create a large CVS file
- $file = tempnam(sys_get_temp_dir(), 'mysqli_test.cvs');
- if (!$fp = fopen($file, 'w'))
- printf("[001] Cannot create CVS file '%s'\n", $file);
-
- $data = str_repeat("a", 127) . ";" . str_repeat("b", 127) . "\n";
-
- $runtime = 5;
- $max_bytes = 1024 * 1024 * 10;
-
- $start = microtime(true);
- $bytes = 0;
- $rowno = 0;
- while (($bytes < $max_bytes) && ((microtime(true) - $start) < $runtime)) {
- if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1))
- $bytes += fwrite($fp, (binary)(++$rowno . ";" . $data));
- else
- $bytes += fwrite($fp, ++$rowno . ";" . $data);
- }
- fclose($fp);
- printf("Filesize in bytes: %d\nRows: %d\n", $bytes, $rowno);
-
- require_once("connect.inc");
- if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)))
- printf("[002] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
-
- if (!mysqli_query($link, "DROP TABLE IF EXISTS test") ||
- !mysqli_query($link, "CREATE TABLE test(id INT, col1 VARCHAR(255), col2 VARCHAR(255)) ENGINE = " . $engine))
- printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
- if (!mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' INTO TABLE test FIELDS TERMINATED BY ';'", mysqli_real_escape_string($link, $file))))
- printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
- if ((!is_string(mysqli_info($link))) || ('' == mysqli_info($link))) {
- printf("[005] [%d] %s, mysqli_info not set \n", mysqli_errno($link), mysqli_error($link));
- }
-
- if (!($res = mysqli_query($link, "SELECT COUNT(*) AS _num FROM test")))
- printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
- $row = mysqli_fetch_assoc($res);
- if (($row["_num"] != $rowno))
- printf("[007] Expecting %d rows, found %d\n", $rowno, $row["_num"]);
-
- mysqli_free_result($res);
-
- $random = mt_rand(1, $rowno);
- if (!$res = mysqli_query($link, "SELECT id, col1, col2 FROM test WHERE id = " . $random))
- printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-
- $row = mysqli_fetch_assoc($res);
- var_dump($row);
- mysqli_free_result($res);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
-$file = tempnam(sys_get_temp_dir(), 'mysqli_test.cvs');
-if (file_exists($file))
- unlink($file);
-
-require_once("connect.inc");
-if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)))
- printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
-
-if (!mysqli_query($link, "DROP TABLE IF EXISTS test"))
- printf("[c002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-?>
---EXPECTF--
-Filesize in bytes: %d
-Rows: %d
-array(3) {
- [%u|b%"id"]=>
- %unicode|string%(%d) "%d"
- [%u|b%"col1"]=>
- %unicode|string%(127) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- [%u|b%"col2"]=>
- %unicode|string%(127) "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
-}
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_default.phpt b/ext/mysqli/tests/mysqli_set_local_infile_default.phpt
deleted file mode 100644
index 0348b01f6a..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_default.phpt
+++ /dev/null
@@ -1,132 +0,0 @@
---TEST--
-mysqli_set_local_infile_default()
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
-if (!$link)
- die(sprintf("skip Can't connect [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
-
- $link = $tmp = null;
- if (!is_null($tmp = @mysqli_set_local_infile_default()))
- printf("[001] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
-
- if (!is_null($tmp = @mysqli_set_local_infile_default($link)))
- printf("[002] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
-
- $link = new mysqli();
- if (!is_null($tmp = @mysqli_set_local_infile_default($link)))
- printf("[002a] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
-
- include("table.inc");
-
- if (!is_null($tmp = @mysqli_set_local_infile_default($link, 'foo')))
- printf("[003] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
-
-
- function callback_simple($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(4);
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(10, $link, $file, 'callback_simple', $expected);
-
- $expected = array(
- array('id' => 97, 'label' => 'x'),
- array('id' => 98, 'label' => 'y'),
- array('id' => 99, 'label' => 'z'),
- );
- try_handler(20, $link, $file, 'default', $expected);
-
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(30, $link, $file, 'callback_simple', $expected);
-
- mysqli_close($link);
-
- if (!is_null($tmp = @mysqli_set_local_infile_default($link)))
- printf("[300] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_simple'
-Callback: 0
-Callback: 1
-Callback set to 'default'
-Callback set to 'callback_simple'
-Callback: 2
-Callback: 3
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt
deleted file mode 100644
index 58f4c70351..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt
+++ /dev/null
@@ -1,196 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler()
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_simple($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- return strlen($buffer);
- }
-
- function callback_fclose($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
-
- fclose($fp);
- return strlen($buffer);
- }
-
- function callback_closefile($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_resource($fp))
- fclose($fp);
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- function callback_invalid_args($fp, &$buffer, $buflen) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- $buffer = fread($fp, $buflen);
-
- return strlen($buffer);
- }
-
- function callback_error($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- $buffer = fread($fp, $buflen);
- $error = 'How to access this error?';
-
- return -1;
- }
-
- if (!is_null($tmp = @mysqli_set_local_infile_handler()))
- printf("[001] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- $handle = null;
- if (!is_null($tmp = @mysqli_set_local_infile_handler($handle)))
- printf("[002] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- $handle = @new mysqli();
- if (!is_null($tmp = @mysqli_set_local_infile_handler($handle, 'callback_simple')))
- printf("[003] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- if (false !== ($tmp = @mysqli_set_local_infile_handler($link, 'unknown')))
- printf("[004] Expecting false/boolean got %s/%s\n", $tmp, gettype($tmp));
-
- $file = create_standard_csv(5);
-
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(10, $link, $file, 'callback_simple', $expected);
-
- $expected = array();
- try_handler(20, $link, $file, 'callback_fclose', $expected);
-
- // FIXME - TODO - KLUDGE -
- // IMHO this is wrong. ext/mysqli should bail as the function signature
- // is not complete. That's a BC break, OK, but it makes perfectly sense.
- $expected = array();
- try_handler(30, $link, $file, 'callback_invalid_args', $expected);
-
- $expected = array();
- try_handler(40, $link, $file, 'callback_error', $expected);
-
-
- mysqli_close($link);
-
- if (!is_null($tmp = @mysqli_set_local_infile_handler($link, 'callback_simple')))
- printf("[300] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_simple'
-Callback: 0
-Callback: 1
-Callback set to 'callback_fclose'
-Callback: 0
-[022] LOAD DATA failed, [2000] File handle close%s
-Callback set to 'callback_invalid_args'
-Callback: 0
-Callback: 1
-[037] More results than expected!
-array(2) {
- [%u|b%"id"]=>
- %unicode|string%(2) "97"
- [%u|b%"label"]=>
- %unicode|string%(1) "x"
-}
-array(2) {
- [%u|b%"id"]=>
- %unicode|string%(2) "98"
- [%u|b%"label"]=>
- %unicode|string%(1) "y"
-}
-array(2) {
- [%u|b%"id"]=>
- %unicode|string%(2) "99"
- [%u|b%"label"]=>
- %unicode|string%(1) "z"
-}
-Callback set to 'callback_error'
-Callback: 0
-[042] LOAD DATA failed, [2000] How to access this error?
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt
deleted file mode 100644
index b8f51c214f..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt
+++ /dev/null
@@ -1,82 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - random ASCII character including \0
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-require_once('connect.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_bad_character($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
-
- $num_chars = (version_compare(PHP_VERSION, '5.9.9', '>') == 1) ? (floor($buflen / 2) - 10) : ($buflen - 5);
- $part1 = floor($num_chars / 2);
- $part2 = $num_chars - $part1;
-
- $buffer = '';
- for ($i = 0; $i < $part1; $i++)
- $buffer .= chr(mt_rand(0, 255));
-
- $buffer .= ';"';
-
- for ($i = 0; $i < $part2; $i++)
- $buffer .= chr(mt_rand(0, 255));
-
- $buffer .= '";';
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(5);
- /* we feed the handler with random data, therefore we cannot specify and expected rows */
- try_handler(20, $link, $file, 'callback_bad_character');
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_bad_character'
-Callback: 0
-Callback: 1
-Callback: 2
-Callback: 3
-Callback: 4
-Callback: 5
-Callback: 6
-Callback: 7
-Callback: 8
-Callback: 9
-Callback: 10
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt
deleted file mode 100644
index a3c8801023..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt
+++ /dev/null
@@ -1,60 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - buffer overflow
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_buffer_overflow($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
- $buffer = fread($fp, $buflen);
-
- $buffer = str_repeat(';', $buflen * 2);
- return strlen($buffer);
- }
-
- $file = create_standard_csv(5);
- $expected = array();
- try_handler(20, $link, $file, 'callback_buffer_overflow', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_buffer_overflow'
-Callback: 0
-
-Warning: mysqli_query(): Too much data returned in %s on line %d
-[022] LOAD DATA failed, [%d] Too much data returned
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt
deleted file mode 100644
index 408bb29ec4..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt
+++ /dev/null
@@ -1,61 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - close database link
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require("table.inc");
- require_once('local_infile_tools.inc');
-
- function callback_close_link($fp, &$buffer, $buflen, &$error) {
- global $link;
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_object($link))
- mysqli_close($link);
-
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_close_link', $expected);
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_close_link'
-Callback: 0
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt
deleted file mode 100644
index 168cbc1358..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt
+++ /dev/null
@@ -1,70 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - do not use the file pointer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once("table.inc");
- require_once('local_infile_tools.inc');
-
- function callback_closefile($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_resource($fp))
- fclose($fp);
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_closefile', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_closefile'
-Callback: 0
-Callback: 1
-Callback: 2
-Callback: 3
-Callback: 4
-Callback: 5
-Callback: 6
-Callback: 7
-Callback: 8
-Callback: 9
-Callback: 10
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt
deleted file mode 100644
index ad7ab32c1c..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt
+++ /dev/null
@@ -1,62 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - use closures as handler
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- $callback_replace_buffer = function ($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
-
- $buffer = fread($fp, $buflen);
-
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- };
-
- $file = create_standard_csv(1);
- if (!try_handler(20, $link, $file, $callback_replace_buffer, null))
- printf("[008] Failure\n");
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'Closure object'
-Callback: 0
-Callback: 1
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt
deleted file mode 100644
index b2b42a22e5..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt
+++ /dev/null
@@ -1,61 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - kill database link
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require("table.inc");
- require_once('local_infile_tools.inc');
-
- function callback_kill_link($fp, &$buffer, $buflen, &$error) {
- global $link;
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_object($link))
- mysqli_kill($link, mysqli_thread_id($link));
-
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- mysqli_set_local_infile_default($link);
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_kill_link', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_kill_link'
-Callback: 0
-[022] LOAD DATA failed, [2000] Can't execute load data local init callback function
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt
deleted file mode 100644
index 16e38c5fa2..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt
+++ /dev/null
@@ -1,58 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - negative return value/buflen to indicate an error
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_negative_len($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
- $buffer = fread($fp, $buflen);
-
- $error = "negative length means error";
- return -1;
- }
-
- $file = create_standard_csv(1);
- $expected = array();
- try_handler(20, $link, $file, 'callback_negative_len', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_negative_len'
-Callback: 0
-[022] LOAD DATA failed, [2000] negative length means error
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt
deleted file mode 100644
index 4663fe236e..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt
+++ /dev/null
@@ -1,107 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - nested calls
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_simple($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback - callback_simple(): %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- /* report the wrong length */
- return strlen($buffer);
- }
-
- function callback_report_short_len($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback - report_short_len(): %d\n", $invocation++);
- return callback_simple($fp, $buffer, $buflen, $error);
- }
-
- $file = create_standard_csv(1);
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(20, $link, $file, 'callback_report_short_len', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_report_short_len'
-Callback - report_short_len(): 0
-Callback - callback_simple(): 0
-Callback - report_short_len(): 1
-Callback - callback_simple(): 1
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt
deleted file mode 100644
index ca06435c5e..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt
+++ /dev/null
@@ -1,71 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - run new query on db link
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_new_query($fp, &$buffer, $buflen, &$error) {
- global $link;
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_object($link)) {
- if (!$res = mysqli_query($link, "SELECT id, label FROM test")) {
- printf("[Callback 001 - %03d] Cannot run query, [%d] %s\n",
- $invocation, mysqli_errno($link), mysqli_error($link));
- }
- if ($res)
- mysqli_free_result($res);
- }
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- mysqli_set_local_infile_default($link);
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_new_query', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_new_query'
-Callback: 0
-[Callback 001 - 001] Cannot run query, [2014] Commands out of sync; you can't run this command now
-[022] LOAD DATA failed, [2000] Can't execute load data local init callback function
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt
deleted file mode 100644
index 601a09e12c..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt
+++ /dev/null
@@ -1,70 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - do not use the file pointer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_nofileop($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
-
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_nofileop', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_nofileop'
-Callback: 0
-Callback: 1
-Callback: 2
-Callback: 3
-Callback: 4
-Callback: 5
-Callback: 6
-Callback: 7
-Callback: 8
-Callback: 9
-Callback: 10
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt
deleted file mode 100644
index 7163aca10d..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt
+++ /dev/null
@@ -1,115 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - open basedir restrictions
---SKIPIF--
-<?php
-if (!$fp = @fopen('skipif.inc', 'r'))
- die("skip open_basedir restrictions forbid opening include files");
-
-include_once('skipif.inc');
-include_once('skipifemb.inc');
-include_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-include_once('connect.inc');
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) {
- mysqli_close($link);
- die("skip Cannot check if Server variable 'local_infile' is set to 'ON'");
-}
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-open_basedir="."
---FILE--
-<?php
- @include('connect.inc');
- if (!isset($db)) {
- // stupid run-tests.php - any idea how to set system ini setting dynamically???
- print "Warning: tempnam(): open_basedir restriction in effect. File(grrr) is not within the allowed path(s): (grrr) in grrr on line 0
-[005 + 1] Cannot create CVS file ''
-Callback set to 'callback_simple'
-[012] LOAD DATA failed, [0] grrr
-[014/0] [0] ''
-done!";
- die();
- }
-
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_simple($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(5);
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(10, $link, $file, 'callback_simple', $expected);
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Warning: tempnam(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s) in %s on line %d
-[005 + 1] Cannot create CVS file ''
-Callback set to 'callback_simple'
-[012] LOAD DATA failed, [%d] %s
-[014/0] [0] ''
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt
deleted file mode 100644
index 0d4024e528..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt
+++ /dev/null
@@ -1,78 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - replace buffer pointer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_replace_buffer($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
-
- $buffer = fread($fp, $buflen);
-
- $ret = "1;'a';\n";
- $buffer = $ret;
-
- $num_chars = ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) ? floor($buflen / 2) : $buflen;
- assert(strlen($buffer) < $num_chars);
-
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- if (!try_handler(20, $link, $file, 'callback_replace_buffer', $expected))
- printf("[008] Failure\n");
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_replace_buffer'
-Callback: 0
-Callback: 1
-Callback: 2
-Callback: 3
-Callback: 4
-Callback: 5
-Callback: 6
-Callback: 7
-Callback: 8
-Callback: 9
-Callback: 10
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt
deleted file mode 100644
index b3144e430e..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt
+++ /dev/null
@@ -1,101 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - report shorter buffer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_short_len($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- /* report the wrong length */
- return strlen($buffer) - 1;
- }
-
- $file = create_standard_csv(1);
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(20, $link, $file, 'callback_short_len', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_short_len'
-Callback: 0
-
-Warning: mysqli_query(): Mismatch between the return value of the callback and the content length of the buffer. in %s on line %d
-[022] LOAD DATA failed, [2000] Mismatch between the return value of the callback and the content length of the buffer.
-[024/0] [0] ''
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt
deleted file mode 100644
index f287f4d874..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt
+++ /dev/null
@@ -1,64 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - do not use the file pointer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_unregister($fp, &$buffer, $buflen, &$error) {
- global $link;
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_resource($fp))
- fclose($fp);
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- mysqli_set_local_infile_default($link);
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_unregister', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_unregister'
-Callback: 0
-
-Warning: mysqli_query(): File handle closed in %s on line %d
-[022] LOAD DATA failed, [2000] File handle closed
-[024/0] [0] ''
-done!
diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt
index afaccaf3c7..739bf56ea1 100644
--- a/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt
+++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt
@@ -12,7 +12,13 @@ if (!function_exists('mysqli_stmt_get_result'))
--FILE--
<?php
require('table.inc');
- $charsets = my_get_charsets($link);
+
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!mysqli_set_charset($link, 'utf8'))
+ printf("[%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+
+ $charsetInfo = mysqli_get_charset($link);
if (!($stmt = mysqli_stmt_init($link)) ||
!mysqli_stmt_prepare($stmt, "SELECT id, label, id + 1 as _id, concat(label, '_') ___label FROM test ORDER BY id ASC LIMIT 3") ||
@@ -39,15 +45,14 @@ if (!function_exists('mysqli_stmt_get_result'))
Label column, result set charset.
All of the following columns are "too hot" - too server dependent
*/
- if ($field->charsetnr != $charsets['results']['nr']) {
+ if ($field->charsetnr != $charsetInfo->number) {
printf("[004] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $field->charsetnr);
+ $charsetInfo->charset,
+ $charsetInfo->number, $field->charsetnr);
}
- if ($field->length != (1 * $charsets['results']['maxlen'])) {
+ if ($field->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
- $field->max_length);
+ $charsetInfo->max_length, $field->max_length);
}
}
}
@@ -173,4 +178,4 @@ object(stdClass)#%d (13) {
[%u|b%"decimals"]=>
int(31)
}
-done! \ No newline at end of file
+done!