diff options
Diffstat (limited to 'ext/mysqlnd')
| -rw-r--r-- | ext/mysqlnd/mysqlnd.c | 26 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd.h | 13 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_charset.c | 4 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_charset.h | 4 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_libmysql_compat.h | 4 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_loaddata.c | 2 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_palloc.c | 20 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_portability.h | 2 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_priv.h | 4 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_ps.c | 65 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_result.c | 238 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_result_meta.c | 2 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_structs.h | 6 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_wireprotocol.c | 15 | ||||
| -rw-r--r-- | ext/mysqlnd/mysqlnd_wireprotocol.h | 6 | 
15 files changed, 296 insertions, 115 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index 2ee2244b18..5e32d7fda7 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -67,7 +67,7 @@ MYSQLND_STATS *mysqlnd_global_stats = NULL;  static zend_bool mysqlnd_library_initted = FALSE; -enum_func_status mysqlnd_send_close(MYSQLND * conn TSRMLS_DC); +static enum_func_status mysqlnd_send_close(MYSQLND * conn TSRMLS_DC);  /* {{{ mysqlnd_library_init */  static @@ -454,11 +454,11 @@ PHPAPI void mysqlnd_end_psession(MYSQLND *conn)  /* {{{ mysqlnd_connect */  PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn, -						 char *host, char *user, -						 char *passwd, unsigned int passwd_len, -						 char *db, unsigned int db_len, +						 const char *host, const char *user, +						 const char *passwd, unsigned int passwd_len, +						 const char *db, unsigned int db_len,  						 unsigned int port, -						 char *socket, +						 const char *socket,  						 unsigned int mysql_flags,  						 MYSQLND_THD_ZVAL_PCACHE *zval_cache  						 TSRMLS_DC) @@ -949,7 +949,7 @@ MYSQLND_METHOD(mysqlnd_conn, sqlstate)(const MYSQLND * const conn)  /* {{{ mysqlnd_old_escape_string */ -PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, int escapestr_len TSRMLS_DC) +PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, size_t escapestr_len TSRMLS_DC)  {  	DBG_ENTER("mysqlnd_old_escape_string");  	DBG_RETURN(mysqlnd_cset_escape_slashes(mysqlnd_find_charset_name("latin1"), @@ -961,7 +961,7 @@ PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, int  /* {{{ mysqlnd_conn::escape_string */  static ulong  MYSQLND_METHOD(mysqlnd_conn, escape_string)(const MYSQLND * const conn, char *newstr, -											const char *escapestr, int escapestr_len TSRMLS_DC) +											const char *escapestr, size_t escapestr_len TSRMLS_DC)  {  	DBG_ENTER("mysqlnd_conn::escape_string");  	DBG_INF_FMT("conn=%llu", conn->thread_id); @@ -1088,7 +1088,7 @@ MYSQLND_METHOD(mysqlnd_conn, kill)(MYSQLND *conn, unsigned int pid TSRMLS_DC)  /* }}} */ -/* {{{ _mysqlnd_conn::set_charset */ +/* {{{ mysqlnd_conn::set_charset */  static enum_func_status  MYSQLND_METHOD(mysqlnd_conn, set_charset)(MYSQLND * const conn, const char * const csname TSRMLS_DC)  { @@ -1696,8 +1696,8 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn,  /* }}} */ -/* {{{ _mysqlnd_conn::use_result */ -MYSQLND_RES * +/* {{{ mysqlnd_conn::use_result */ +static MYSQLND_RES *  MYSQLND_METHOD(mysqlnd_conn, use_result)(MYSQLND * const conn TSRMLS_DC)  {  	MYSQLND_RES *result; @@ -1729,8 +1729,8 @@ MYSQLND_METHOD(mysqlnd_conn, use_result)(MYSQLND * const conn TSRMLS_DC)  /* }}} */ -/* {{{ _mysqlnd_conn::store_result */ -MYSQLND_RES * +/* {{{ mysqlnd_conn::store_result */ +static MYSQLND_RES *  MYSQLND_METHOD(mysqlnd_conn, store_result)(MYSQLND * const conn TSRMLS_DC)  {  	MYSQLND_RES *result; @@ -1762,7 +1762,7 @@ MYSQLND_METHOD(mysqlnd_conn, store_result)(MYSQLND * const conn TSRMLS_DC)  /* {{{ mysqlnd_conn::get_connection_stats */ -void +static void  MYSQLND_METHOD(mysqlnd_conn, get_connection_stats)(const MYSQLND * const conn,  												   zval *return_value  												   TSRMLS_DC ZEND_FILE_LINE_DC) diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h index 92718efc81..d008adb8cd 100644 --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@ -69,11 +69,11 @@ PHPAPI const MYSQLND_CHARSET * mysqlnd_find_charset_name(const char * const char  #define mysqlnd_init(persistent) _mysqlnd_init((persistent) TSRMLS_CC)  PHPAPI MYSQLND * _mysqlnd_init(zend_bool persistent TSRMLS_DC);  PHPAPI MYSQLND * mysqlnd_connect(MYSQLND *conn, -						  char *host, char *user, -						  char *passwd, unsigned int passwd_len, -						  char *db, unsigned int db_len, +						  const char *host, const char *user, +						  const char *passwd, unsigned int passwd_len, +						  const char *db, unsigned int db_len,  						  unsigned int port, -						  char *socket, +						  const char *socket,  						  unsigned int mysql_flags,  						  MYSQLND_THD_ZVAL_PCACHE *zval_cache  						  TSRMLS_DC); @@ -85,6 +85,7 @@ void _mysqlnd_debug(const char *mode TSRMLS_DC);  /* Query */  #define mysqlnd_fetch_into(result, flags, ret_val, ext)	(result)->m.fetch_into((result), (flags), (ret_val), (ext) TSRMLS_CC ZEND_FILE_LINE_CC) +#define mysqlnd_fetch_row_c(result)						(result)->m.fetch_row_c((result) TSRMLS_CC)  #define mysqlnd_fetch_all(result, flags, return_value)	(result)->m.fetch_all((result), (flags), (return_value) TSRMLS_CC ZEND_FILE_LINE_CC)  #define mysqlnd_result_fetch_field_data(res,offset,ret)	(res)->m.fetch_field_data((res), (offset), (ret) TSRMLS_CC)  #define mysqlnd_get_connection_stats(conn, values)		(conn)->m->get_statistics((conn),  (values) TSRMLS_CC ZEND_FILE_LINE_CC) @@ -235,7 +236,7 @@ PHPAPI void mysqlnd_set_local_infile_handler(MYSQLND * const conn, const char *  #define mysqlnd_escape_string(newstr, escapestr, escapestr_len) \  		mysqlnd_old_escape_string((newstr), (escapestr), (escapestr_len) TSRMLS_CC) -PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, int escapestr_len TSRMLS_DC); +PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, size_t escapestr_len TSRMLS_DC);  /* PS */ @@ -247,10 +248,10 @@ PHPAPI ulong mysqlnd_old_escape_string(char *newstr, const char *escapestr, int  #define mysqlnd_stmt_execute(stmt) 			(stmt)->m->execute((stmt) TSRMLS_CC)  #define mysqlnd_stmt_send_long_data(s,p,d,l) (s)->m->send_long_data((s), (p), (d), (l) TSRMLS_CC)  #define mysqlnd_stmt_bind_param(stmt,bind)	(stmt)->m->bind_param((stmt), (bind) TSRMLS_CC) +#define mysqlnd_stmt_refresh_bind_param(s)	(s)->m->refresh_bind_param((s) TSRMLS_CC)  #define mysqlnd_stmt_bind_result(stmt,bind)	(stmt)->m->bind_result((stmt), (bind) TSRMLS_CC)  #define mysqlnd_stmt_param_metadata(stmt)	(stmt)->m->get_parameter_metadata((stmt))  #define mysqlnd_stmt_result_metadata(stmt)	(stmt)->m->get_result_metadata((stmt) TSRMLS_CC) -#define mysqlnd_stmt_ronly_result_metadata(stmt) ((stmt)->result)  #define	mysqlnd_stmt_free_result(stmt)		(stmt)->m->free_result((stmt) TSRMLS_CC)  #define	mysqlnd_stmt_close(stmt, implicit)	(stmt)->m->dtor((stmt), (implicit) TSRMLS_CC) diff --git a/ext/mysqlnd/mysqlnd_charset.c b/ext/mysqlnd/mysqlnd_charset.c index eed35d46b4..989d977bd8 100644 --- a/ext/mysqlnd/mysqlnd_charset.c +++ b/ext/mysqlnd/mysqlnd_charset.c @@ -463,7 +463,7 @@ PHPAPI const MYSQLND_CHARSET * mysqlnd_find_charset_name(const char * const name  /* {{{ mysqlnd_cset_escape_quotes */  PHPAPI ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const cset, char *newstr, -										const char *escapestr, int escapestr_len TSRMLS_DC) +										const char *escapestr, size_t escapestr_len TSRMLS_DC)  {  	const char 	*newstr_s = newstr;  	const char 	*newstr_e = newstr + 2 * escapestr_len; @@ -517,7 +517,7 @@ PHPAPI ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const cset, char  /* {{{ mysqlnd_cset_escape_slashes */  PHPAPI ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, char *newstr, -										 const char *escapestr, int escapestr_len TSRMLS_DC) +										 const char *escapestr, size_t escapestr_len TSRMLS_DC)  {  	const char 	*newstr_s = newstr;  	const char 	*newstr_e = newstr + 2 * escapestr_len; diff --git a/ext/mysqlnd/mysqlnd_charset.h b/ext/mysqlnd/mysqlnd_charset.h index b9dc6b69da..34f742fc5d 100644 --- a/ext/mysqlnd/mysqlnd_charset.h +++ b/ext/mysqlnd/mysqlnd_charset.h @@ -22,10 +22,10 @@  #define MYSQLND_CHARSET_H  PHPAPI ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const charset, char *newstr, -										const char *escapestr, int escapestr_len TSRMLS_DC); +										const char *escapestr, size_t escapestr_len TSRMLS_DC);  PHPAPI ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, char *newstr, -										 const char *escapestr, int escapestr_len TSRMLS_DC); +										 const char *escapestr, size_t escapestr_len TSRMLS_DC);  #endif /* MYSQLND_CHARSET_H */ diff --git a/ext/mysqlnd/mysqlnd_libmysql_compat.h b/ext/mysqlnd/mysqlnd_libmysql_compat.h index 3786eece0a..546bd12693 100644 --- a/ext/mysqlnd/mysqlnd_libmysql_compat.h +++ b/ext/mysqlnd/mysqlnd_libmysql_compat.h @@ -28,7 +28,7 @@  #define MYSQL_STMT				MYSQLND_STMT  #define MYSQL_FIELD				MYSQLND_FIELD  #define MYSQL_RES				MYSQLND_RES -#define MYSQL_ROW				MYSQLND_ROW +#define MYSQL_ROW				MYSQLND_ROW_C  #define MYSQL					MYSQLND  #define my_bool					zend_bool  #define my_ulonglong			uint64 @@ -58,7 +58,7 @@  #define mysql_fetch_field(r)			mysqlnd_fetch_field((r))  #define mysql_fetch_field_direct(r,o)	mysqlnd_fetch_field_direct((r), (o))  #define mysql_fetch_lengths(r)			mysqlnd_fetch_lengths((r)) -#define mysql_fetch_row(r)				mysqlnd_fetch_row((r)) +#define mysql_fetch_row(r)				mysqlnd_fetch_row_c((r))  #define mysql_field_count(r)			mysqlnd_field_count((r))  #define mysql_field_seek(r,o)			mysqlnd_field_seek((r), (o))  #define mysql_field_tell(r)				mysqlnd_field_tell((r)) diff --git a/ext/mysqlnd/mysqlnd_loaddata.c b/ext/mysqlnd/mysqlnd_loaddata.c index 02166ca210..2064aa39b1 100644 --- a/ext/mysqlnd/mysqlnd_loaddata.c +++ b/ext/mysqlnd/mysqlnd_loaddata.c @@ -118,7 +118,7 @@ int	mysqlnd_local_infile_error(void *ptr, char *error_buf, uint error_buf_len TS  		DBG_RETURN(info->error_no);  	} -	strncpy(error_buf, "Unknown error", error_buf_len); +	strlcpy(error_buf, "Unknown error", error_buf_len);  	DBG_INF_FMT("no info, %d", CR_UNKNOWN_ERROR);  	DBG_RETURN(CR_UNKNOWN_ERROR);  } diff --git a/ext/mysqlnd/mysqlnd_palloc.c b/ext/mysqlnd/mysqlnd_palloc.c index 2aeb0b3d73..976e473733 100644 --- a/ext/mysqlnd/mysqlnd_palloc.c +++ b/ext/mysqlnd/mysqlnd_palloc.c @@ -294,9 +294,11 @@ void *mysqlnd_palloc_get_zval(MYSQLND_THD_ZVAL_PCACHE * const thd_cache, zend_bo  	void *ret = NULL;  	DBG_ENTER("mysqlnd_palloc_get_zval"); -	DBG_INF_FMT("cache=%p *last_added=%p free_items=%d", -				thd_cache, thd_cache? thd_cache->parent->free_list.last_added:NULL, -				thd_cache->parent->free_items); +	if (thd_cache) { +		DBG_INF_FMT("cache=%p *last_added=%p free_items=%d", +					thd_cache, thd_cache->parent->free_list.last_added, +					thd_cache->parent->free_items); +	}  	if (thd_cache) {  		MYSQLND_ZVAL_PCACHE *cache = thd_cache->parent; @@ -343,11 +345,13 @@ void mysqlnd_palloc_zval_ptr_dtor(zval **zv, MYSQLND_THD_ZVAL_PCACHE * const thd  {  	MYSQLND_ZVAL_PCACHE *cache;  	DBG_ENTER("mysqlnd_palloc_zval_ptr_dtor"); -	DBG_INF_FMT("cache=%p parent_block=%p last_in_block=%p *zv=%p refc=%d type=%d ", -				thd_cache, -				thd_cache->parent? thd_cache->parent->block:NULL, -				thd_cache->parent? thd_cache->parent->last_in_block:NULL, -				*zv, Z_REFCOUNT_PP(zv), type); +	if (thd_cache) { +		DBG_INF_FMT("cache=%p parent_block=%p last_in_block=%p *zv=%p refc=%d type=%d ", +					thd_cache, +					thd_cache->parent->block, +					thd_cache->parent->last_in_block, +					*zv, Z_REFCOUNT_PP(zv), type); +	}  	*copy_ctor_called = FALSE;  	/* Check whether cache is used and the zval is from the cache */  	if (!thd_cache || !(cache = thd_cache->parent) || ((char *)*zv < (char *)thd_cache->parent->block || diff --git a/ext/mysqlnd/mysqlnd_portability.h b/ext/mysqlnd/mysqlnd_portability.h index 049aa9707a..b7c4c8f096 100644 --- a/ext/mysqlnd/mysqlnd_portability.h +++ b/ext/mysqlnd/mysqlnd_portability.h @@ -325,7 +325,7 @@ typedef union {                                 (((uint32) ((uchar) (A)[3])) << 24)) -#define uint8korr(A) ((ulonglong)(((uint32) (((uchar*) (A))[7])) +\ +#define bit_uint8korr(A) ((ulonglong)(((uint32) (((uchar*) (A))[7])) +\  									(((uint32) (((uchar*) (A))[6])) << 8) +\  									(((uint32) (((uchar*) (A))[5])) << 16) +\  									(((uint32) (((uchar*) (A))[4])) << 24)) +\ diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h index cf6424e49f..9762a60542 100644 --- a/ext/mysqlnd/mysqlnd_priv.h +++ b/ext/mysqlnd/mysqlnd_priv.h @@ -149,8 +149,8 @@  #define SET_CLIENT_ERROR(error_info, a, b, c) \  	{ \  		error_info.error_no = a; \ -		strncpy(error_info.sqlstate, b, sizeof(error_info.sqlstate)); \ -		strncpy(error_info.error, c, sizeof(error_info.error)); \ +		strlcpy(error_info.sqlstate, b, sizeof(error_info.sqlstate)); \ +		strlcpy(error_info.error, c, sizeof(error_info.error)); \  	}  #define SET_STMT_ERROR(stmt, a, b, c)	SET_CLIENT_ERROR(stmt->error_info, a, b, c) diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 6e4d39ae72..3f06f4beb0 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -331,7 +331,9 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const stmt, const char * co  	  no metadata at prepare.  	*/  	if (stmt_to_prepare->field_count) { -		MYSQLND_RES *result = mysqlnd_result_init(stmt_to_prepare->field_count, NULL TSRMLS_CC); +		MYSQLND_RES *result = mysqlnd_result_init(stmt_to_prepare->field_count, +												  mysqlnd_palloc_get_thd_cache_reference(stmt->conn->zval_cache) +												  TSRMLS_CC);  		/* Allocate the result now as it is needed for the reading of metadata */  		stmt_to_prepare->result = result;  @@ -731,37 +733,16 @@ MYSQLND_METHOD(mysqlnd_stmt, use_result)(MYSQLND_STMT *stmt TSRMLS_DC)  	}  	SET_EMPTY_ERROR(stmt->error_info); -	SET_EMPTY_ERROR(stmt->conn->error_info);  	MYSQLND_INC_CONN_STATISTIC(&stmt->conn->stats, STAT_PS_UNBUFFERED_SETS); - -	result					= stmt->result; -	result->type			= MYSQLND_RES_PS_UNBUF; -	result->m.fetch_row		= stmt->cursor_exists? mysqlnd_fetch_stmt_row_cursor: -													mysqlnd_stmt_fetch_row_unbuffered; -	result->m.fetch_lengths	= NULL; /* makes no sense */ -	result->zval_cache		= mysqlnd_palloc_get_thd_cache_reference(conn->zval_cache); - -	result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED)); - -	DBG_INF_FMT("cursor=%d zval_cache=%p", stmt->cursor_exists, result->zval_cache); -	/* -	  Will be freed in the mysqlnd_internal_free_result_contents() called -	  by the resource destructor. mysqlnd_fetch_row_unbuffered() expects -	  this to be not NULL. -	*/ -	PACKET_INIT(result->row_packet, PROT_ROW_PACKET, php_mysql_packet_row *); -	result->row_packet->field_count = result->field_count; -	result->row_packet->binary_protocol = TRUE; -	result->row_packet->fields_metadata = stmt->result->meta->fields; -	result->row_packet->bit_fields_count = result->meta->bit_fields_count; -	result->row_packet->bit_fields_total_len = result->meta->bit_fields_total_len; -	result->lengths = NULL; +	result = stmt->result; +	 +	result->m.use_result(stmt->result, TRUE TSRMLS_CC); +	result->m.fetch_row	= stmt->cursor_exists? mysqlnd_fetch_stmt_row_cursor: +											   mysqlnd_stmt_fetch_row_unbuffered;  	stmt->state = MYSQLND_STMT_USE_OR_STORE_CALLED; -	/* No multithreading issues as we don't share the connection :) */ -  	DBG_INF_FMT("%p", result);  	DBG_RETURN(result);  } @@ -1164,6 +1145,31 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_param)(MYSQLND_STMT * const stmt,  /* }}} */ +/* {{{ _mysqlnd_stmt_refresh_bind_param */ +static enum_func_status +MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param)(MYSQLND_STMT * const stmt TSRMLS_DC) +{ +	DBG_ENTER("mysqlnd_stmt::refresh_bind_param"); +	DBG_INF_FMT("stmt=%lu param_count=%u", stmt->stmt_id, stmt->param_count); + +	if (stmt->state < MYSQLND_STMT_PREPARED) { +		SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared); +		DBG_ERR("not prepared"); +		DBG_RETURN(FAIL); +	} + +	SET_EMPTY_ERROR(stmt->error_info); +	SET_EMPTY_ERROR(stmt->conn->error_info); + +	if (stmt->param_count) { +		stmt->send_types_to_server = 1; +	} +	DBG_INF("PASS"); +	DBG_RETURN(PASS); +} +/* }}} */ + +  /* {{{ mysqlnd_stmt::bind_result */  static enum_func_status  MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const stmt, @@ -1535,7 +1541,7 @@ void mysqlnd_internal_free_stmt_content(MYSQLND_STMT *stmt TSRMLS_DC)  	/* Destroy the input bind */  	if (stmt->param_bind) { -		int i; +		unsigned int i;  		/*  		  Because only the bound variables can point to our internal buffers, then  		  separate or free only them. Free is possible because the user could have @@ -1651,7 +1657,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, dtor)(MYSQLND_STMT * const stmt, zend_bool  {  	enum_func_status ret; -	DBG_ENTER("mysqlnd_stmt::close"); +	DBG_ENTER("mysqlnd_stmt::dtor");  	DBG_INF_FMT("stmt=%p", stmt);  	MYSQLND_INC_GLOBAL_STATISTIC(implicit == TRUE?	STAT_STMT_CLOSE_IMPLICIT: @@ -1683,6 +1689,7 @@ struct st_mysqlnd_stmt_methods mysqlnd_stmt_methods = {  	MYSQLND_METHOD(mysqlnd_stmt, fetch),  	MYSQLND_METHOD(mysqlnd_stmt, bind_param), +	MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param),  	MYSQLND_METHOD(mysqlnd_stmt, bind_result),  	MYSQLND_METHOD(mysqlnd_stmt, send_long_data),  	MYSQLND_METHOD(mysqlnd_stmt, param_metadata), diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index ce5322b7ac..9a19f39789 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -438,7 +438,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC  static   unsigned long * mysqlnd_fetch_lengths_buffered(MYSQLND_RES * const result)  { -	int i; +	unsigned int i;  	zval **previous_row;  	/* @@ -481,6 +481,102 @@ PHPAPI unsigned long * mysqlnd_fetch_lengths(MYSQLND_RES * const result)  /* }}} */ +/* {{{ mysqlnd_fetch_row_unbuffered_c */ +static MYSQLND_ROW_C +mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES *result TSRMLS_DC) +{ +	enum_func_status		ret; +	MYSQLND_ROW_C 			retrow = NULL; +	unsigned int			i, +							field_count = result->field_count; +	php_mysql_packet_row	*row_packet = result->row_packet; +	unsigned long			*lengths = result->lengths; + +	DBG_ENTER("mysqlnd_fetch_row_unbuffered"); + +	if (result->unbuf->eof_reached) { +		/* No more rows obviously */ +		DBG_RETURN(retrow); +	} +	if (result->conn->state != CONN_FETCHING_DATA) { +		SET_CLIENT_ERROR(result->conn->error_info, CR_COMMANDS_OUT_OF_SYNC, +						 UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);  +		DBG_RETURN(retrow); +	} +	/* Let the row packet fill our buffer and skip additional mnd_malloc + memcpy */ +	row_packet->skip_extraction = FALSE; + +	/* +	  If we skip rows (row == NULL) we have to +	  mysqlnd_unbuffered_free_last_data() before it. The function returns always true. +	*/ +	if (PASS == (ret = PACKET_READ(row_packet, result->conn)) && !row_packet->eof) { +		MYSQLND_FIELD *field = result->meta->fields; + +		result->unbuf->row_count++; + +		retrow = mnd_malloc(result->field_count * sizeof(char *)); + +		mysqlnd_unbuffered_free_last_data(result TSRMLS_CC); + +		result->unbuf->last_row_data = row_packet->fields; +		result->unbuf->last_row_buffer = row_packet->row_buffer; +		row_packet->fields = NULL; +		row_packet->row_buffer = NULL; + +		MYSQLND_INC_CONN_STATISTIC(&result->conn->stats, STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_UNBUF); + +		for (i = 0; i < field_count; i++, field++) { +			zval *data = result->unbuf->last_row_data[i]; +			int len; + +			if (Z_TYPE_P(data) != IS_NULL) { +				convert_to_string(data); +				retrow[i] = Z_STRVAL_P(data); +				len = Z_STRLEN_P(data); +			} else { +				retrow[i] = NULL; +				len = 0; +			} + +			if (lengths) { +				lengths[i] = len; +			} + +			if (field->max_length < len) { +				field->max_length = len; +			} +		} +	} else if (ret == FAIL) { +		if (row_packet->error_info.error_no) { +			result->conn->error_info = row_packet->error_info; +			DBG_ERR_FMT("errorno=%d error=%s", row_packet->error_info.error_no, row_packet->error_info.error);  +		} +		result->conn->state = CONN_READY; +		result->unbuf->eof_reached = TRUE; /* so next time we won't get an error */ +	} else if (row_packet->eof) { +		/* Mark the connection as usable again */ +		DBG_INF_FMT("warns=%u status=%u", row_packet->warning_count, row_packet->server_status); +		result->unbuf->eof_reached = TRUE; +		result->conn->upsert_status.warning_count = row_packet->warning_count; +		result->conn->upsert_status.server_status = row_packet->server_status; +		/* +		  result->row_packet will be cleaned when +		  destroying the result object +		*/ +		if (result->conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) { +			result->conn->state = CONN_NEXT_RESULT_PENDING; +		} else { +			result->conn->state = CONN_READY; +		} +		mysqlnd_unbuffered_free_last_data(result TSRMLS_CC); +	} + +	DBG_RETURN(retrow); +} +/* }}} */ + +  /* {{{ mysqlnd_fetch_row_unbuffered */  static enum_func_status  mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flags, @@ -528,11 +624,12 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag  		if (!row_packet->skip_extraction) {  			HashTable *row_ht = Z_ARRVAL_P(row); +			MYSQLND_FIELD *field = result->meta->fields; +			struct mysqlnd_field_hash_key *zend_hash_key = result->meta->zend_hash_keys; -			for (i = 0; i < field_count; i++) { +			for (i = 0; i < field_count; i++, field++, zend_hash_key++) {  				zval *data = result->unbuf->last_row_data[i];  				int len = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data); -				MYSQLND_RES_METADATA *meta = result->meta;  				if (lengths) {  					lengths[i] = len; @@ -555,31 +652,31 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag  					  the index is a numeric and convert it to it. This however means constant  					  hashing of the column name, which is not needed as it can be precomputed.  					*/ -					if (meta->zend_hash_keys[i].is_numeric == FALSE) { +					if (zend_hash_key->is_numeric == FALSE) {  #if PHP_MAJOR_VERSION >= 6  						if (UG(unicode)) {  							zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE, -													 meta->zend_hash_keys[i].ustr, -													 meta->zend_hash_keys[i].ulen + 1, -													 meta->zend_hash_keys[i].key, +													 zend_hash_key->ustr, +													 zend_hash_key->ulen + 1, +													 zend_hash_key->key,  													 (void *) &data, sizeof(zval *), NULL);  						} else  #endif  						{  							zend_hash_quick_update(Z_ARRVAL_P(row), -												   meta->fields[i].name, -												   meta->fields[i].name_length + 1, -												   meta->zend_hash_keys[i].key, +												   field->name, +												   field->name_length + 1, +												   zend_hash_key->key,  												   (void *) &data, sizeof(zval *), NULL);  						}  					} else {  						zend_hash_index_update(Z_ARRVAL_P(row), -											   meta->zend_hash_keys[i].key, +											   zend_hash_key->key,  											   (void *) &data, sizeof(zval *), NULL);  					}  				} -				if (meta->fields[i].max_length < len) { -					meta->fields[i].max_length = len; +				if (field->max_length < len) { +					field->max_length = len;  				}  			}  		} @@ -617,16 +714,27 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag  /* {{{ mysqlnd_res::use_result */ -MYSQLND_RES * +static MYSQLND_RES *  MYSQLND_METHOD(mysqlnd_res, use_result)(MYSQLND_RES * const result, zend_bool ps TSRMLS_DC)  {  	DBG_ENTER("mysqlnd_res::use_result");  	DBG_INF_FMT("ps=%d", ps); -	result->type			= MYSQLND_RES_NORMAL; -	result->m.fetch_row		= result->m.fetch_row_normal_unbuffered; -	result->m.fetch_lengths	= mysqlnd_fetch_lengths_unbuffered; -	result->unbuf			= mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED)); +	SET_EMPTY_ERROR(result->conn->error_info); + +	if (ps == FALSE) { +		result->type			= MYSQLND_RES_NORMAL; +		result->m.fetch_row		= result->m.fetch_row_normal_unbuffered; +		result->m.fetch_lengths	= mysqlnd_fetch_lengths_unbuffered; +		result->lengths			= mnd_ecalloc(result->field_count, sizeof(unsigned long)); +	} else { +		result->type			= MYSQLND_RES_PS_UNBUF; +		/* result->m.fetch_row() will be set in mysqlnd_ps.c */ +		result->m.fetch_lengths	= NULL; /* makes no sense */ +		result->lengths 		= NULL; +	} + +	result->unbuf = mnd_ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));  	/*  	  Will be freed in the mysqlnd_internal_free_result_contents() called @@ -635,19 +743,52 @@ MYSQLND_METHOD(mysqlnd_res, use_result)(MYSQLND_RES * const result, zend_bool ps  	*/  	PACKET_INIT(result->row_packet, PROT_ROW_PACKET, php_mysql_packet_row *);  	result->row_packet->field_count = result->field_count; -	result->row_packet->binary_protocol = FALSE; +	result->row_packet->binary_protocol = ps;  	result->row_packet->fields_metadata = result->meta->fields;  	result->row_packet->bit_fields_count = result->meta->bit_fields_count;  	result->row_packet->bit_fields_total_len = result->meta->bit_fields_total_len; -	result->lengths = mnd_ecalloc(result->field_count, sizeof(unsigned long)); - -	/* No multithreading issues as we don't share the connection :) */  	DBG_RETURN(result);  }  /* }}} */ +/* {{{ mysqlnd_fetch_row_buffered_c */ +static MYSQLND_ROW_C +mysqlnd_fetch_row_buffered_c(MYSQLND_RES *result TSRMLS_DC) +{ +	MYSQLND_ROW_C ret = NULL; +	unsigned int i; + +	DBG_ENTER("mysqlnd_fetch_row_buffered_c"); + +	/* If we haven't read everything */ +	if (result->data->data_cursor && +		(result->data->data_cursor - result->data->data) < result->data->row_count) +	{ +		ret = mnd_malloc(result->field_count * sizeof(char *)); + +		zval **current_row = *result->data->data_cursor; +		for (i = 0; i < result->field_count; i++) { +			zval *data = current_row[i]; +			if (Z_TYPE_P(data) != IS_NULL) { +				convert_to_string(data); +				ret[i] = Z_STRVAL_P(data); +			} else { +				ret[i] = NULL; +			} +		} +		result->data->data_cursor++; +		MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF); +	} else { +		result->data->data_cursor = NULL; +		DBG_INF("EOF reached"); +	} +	DBG_RETURN(ret); +} +/* }}} */ + +  /* {{{ mysqlnd_fetch_row_buffered */  static enum_func_status  mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags, @@ -664,7 +805,10 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags,  		(result->data->data_cursor - result->data->data) < result->data->row_count)  	{  		zval **current_row = *result->data->data_cursor; -		for (i = 0; i < result->field_count; i++) { +		MYSQLND_FIELD *field = result->meta->fields; +		struct mysqlnd_field_hash_key *zend_hash_key = result->meta->zend_hash_keys; + +		for (i = 0; i < result->field_count; i++, field++, zend_hash_key++) {  			zval *data = current_row[i];  			/* @@ -687,26 +831,26 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags,  				  the index is a numeric and convert it to it. This however means constant  				  hashing of the column name, which is not needed as it can be precomputed.  				*/ -				if (result->meta->zend_hash_keys[i].is_numeric == FALSE) { +				if (zend_hash_key->is_numeric == FALSE) {  #if PHP_MAJOR_VERSION >= 6  					if (UG(unicode)) {  						zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE, -												 result->meta->zend_hash_keys[i].ustr, -												 result->meta->zend_hash_keys[i].ulen + 1, -												 result->meta->zend_hash_keys[i].key, +												 zend_hash_key->ustr, +												 zend_hash_key->ulen + 1, +												 zend_hash_key->key,  												 (void *) &data, sizeof(zval *), NULL);  					} else  #endif  					{  						zend_hash_quick_update(Z_ARRVAL_P(row), -											   result->meta->fields[i].name, -											   result->meta->fields[i].name_length + 1, -											   result->meta->zend_hash_keys[i].key, +											   field->name, +											   field->name_length + 1, +											   zend_hash_key->key,  											   (void *) &data, sizeof(zval *), NULL);  					}  				} else {  					zend_hash_index_update(Z_ARRVAL_P(row), -										   result->meta->zend_hash_keys[i].key, +										   zend_hash_key->key,  										   (void *) &data, sizeof(zval *), NULL);  				}  			} @@ -761,7 +905,7 @@ mysqlnd_store_result_fetch_data(MYSQLND * const conn, MYSQLND_RES *result,  	row_packet.bit_fields_total_len = meta->bit_fields_total_len;  	/* Let the row packet fill our buffer and skip additional malloc + memcpy */  	while (FAIL != (ret = PACKET_READ_ALLOCA(row_packet, conn)) && !row_packet.eof) { -		int i; +		unsigned int i;  		zval **current_row;  		if (!free_rows) { @@ -849,7 +993,7 @@ mysqlnd_store_result_fetch_data(MYSQLND * const conn, MYSQLND_RES *result,  /* {{{ mysqlnd_res::store_result */ -MYSQLND_RES * +static MYSQLND_RES *  MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,  										  MYSQLND * const conn,  										  zend_bool ps_protocol TSRMLS_DC) @@ -959,7 +1103,7 @@ MYSQLND_METHOD(mysqlnd_res, data_seek)(MYSQLND_RES *result, uint64 row TSRMLS_DC  /* {{{ mysqlnd_res::num_fields */ -uint64 +static uint64  MYSQLND_METHOD(mysqlnd_res, num_rows)(const MYSQLND_RES * const res)  {  	/* Be compatible with libmysql. We count row_count, but will return 0 */ @@ -969,7 +1113,7 @@ MYSQLND_METHOD(mysqlnd_res, num_rows)(const MYSQLND_RES * const res)  /* {{{ mysqlnd_res::num_fields */ -unsigned int +static unsigned int  MYSQLND_METHOD(mysqlnd_res, num_fields)(const MYSQLND_RES * const res)  {  	return res->field_count; @@ -1066,6 +1210,27 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES *result, unsigned int flags,  /* }}} */ +/* {{{ mysqlnd_res::fetch_row_c */ +static MYSQLND_ROW_C +MYSQLND_METHOD(mysqlnd_res, fetch_row_c)(MYSQLND_RES *result TSRMLS_DC) +{ +	MYSQLND_ROW_C ret = NULL; +	DBG_ENTER("mysqlnd_res::fetch_row_c"); + +	if (result->m.fetch_row) { +		if (result->m.fetch_row == result->m.fetch_row_normal_buffered) { +			return mysqlnd_fetch_row_buffered_c(result TSRMLS_CC); +		} else if (result->m.fetch_row == result->m.fetch_row_normal_unbuffered) { +			return mysqlnd_fetch_row_unbuffered_c(result TSRMLS_CC); +		} else { +			*((int*)NULL) = 1; +		} +	} +	DBG_RETURN(ret); +} +/* }}} */ + +  /* {{{ mysqlnd_res::fetch_all */  static void  MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES *result, unsigned int flags, @@ -1108,7 +1273,7 @@ MYSQLND_METHOD(mysqlnd_res, fetch_field_data)(MYSQLND_RES *result, unsigned int  {  	zval row;  	zval **entry; -	uint i = 0; +	unsigned int i = 0;  	DBG_ENTER("mysqlnd_res::fetch_field_data");  	DBG_INF_FMT("offset=%u", offset); @@ -1164,6 +1329,7 @@ MYSQLND_RES *mysqlnd_result_init(unsigned int field_count, MYSQLND_THD_ZVAL_PCAC  	ret->m.num_rows		= MYSQLND_METHOD(mysqlnd_res, num_rows);  	ret->m.num_fields	= MYSQLND_METHOD(mysqlnd_res, num_fields);  	ret->m.fetch_into	= MYSQLND_METHOD(mysqlnd_res, fetch_into); +	ret->m.fetch_row_c	= MYSQLND_METHOD(mysqlnd_res, fetch_row_c);  	ret->m.fetch_all	= MYSQLND_METHOD(mysqlnd_res, fetch_all);  	ret->m.fetch_field_data	= MYSQLND_METHOD(mysqlnd_res, fetch_field_data);  	ret->m.seek_field	= MYSQLND_METHOD(mysqlnd_res, field_seek); diff --git a/ext/mysqlnd/mysqlnd_result_meta.c b/ext/mysqlnd/mysqlnd_result_meta.c index e75bfb8647..fac775de29 100644 --- a/ext/mysqlnd/mysqlnd_result_meta.c +++ b/ext/mysqlnd/mysqlnd_result_meta.c @@ -141,7 +141,7 @@ static enum_func_status  MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta,  												MYSQLND *conn TSRMLS_DC)  { -	int i = 0; +	unsigned int i = 0;  	php_mysql_packet_res_field field_packet;  	DBG_ENTER("mysqlnd_res_meta::read_metadata"); diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index 367d33c6a0..85785b14bd 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -152,7 +152,7 @@ typedef struct st_mysqlnd_option  typedef struct st_mysqlnd_connection MYSQLND;  typedef struct st_mysqlnd_res	MYSQLND_RES; -typedef char** 					MYSQLND_ROW;		/* return data as array of strings */ +typedef char** 					MYSQLND_ROW_C;		/* return data as array of strings */  typedef struct st_mysqlnd_stmt	MYSQLND_STMT;  typedef unsigned int			MYSQLND_FIELD_OFFSET; @@ -200,7 +200,7 @@ typedef struct st_mysqlnd_net  struct st_mysqlnd_conn_methods  { -	ulong				(*escape_string)(const MYSQLND * const conn, char *newstr, const char *escapestr, int escapestr_len TSRMLS_DC); +	ulong				(*escape_string)(const MYSQLND * const conn, char *newstr, const char *escapestr, size_t escapestr_len TSRMLS_DC);  	enum_func_status	(*set_charset)(MYSQLND * const conn, const char * const charset TSRMLS_DC);  	enum_func_status	(*query)(MYSQLND *conn, const char *query, unsigned int query_len TSRMLS_DC);  	MYSQLND_RES *		(*use_result)(MYSQLND * const conn TSRMLS_DC); @@ -261,6 +261,7 @@ struct st_mysqlnd_res_methods  	MYSQLND_RES *		(*use_result)(MYSQLND_RES * const result, zend_bool ps_protocol TSRMLS_DC);  	MYSQLND_RES *		(*store_result)(MYSQLND_RES * result, MYSQLND * const conn, zend_bool ps TSRMLS_DC);  	void 				(*fetch_into)(MYSQLND_RES *result, unsigned int flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC); +	MYSQLND_ROW_C 		(*fetch_row_c)(MYSQLND_RES *result TSRMLS_DC);  	void 				(*fetch_all)(MYSQLND_RES *result, unsigned int flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC);  	void 				(*fetch_field_data)(MYSQLND_RES *result, unsigned int offset, zval *return_value TSRMLS_DC);  	uint64		(*num_rows)(const MYSQLND_RES * const result); @@ -308,6 +309,7 @@ struct st_mysqlnd_stmt_methods  	enum_func_status	(*fetch)(MYSQLND_STMT * const stmt, zend_bool * const fetched_anything TSRMLS_DC);  	enum_func_status	(*bind_param)(MYSQLND_STMT * const stmt, MYSQLND_PARAM_BIND * const param_bind TSRMLS_DC); +	enum_func_status	(*refresh_bind_param)(MYSQLND_STMT * const stmt TSRMLS_DC);  	enum_func_status	(*bind_result)(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND * const result_bind TSRMLS_DC);  	enum_func_status	(*send_long_data)(MYSQLND_STMT * const stmt, unsigned int param_num,  										  const char * const data, unsigned long length TSRMLS_DC); diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 5f1ee54b88..cc8b29ad3b 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -480,7 +480,7 @@ size_t mysqlnd_read_body(MYSQLND *conn, zend_uchar *buf, size_t size TSRMLS_DC)  {  	size_t ret;  	char *p = (char *)buf; -	int iter = 0; +	unsigned int iter = 0;  	MYSQLND_NET *net = &conn->net;  	size_t old_chunk_size = net->stream->chunk_size; @@ -502,7 +502,7 @@ size_t mysqlnd_read_body(MYSQLND *conn, zend_uchar *buf, size_t size TSRMLS_DC)  #ifdef MYSQLND_DUMP_HEADER_N_BODY_FULL  	{ -		int i; +		unsigned int i;  		DBG_INF_FMT("BODY: requested=%d last_read=%3d", p - (char*)buf, ret);  		for (i = 0 ; i < p - (char*)buf; i++) {  			if (i && (i % 30 == 0)) { @@ -746,7 +746,7 @@ php_mysqlnd_ok_read(void *_packet, MYSQLND *conn TSRMLS_DC)  	zend_uchar buf[1024];  	zend_uchar *p = buf;  	zend_uchar *begin = buf; -	int i; +	unsigned long i;  	register php_mysql_packet_ok *packet= (php_mysql_packet_ok *) _packet;  	DBG_ENTER("php_mysqlnd_ok_read"); @@ -1068,7 +1068,8 @@ php_mysqlnd_rset_field_read(void *_packet, MYSQLND *conn TSRMLS_DC)  	zend_uchar *p = buf;  	zend_uchar *begin = buf;  	char *root_ptr; -	size_t buf_len = conn->net.cmd_buffer.length, len, total_len = 0; +	size_t buf_len = conn->net.cmd_buffer.length, total_len = 0; +	unsigned long len;  	MYSQLND_FIELD *meta;  	unsigned int i, field_count = sizeof(rset_field_offsets)/sizeof(size_t); @@ -1309,7 +1310,7 @@ static  void php_mysqlnd_rowp_read_binary_protocol(php_mysql_packet_row *packet, MYSQLND *conn,  										   zend_uchar *p, size_t data_size TSRMLS_DC)  { -	int i; +	unsigned int i;  	zend_uchar *null_ptr, bit;  	zval **current_field, **end_field, **start_field;  	zend_bool as_unicode = conn->options.numeric_and_datetime_as_unicode; @@ -1348,7 +1349,7 @@ void php_mysqlnd_rowp_read_binary_protocol(php_mysql_packet_row *packet, MYSQLND  												  0, &p, as_unicode TSRMLS_CC);  		}  		if (!((bit<<=1) & 255)) { -			bit= 1;					/* To next byte */ +			bit = 1;	/* to the following byte */  			null_ptr++;  		}  	} @@ -1365,7 +1366,7 @@ static  void php_mysqlnd_rowp_read_text_protocol(php_mysql_packet_row *packet, MYSQLND *conn,  										 zend_uchar *p, size_t data_size TSRMLS_DC)  { -	int i; +	unsigned int i;  	zend_bool last_field_was_string;  	zval **current_field, **end_field, **start_field;  	zend_uchar *bit_area = packet->row_buffer + data_size + 1; /* we allocate from here */ diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h index 30d4ab90e5..d9c733428d 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.h +++ b/ext/mysqlnd/mysqlnd_wireprotocol.h @@ -157,13 +157,13 @@ typedef struct st_php_mysql_packet_auth {  	uint32		max_packet_size;  	mysqlnd_1b	charset_no;  	/* 23 byte pad */ -	char		*user; +	const char	*user;  	/* 8 byte scramble */ -	char		*db; +	const char	*db;  	/* 12 byte scramble */  	/* Here the packet ends. This is user supplied data */ -	char		*password; +	const char	*password;  	/* +1 for \0 because of scramble() */  	unsigned char	*server_scramble_buf;  	size_t			db_len;  | 
