mirror of
https://github.com/php/php-src.git
synced 2026-04-22 15:38:49 +02:00
Merge branch 'phpng' into call-frame
* phpng: Remove temp file committed by accident Don't use zend_string for other fields (only name here is enough) Fixed _zend_get_parameters_array Fixed use of uninitialized value Cleanup (refactoring is finish) We don't need extra 1 byte anymore Conflicts: Zend/zend_API.c
This commit is contained in:
@@ -76,38 +76,6 @@ ZEND_API int zend_get_parameters(int ht, int param_count, ...) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval *argument_array TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
int arg_count;
|
||||
zval *param_ptr;
|
||||
|
||||
param_ptr = ZEND_CALL_ARG(EG(current_execute_data)->call, 1);
|
||||
arg_count = EG(current_execute_data)->call->num_args;
|
||||
|
||||
if (param_count>arg_count) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
while (param_count-->0) {
|
||||
if (Z_REFCOUNTED_P(param_ptr) &&
|
||||
!Z_ISREF_P(param_ptr) &&
|
||||
Z_REFCOUNT_P(param_ptr) > 1) {
|
||||
zval new_tmp;
|
||||
|
||||
ZVAL_DUP(&new_tmp, param_ptr);
|
||||
Z_DELREF_P(param_ptr);
|
||||
ZVAL_COPY_VALUE(argument_array, &new_tmp);
|
||||
} else {
|
||||
ZVAL_COPY_VALUE(argument_array, param_ptr);
|
||||
}
|
||||
argument_array++;
|
||||
param_ptr++;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Zend-optimized Extended functions */
|
||||
/* this function doesn't check for too many parameters */
|
||||
ZEND_API int zend_get_parameters_ex(int param_count, ...) /* {{{ */
|
||||
|
||||
+1
-2
@@ -233,7 +233,6 @@ int zend_next_free_module(void);
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API int zend_get_parameters(int ht, int param_count, ...);
|
||||
ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval *argument_array TSRMLS_DC);
|
||||
ZEND_API ZEND_ATTRIBUTE_DEPRECATED int zend_get_parameters_ex(int param_count, ...);
|
||||
ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array TSRMLS_DC);
|
||||
|
||||
@@ -241,7 +240,7 @@ ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array
|
||||
ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TSRMLS_DC);
|
||||
|
||||
#define zend_get_parameters_array(ht, param_count, argument_array) \
|
||||
_zend_get_parameters_array(ht, param_count, argument_array TSRMLS_CC)
|
||||
_zend_get_parameters_array_ex(param_count, argument_array TSRMLS_CC)
|
||||
#define zend_get_parameters_array_ex(param_count, argument_array) \
|
||||
_zend_get_parameters_array_ex(param_count, argument_array TSRMLS_CC)
|
||||
#define zend_parse_parameters_none() \
|
||||
|
||||
+8
-16
@@ -1969,11 +1969,9 @@ Q: String or long first?
|
||||
}
|
||||
mysql_field_seek(mysql_result, 0);
|
||||
while ((tmp_field = mysql_fetch_field(mysql_result))) {
|
||||
#ifdef MYSQL_USE_MYSQLND
|
||||
if ((!table_name || !strncasecmp(tmp_field->table->val, table_name, tmp_field->table->len)) && !strncasecmp(tmp_field->name->val, field_name, tmp_field->name->len)) {
|
||||
#else
|
||||
if ((!table_name || !strcasecmp(tmp_field->table, table_name)) && !strcasecmp(tmp_field->name, field_name)) {
|
||||
#endif
|
||||
if ((!table_name ||
|
||||
!strncasecmp(tmp_field->table, table_name, tmp_field->table_length)) &&
|
||||
!strncasecmp(tmp_field->name, field_name, tmp_field->name_length)) {
|
||||
field_offset = i;
|
||||
break;
|
||||
}
|
||||
@@ -2424,14 +2422,12 @@ PHP_FUNCTION(mysql_fetch_field)
|
||||
object_init(return_value);
|
||||
|
||||
#if MYSQL_USE_MYSQLND
|
||||
add_property_str(return_value, "name", STR_COPY(mysql_field->name));
|
||||
add_property_str(return_value, "table", STR_COPY(mysql_field->table));
|
||||
add_property_str(return_value, "def", mysql_field->def? STR_COPY(mysql_field->def) : STR_EMPTY_ALLOC());
|
||||
add_property_str(return_value, "name", STR_COPY(mysql_field->sname));
|
||||
#else
|
||||
add_property_string(return_value, "name", (mysql_field->name?mysql_field->name:""));
|
||||
add_property_string(return_value, "table", (mysql_field->table?mysql_field->table:""));
|
||||
add_property_string(return_value, "def", (mysql_field->def?mysql_field->def:""));
|
||||
add_property_stringl(return_value, "name", (mysql_field->name?mysql_field->name:""), mysql_field->name_length);
|
||||
#endif
|
||||
add_property_stringl(return_value, "table", (mysql_field->table?mysql_field->table:""), mysql_field->table_length);
|
||||
add_property_stringl(return_value, "def", (mysql_field->def?mysql_field->def:""), mysql_field->def_length);
|
||||
add_property_long(return_value, "max_length", mysql_field->max_length);
|
||||
add_property_long(return_value, "not_null", IS_NOT_NULL(mysql_field->flags)?1:0);
|
||||
add_property_long(return_value, "primary_key", IS_PRI_KEY(mysql_field->flags)?1:0);
|
||||
@@ -2502,17 +2498,13 @@ static void php_mysql_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
|
||||
switch (entry_type) {
|
||||
case PHP_MYSQL_FIELD_NAME:
|
||||
#ifdef MYSQL_USE_MYSQLND
|
||||
RETVAL_STR(STR_COPY(mysql_field->name));
|
||||
RETVAL_STR(STR_COPY(mysql_field->sname));
|
||||
#else
|
||||
RETVAL_STRING(mysql_field->name);
|
||||
#endif
|
||||
break;
|
||||
case PHP_MYSQL_FIELD_TABLE:
|
||||
#ifdef MYSQL_USE_MYSQLND
|
||||
RETVAL_STR(STR_COPY(mysql_field->table));
|
||||
#else
|
||||
RETVAL_STRING(mysql_field->table);
|
||||
#endif
|
||||
break;
|
||||
case PHP_MYSQL_FIELD_LEN:
|
||||
RETVAL_LONG(mysql_field->length);
|
||||
|
||||
+8
-12
@@ -1149,21 +1149,17 @@ PHP_FUNCTION(mysqli_stmt_fetch)
|
||||
static void php_add_field_properties(zval *value, const MYSQL_FIELD *field TSRMLS_DC)
|
||||
{
|
||||
#ifdef MYSQLI_USE_MYSQLND
|
||||
add_property_str(value, "name", STR_COPY(field->name));
|
||||
add_property_str(value, "orgname", STR_COPY(field->org_name));
|
||||
add_property_str(value, "table", STR_COPY(field->table));
|
||||
add_property_str(value, "orgtable", STR_COPY(field->org_table));
|
||||
add_property_str(value, "def", field->def? STR_COPY(field->def) : STR_EMPTY_ALLOC());
|
||||
add_property_str(value, "db", STR_COPY(field->db));
|
||||
add_property_str(value, "name", STR_COPY(field->sname));
|
||||
#else
|
||||
add_property_string(value, "name",(field->name ? field->name : ""));
|
||||
add_property_string(value, "orgname",(field->org_name ? field->org_name : ""));
|
||||
add_property_string(value, "table",(field->table ? field->table : ""));
|
||||
add_property_string(value, "orgtable",(field->org_table ? field->org_table : ""));
|
||||
add_property_string(value, "def",(field->def ? field->def : ""));
|
||||
add_property_string(value, "db",(field->db ? field->db : ""));
|
||||
add_property_string(value, "name",(field->name ? field->name : ""), field->name_length);
|
||||
#endif
|
||||
|
||||
add_property_stringl(value, "orgname", (field->org_name ? field->org_name : ""), field->org_name_length);
|
||||
add_property_stringl(value, "table", (field->table ? field->table : ""), field->table_length);
|
||||
add_property_stringl(value, "orgtable", (field->org_table ? field->org_table : ""), field->org_table_length);
|
||||
add_property_stringl(value, "def", (field->def ? field->def : ""), field->def_length);
|
||||
add_property_stringl(value, "db", (field->db ? field->db : ""), field->db_length);
|
||||
|
||||
/* FIXME: manually set the catalog to "def" due to bug in
|
||||
* libmysqlclient which does not initialize field->catalog
|
||||
* and in addition, the catalog is always be "def"
|
||||
|
||||
@@ -776,7 +776,6 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned int
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
//??? if (Z_TYPE(current_row[i]) >= IS_STRING) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
@@ -2025,28 +2024,10 @@ mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const s TSRMLS_DC)
|
||||
if (stmt->result_bind[i].bound == TRUE) {
|
||||
DBG_INF_FMT("%u has refcount=%u", i,
|
||||
Z_REFCOUNTED(stmt->result_bind[i].zv)? Z_REFCOUNT(stmt->result_bind[i].zv) : 0);
|
||||
/*
|
||||
We have to separate the actual zval value of the bound
|
||||
variable from our allocated zvals or we will face double-free
|
||||
*/
|
||||
if (Z_REFCOUNTED(stmt->result_bind[i].zv) && Z_REFCOUNT(stmt->result_bind[i].zv) > 1) {
|
||||
#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
|
||||
Z_TRY_ADDREF_P(&stmt->result_bind[i].zv);
|
||||
#endif
|
||||
zval_ptr_dtor(&stmt->result_bind[i].zv);
|
||||
} else {
|
||||
/*
|
||||
If it is a string, what is pointed will be freed
|
||||
later in free_result(). We need to remove the variable to
|
||||
which the user has lost reference.
|
||||
*/
|
||||
#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
|
||||
//??? ZVAL_NULL(&stmt->result_bind[i].zv);
|
||||
#endif
|
||||
zval_ptr_dtor(&stmt->result_bind[i].zv);
|
||||
}
|
||||
zval_ptr_dtor(&stmt->result_bind[i].zv);
|
||||
}
|
||||
}
|
||||
|
||||
s->m->free_result_bind(s, stmt->result_bind TSRMLS_CC);
|
||||
stmt->result_bind = NULL;
|
||||
|
||||
@@ -2080,26 +2061,7 @@ mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const s, unsigned int param
|
||||
DBG_INF_FMT("%u has refcount=%u", param_no,
|
||||
Z_REFCOUNTED(stmt->result_bind[param_no].zv)?
|
||||
Z_REFCOUNT(stmt->result_bind[param_no].zv) : 0);
|
||||
/*
|
||||
We have to separate the actual zval value of the bound
|
||||
variable from our allocated zvals or we will face double-free
|
||||
*/
|
||||
if (Z_REFCOUNTED(stmt->result_bind[param_no].zv) && Z_REFCOUNT(stmt->result_bind[param_no].zv) > 1) {
|
||||
#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
|
||||
Z_TRY_ADDREF_P(&stmt->result_bind[param_no].zv);
|
||||
#endif
|
||||
zval_ptr_dtor(&stmt->result_bind[param_no].zv);
|
||||
} else {
|
||||
/*
|
||||
If it is a string, what is pointed will be freed
|
||||
later in free_result(). We need to remove the variable to
|
||||
which the user has lost reference.
|
||||
*/
|
||||
#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
|
||||
//???ZVAL_NULL(&stmt->result_bind[param_no].zv);
|
||||
#endif
|
||||
zval_ptr_dtor(&stmt->result_bind[param_no].zv);
|
||||
}
|
||||
zval_ptr_dtor(&stmt->result_bind[param_no].zv);
|
||||
}
|
||||
|
||||
DBG_VOID_RETURN;
|
||||
|
||||
@@ -506,8 +506,6 @@ mysqlnd_stmt_copy_it(zval ** copies, zval * original, unsigned int param_count,
|
||||
}
|
||||
if (*copies) {
|
||||
ZVAL_COPY(&(*copies)[current], original);
|
||||
//????Z_SET_REFCOUNT_P((*copies)[current], 1);
|
||||
//zval_copy_ctor((*copies)[current]);
|
||||
return PASS;
|
||||
}
|
||||
return FAIL;
|
||||
|
||||
@@ -70,7 +70,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest)(MYSQLND
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
//???? if (Z_TYPE_P(data_cursor[i]) >= IS_STRING) {
|
||||
if (Z_TYPE(data_cursor[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(data_cursor[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
@@ -126,7 +125,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RE
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
//??? if (Z_TYPE(current_row[i]) >= IS_STRING) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
@@ -143,55 +141,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RE
|
||||
/* }}} */
|
||||
|
||||
|
||||
#if 0
|
||||
/* {{{ mysqlnd_rset_zval_ptr_dtor */
|
||||
static void
|
||||
mysqlnd_rset_zval_ptr_dtor(zval *zv, enum_mysqlnd_res_type type, zend_bool * copy_ctor_called TSRMLS_DC)
|
||||
{
|
||||
DBG_ENTER("mysqlnd_rset_zval_ptr_dtor");
|
||||
DBG_INF_FMT("type=%u", type);
|
||||
if (!zv) {
|
||||
*copy_ctor_called = FALSE;
|
||||
DBG_ERR_FMT("zv was NULL");
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
/*
|
||||
This zval is not from the cache block.
|
||||
Thus the refcount is -1 than of a zval from the cache,
|
||||
because the zvals from the cache are owned by it.
|
||||
*/
|
||||
if (type == MYSQLND_RES_PS_BUF || type == MYSQLND_RES_PS_UNBUF) {
|
||||
*copy_ctor_called = FALSE;
|
||||
; /* do nothing, zval_ptr_dtor will do the job*/
|
||||
} else if (Z_REFCOUNTED_P(zv) && Z_REFCOUNT_P(zv) > 1) {
|
||||
/*
|
||||
Not a prepared statement, then we have to
|
||||
call copy_ctor and then zval_ptr_dtor()
|
||||
*/
|
||||
if (Z_TYPE_P(zv) == IS_STRING) {
|
||||
zval_copy_ctor(zv);
|
||||
}
|
||||
*copy_ctor_called = TRUE;
|
||||
} else {
|
||||
/*
|
||||
noone but us point to this, so we can safely ZVAL_NULL the zval,
|
||||
so Zend does not try to free what the zval points to - which is
|
||||
in result set buffers
|
||||
*/
|
||||
*copy_ctor_called = FALSE;
|
||||
if (Z_TYPE_P(zv) == IS_STRING) {
|
||||
ZVAL_NULL(zv);
|
||||
}
|
||||
}
|
||||
|
||||
DBG_INF_FMT("call the dtor on zval with refc %u", Z_REFCOUNTED_P(zv)? Z_REFCOUNT_P(zv) : 0);
|
||||
zval_ptr_dtor(zv);
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_unbuffered::free_last_data */
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_result_unbuffered, free_last_data)(MYSQLND_RES_UNBUFFERED * unbuf, MYSQLND_STATS * const global_stats TSRMLS_DC)
|
||||
@@ -206,7 +155,6 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, free_last_data)(MYSQLND_RES_UNBUFFERED
|
||||
if (unbuf->last_row_data) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < unbuf->field_count; i++) {
|
||||
//???mysqlnd_rset_zval_ptr_dtor(&(unbuf->last_row_data[i]), unbuf->ps ? MYSQLND_RES_PS_UNBUF : MYSQLND_RES_NORMAL, ©_ctor_called TSRMLS_CC);
|
||||
zval_ptr_dtor(&(unbuf->last_row_data[i]));
|
||||
}
|
||||
|
||||
@@ -921,7 +869,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void
|
||||
*/
|
||||
Z_TRY_ADDREF_P(data);
|
||||
if (meta->zend_hash_keys[i].is_numeric == FALSE) {
|
||||
zend_hash_update(Z_ARRVAL_P(row), meta->fields[i].name, data);
|
||||
zend_hash_update(Z_ARRVAL_P(row), meta->fields[i].sname, data);
|
||||
} else {
|
||||
zend_hash_index_update(Z_ARRVAL_P(row), meta->zend_hash_keys[i].key, data);
|
||||
}
|
||||
@@ -1053,7 +1001,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
//???? if (Z_TYPE(current_row[i]) >= IS_STRING) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
@@ -1145,7 +1092,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, vo
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
//???? if (Z_TYPE_P(current_row[i]) >= IS_STRING) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
@@ -1174,7 +1120,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, vo
|
||||
*/
|
||||
Z_TRY_ADDREF_P(data);
|
||||
if (meta->zend_hash_keys[i].is_numeric == FALSE) {
|
||||
zend_hash_update(Z_ARRVAL_P(row), meta->fields[i].name, data);
|
||||
zend_hash_update(Z_ARRVAL_P(row), meta->fields[i].sname, data);
|
||||
} else {
|
||||
zend_hash_index_update(Z_ARRVAL_P(row), meta->zend_hash_keys[i].key, data);
|
||||
}
|
||||
@@ -1241,7 +1187,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
//???? if (Z_TYPE(current_row[i]) >= IS_STRING) {
|
||||
if (Z_TYPE(current_row[i]) == IS_STRING) {
|
||||
unsigned long len = Z_STRLEN(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
@@ -1270,7 +1215,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void
|
||||
*/
|
||||
Z_TRY_ADDREF_P(data);
|
||||
if (meta->zend_hash_keys[i].is_numeric == FALSE) {
|
||||
zend_hash_update(Z_ARRVAL_P(row), meta->fields[i].name, data);
|
||||
zend_hash_update(Z_ARRVAL_P(row), meta->fields[i].sname, data);
|
||||
} else {
|
||||
zend_hash_index_update(Z_ARRVAL_P(row), meta->zend_hash_keys[i].key, data);
|
||||
}
|
||||
@@ -1886,7 +1831,6 @@ MYSQLND_METHOD(mysqlnd_res, fetch_field_data)(MYSQLND_RES * result, unsigned int
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL(row));
|
||||
while (i++ < offset) {
|
||||
zend_hash_move_forward(Z_ARRVAL(row));
|
||||
//???entry = zend_hash_get_current_data(Z_ARRVAL(row));
|
||||
}
|
||||
|
||||
entry = zend_hash_get_current_data(Z_ARRVAL(row));
|
||||
|
||||
@@ -33,26 +33,16 @@ static void
|
||||
php_mysqlnd_free_field_metadata(MYSQLND_FIELD *meta, zend_bool persistent TSRMLS_DC)
|
||||
{
|
||||
if (meta) {
|
||||
if (meta->root) {
|
||||
mnd_pefree(meta->root, persistent);
|
||||
meta->root = NULL;
|
||||
}
|
||||
if (meta->def) {
|
||||
STR_RELEASE(meta->def);
|
||||
mnd_pefree(meta->def, persistent);
|
||||
meta->def = NULL;
|
||||
}
|
||||
if (meta->name) {
|
||||
STR_RELEASE(meta->name);
|
||||
}
|
||||
if (meta->org_name) {
|
||||
STR_RELEASE(meta->org_name);
|
||||
}
|
||||
if (meta->table) {
|
||||
STR_RELEASE(meta->table);
|
||||
}
|
||||
if (meta->org_table) {
|
||||
STR_RELEASE(meta->org_table);
|
||||
}
|
||||
if (meta->db) {
|
||||
STR_RELEASE(meta->db);
|
||||
}
|
||||
if (meta->catalog) {
|
||||
STR_RELEASE(meta->catalog);
|
||||
if (meta->sname) {
|
||||
STR_RELEASE(meta->sname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,6 +113,12 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
|
||||
for (;i < meta->field_count; i++) {
|
||||
long idx;
|
||||
|
||||
if (meta->fields[i].root) {
|
||||
/* We re-read metadata for PS */
|
||||
mnd_pefree(meta->fields[i].root, meta->persistent);
|
||||
meta->fields[i].root = NULL;
|
||||
}
|
||||
|
||||
field_packet->metadata = &(meta->fields[i]);
|
||||
if (FAIL == PACKET_READ(field_packet, conn)) {
|
||||
PACKET_FREE(field_packet);
|
||||
@@ -187,8 +183,8 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
|
||||
|
||||
/* For BC we have to check whether the key is numeric and use it like this */
|
||||
if ((meta->zend_hash_keys[i].is_numeric =
|
||||
mysqlnd_is_key_numeric(field_packet->metadata->name->val,
|
||||
field_packet->metadata->name->len + 1,
|
||||
mysqlnd_is_key_numeric(field_packet->metadata->name,
|
||||
field_packet->metadata->name_length + 1,
|
||||
&idx))) {
|
||||
meta->zend_hash_keys[i].key = idx;
|
||||
}
|
||||
@@ -270,14 +266,47 @@ MYSQLND_METHOD(mysqlnd_res_meta, clone_metadata)(const MYSQLND_RES_METADATA * co
|
||||
*/
|
||||
memcpy(new_fields, orig_fields, (meta->field_count) * sizeof(MYSQLND_FIELD));
|
||||
for (i = 0; i < meta->field_count; i++) {
|
||||
new_fields[i].name = STR_DUP(orig_fields[i].name, persistent);
|
||||
new_fields[i].org_name = STR_DUP(orig_fields[i].org_name, persistent);
|
||||
new_fields[i].table = STR_DUP(orig_fields[i].table, persistent);
|
||||
new_fields[i].org_table = STR_DUP(orig_fields[i].org_table, persistent);
|
||||
new_fields[i].db = STR_DUP(orig_fields[i].db, persistent);
|
||||
new_fields[i].catalog = STR_DUP(orig_fields[i].catalog, persistent);
|
||||
/* First copy the root, then field by field adjust the pointers */
|
||||
new_fields[i].root = mnd_pemalloc(orig_fields[i].root_len, persistent);
|
||||
|
||||
if (!new_fields[i].root) {
|
||||
goto oom;
|
||||
}
|
||||
|
||||
memcpy(new_fields[i].root, orig_fields[i].root, new_fields[i].root_len);
|
||||
|
||||
if (orig_fields[i].sname) {
|
||||
new_fields[i].sname = STR_COPY(orig_fields[i].sname);
|
||||
new_fields[i].name = new_fields[i].sname->val;
|
||||
new_fields[i].name_length = new_fields[i].sname->len;
|
||||
}
|
||||
|
||||
if (orig_fields[i].org_name && orig_fields[i].org_name != mysqlnd_empty_string) {
|
||||
new_fields[i].org_name = new_fields[i].root +
|
||||
(orig_fields[i].org_name - orig_fields[i].root);
|
||||
}
|
||||
if (orig_fields[i].table && orig_fields[i].table != mysqlnd_empty_string) {
|
||||
new_fields[i].table = new_fields[i].root +
|
||||
(orig_fields[i].table - orig_fields[i].root);
|
||||
}
|
||||
if (orig_fields[i].org_table && orig_fields[i].org_table != mysqlnd_empty_string) {
|
||||
new_fields[i].org_table = new_fields[i].root +
|
||||
(orig_fields[i].org_table - orig_fields[i].root);
|
||||
}
|
||||
if (orig_fields[i].db && orig_fields[i].db != mysqlnd_empty_string) {
|
||||
new_fields[i].db = new_fields[i].root + (orig_fields[i].db - orig_fields[i].root);
|
||||
}
|
||||
if (orig_fields[i].catalog && orig_fields[i].catalog != mysqlnd_empty_string) {
|
||||
new_fields[i].catalog = new_fields[i].root + (orig_fields[i].catalog - orig_fields[i].root);
|
||||
}
|
||||
/* def is not on the root, if allocated at all */
|
||||
if (orig_fields[i].def) {
|
||||
new_fields[i].def = STR_DUP(orig_fields[i].def, persistent);
|
||||
new_fields[i].def = mnd_pemalloc(orig_fields[i].def_length + 1, persistent);
|
||||
if (!new_fields[i].def) {
|
||||
goto oom;
|
||||
}
|
||||
/* copy the trailing \0 too */
|
||||
memcpy(new_fields[i].def, orig_fields[i].def, orig_fields[i].def_length + 1);
|
||||
}
|
||||
}
|
||||
new_meta->current_field = 0;
|
||||
@@ -306,7 +335,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, fetch_field)(MYSQLND_RES_METADATA * const meta
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
DBG_INF_FMT("name=%s max_length=%u",
|
||||
meta->fields[meta->current_field].name? meta->fields[meta->current_field].name->val:"",
|
||||
meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"",
|
||||
meta->fields[meta->current_field].max_length);
|
||||
DBG_RETURN(&meta->fields[meta->current_field++]);
|
||||
}
|
||||
@@ -320,7 +349,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, fetch_field_direct)(const MYSQLND_RES_METADATA
|
||||
DBG_ENTER("mysqlnd_res_meta::fetch_field_direct");
|
||||
DBG_INF_FMT("fieldnr=%u", fieldnr);
|
||||
DBG_INF_FMT("name=%s max_length=%u",
|
||||
meta->fields[meta->current_field].name? meta->fields[meta->current_field].name->val:"",
|
||||
meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"",
|
||||
meta->fields[meta->current_field].max_length);
|
||||
DBG_RETURN(&meta->fields[fieldnr]);
|
||||
}
|
||||
|
||||
@@ -72,19 +72,29 @@ typedef struct st_mysqlnd_cmd_buffer
|
||||
|
||||
typedef struct st_mysqlnd_field
|
||||
{
|
||||
zend_string *name; /* Name of column */
|
||||
zend_string *org_name; /* Original column name, if an alias */
|
||||
zend_string *table; /* Table of column if column was a field */
|
||||
zend_string *org_table; /* Org table name, if table was an alias */
|
||||
zend_string *db; /* Database for table */
|
||||
zend_string *catalog; /* Catalog for table */
|
||||
zend_string *def; /* Default value (set by mysql_list_fields) */
|
||||
zend_string *sname; /* Name of column */
|
||||
const char *name; /* Name of column in C string */
|
||||
const char *org_name; /* Original column name, if an alias */
|
||||
const char *table; /* Table of column if column was a field */
|
||||
const char *org_table; /* Org table name, if table was an alias */
|
||||
const char *db; /* Database for table */
|
||||
const char *catalog; /* Catalog for table */
|
||||
char *def; /* Default value (set by mysql_list_fields) */
|
||||
unsigned long length; /* Width of column (create length) */
|
||||
unsigned long max_length; /* Max width for selected set */
|
||||
unsigned int name_length;
|
||||
unsigned int org_name_length;
|
||||
unsigned int table_length;
|
||||
unsigned int org_table_length;
|
||||
unsigned int db_length;
|
||||
unsigned int catalog_length;
|
||||
unsigned int def_length;
|
||||
unsigned int flags; /* Diverse flags */
|
||||
unsigned int decimals; /* Number of decimals in field */
|
||||
unsigned int charsetnr; /* Character set */
|
||||
enum mysqlnd_field_types type; /* Type of field. See mysql_com.h for types */
|
||||
char *root;
|
||||
size_t root_len;
|
||||
} MYSQLND_FIELD;
|
||||
|
||||
|
||||
|
||||
@@ -69,12 +69,12 @@
|
||||
|
||||
|
||||
static const char *unknown_sqlstate= "HY000";
|
||||
const char * const mysqlnd_empty_string = "";
|
||||
|
||||
/* Used in mysqlnd_debug.c */
|
||||
const char mysqlnd_read_header_name[] = "mysqlnd_read_header";
|
||||
const char mysqlnd_read_body_name[] = "mysqlnd_read_body";
|
||||
|
||||
|
||||
#define ERROR_MARKER 0xFF
|
||||
#define EODATA_MARKER 0xFE
|
||||
|
||||
@@ -1205,11 +1205,17 @@ void php_mysqlnd_rset_header_free_mem(void * _packet, zend_bool stack_allocation
|
||||
static size_t rset_field_offsets[] =
|
||||
{
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, catalog),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, catalog_length),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, db),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, db_length),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, table),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, table_length),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, org_table),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, org_table_length),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, name),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, name_length),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, org_name),
|
||||
STRUCT_OFFSET(MYSQLND_FIELD, org_name_length),
|
||||
};
|
||||
|
||||
|
||||
@@ -1223,6 +1229,7 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
|
||||
zend_uchar *buf = (zend_uchar *) conn->net->cmd_buffer.buffer;
|
||||
zend_uchar *p = buf;
|
||||
zend_uchar *begin = buf;
|
||||
char *root_ptr;
|
||||
unsigned long len;
|
||||
MYSQLND_FIELD *meta;
|
||||
unsigned int i, field_count = sizeof(rset_field_offsets)/sizeof(size_t);
|
||||
@@ -1255,17 +1262,19 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
|
||||
|
||||
meta = packet->metadata;
|
||||
|
||||
for (i = 0; i < field_count; i++) {
|
||||
for (i = 0; i < field_count; i += 2) {
|
||||
len = php_mysqlnd_net_field_length(&p);
|
||||
BAIL_IF_NO_MORE_DATA;
|
||||
switch ((len)) {
|
||||
case 0:
|
||||
*(zend_string **)(((char*)meta) + rset_field_offsets[i]) = STR_EMPTY_ALLOC();
|
||||
*(const char **)(((char*)meta) + rset_field_offsets[i]) = mysqlnd_empty_string;
|
||||
*(unsigned int *)(((char*)meta) + rset_field_offsets[i+1]) = 0;
|
||||
break;
|
||||
case MYSQLND_NULL_LENGTH:
|
||||
goto faulty_or_fake;
|
||||
default:
|
||||
*(zend_string **)(((char *)meta) + rset_field_offsets[i]) = STR_INIT((char *)p, len, packet->persistent_alloc);
|
||||
*(const char **)(((char *)meta) + rset_field_offsets[i]) = (const char *)p;
|
||||
*(unsigned int *)(((char*)meta) + rset_field_offsets[i+1]) = len;
|
||||
p += len;
|
||||
total_len += len + 1;
|
||||
break;
|
||||
@@ -1278,6 +1287,7 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
|
||||
DBG_ERR_FMT("Protocol error. Server sent false length. Expected 12 got %d", (int) *p);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Protocol error. Server sent false length. Expected 12");
|
||||
}
|
||||
|
||||
p++;
|
||||
BAIL_IF_NO_MORE_DATA;
|
||||
|
||||
@@ -1326,14 +1336,73 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
|
||||
{
|
||||
BAIL_IF_NO_MORE_DATA;
|
||||
DBG_INF_FMT("Def found, length %lu, persistent=%u", len, packet->persistent_alloc);
|
||||
meta->def = STR_INIT((char *)p, len, packet->persistent_alloc);
|
||||
p += len;
|
||||
meta->def = mnd_pemalloc(len + 1, packet->persistent_alloc);
|
||||
if (!meta->def) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
memcpy(meta->def, p, len);
|
||||
meta->def[len] = '\0';
|
||||
meta->def_length = len;
|
||||
p += len;
|
||||
}
|
||||
|
||||
root_ptr = meta->root = mnd_pemalloc(total_len, packet->persistent_alloc);
|
||||
if (!root_ptr) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
|
||||
meta->root_len = total_len;
|
||||
|
||||
if (meta->name != mysqlnd_empty_string) {
|
||||
meta->sname = STR_INIT(meta->name, meta->name_length, packet->persistent_alloc);
|
||||
} else {
|
||||
meta->sname = STR_EMPTY_ALLOC();
|
||||
}
|
||||
meta->name = meta->sname->val;
|
||||
meta->name_length = meta->sname->len;
|
||||
|
||||
/* Now do allocs */
|
||||
if (meta->catalog && meta->catalog != mysqlnd_empty_string) {
|
||||
len = meta->catalog_length;
|
||||
meta->catalog = memcpy(root_ptr, meta->catalog, len);
|
||||
*(root_ptr +=len) = '\0';
|
||||
root_ptr++;
|
||||
}
|
||||
|
||||
if (meta->db && meta->db != mysqlnd_empty_string) {
|
||||
len = meta->db_length;
|
||||
meta->db = memcpy(root_ptr, meta->db, len);
|
||||
*(root_ptr +=len) = '\0';
|
||||
root_ptr++;
|
||||
}
|
||||
|
||||
if (meta->table && meta->table != mysqlnd_empty_string) {
|
||||
len = meta->table_length;
|
||||
meta->table = memcpy(root_ptr, meta->table, len);
|
||||
*(root_ptr +=len) = '\0';
|
||||
root_ptr++;
|
||||
}
|
||||
|
||||
if (meta->org_table && meta->org_table != mysqlnd_empty_string) {
|
||||
len = meta->org_table_length;
|
||||
meta->org_table = memcpy(root_ptr, meta->org_table, len);
|
||||
*(root_ptr +=len) = '\0';
|
||||
root_ptr++;
|
||||
}
|
||||
|
||||
if (meta->org_name && meta->org_name != mysqlnd_empty_string) {
|
||||
len = meta->org_name_length;
|
||||
meta->org_name = memcpy(root_ptr, meta->org_name, len);
|
||||
*(root_ptr +=len) = '\0';
|
||||
root_ptr++;
|
||||
}
|
||||
|
||||
DBG_INF_FMT("allocing root. persistent=%u", packet->persistent_alloc);
|
||||
|
||||
DBG_INF_FMT("FIELD=[%s.%s.%s]", meta->db? meta->db->val:"*NA*", meta->table? meta->table->val:"*NA*",
|
||||
meta->name? meta->name->val:"*NA*");
|
||||
DBG_INF_FMT("FIELD=[%s.%s.%s]", meta->db? meta->db:"*NA*", meta->table? meta->table:"*NA*",
|
||||
meta->name? meta->name:"*NA*");
|
||||
|
||||
DBG_RETURN(PASS);
|
||||
|
||||
@@ -1397,11 +1466,7 @@ php_mysqlnd_read_row_ex(MYSQLND_CONN_DATA * conn, MYSQLND_MEMORY_POOL * result_s
|
||||
|
||||
if (first_iteration) {
|
||||
first_iteration = FALSE;
|
||||
/*
|
||||
We need a trailing \0 for the last string, in case of text-mode,
|
||||
to be able to implement read-only variables. Thus, we add + 1.
|
||||
*/
|
||||
*buffer = result_set_memory_pool->get_chunk(result_set_memory_pool, *data_size + 1 TSRMLS_CC);
|
||||
*buffer = result_set_memory_pool->get_chunk(result_set_memory_pool, *data_size TSRMLS_CC);
|
||||
if (!*buffer) {
|
||||
ret = FAIL;
|
||||
break;
|
||||
@@ -1415,11 +1480,8 @@ php_mysqlnd_read_row_ex(MYSQLND_CONN_DATA * conn, MYSQLND_MEMORY_POOL * result_s
|
||||
|
||||
/*
|
||||
We have to realloc the buffer.
|
||||
|
||||
We need a trailing \0 for the last string, in case of text-mode,
|
||||
to be able to implement read-only variables.
|
||||
*/
|
||||
if (FAIL == (*buffer)->resize_chunk((*buffer), *data_size + 1 TSRMLS_CC)) {
|
||||
if (FAIL == (*buffer)->resize_chunk((*buffer), *data_size TSRMLS_CC)) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
ret = FAIL;
|
||||
break;
|
||||
@@ -1637,7 +1699,6 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
#error Need fix for this architecture
|
||||
#endif /* SIZEOF */
|
||||
{
|
||||
//???? ZVAL_STRINGL(current_field, (char *)p, len, 0);
|
||||
ZVAL_STRINGL(current_field, (char *)p, len);
|
||||
} else {
|
||||
ZVAL_LONG(current_field, (long) v); /* the cast is safe */
|
||||
@@ -1671,7 +1732,6 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
|
||||
p -= len;
|
||||
if (Z_TYPE_P(current_field) == IS_LONG) {
|
||||
bit_area += 1 + sprintf((char *)start, "%ld", Z_LVAL_P(current_field));
|
||||
//???? ZVAL_STRINGL(current_field, (char *) start, bit_area - start - 1, copy_data);
|
||||
ZVAL_STRINGL(current_field, (char *) start, bit_area - start - 1);
|
||||
} else if (Z_TYPE_P(current_field) == IS_STRING){
|
||||
memcpy(bit_area, Z_STRVAL_P(current_field), Z_STRLEN_P(current_field));
|
||||
|
||||
@@ -304,6 +304,7 @@ unsigned long php_mysqlnd_net_field_length(zend_uchar **packet);
|
||||
zend_uchar * php_mysqlnd_net_store_length(zend_uchar *packet, uint64_t length);
|
||||
size_t php_mysqlnd_net_store_length_size(uint64_t length);
|
||||
|
||||
PHPAPI const extern char * const mysqlnd_empty_string;
|
||||
|
||||
enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
|
||||
@@ -302,6 +302,7 @@ static PHP_METHOD(PDO, dbh_constructor)
|
||||
/* is the connection still alive ? */
|
||||
if (pdbh->methods->check_liveness && FAILURE == (pdbh->methods->check_liveness)(pdbh TSRMLS_CC)) {
|
||||
/* nope... need to kill it */
|
||||
/*??? memory leak */
|
||||
zend_list_close(le);
|
||||
pdbh = NULL;
|
||||
}
|
||||
@@ -372,6 +373,7 @@ static PHP_METHOD(PDO, dbh_constructor)
|
||||
|
||||
le.type = php_pdo_list_entry();
|
||||
le.ptr = dbh;
|
||||
GC_REFCOUNT(&le) = 1;
|
||||
|
||||
if ((zend_hash_str_update_mem(&EG(persistent_list),
|
||||
(char*)dbh->persistent_id, dbh->persistent_id_len, &le, sizeof(le))) == NULL) {
|
||||
|
||||
@@ -699,21 +699,11 @@ static int pdo_mysql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{
|
||||
int namelen;
|
||||
|
||||
if (S->H->fetch_table_names) {
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
namelen = spprintf(&cols[i].name, 0, "%s.%s", S->fields[i].table->val, S->fields[i].name->val);
|
||||
#else
|
||||
namelen = spprintf(&cols[i].name, 0, "%s.%s", S->fields[i].table, S->fields[i].name);
|
||||
#endif
|
||||
cols[i].namelen = namelen;
|
||||
} else {
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
cols[i].namelen = S->fields[i].name->len;
|
||||
cols[i].name = estrndup(S->fields[i].name->val, S->fields[i].name->len);
|
||||
#else
|
||||
namelen = strlen(S->fields[i].name);
|
||||
cols[i].namelen = namelen;
|
||||
cols[i].name = estrndup(S->fields[i].name, namelen);
|
||||
#endif
|
||||
cols[i].namelen = S->fields[i].name_length;
|
||||
cols[i].name = estrndup(S->fields[i].name, S->fields[i].name_length);
|
||||
}
|
||||
|
||||
cols[i].precision = S->fields[i].decimals;
|
||||
@@ -856,11 +846,7 @@ static int pdo_mysql_stmt_col_meta(pdo_stmt_t *stmt, long colno, zval *return_va
|
||||
F = S->fields + colno;
|
||||
|
||||
if (F->def) {
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
add_assoc_str(return_value, "mysql:def", STR_COPY(F->def));
|
||||
#else
|
||||
add_assoc_string(return_value, "mysql:def", F->def);
|
||||
#endif
|
||||
}
|
||||
if (IS_NOT_NULL(F->flags)) {
|
||||
add_next_index_string(&flags, "not_null");
|
||||
@@ -902,11 +888,7 @@ static int pdo_mysql_stmt_col_meta(pdo_stmt_t *stmt, long colno, zval *return_va
|
||||
#endif
|
||||
|
||||
add_assoc_zval(return_value, "flags", &flags);
|
||||
#ifdef PDO_USE_MYSQLND
|
||||
add_assoc_str(return_value, "table", STR_COPY(F->table));
|
||||
#else
|
||||
add_assoc_string(return_value, "table", (char *) (F->table?F->table : ""));
|
||||
#endif
|
||||
|
||||
PDO_DBG_RETURN(SUCCESS);
|
||||
} /* }}} */
|
||||
|
||||
Reference in New Issue
Block a user