mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-08 01:37:30 +00:00
Merge remote-tracking branch 'origin/PHP-5.6' into str_size_and_int64_56_backport
* origin/PHP-5.6: (41 commits) fix crash in MINFO when no mysqlnd plugins are loaded backported some ext/intl tests from 5.6 into 5.4 test fixes for ICU 53.1 Fixed bug #67033 Remove reference to Windows 95 fix NEWS Fixed bug #64604 Fix #66562: Consistency bug where curl_multi_getcontent behaves different from curl_exec Fix bug #66482, replace wrong item name 'priority' with 'process.priority' in php-fpm.conf Fix windows build Fix bug #66721 fix apr_psprintf format string frome0df4e3dbaFixed bug #67024 - getimagesize should recognize BMP files with negative height Bug #66840: Fix broken build when extension built separately Reverted to5a0da281e5Discussion: http://news.php.net/php.cvs/76836 Forgot title in phpt for bug #67064 Updated NEWS Fix bug #67064 in a BC safe way You can use an optional parameter now when implementing the Countable interface to get the $mode passed to count(). Added UPGRAING notice for bug #66015 in BC break section Add new zend_hash_* APIs to UPGRADING.INTERNALS Add str_* macros to UPGRADING.INTERNALS ... Conflicts: Zend/zend_compile.c Zend/zend_execute_API.c Zend/zend_language_parser.y ext/mysqli/mysqli.c ext/mysqlnd/mysqlnd.c ext/mysqlnd/mysqlnd.h ext/mysqlnd/mysqlnd_ps.c ext/mysqlnd/mysqlnd_result.c ext/mysqlnd/mysqlnd_result.h ext/mysqlnd/mysqlnd_structs.h ext/mysqlnd/mysqlnd_wireprotocol.c ext/mysqlnd/mysqlnd_wireprotocol.h ext/opcache/zend_accelerator_util_funcs.c ext/spl/spl_observer.c ext/standard/array.c
This commit is contained in:
commit
f166237626
139 files changed
+5520
-2701
No files matched your search
@@ -2,6 +2,50 @@ PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? 2014, PHP 5.6.0 Beta 2
|
||||
|
||||
- Core:
|
||||
. Fixed bug #64604 (parse_url is inconsistent with specified port).
|
||||
(Ingo Walz)
|
||||
. Fixed bug #66015 (Unexpected array indexing in class's static property). (Bob)
|
||||
. Added (constant) string/array dereferencing to static scalar expressions
|
||||
to complete the set; now possible thanks to bug #66015 being fixed. (Bob)
|
||||
. Fixed bug #66568 (Update reflection information for unserialize() function).
|
||||
(Ferenc)
|
||||
. Fixed bug #66660 (Composer.phar install/update fails). (Ferenc)
|
||||
. Fixed bug #67024 (getimagesize should recognize BMP files with negative
|
||||
height). (Gabor Buella)
|
||||
. Fixed bug #67064 (Countable interface prevents using 2nd parameter
|
||||
($mode) of count() function). (Bob)
|
||||
|
||||
- cURL:
|
||||
. Fixed bug #66562 (curl_exec returns differently than curl_multi_getcontent).
|
||||
(Freek Lijten)
|
||||
|
||||
- Date:
|
||||
. Fixed bug #66721 (__wakeup of DateTime segfaults when invalid object data is
|
||||
supplied). (Boro Sitnikovski)
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #66482 (unknown entry 'priority' in php-fpm.conf).
|
||||
|
||||
- JSON:
|
||||
. Fixed bug #66021 (Blank line inside empty array/object when
|
||||
JSON_PRETTY_PRINT is set). (Kevin Israel)
|
||||
|
||||
- mysqlnd:
|
||||
. Added a new fetching mode to mysqlnd. (Andrey)
|
||||
|
||||
- PDO:
|
||||
. Fixed bug #66604 ('pdo/php_pdo_error.h' not copied to the include dir).
|
||||
(Matteo)
|
||||
|
||||
- SQLite:
|
||||
. Fixed bug #66967 (Updated bundled libsqlite to 3.8.4.3). (Anatol)
|
||||
|
||||
- Apache2 Handler SAPI:
|
||||
. Fixed Apache log issue caused by APR's lack of support for %zu
|
||||
(APR issue https://issues.apache.org/bugzilla/show_bug.cgi?id=56120).
|
||||
(Jeff Trawick)
|
||||
|
||||
10 Apr 2014, PHP 5.6.0 Beta 1
|
||||
|
||||
- Core:
|
||||
|
||||
@@ -20,6 +20,21 @@ PHP 5.6 UPGRADE NOTES
|
||||
1. Backward Incompatible Changes
|
||||
========================================
|
||||
|
||||
- Core:
|
||||
By fixing bug #66015 it is no longer possible to overwrite keys in static scalar
|
||||
arrays. Quick example to illustrate:
|
||||
class Test {
|
||||
const FIRST = 1;
|
||||
public $array = array(
|
||||
self::FIRST => 'first',
|
||||
'second',
|
||||
'third'
|
||||
);
|
||||
}
|
||||
Test::$array will have as expected three array keys (1, 2, 3) and no longer
|
||||
two (0, 1). self::FIRST will no longer overwrite 'third' having key 1 then,
|
||||
but will mark the beginning of indexing.
|
||||
|
||||
- JSON:
|
||||
json_decode() no longer accepts non-lowercase variants of lone JSON true,
|
||||
false or null values. For example, True or FALSE will now cause json_decode to
|
||||
|
||||
+67
-1
@@ -9,6 +9,9 @@ UPGRADE NOTES - PHP X.Y
|
||||
d. Arginfo changes
|
||||
e. tsrm_virtual_cwd.h moved to zend_virtual_cwd.h
|
||||
f. empty strings are interned
|
||||
g. Additional str_* APIs
|
||||
h. Addition of zend_hash_reindex
|
||||
i. Addition of zend_hash_splice
|
||||
|
||||
2. Build system changes
|
||||
a. Unix build system changes
|
||||
@@ -120,8 +123,71 @@ UPGRADE NOTES - PHP X.Y
|
||||
|
||||
String created using STR_EMPTY_ALLOC() are now interned.
|
||||
convert_to_string use STR_EMPTY_ALLOC() for zval when IS_NULL.
|
||||
STR_FREE() shoud be prefered as efree on such strings can raise memory corruption.
|
||||
str_efree() shoud be preferred as efree() on such strings can cause memory
|
||||
corruption.
|
||||
|
||||
g. Additional str_* APIs
|
||||
|
||||
In addition to the previously existing str_free() and str_efree() macros, the
|
||||
following macros have been introduced to simplify dealing with potentially
|
||||
interned strings:
|
||||
|
||||
str_efree_rel(str) - efree_rel() if not interned
|
||||
str_erealloc(str, new_len) - erealloc() or emalloc+memcpy if interned
|
||||
str_estrndup(str, len) - estrndup() if not interned
|
||||
str_strndup(str, len) - zend_strndup() if not interned
|
||||
str_hash(str, len) - INTERNED_HASH(str) if interned,
|
||||
zend_hash_func(str, len+1) otherwise
|
||||
|
||||
h. Addition of zend_hash_reindex
|
||||
|
||||
A zend_hash_reindex() function with the following prototype has been added:
|
||||
|
||||
void zend_hash_reindex(HashTable *ht, zend_bool only_integer_keys);
|
||||
|
||||
If only_integer_keys==0, this function will change all keys to be continuous,
|
||||
zero-based integers in hash order. If only_integer_keys==1 the same will be
|
||||
done only for keys that were already integers previously, while leaving
|
||||
string keys alone.
|
||||
|
||||
i. Addition of zend_hash_splice
|
||||
|
||||
A zend_hash_splice() macro with the following prototype has been added:
|
||||
|
||||
void zend_hash_splice(
|
||||
HashTable *ht, uint nDataSize, copy_ctor_func_t pCopyConstructor,
|
||||
uint offset, uint length,
|
||||
void **list, uint list_count, HashTable *removed
|
||||
);
|
||||
|
||||
This function performs an in-place splice operation on a hashtable:
|
||||
|
||||
The elements between offset and offset+length are removed and the elements in
|
||||
list[list_count] are inserted in their place. The removed elements can be
|
||||
optionally collected into a hashtable.
|
||||
|
||||
This operation reindexes the hashtable, i.e. integer keys will be zero-based
|
||||
and sequential, while string keys stay intact. The same applies to the
|
||||
elements inserted into the removed HT.
|
||||
|
||||
As a side-effect of this addition the signature of the php_splice() function
|
||||
changed:
|
||||
|
||||
void php_splice(
|
||||
HashTable *ht, zend_uint offset, zend_uint length,
|
||||
zval ***list, zend_uint list_count, HashTable *removed TSRMLS_DC
|
||||
)
|
||||
|
||||
This function now directly forwards to zend_hash_splice(), resets the
|
||||
IAP of ht (for compatibility with the previous implementation) and resets
|
||||
CVs if the passed hashtable is the global symbol table.
|
||||
|
||||
j. An additional parameter is sent to Countable::count()
|
||||
|
||||
That parameter denotes the $mode passed to count; it shouldn't affect any
|
||||
userland code, but any zend_parse_parameters() used with no arguments should
|
||||
fail. Extensions which implement Countable internally, need to accept one
|
||||
optional long as parameter.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Bug #66015 (wrong array indexing in class's static property)
|
||||
--FILE--
|
||||
<?php
|
||||
class Test
|
||||
{
|
||||
const FIRST = 1;
|
||||
const SECOND = 2;
|
||||
const THIRD = 3;
|
||||
|
||||
protected static $array = [
|
||||
self::FIRST => 'first',
|
||||
'second',
|
||||
'third'
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
var_export(self::$array);
|
||||
}
|
||||
}
|
||||
|
||||
$test = new Test();
|
||||
?>
|
||||
--EXPECTF--
|
||||
array (
|
||||
1 => 'first',
|
||||
2 => 'second',
|
||||
3 => 'third',
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Bug #66660 (Composer.phar install/update fails)
|
||||
--STDIN--
|
||||
<?php __CLASS__ ?>
|
||||
--FILE--
|
||||
<?php
|
||||
file_put_contents(__DIR__."/bug66660.tmp.php", "<?php __CLASS__ ?>");
|
||||
echo php_strip_whitespace(__DIR__."/bug66660.tmp.php");
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php unlink(__DIR__."/bug66660.tmp.php"); ?>
|
||||
--EXPECT--
|
||||
<?php __CLASS__ ?>
|
||||
@@ -7,7 +7,9 @@ class test {
|
||||
const TEST = array(1,2,3);
|
||||
}
|
||||
|
||||
var_dump(test::TEST);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Arrays are not allowed in class constants in %s on line %d
|
||||
Fatal error: Arrays are not allowed in constants at run-time in %s on line %d
|
||||
@@ -3,6 +3,9 @@
|
||||
--FILE--
|
||||
<?php
|
||||
const C = array();
|
||||
|
||||
var_dump(C);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Arrays are not allowed as constants in %sns_059.php on line 2
|
||||
Fatal error: Arrays are not allowed in constants at run-time in %sns_059.php on line 4
|
||||
|
||||
+2
-5
@@ -589,14 +589,11 @@ typedef int (*zend_write_func_t)(const char *str, zend_size_t str_length);
|
||||
#define IS_STRING 6
|
||||
#define IS_RESOURCE 7
|
||||
#define IS_CONSTANT 8
|
||||
#define IS_CONSTANT_ARRAY 9
|
||||
#define IS_CONSTANT_AST 10
|
||||
#define IS_CALLABLE 11
|
||||
#define IS_CONSTANT_AST 9
|
||||
#define IS_CALLABLE 10
|
||||
|
||||
/* Ugly hack to support constants as static array indices */
|
||||
#define IS_CONSTANT_TYPE_MASK 0x00f
|
||||
#define IS_CONSTANT_UNQUALIFIED 0x010
|
||||
#define IS_CONSTANT_INDEX 0x080
|
||||
#define IS_LEXICAL_VAR 0x020
|
||||
#define IS_LEXICAL_REF 0x040
|
||||
#define IS_CONSTANT_IN_NAMESPACE 0x100
|
||||
|
||||
+3
-4
@@ -1077,7 +1077,7 @@ static int zval_update_class_constant(zval **pp, int is_static, int offset TSRML
|
||||
int ret;
|
||||
zend_class_entry *old_scope = *scope;
|
||||
*scope = prop_info->ce;
|
||||
ret = zval_update_constant(pp, (void*)1 TSRMLS_CC);
|
||||
ret = zval_update_constant(pp, 1 TSRMLS_CC);
|
||||
*scope = old_scope;
|
||||
return ret;
|
||||
}
|
||||
@@ -1086,7 +1086,7 @@ static int zval_update_class_constant(zval **pp, int is_static, int offset TSRML
|
||||
} while (ce);
|
||||
|
||||
}
|
||||
return zval_update_constant(pp, (void*)1 TSRMLS_CC);
|
||||
return zval_update_constant(pp, 1 TSRMLS_CC);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1100,7 +1100,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC
|
||||
int i;
|
||||
|
||||
*scope = class_type;
|
||||
zend_hash_apply_with_argument(&class_type->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
|
||||
zend_hash_apply_with_argument(&class_type->constants_table, (apply_func_arg_t) zval_update_constant, (void *)1 TSRMLS_CC);
|
||||
|
||||
for (i = 0; i < class_type->default_properties_count; i++) {
|
||||
if (class_type->default_properties_table[i]) {
|
||||
@@ -3470,7 +3470,6 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, const char *name, ze
|
||||
if (ce->type & ZEND_INTERNAL_CLASS) {
|
||||
switch(Z_TYPE_P(property)) {
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY:
|
||||
case IS_OBJECT:
|
||||
case IS_RESOURCE:
|
||||
zend_error(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
|
||||
|
||||
+60
-19
@@ -63,6 +63,27 @@ ZEND_API zend_ast* zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *o
|
||||
return ast;
|
||||
}
|
||||
|
||||
ZEND_API zend_ast* zend_ast_create_dynamic(uint kind)
|
||||
{
|
||||
zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 3); /* use 4 children as deafult */
|
||||
ast->kind = kind;
|
||||
ast->children = 0;
|
||||
return ast;
|
||||
}
|
||||
|
||||
ZEND_API void zend_ast_dynamic_add(zend_ast **ast, zend_ast *op)
|
||||
{
|
||||
if ((*ast)->children >= 4 && (*ast)->children == ((*ast)->children & -(*ast)->children)) {
|
||||
*ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children * 2 + 1));
|
||||
}
|
||||
(&(*ast)->u.child)[(*ast)->children++] = op;
|
||||
}
|
||||
|
||||
ZEND_API void zend_ast_dynamic_shrink(zend_ast **ast)
|
||||
{
|
||||
*ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children - 1));
|
||||
}
|
||||
|
||||
ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
|
||||
{
|
||||
int i;
|
||||
@@ -233,7 +254,7 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
|
||||
*result = *ast->u.val;
|
||||
zval_copy_ctor(result);
|
||||
if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
|
||||
zval_update_constant_ex(&result, (void *) 1, scope TSRMLS_CC);
|
||||
zval_update_constant_ex(&result, 1, scope TSRMLS_CC);
|
||||
}
|
||||
break;
|
||||
case ZEND_BOOL_AND:
|
||||
@@ -284,6 +305,35 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
|
||||
sub_function(result, &op1, &op2 TSRMLS_CC);
|
||||
zval_dtor(&op2);
|
||||
break;
|
||||
case ZEND_INIT_ARRAY:
|
||||
INIT_PZVAL(result);
|
||||
array_init(result);
|
||||
{
|
||||
int i;
|
||||
zend_bool has_key;
|
||||
for (i = 0; i < ast->children; i+=2) {
|
||||
zval *expr;
|
||||
MAKE_STD_ZVAL(expr);
|
||||
if ((has_key = !!(&ast->u.child)[i])) {
|
||||
zend_ast_evaluate(&op1, (&ast->u.child)[i], scope TSRMLS_CC);
|
||||
}
|
||||
zend_ast_evaluate(expr, (&ast->u.child)[i+1], scope TSRMLS_CC);
|
||||
zend_do_add_static_array_element(result, has_key?&op1:NULL, expr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_FETCH_DIM_R:
|
||||
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
|
||||
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
|
||||
{
|
||||
zval *tmp;
|
||||
zend_fetch_dimension_by_zval(&tmp, &op1, &op2 TSRMLS_CC);
|
||||
*result = *tmp;
|
||||
efree(tmp);
|
||||
}
|
||||
zval_dtor(&op1);
|
||||
zval_dtor(&op2);
|
||||
break;
|
||||
default:
|
||||
zend_error(E_ERROR, "Unsupported constant expression");
|
||||
}
|
||||
@@ -297,26 +347,17 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast)
|
||||
zend_ast *copy = zend_ast_create_constant(ast->u.val);
|
||||
zval_copy_ctor(copy->u.val);
|
||||
return copy;
|
||||
} else {
|
||||
switch (ast->children) {
|
||||
case 1:
|
||||
return zend_ast_create_unary(
|
||||
ast->kind,
|
||||
zend_ast_copy((&ast->u.child)[0]));
|
||||
case 2:
|
||||
return zend_ast_create_binary(
|
||||
ast->kind,
|
||||
zend_ast_copy((&ast->u.child)[0]),
|
||||
zend_ast_copy((&ast->u.child)[1]));
|
||||
case 3:
|
||||
return zend_ast_create_ternary(
|
||||
ast->kind,
|
||||
zend_ast_copy((&ast->u.child)[0]),
|
||||
zend_ast_copy((&ast->u.child)[1]),
|
||||
zend_ast_copy((&ast->u.child)[2]));
|
||||
} else if (ast->children) {
|
||||
zend_ast *new = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1));
|
||||
int i;
|
||||
new->kind = ast->kind;
|
||||
new->children = ast->children;
|
||||
for (i = 0; i < ast->children; i++) {
|
||||
(&new->u.child)[i] = zend_ast_copy((&ast->u.child)[i]);
|
||||
}
|
||||
return new;
|
||||
}
|
||||
return NULL;
|
||||
return zend_ast_create_dynamic(ast->kind);
|
||||
}
|
||||
|
||||
ZEND_API void zend_ast_destroy(zend_ast *ast)
|
||||
|
||||
@@ -50,6 +50,9 @@ ZEND_API zend_ast *zend_ast_create_constant(zval *zv);
|
||||
ZEND_API zend_ast *zend_ast_create_unary(uint kind, zend_ast *op0);
|
||||
ZEND_API zend_ast *zend_ast_create_binary(uint kind, zend_ast *op0, zend_ast *op1);
|
||||
ZEND_API zend_ast *zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *op1, zend_ast *op2);
|
||||
ZEND_API zend_ast* zend_ast_create_dynamic(uint kind);
|
||||
ZEND_API void zend_ast_dynamic_add(zend_ast **ast, zend_ast *op);
|
||||
ZEND_API void zend_ast_dynamic_shrink(zend_ast **ast);
|
||||
|
||||
ZEND_API int zend_ast_is_ct_constant(zend_ast *ast);
|
||||
|
||||
|
||||
+11
-46
@@ -1933,7 +1933,7 @@ void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initializ
|
||||
if (op == ZEND_RECV_INIT) {
|
||||
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
|
||||
cur_arg_info->allow_null = 1;
|
||||
} else if (Z_TYPE(initialization->u.constant) != IS_ARRAY && Z_TYPE(initialization->u.constant) != IS_CONSTANT_ARRAY) {
|
||||
} else if (Z_TYPE(initialization->u.constant) != IS_ARRAY) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL");
|
||||
}
|
||||
}
|
||||
@@ -3461,7 +3461,7 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{
|
||||
*zv = *precv->op2.zv;
|
||||
zval_copy_ctor(zv);
|
||||
INIT_PZVAL(zv);
|
||||
zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC);
|
||||
zval_update_constant_ex(&zv, 1, fptr->common.scope TSRMLS_CC);
|
||||
if (Z_TYPE_P(zv) == IS_BOOL) {
|
||||
if (Z_IVAL_P(zv)) {
|
||||
memcpy(offset, "true", 4);
|
||||
@@ -5442,10 +5442,6 @@ void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_D
|
||||
const char *cname = NULL;
|
||||
zend_uint_t hash;
|
||||
|
||||
if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants");
|
||||
return;
|
||||
}
|
||||
if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants");
|
||||
return;
|
||||
@@ -5887,57 +5883,30 @@ void zend_do_add_array_element(znode *result, const znode *expr, const znode *of
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr) /* {{{ */
|
||||
void zend_do_add_static_array_element(zval *result, zval *offset, const zval *expr) /* {{{ */
|
||||
{
|
||||
zval *element;
|
||||
|
||||
ALLOC_ZVAL(element);
|
||||
*element = expr->u.constant;
|
||||
if (offset) {
|
||||
switch (Z_TYPE(offset->u.constant) & IS_CONSTANT_TYPE_MASK) {
|
||||
case IS_CONSTANT:
|
||||
/* Ugly hack to denote that this value has a constant index */
|
||||
Z_TYPE_P(element) |= IS_CONSTANT_INDEX;
|
||||
Z_STRVAL(offset->u.constant) = erealloc(Z_STRVAL(offset->u.constant), Z_STRSIZE(offset->u.constant)+3);
|
||||
Z_STRVAL(offset->u.constant)[Z_STRSIZE(offset->u.constant)+1] = Z_TYPE(offset->u.constant);
|
||||
Z_STRVAL(offset->u.constant)[Z_STRSIZE(offset->u.constant)+2] = 0;
|
||||
zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRSIZE(offset->u.constant)+3, &element, sizeof(zval *), NULL);
|
||||
zval_dtor(&offset->u.constant);
|
||||
break;
|
||||
case IS_CONSTANT_AST: {
|
||||
/* Another ugly hack to store the data about the AST in the array */
|
||||
char* key;
|
||||
int len = sizeof(zend_ast *);
|
||||
Z_TYPE_P(element) |= IS_CONSTANT_INDEX;
|
||||
|
||||
key = emalloc(len + 2);
|
||||
*(zend_ast **)key = Z_AST(offset->u.constant);
|
||||
key[len] = Z_TYPE(offset->u.constant);
|
||||
key[len + 1] = 0;
|
||||
zend_symtable_update(Z_ARRVAL(result->u.constant), key, len + 2, &element, sizeof(zval *), NULL);
|
||||
efree(key);
|
||||
break;
|
||||
}
|
||||
switch (Z_TYPE_P(offset)) {
|
||||
case IS_STRING:
|
||||
zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRSIZE(offset->u.constant)+1, &element, sizeof(zval *), NULL);
|
||||
zval_dtor(&offset->u.constant);
|
||||
zend_symtable_update(Z_ARRVAL_P(result), Z_STRVAL_P(offset), Z_STRSIZE_P(offset)+1, &expr, sizeof(zval *), NULL);
|
||||
zval_dtor(offset);
|
||||
break;
|
||||
case IS_NULL:
|
||||
zend_symtable_update(Z_ARRVAL(result->u.constant), "", 1, &element, sizeof(zval *), NULL);
|
||||
zend_symtable_update(Z_ARRVAL_P(result), "", 1, &expr, sizeof(zval *), NULL);
|
||||
break;
|
||||
case IS_INT:
|
||||
case IS_BOOL:
|
||||
zend_hash_index_update(Z_ARRVAL(result->u.constant), Z_IVAL(offset->u.constant), &element, sizeof(zval *), NULL);
|
||||
zend_hash_index_update(Z_ARRVAL_P(result), Z_IVAL_P(offset), &expr, sizeof(zval *), NULL);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
zend_hash_index_update(Z_ARRVAL(result->u.constant), zend_dval_to_ival(Z_DVAL(offset->u.constant)), &element, sizeof(zval *), NULL);
|
||||
zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_ival(Z_DVAL_P(offset)), &expr, sizeof(zval *), NULL);
|
||||
break;
|
||||
case IS_CONSTANT_ARRAY:
|
||||
case IS_ARRAY:
|
||||
zend_error(E_ERROR, "Illegal offset type");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
zend_hash_next_index_insert(Z_ARRVAL(result->u.constant), &element, sizeof(zval *), NULL);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(result), &expr, sizeof(zval *), NULL);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -7318,10 +7287,6 @@ void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */
|
||||
zend_op *opline;
|
||||
zval **ns_name;
|
||||
|
||||
if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed as constants");
|
||||
}
|
||||
|
||||
if (zend_get_ct_const(&name->u.constant, 0 TSRMLS_CC)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant));
|
||||
}
|
||||
|
||||
+1
-1
@@ -602,7 +602,7 @@ void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC);
|
||||
|
||||
void zend_do_init_array(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC);
|
||||
void zend_do_add_array_element(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC);
|
||||
void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr);
|
||||
void zend_do_add_static_array_element(zval *result, zval *offset, const zval *expr);
|
||||
void zend_do_list_init(TSRMLS_D);
|
||||
void zend_do_list_end(znode *result, znode *expr TSRMLS_DC);
|
||||
void zend_do_add_list_element(const znode *element TSRMLS_DC);
|
||||
|
||||
@@ -408,7 +408,7 @@ ZEND_API int zend_get_constant_ex(const char *name, zend_size_t name_len, zval *
|
||||
efree(lcname);
|
||||
if(found_const) {
|
||||
*result = c->value;
|
||||
zval_update_constant_ex(&result, (void*)1, NULL TSRMLS_CC);
|
||||
zval_update_constant_ex(&result, 1, NULL TSRMLS_CC);
|
||||
zval_copy_ctor(result);
|
||||
Z_SET_REFCOUNT_P(result, 1);
|
||||
Z_UNSET_ISREF_P(result);
|
||||
@@ -423,7 +423,7 @@ ZEND_API int zend_get_constant_ex(const char *name, zend_size_t name_len, zval *
|
||||
retval = 0;
|
||||
finish:
|
||||
if (retval) {
|
||||
zval_update_constant_ex(ret_constant, (void*)1, ce TSRMLS_CC);
|
||||
zval_update_constant_ex(ret_constant, 1, ce TSRMLS_CC);
|
||||
*result = **ret_constant;
|
||||
zval_copy_ctor(result);
|
||||
INIT_PZVAL(result);
|
||||
|
||||
+7
-1
@@ -1352,9 +1352,15 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval *conta
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC) {
|
||||
temp_variable tmp;
|
||||
zend_fetch_dimension_address_read(&tmp, container, dim, IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
|
||||
*result = tmp.var.ptr;
|
||||
}
|
||||
|
||||
static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, const zend_literal *key, int type TSRMLS_DC)
|
||||
{
|
||||
zval *container = *container_ptr;;
|
||||
zval *container = *container_ptr;
|
||||
|
||||
if (Z_TYPE_P(container) != IS_OBJECT) {
|
||||
if (container == &EG(error_zval)) {
|
||||
|
||||
+6
-4
@@ -158,10 +158,10 @@ static zend_always_inline int i_zend_is_true(zval *op)
|
||||
return result;
|
||||
}
|
||||
|
||||
ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_inline_change(zval **pp, void *arg TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_no_inline_change(zval **pp, void *arg TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant(zval **pp, zend_bool inline_change TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_no_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC);
|
||||
ZEND_API int zval_update_constant_ex(zval **pp, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC);
|
||||
|
||||
/* dedicated Zend executor functions - do not use! */
|
||||
#define ZEND_VM_STACK_PAGE_SIZE ((16 * 1024) - 16)
|
||||
@@ -362,6 +362,8 @@ ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, zend_size_t
|
||||
ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, zend_size_t class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC);
|
||||
void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
|
||||
|
||||
ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC);
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
void zend_init_timeout_thread(void);
|
||||
void zend_shutdown_timeout_thread(void);
|
||||
|
||||
+8
-126
@@ -451,28 +451,14 @@ ZEND_API int zend_is_true(zval *op) /* {{{ */
|
||||
|
||||
#include "../TSRM/tsrm_strtok_r.h"
|
||||
|
||||
#define IS_VISITED_CONSTANT IS_CONSTANT_INDEX
|
||||
#define IS_VISITED_CONSTANT 0x80
|
||||
#define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT)
|
||||
#define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT)
|
||||
#define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT
|
||||
|
||||
static void zval_deep_copy(zval **p)
|
||||
{
|
||||
zval *value;
|
||||
|
||||
ALLOC_ZVAL(value);
|
||||
*value = **p;
|
||||
Z_TYPE_P(value) &= ~IS_CONSTANT_INDEX;
|
||||
zval_copy_ctor(value);
|
||||
Z_TYPE_P(value) = Z_TYPE_PP(p);
|
||||
INIT_PZVAL(value);
|
||||
*p = value;
|
||||
}
|
||||
|
||||
ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zval_update_constant_ex(zval **pp, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *p = *pp;
|
||||
zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg;
|
||||
zval const_value;
|
||||
char *colon;
|
||||
|
||||
@@ -559,110 +545,6 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
|
||||
|
||||
Z_SET_REFCOUNT_P(p, refcount);
|
||||
Z_SET_ISREF_TO_P(p, is_ref);
|
||||
} else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) {
|
||||
zval **element, *new_val;
|
||||
char *str_index;
|
||||
zend_size_t str_index_len;
|
||||
zend_uint_t num_index;
|
||||
int ret;
|
||||
|
||||
SEPARATE_ZVAL_IF_NOT_REF(pp);
|
||||
p = *pp;
|
||||
Z_TYPE_P(p) = IS_ARRAY;
|
||||
|
||||
if (!inline_change) {
|
||||
zval *tmp;
|
||||
HashTable *tmp_ht = NULL;
|
||||
|
||||
ALLOC_HASHTABLE(tmp_ht);
|
||||
zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *));
|
||||
Z_ARRVAL_P(p) = tmp_ht;
|
||||
}
|
||||
|
||||
/* First go over the array and see if there are any constant indices */
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
|
||||
while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) {
|
||||
if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) {
|
||||
zend_hash_move_forward(Z_ARRVAL_P(p));
|
||||
continue;
|
||||
}
|
||||
Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX;
|
||||
if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) {
|
||||
zend_hash_move_forward(Z_ARRVAL_P(p));
|
||||
continue;
|
||||
}
|
||||
if (str_index[str_index_len - 2] == IS_CONSTANT_AST) {
|
||||
zend_ast_evaluate(&const_value, *(zend_ast **)str_index, scope TSRMLS_CC);
|
||||
zend_ast_destroy(*(zend_ast **)str_index);
|
||||
} else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) {
|
||||
char *actual;
|
||||
const char *save = str_index;
|
||||
if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) {
|
||||
zend_error(E_ERROR, "Undefined class constant '%s'", str_index);
|
||||
str_index_len -= ((colon - str_index) + 1);
|
||||
str_index = colon;
|
||||
} else {
|
||||
if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) {
|
||||
if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) {
|
||||
actual++;
|
||||
str_index_len -= (actual - str_index);
|
||||
str_index = actual;
|
||||
}
|
||||
}
|
||||
if (str_index[0] == '\\') {
|
||||
++str_index;
|
||||
--str_index_len;
|
||||
}
|
||||
if (save[0] == '\\') {
|
||||
++save;
|
||||
}
|
||||
if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) {
|
||||
zend_error(E_ERROR, "Undefined constant '%s'", save);
|
||||
}
|
||||
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index);
|
||||
}
|
||||
ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1);
|
||||
}
|
||||
|
||||
if (Z_REFCOUNT_PP(element) > 1) {
|
||||
ALLOC_ZVAL(new_val);
|
||||
*new_val = **element;
|
||||
zval_copy_ctor(new_val);
|
||||
Z_SET_REFCOUNT_P(new_val, 1);
|
||||
Z_UNSET_ISREF_P(new_val);
|
||||
|
||||
/* preserve this bit for inheritance */
|
||||
Z_TYPE_PP(element) |= IS_CONSTANT_INDEX;
|
||||
zval_ptr_dtor(element);
|
||||
*element = new_val;
|
||||
}
|
||||
|
||||
switch (Z_TYPE(const_value)) {
|
||||
case IS_STRING:
|
||||
ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRSIZE(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE);
|
||||
break;
|
||||
case IS_BOOL:
|
||||
case IS_INT:
|
||||
ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_INT, NULL, 0, Z_IVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_INT, NULL, 0, zend_dval_to_ival(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL);
|
||||
break;
|
||||
case IS_NULL:
|
||||
ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL);
|
||||
break;
|
||||
default:
|
||||
ret = SUCCESS;
|
||||
break;
|
||||
}
|
||||
if (ret == SUCCESS) {
|
||||
zend_hash_move_forward(Z_ARRVAL_P(p));
|
||||
}
|
||||
zval_dtor(&const_value);
|
||||
}
|
||||
zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC);
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
|
||||
} else if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
|
||||
SEPARATE_ZVAL_IF_NOT_REF(pp);
|
||||
p = *pp;
|
||||
@@ -677,21 +559,21 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zval_update_constant_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zval_update_constant_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return zval_update_constant_ex(pp, (void*)1, scope TSRMLS_CC);
|
||||
return zval_update_constant_ex(pp, 1, scope TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zval_update_constant_no_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zval_update_constant_no_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return zval_update_constant_ex(pp, (void*)0, scope TSRMLS_CC);
|
||||
return zval_update_constant_ex(pp, 0, scope TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zval_update_constant(zval **pp, zend_bool inline_change TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return zval_update_constant_ex(pp, arg, NULL TSRMLS_CC);
|
||||
return zval_update_constant_ex(pp, inline_change, NULL TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
break;
|
||||
|
||||
default:
|
||||
efree(token.value.str.val);
|
||||
STR_FREE(token.value.str.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-10
@@ -986,9 +986,7 @@ static_class_constant:
|
||||
;
|
||||
|
||||
static_scalar: /* compile-time evaluated scalars */
|
||||
static_scalar_value { zend_do_constant_expression(&$$, $1.u.ast TSRMLS_CC); }
|
||||
| T_ARRAY '(' static_array_pair_list ')' { $$ = $3; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; }
|
||||
| '[' static_array_pair_list ']' { $$ = $2; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; }
|
||||
static_scalar_value { zend_do_constant_expression(&$$, $1.u.ast TSRMLS_CC); }
|
||||
;
|
||||
|
||||
static_scalar_value:
|
||||
@@ -997,13 +995,16 @@ static_scalar_value:
|
||||
| namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
|
||||
| T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
|
||||
| T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRSIZE($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRSIZE($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRSIZE($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
|
||||
| T_ARRAY '(' static_array_pair_list ')' { $$ = $3; }
|
||||
| '[' static_array_pair_list ']' { $$ = $2; }
|
||||
| static_class_constant { $$.u.ast = zend_ast_create_constant(&$1.u.constant); }
|
||||
| T_CLASS_C { $$.u.ast = zend_ast_create_constant(&$1.u.constant); }
|
||||
| static_operation { $$ = $1; }
|
||||
;
|
||||
|
||||
static_operation:
|
||||
static_scalar_value '+' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_ADD, $1.u.ast, $3.u.ast); }
|
||||
static_scalar_value '[' static_scalar_value ']' { $$.u.ast = zend_ast_create_binary(ZEND_FETCH_DIM_R, $1.u.ast, $3.u.ast); }
|
||||
| static_scalar_value '+' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_ADD, $1.u.ast, $3.u.ast); }
|
||||
| static_scalar_value '-' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_SUB, $1.u.ast, $3.u.ast); }
|
||||
| static_scalar_value '*' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_MUL, $1.u.ast, $3.u.ast); }
|
||||
| static_scalar_value T_POW static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_POW, $1.u.ast, $3.u.ast); }
|
||||
@@ -1053,8 +1054,8 @@ scalar:
|
||||
|
||||
|
||||
static_array_pair_list:
|
||||
/* empty */ { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); }
|
||||
| non_empty_static_array_pair_list possible_comma { $$ = $1; }
|
||||
/* empty */ { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
|
||||
| non_empty_static_array_pair_list possible_comma { zend_ast_dynamic_shrink(&$1.u.ast); $$ = $1; }
|
||||
;
|
||||
|
||||
possible_comma:
|
||||
@@ -1063,10 +1064,10 @@ possible_comma:
|
||||
;
|
||||
|
||||
non_empty_static_array_pair_list:
|
||||
non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW static_scalar { zend_do_add_static_array_element(&$$, &$3, &$5); }
|
||||
| non_empty_static_array_pair_list ',' static_scalar { zend_do_add_static_array_element(&$$, NULL, &$3); }
|
||||
| static_scalar T_DOUBLE_ARROW static_scalar { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, &$1, &$3); }
|
||||
| static_scalar { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, NULL, &$1); }
|
||||
non_empty_static_array_pair_list ',' static_scalar_value T_DOUBLE_ARROW static_scalar_value { zend_ast_dynamic_add(&$$.u.ast, $3.u.ast); zend_ast_dynamic_add(&$$.u.ast, $5.u.ast); }
|
||||
| non_empty_static_array_pair_list ',' static_scalar_value { zend_ast_dynamic_add(&$$.u.ast, NULL); zend_ast_dynamic_add(&$$.u.ast, $3.u.ast); }
|
||||
| static_scalar_value T_DOUBLE_ARROW static_scalar_value { $$.u.ast = zend_ast_create_dynamic(ZEND_INIT_ARRAY); zend_ast_dynamic_add(&$$.u.ast, $1.u.ast); zend_ast_dynamic_add(&$$.u.ast, $3.u.ast); }
|
||||
| static_scalar_value { $$.u.ast = zend_ast_create_dynamic(ZEND_INIT_ARRAY); zend_ast_dynamic_add(&$$.u.ast, NULL); zend_ast_dynamic_add(&$$.u.ast, $1.u.ast); }
|
||||
;
|
||||
|
||||
expr:
|
||||
|
||||
@@ -170,6 +170,8 @@ ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC
|
||||
}
|
||||
|
||||
zend_error_noreturn(E_ERROR, ZEND_DEBUGINFO_FUNC_NAME "() must return an array");
|
||||
|
||||
return NULL; /* Compilers are dumb and don't understand that noreturn means that the function does NOT need a return value... */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@ ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
CHECK_ZVAL_STRING_REL(zvalue);
|
||||
str_efree_rel(zvalue->value.str.val);
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY: {
|
||||
case IS_ARRAY: {
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
|
||||
@@ -86,7 +85,6 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
str_free(zvalue->value.str.val);
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY:
|
||||
case IS_CONSTANT_AST:
|
||||
case IS_OBJECT:
|
||||
case IS_RESOURCE:
|
||||
@@ -128,8 +126,7 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
zvalue->value.str.val = (char *) estrndup_rel(zvalue->value.str.val, zvalue->value.str.len);
|
||||
}
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY: {
|
||||
case IS_ARRAY: {
|
||||
zval *tmp;
|
||||
HashTable *original_ht = zvalue->value.ht;
|
||||
HashTable *tmp_ht = NULL;
|
||||
|
||||
+11
-15
@@ -1081,7 +1081,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
|
||||
FREE_OP1();
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (OP1_TYPE == IS_VAR && !free_op1.var) {
|
||||
@@ -3710,8 +3710,6 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
|
||||
retval = &EX_T(opline->result.var).tmp_var;
|
||||
ZVAL_COPY_VALUE(retval, &c->value);
|
||||
zval_copy_ctor(retval);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
/* class constant */
|
||||
zend_class_entry *ce;
|
||||
@@ -3722,8 +3720,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
|
||||
value = CACHED_PTR(opline->op2.literal->cache_slot);
|
||||
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
|
||||
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
goto constant_fetch_end;
|
||||
} else if (CACHED_PTR(opline->op1.literal->cache_slot)) {
|
||||
ce = CACHED_PTR(opline->op1.literal->cache_slot);
|
||||
} else {
|
||||
@@ -3741,8 +3738,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
|
||||
if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) {
|
||||
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
|
||||
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
goto constant_fetch_end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3751,7 +3747,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
|
||||
zend_class_entry *old_scope = EG(scope);
|
||||
|
||||
EG(scope) = ce;
|
||||
zval_update_constant(value, (void *) 1 TSRMLS_CC);
|
||||
zval_update_constant(value, 1 TSRMLS_CC);
|
||||
EG(scope) = old_scope;
|
||||
}
|
||||
if (OP1_TYPE == IS_CONST) {
|
||||
@@ -3767,10 +3763,13 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
|
||||
}
|
||||
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
constant_fetch_end:
|
||||
if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) {
|
||||
zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time");
|
||||
}
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUSED|CV)
|
||||
@@ -5376,11 +5375,8 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
|
||||
zval *tmp_ptr = &tmp;
|
||||
|
||||
ZVAL_COPY_VALUE(&tmp, val);
|
||||
if (Z_TYPE_P(val) == IS_CONSTANT_ARRAY) {
|
||||
zval_copy_ctor(&tmp);
|
||||
}
|
||||
INIT_PZVAL(&tmp);
|
||||
zval_update_constant(&tmp_ptr, NULL TSRMLS_CC);
|
||||
zval_update_constant(&tmp_ptr, 0 TSRMLS_CC);
|
||||
c.value = *tmp_ptr;
|
||||
} else {
|
||||
INIT_PZVAL_COPY(&c.value, val);
|
||||
|
||||
+40
-46
@@ -3684,7 +3684,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type
|
||||
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_CONST == IS_VAR && !free_op1.var) {
|
||||
@@ -3971,8 +3971,6 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
|
||||
retval = &EX_T(opline->result.var).tmp_var;
|
||||
ZVAL_COPY_VALUE(retval, &c->value);
|
||||
zval_copy_ctor(retval);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
/* class constant */
|
||||
zend_class_entry *ce;
|
||||
@@ -3983,8 +3981,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
|
||||
value = CACHED_PTR(opline->op2.literal->cache_slot);
|
||||
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
|
||||
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
goto constant_fetch_end;
|
||||
} else if (CACHED_PTR(opline->op1.literal->cache_slot)) {
|
||||
ce = CACHED_PTR(opline->op1.literal->cache_slot);
|
||||
} else {
|
||||
@@ -4002,8 +3999,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
|
||||
if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) {
|
||||
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
|
||||
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
goto constant_fetch_end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4012,7 +4008,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
|
||||
zend_class_entry *old_scope = EG(scope);
|
||||
|
||||
EG(scope) = ce;
|
||||
zval_update_constant(value, (void *) 1 TSRMLS_CC);
|
||||
zval_update_constant(value, 1 TSRMLS_CC);
|
||||
EG(scope) = old_scope;
|
||||
}
|
||||
if (IS_CONST == IS_CONST) {
|
||||
@@ -4028,10 +4024,13 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
|
||||
}
|
||||
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
constant_fetch_end:
|
||||
if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) {
|
||||
zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time");
|
||||
}
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@@ -4309,11 +4308,8 @@ static int ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD
|
||||
zval *tmp_ptr = &tmp;
|
||||
|
||||
ZVAL_COPY_VALUE(&tmp, val);
|
||||
if (Z_TYPE_P(val) == IS_CONSTANT_ARRAY) {
|
||||
zval_copy_ctor(&tmp);
|
||||
}
|
||||
INIT_PZVAL(&tmp);
|
||||
zval_update_constant(&tmp_ptr, NULL TSRMLS_CC);
|
||||
zval_update_constant(&tmp_ptr, 0 TSRMLS_CC);
|
||||
c.value = *tmp_ptr;
|
||||
} else {
|
||||
INIT_PZVAL_COPY(&c.value, val);
|
||||
@@ -5572,7 +5568,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type,
|
||||
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_CONST == IS_VAR && !free_op1.var) {
|
||||
@@ -6324,7 +6320,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ
|
||||
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_CONST == IS_VAR && !free_op1.var) {
|
||||
@@ -9094,7 +9090,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
|
||||
zval_dtor(free_op1.var);
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_TMP_VAR == IS_VAR && !free_op1.var) {
|
||||
@@ -10850,7 +10846,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
|
||||
zval_dtor(free_op1.var);
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_TMP_VAR == IS_VAR && !free_op1.var) {
|
||||
@@ -11604,7 +11600,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
|
||||
zval_dtor(free_op1.var);
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_TMP_VAR == IS_VAR && !free_op1.var) {
|
||||
@@ -15024,7 +15020,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
|
||||
zval_ptr_dtor_nogc(&free_op1.var);
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_VAR == IS_VAR && !free_op1.var) {
|
||||
@@ -15924,8 +15920,6 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
|
||||
retval = &EX_T(opline->result.var).tmp_var;
|
||||
ZVAL_COPY_VALUE(retval, &c->value);
|
||||
zval_copy_ctor(retval);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
/* class constant */
|
||||
zend_class_entry *ce;
|
||||
@@ -15936,8 +15930,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
|
||||
value = CACHED_PTR(opline->op2.literal->cache_slot);
|
||||
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
|
||||
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
goto constant_fetch_end;
|
||||
} else if (CACHED_PTR(opline->op1.literal->cache_slot)) {
|
||||
ce = CACHED_PTR(opline->op1.literal->cache_slot);
|
||||
} else {
|
||||
@@ -15955,8 +15948,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
|
||||
if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) {
|
||||
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
|
||||
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
goto constant_fetch_end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15965,7 +15957,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
|
||||
zend_class_entry *old_scope = EG(scope);
|
||||
|
||||
EG(scope) = ce;
|
||||
zval_update_constant(value, (void *) 1 TSRMLS_CC);
|
||||
zval_update_constant(value, 1 TSRMLS_CC);
|
||||
EG(scope) = old_scope;
|
||||
}
|
||||
if (IS_VAR == IS_CONST) {
|
||||
@@ -15981,10 +15973,13 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
|
||||
}
|
||||
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
constant_fetch_end:
|
||||
if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) {
|
||||
zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time");
|
||||
}
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@@ -19622,7 +19617,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
|
||||
zval_ptr_dtor_nogc(&free_op1.var);
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_VAR == IS_VAR && !free_op1.var) {
|
||||
@@ -21610,7 +21605,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
|
||||
zval_ptr_dtor_nogc(&free_op1.var);
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_VAR == IS_VAR && !free_op1.var) {
|
||||
@@ -25537,8 +25532,6 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
|
||||
retval = &EX_T(opline->result.var).tmp_var;
|
||||
ZVAL_COPY_VALUE(retval, &c->value);
|
||||
zval_copy_ctor(retval);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
/* class constant */
|
||||
zend_class_entry *ce;
|
||||
@@ -25549,8 +25542,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
|
||||
value = CACHED_PTR(opline->op2.literal->cache_slot);
|
||||
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
|
||||
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
goto constant_fetch_end;
|
||||
} else if (CACHED_PTR(opline->op1.literal->cache_slot)) {
|
||||
ce = CACHED_PTR(opline->op1.literal->cache_slot);
|
||||
} else {
|
||||
@@ -25568,8 +25560,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
|
||||
if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) {
|
||||
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
|
||||
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
goto constant_fetch_end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25578,7 +25569,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
|
||||
zend_class_entry *old_scope = EG(scope);
|
||||
|
||||
EG(scope) = ce;
|
||||
zval_update_constant(value, (void *) 1 TSRMLS_CC);
|
||||
zval_update_constant(value, 1 TSRMLS_CC);
|
||||
EG(scope) = old_scope;
|
||||
}
|
||||
if (IS_UNUSED == IS_CONST) {
|
||||
@@ -25594,10 +25585,13 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
|
||||
}
|
||||
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
constant_fetch_end:
|
||||
if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) {
|
||||
zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time");
|
||||
}
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@@ -32488,7 +32482,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
|
||||
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_CV == IS_VAR && !free_op1.var) {
|
||||
@@ -36712,7 +36706,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
|
||||
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_CV == IS_VAR && !free_op1.var) {
|
||||
@@ -38560,7 +38554,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
|
||||
|
||||
break;
|
||||
case ZEND_FETCH_STATIC:
|
||||
zval_update_constant(retval, (void*) 1 TSRMLS_CC);
|
||||
zval_update_constant(retval, 1 TSRMLS_CC);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBAL_LOCK:
|
||||
if (IS_CV == IS_VAR && !free_op1.var) {
|
||||
|
||||
@@ -160,7 +160,7 @@ PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, php_int_t
|
||||
|
||||
case IS_RESOURCE:
|
||||
case IS_CONSTANT:
|
||||
case IS_CONSTANT_ARRAY:
|
||||
case IS_CONSTANT_AST:
|
||||
default:
|
||||
V_VT(v) = VT_NULL;
|
||||
break;
|
||||
|
||||
@@ -248,6 +248,8 @@ PHP_FUNCTION(curl_multi_getcontent)
|
||||
smart_str_0(&ch->handlers->write->buf);
|
||||
RETURN_STRINGL(ch->handlers->write->buf.c, ch->handlers->write->buf.len, 1);
|
||||
}
|
||||
|
||||
RETURN_EMPTY_STRING();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -2801,6 +2801,10 @@ static int php_date_initialize_from_hash(zval **return_value, php_date_obj **dat
|
||||
|
||||
tzi = php_date_parse_tzfile(Z_STRVAL_PP(z_timezone), DATE_TIMEZONEDB TSRMLS_CC);
|
||||
|
||||
if (tzi == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ALLOC_INIT_ZVAL(tmp_obj);
|
||||
tzobj = zend_object_store_get_object(php_date_instantiate(date_ce_timezone, tmp_obj TSRMLS_CC) TSRMLS_CC);
|
||||
tzobj->type = TIMELIB_ZONETYPE_ID;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
Test for bug #66721: __wakeup of DateTime segfaults when invalid object data is supplied
|
||||
--CREDITS--
|
||||
Boro Sitnikovski <buritomath@yahoo.com>
|
||||
--FILE--
|
||||
<?php
|
||||
$y = 'O:8:"DateTime":3:{s:4:"date";s:19:"2014-02-15 02:00:51";s:13:"timezone_type";i:3;s:8:"timezone";s:10:"1234567890";}';
|
||||
var_dump(unserialize($y));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Invalid serialization data for DateTime object in %s on line %d
|
||||
@@ -1,7 +1,3 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
PHP_ARG_WITH(interbase,for InterBase support,
|
||||
[ --with-interbase[=DIR] Include InterBase support. DIR is the InterBase base
|
||||
install directory [/usr/interbase]])
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("interbase", "InterBase support", "no");
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_IBASE_INCLUDES_H
|
||||
#define PHP_IBASE_INCLUDES_H
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/**
|
||||
* This UDF library adds the ability to call PHP functions from SQL
|
||||
* statements. Because of SQL's strong typing, you will have to declare
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_INTERBASE_H
|
||||
#define PHP_INTERBASE_H
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php /* $Id$ */
|
||||
<?php
|
||||
|
||||
srand((double)microtime()*1000000);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php /* $Id$ */
|
||||
<?php
|
||||
|
||||
if (!extension_loaded("interbase")) print "skip interbase extension not available";
|
||||
require("interbase.inc");
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
--TEST--
|
||||
IntlBreakIterator::getLocale(): basic test
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('intl'))
|
||||
die('skip intl extension not enabled');
|
||||
<?php if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') >= 0) die('skip for ICU < 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set("intl.error_level", E_WARNING);
|
||||
@@ -18,4 +17,4 @@ var_dump($bi->getLocale(1));
|
||||
--EXPECT--
|
||||
string(4) "root"
|
||||
string(4) "root"
|
||||
==DONE==
|
||||
==DONE==
|
||||
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
IntlBreakIterator::getLocale(): basic test
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') < 0) die('skip for ICU >= 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set("intl.error_level", E_WARNING);
|
||||
ini_set("intl.default_locale", "pt_PT");
|
||||
|
||||
$bi = IntlBreakIterator::createSentenceInstance('pt');
|
||||
|
||||
var_dump($bi->getLocale(0));
|
||||
var_dump($bi->getLocale(1));
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
string(4) "root"
|
||||
string(2) "pt"
|
||||
==DONE==
|
||||
@@ -1,11 +1,9 @@
|
||||
--TEST--
|
||||
Bug #62070: Collator::getSortKey() returns garbage
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('intl'))
|
||||
die('skip intl extension not enabled');
|
||||
if (version_compare(INTL_ICU_VERSION, '49') < 0)
|
||||
die('skip ICU >= 49 only');
|
||||
<?php if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '49') < 0) die('skip for ICU >= 49'); ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') >= 0) die('skip for ICU < 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$s1 = 'Hello';
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Bug #62070: Collator::getSortKey() returns garbage
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') < 0) die('skip for ICU >= 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$s1 = 'Hello';
|
||||
|
||||
$coll = collator_create('en_US');
|
||||
$res = collator_get_sort_key($coll, $s1);
|
||||
|
||||
echo urlencode($res);
|
||||
--EXPECT--
|
||||
71%3F%3FE%01%09%01%DC%08
|
||||
@@ -1,8 +1,9 @@
|
||||
--TEST--
|
||||
create() icu >= 4.8
|
||||
create() icu >= 4.8 && icu < 53.1
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
<?php if(version_compare(INTL_ICU_VERSION, '4.8') < 0) print 'skip'; ?>
|
||||
<?php if(version_compare(INTL_ICU_VERSION, '4.8') < 0) print 'skip for ICU >= 4.8'; ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') >= 0) die('skip for ICU < 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
--TEST--
|
||||
create() icu >= 53.1
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') < 0) die('skip for ICU >= 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Try creating collator with different locales
|
||||
* with Procedural and Object methods.
|
||||
*/
|
||||
|
||||
function ut_main()
|
||||
{
|
||||
$res_str = '';
|
||||
|
||||
$locales = array(
|
||||
'EN-US-ODESSA',
|
||||
'UK_UA_ODESSA',
|
||||
'uk-ua_CALIFORNIA@currency=;currency=GRN',
|
||||
'',
|
||||
'root',
|
||||
'uk@currency=EURO',
|
||||
'1234567891113151719212325272931333537394143454749515357596163656769717375777981838587899193959799'
|
||||
);
|
||||
|
||||
foreach( $locales as $locale )
|
||||
{
|
||||
// Create Collator with the current locale.
|
||||
$coll = ut_coll_create( $locale );
|
||||
if( !is_object($coll) )
|
||||
{
|
||||
$res_str .= "Error creating collator with '$locale' locale: " .
|
||||
intl_get_error_message() . "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the requested, valid and actual locales.
|
||||
$vloc = ut_coll_get_locale( $coll, Locale::VALID_LOCALE );
|
||||
$aloc = ut_coll_get_locale( $coll, Locale::ACTUAL_LOCALE );
|
||||
|
||||
// Show them.
|
||||
$res_str .= "Locale: '$locale'\n" .
|
||||
" ULOC_REQUESTED_LOCALE = '$locale'\n" .
|
||||
" ULOC_VALID_LOCALE = '$vloc'\n" .
|
||||
" ULOC_ACTUAL_LOCALE = '$aloc'\n";
|
||||
}
|
||||
|
||||
return $res_str;
|
||||
}
|
||||
|
||||
include_once( 'ut_common.inc' );
|
||||
ut_run();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Locale: 'EN-US-ODESSA'
|
||||
ULOC_REQUESTED_LOCALE = 'EN-US-ODESSA'
|
||||
ULOC_VALID_LOCALE = 'en_US'
|
||||
ULOC_ACTUAL_LOCALE = 'root'
|
||||
Locale: 'UK_UA_ODESSA'
|
||||
ULOC_REQUESTED_LOCALE = 'UK_UA_ODESSA'
|
||||
ULOC_VALID_LOCALE = 'uk'
|
||||
ULOC_ACTUAL_LOCALE = 'uk'
|
||||
Locale: 'uk-ua_CALIFORNIA@currency=;currency=GRN'
|
||||
ULOC_REQUESTED_LOCALE = 'uk-ua_CALIFORNIA@currency=;currency=GRN'
|
||||
ULOC_VALID_LOCALE = 'root'
|
||||
ULOC_ACTUAL_LOCALE = 'root'
|
||||
Locale: ''
|
||||
ULOC_REQUESTED_LOCALE = ''
|
||||
ULOC_VALID_LOCALE = '%s'
|
||||
ULOC_ACTUAL_LOCALE = '%s'
|
||||
Locale: 'root'
|
||||
ULOC_REQUESTED_LOCALE = 'root'
|
||||
ULOC_VALID_LOCALE = 'root'
|
||||
ULOC_ACTUAL_LOCALE = 'root'
|
||||
Locale: 'uk@currency=EURO'
|
||||
ULOC_REQUESTED_LOCALE = 'uk@currency=EURO'
|
||||
ULOC_VALID_LOCALE = 'uk'
|
||||
ULOC_ACTUAL_LOCALE = 'uk'
|
||||
Error creating collator with '1234567891113151719212325272931333537394143454749515357596163656769717375777981838587899193959799' locale: Locale string too long, should be no longer than 80 characters: U_ILLEGAL_ARGUMENT_ERROR
|
||||
@@ -3,6 +3,7 @@ collator_get_sort_key()
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') >= 0) die('skip for ICU < 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
--TEST--
|
||||
collator_get_sort_key()
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') < 0) die('skip for ICU >= 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Get sort keys using various locales
|
||||
*/
|
||||
function sort_arrays( $locale, $data )
|
||||
{
|
||||
$res_str = '';
|
||||
|
||||
$coll = ut_coll_create( $locale );
|
||||
|
||||
foreach($data as $value) {
|
||||
$res_val = ut_coll_get_sort_key( $coll, $value );
|
||||
$res_str .= "source: ".$value."\n".
|
||||
"key: ".bin2hex($res_val)."\n";
|
||||
}
|
||||
|
||||
return $res_str;
|
||||
}
|
||||
|
||||
|
||||
function ut_main()
|
||||
{
|
||||
$res_str = '';
|
||||
|
||||
// Regular strings keys
|
||||
$test_params = array(
|
||||
'abc', 'abd', 'aaa',
|
||||
'аа', 'а', 'z',
|
||||
'', null , '3',
|
||||
'y' , 'i' , 'k'
|
||||
);
|
||||
|
||||
$res_str .= sort_arrays( 'en_US', $test_params );
|
||||
|
||||
// Sort a non-ASCII array using ru_RU locale.
|
||||
$test_params = array(
|
||||
'абг', 'абв', 'жжж', 'эюя'
|
||||
);
|
||||
|
||||
$res_str .= sort_arrays( 'ru_RU', $test_params );
|
||||
|
||||
// Sort an array using Lithuanian locale.
|
||||
$res_str .= sort_arrays( 'lt_LT', $test_params );
|
||||
|
||||
return $res_str . "\n";
|
||||
}
|
||||
|
||||
include_once( 'ut_common.inc' );
|
||||
ut_run();
|
||||
?>
|
||||
--EXPECT--
|
||||
source: abc
|
||||
key: 292b2d01070107
|
||||
source: abd
|
||||
key: 292b2f01070107
|
||||
source: aaa
|
||||
key: 29292901070107
|
||||
source: аа
|
||||
key: 5e090901060106
|
||||
source: а
|
||||
key: 5e0901050105
|
||||
source: z
|
||||
key: 5b01050105
|
||||
source:
|
||||
key: 0101
|
||||
source:
|
||||
key: 0101
|
||||
source: 3
|
||||
key: 1a01050105
|
||||
source: y
|
||||
key: 5901050105
|
||||
source: i
|
||||
key: 3901050105
|
||||
source: k
|
||||
key: 3d01050105
|
||||
source: абг
|
||||
key: 2809131701070107
|
||||
source: абв
|
||||
key: 2809131501070107
|
||||
source: жжж
|
||||
key: 2833333301070107
|
||||
source: эюя
|
||||
key: 28cdd1d501070107
|
||||
source: абг
|
||||
key: 5e09131701070107
|
||||
source: абв
|
||||
key: 5e09131501070107
|
||||
source: жжж
|
||||
key: 5e33333301070107
|
||||
source: эюя
|
||||
key: 5ecdd1d501070107
|
||||
@@ -1,8 +1,9 @@
|
||||
--TEST--
|
||||
numfmt_format() icu >= 52.1
|
||||
numfmt_format() icu >= 52.1 && icu < 53.1
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
<?php if(version_compare(INTL_ICU_VERSION, '52.1') < 0) print 'skip'; ?>
|
||||
<?php if(version_compare(INTL_ICU_VERSION, '52.1') < 0) print 'skip for ICU >= 52.1'; ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') >= 0) die('skip for ICU < 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
--TEST--
|
||||
numfmt_format() icu >= 53.1
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') < 0) die('skip for ICU >= 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Format a number using misc locales/patterns.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: doesn't pass on ICU 3.6 because 'ru' and 'de' locales changed
|
||||
* currency and percent formatting.
|
||||
*/
|
||||
|
||||
function ut_main()
|
||||
{
|
||||
$styles = array(
|
||||
NumberFormatter::PATTERN_DECIMAL => '##.#####################',
|
||||
NumberFormatter::DECIMAL => '',
|
||||
NumberFormatter::CURRENCY => '',
|
||||
NumberFormatter::PERCENT => '',
|
||||
NumberFormatter::SCIENTIFIC => '',
|
||||
NumberFormatter::SPELLOUT => '@@@@@@@',
|
||||
NumberFormatter::ORDINAL => '',
|
||||
NumberFormatter::DURATION => '',
|
||||
NumberFormatter::PATTERN_RULEBASED => '#####.###',
|
||||
1234999, // bad one
|
||||
);
|
||||
|
||||
$integer = array(
|
||||
NumberFormatter::ORDINAL => '',
|
||||
NumberFormatter::DURATION => '',
|
||||
);
|
||||
$locales = array(
|
||||
'en_US',
|
||||
'ru_UA',
|
||||
'de',
|
||||
'fr',
|
||||
'en_UK'
|
||||
);
|
||||
|
||||
$str_res = '';
|
||||
$number = 1234567.891234567890000;
|
||||
|
||||
foreach( $locales as $locale )
|
||||
{
|
||||
$str_res .= "\nLocale is: $locale\n";
|
||||
foreach( $styles as $style => $pattern )
|
||||
{
|
||||
$fmt = ut_nfmt_create( $locale, $style, $pattern );
|
||||
|
||||
if(!$fmt) {
|
||||
$str_res .= "Bad formatter!\n";
|
||||
continue;
|
||||
}
|
||||
$str_res .= dump( isset($integer[$style])?ut_nfmt_format( $fmt, $number, NumberFormatter::TYPE_INT32):ut_nfmt_format( $fmt, $number ) ) . "\n";
|
||||
}
|
||||
}
|
||||
return $str_res;
|
||||
}
|
||||
|
||||
include_once( 'ut_common.inc' );
|
||||
|
||||
// Run the test
|
||||
ut_run();
|
||||
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
Locale is: en_US
|
||||
'1234567.89123457'
|
||||
'1,234,567.891'
|
||||
'\$1,234,567.89'
|
||||
'123,456,789%'
|
||||
'1.23456789123457E6'
|
||||
'one million,? two hundred (and )?thirty-four thousand,? five hundred (and )?sixty-seven point eight nine one two three four five seven'
|
||||
'1,234,567(th|ᵗʰ)'
|
||||
'342:56:07'
|
||||
'#####.###'
|
||||
'USD1,234,567.89'
|
||||
|
||||
Locale is: ru_UA
|
||||
'1234567,89123457'
|
||||
'1 234 567,891'
|
||||
'1 234 567,89 ?(грн\.|₴)'
|
||||
'123 456 789 ?%'
|
||||
'1,23456789123457E6'
|
||||
'один миллион двести тридцать четыре тысяч пятьсот шестьдесят семь запятая восемь девять один два три четыре пять семь'
|
||||
'1 234 567.?'
|
||||
'1 234 567'
|
||||
'#####.###'
|
||||
'1 234 567,89 UAH'
|
||||
|
||||
Locale is: de
|
||||
'1234567,89123457'
|
||||
'1.234.567,891'
|
||||
'(¤ )?1.234.567,89( ¤)?'
|
||||
'123\.456\.789 %'
|
||||
'1,23456789123457E6'
|
||||
'eine Million zweihundertvierunddreißigtausendfünfhundertsiebenundsechzig Komma acht neun eins zwei drei vier fünf sieben'
|
||||
'1.234.567.?'
|
||||
'1.234.567'
|
||||
'#####.###'
|
||||
'1.234.567,89 ¤¤'
|
||||
|
||||
Locale is: fr
|
||||
'1234567,89123457'
|
||||
'1 234 567,891'
|
||||
'1 234 567,89 ¤'
|
||||
'123 456 789 ?%'
|
||||
'1,23456789123457E6'
|
||||
'un million deux cent trente-quatre mille cinq cent soixante-sept virgule huit neuf un deux trois quatre cinq sept'
|
||||
'1 234 567e'
|
||||
'1 234 567'
|
||||
'#####.###'
|
||||
'1 234 567,89 ¤¤'
|
||||
|
||||
Locale is: en_UK
|
||||
'1234567.89123457'
|
||||
'1,234,567.891'
|
||||
'¤1,234,567.89'
|
||||
'123,456,789%'
|
||||
'1.23456789123457E6'
|
||||
'one million,? two hundred (and )?thirty-four thousand,? five hundred (and )?sixty-seven point eight nine one two three four five seven'
|
||||
'1,234,567(th|ᵗʰ)'
|
||||
'342:56:07'
|
||||
'#####.###'
|
||||
'¤¤1,234,567.89'
|
||||
@@ -1,8 +1,9 @@
|
||||
--TEST--
|
||||
locale_get_display_name() icu >= 52.1
|
||||
locale_get_display_name() icu >= 52.1 && icu < 53.1
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '52.1') < 0) die('skip for ICU >= 52.1'); ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') >= 0) die('skip for ICU < 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
--TEST--
|
||||
locale_get_display_name() icu >= 53.1
|
||||
--SKIPIF--
|
||||
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') < 0) die('skip for ICU >= 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Try getting the display_name for different locales
|
||||
* with Procedural and Object methods.
|
||||
*/
|
||||
|
||||
function ut_main()
|
||||
{
|
||||
$res_str='';
|
||||
|
||||
$disp_locales=array('en','fr','de');
|
||||
|
||||
$locales = array(
|
||||
'sl_IT_nedis_KIRTI',
|
||||
'sl_IT_nedis-a-kirti-x-xyz',
|
||||
'sl_IT_rozaj',
|
||||
'sl_IT_NEDIS_ROJAZ_1901',
|
||||
'i-enochian',
|
||||
'zh-hakka',
|
||||
'zh-wuu',
|
||||
'i-tay',
|
||||
'sgn-BE-nl',
|
||||
'sgn-CH-de',
|
||||
'sl_IT_rozaj@currency=EUR',
|
||||
'uk-ua_CALIFORNIA@currency=;currency=GRN',
|
||||
'root',
|
||||
'uk@currency=EURO',
|
||||
'Hindi',
|
||||
//Simple language subtag
|
||||
'de',
|
||||
'fr',
|
||||
'ja',
|
||||
'i-enochian', //(example of a grandfathered tag)
|
||||
//Language subtag plus Script subtag:
|
||||
'zh-Hant',
|
||||
'zh-Hans',
|
||||
'sr-Cyrl',
|
||||
'sr-Latn',
|
||||
//Language-Script-Region
|
||||
'zh-Hans-CN',
|
||||
'sr-Latn-CS',
|
||||
//Language-Variant
|
||||
'sl-rozaj',
|
||||
'sl-nedis',
|
||||
//Language-Region-Variant
|
||||
'de-CH-1901',
|
||||
'sl-IT-nedis',
|
||||
//Language-Script-Region-Variant
|
||||
'sl-Latn-IT-nedis',
|
||||
//Language-Region:
|
||||
'de-DE',
|
||||
'en-US',
|
||||
'es-419',
|
||||
//Private use subtags:
|
||||
'de-CH-x-phonebk',
|
||||
'az-Arab-x-AZE-derbend',
|
||||
//Extended language subtags
|
||||
'zh-min',
|
||||
'zh-min-nan-Hant-CN',
|
||||
//Private use registry values
|
||||
'x-whatever',
|
||||
'qaa-Qaaa-QM-x-southern',
|
||||
'sr-Latn-QM',
|
||||
'sr-Qaaa-CS',
|
||||
/*Tags that use extensions (examples ONLY: extensions MUST be defined
|
||||
by revision or update to this document or by RFC): */
|
||||
'en-US-u-islamCal',
|
||||
'zh-CN-a-myExt-x-private',
|
||||
'en-a-myExt-b-another',
|
||||
//Some Invalid Tags:
|
||||
'de-419-DE',
|
||||
'a-DE',
|
||||
'ar-a-aaa-b-bbb-a-ccc'
|
||||
);
|
||||
|
||||
|
||||
$res_str = '';
|
||||
|
||||
foreach( $locales as $locale )
|
||||
{
|
||||
$res_str .= "locale='$locale'\n";
|
||||
foreach( $disp_locales as $disp_locale )
|
||||
{
|
||||
$scr = ut_loc_get_display_name( $locale ,$disp_locale );
|
||||
$scr = str_replace(array('(', ')'), '#', $scr);
|
||||
$res_str .= "disp_locale=$disp_locale : display_name=$scr";
|
||||
$res_str .= "\n";
|
||||
}
|
||||
$res_str .= "-----------------\n";
|
||||
}
|
||||
|
||||
return $res_str;
|
||||
|
||||
}
|
||||
|
||||
include_once( 'ut_common.inc' );
|
||||
ut_run();
|
||||
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
locale='sl_IT_nedis_KIRTI'
|
||||
disp_locale=en : display_name=Slovenian #Italy, NEDIS_KIRTI#
|
||||
disp_locale=fr : display_name=slovène #Italie, NEDIS_KIRTI#
|
||||
disp_locale=de : display_name=Slowenisch #Italien, NEDIS_KIRTI#
|
||||
-----------------
|
||||
locale='sl_IT_nedis-a-kirti-x-xyz'
|
||||
disp_locale=en : display_name=Slovenian #Italy, NEDIS_A_KIRTI_X_XYZ#
|
||||
disp_locale=fr : display_name=slovène #Italie, NEDIS_A_KIRTI_X_XYZ#
|
||||
disp_locale=de : display_name=Slowenisch #Italien, NEDIS_A_KIRTI_X_XYZ#
|
||||
-----------------
|
||||
locale='sl_IT_rozaj'
|
||||
disp_locale=en : display_name=Slovenian #Italy, Resian#
|
||||
disp_locale=fr : display_name=slovène #Italie, dialecte de Resia#
|
||||
disp_locale=de : display_name=Slowenisch #Italien, (ROZAJ|Resianisch)#
|
||||
-----------------
|
||||
locale='sl_IT_NEDIS_ROJAZ_1901'
|
||||
disp_locale=en : display_name=Slovenian #Italy, NEDIS_ROJAZ_1901#
|
||||
disp_locale=fr : display_name=slovène #Italie, NEDIS_ROJAZ_1901#
|
||||
disp_locale=de : display_name=Slowenisch #Italien, NEDIS_ROJAZ_1901#
|
||||
-----------------
|
||||
locale='i-enochian'
|
||||
disp_locale=en : display_name=i-enochian #Private-Use=i-enochian#
|
||||
disp_locale=fr : display_name=i-enochian #Usage privé=i-enochian#
|
||||
disp_locale=de : display_name=i-enochian #Privatnutzung=i-enochian#
|
||||
-----------------
|
||||
locale='zh-hakka'
|
||||
disp_locale=en : display_name=Chinese( #HAKKA#)?
|
||||
disp_locale=fr : display_name=chinois( #HAKKA#)?
|
||||
disp_locale=de : display_name=Chinesisch( #HAKKA#)?
|
||||
-----------------
|
||||
locale='zh-wuu'
|
||||
disp_locale=en : display_name=Chinese #WUU#
|
||||
disp_locale=fr : display_name=chinois #WUU#
|
||||
disp_locale=de : display_name=Chinesisch #WUU#
|
||||
-----------------
|
||||
locale='i-tay'
|
||||
disp_locale=en : display_name=i-tay
|
||||
disp_locale=fr : display_name=i-tay
|
||||
disp_locale=de : display_name=i-tay
|
||||
-----------------
|
||||
locale='sgn-BE-nl'
|
||||
disp_locale=en : display_name=sgn #Belgium, NL#
|
||||
disp_locale=fr : display_name=sgn #Belgique, NL#
|
||||
disp_locale=de : display_name=sgn #Belgien, NL#
|
||||
-----------------
|
||||
locale='sgn-CH-de'
|
||||
disp_locale=en : display_name=sgn #Switzerland, DE#
|
||||
disp_locale=fr : display_name=sgn #Suisse, DE#
|
||||
disp_locale=de : display_name=sgn #Schweiz, DE#
|
||||
-----------------
|
||||
locale='sl_IT_rozaj@currency=EUR'
|
||||
disp_locale=en : display_name=Slovenian #Italy, Resian, [Cc]urrency=Euro#
|
||||
disp_locale=fr : display_name=slovène #Italie, dialecte de Resia, [Dd]evise=euro#
|
||||
disp_locale=de : display_name=Slowenisch #Italien, (ROZAJ|Resianisch), Währung=Euro#
|
||||
-----------------
|
||||
locale='uk-ua_CALIFORNIA@currency=;currency=GRN'
|
||||
disp_locale=en : display_name=
|
||||
disp_locale=fr : display_name=
|
||||
disp_locale=de : display_name=
|
||||
-----------------
|
||||
locale='root'
|
||||
disp_locale=en : display_name=Root
|
||||
disp_locale=fr : display_name=racine
|
||||
disp_locale=de : display_name=[Rr]oot
|
||||
-----------------
|
||||
locale='uk@currency=EURO'
|
||||
disp_locale=en : display_name=Ukrainian #[Cc]urrency=EURO#
|
||||
disp_locale=fr : display_name=ukrainien #[Dd]evise=EURO#
|
||||
disp_locale=de : display_name=Ukrainisch #Währung=EURO#
|
||||
-----------------
|
||||
locale='Hindi'
|
||||
disp_locale=en : display_name=hindi
|
||||
disp_locale=fr : display_name=hindi
|
||||
disp_locale=de : display_name=hindi
|
||||
-----------------
|
||||
locale='de'
|
||||
disp_locale=en : display_name=German
|
||||
disp_locale=fr : display_name=allemand
|
||||
disp_locale=de : display_name=Deutsch
|
||||
-----------------
|
||||
locale='fr'
|
||||
disp_locale=en : display_name=French
|
||||
disp_locale=fr : display_name=français
|
||||
disp_locale=de : display_name=Französisch
|
||||
-----------------
|
||||
locale='ja'
|
||||
disp_locale=en : display_name=Japanese
|
||||
disp_locale=fr : display_name=japonais
|
||||
disp_locale=de : display_name=Japanisch
|
||||
-----------------
|
||||
locale='i-enochian'
|
||||
disp_locale=en : display_name=i-enochian #Private-Use=i-enochian#
|
||||
disp_locale=fr : display_name=i-enochian #Usage privé=i-enochian#
|
||||
disp_locale=de : display_name=i-enochian #Privatnutzung=i-enochian#
|
||||
-----------------
|
||||
locale='zh-Hant'
|
||||
disp_locale=en : display_name=Chinese #Traditional#
|
||||
disp_locale=fr : display_name=chinois #traditionnel#
|
||||
disp_locale=de : display_name=Chinesisch #Traditionell#
|
||||
-----------------
|
||||
locale='zh-Hans'
|
||||
disp_locale=en : display_name=Chinese #Simplified#
|
||||
disp_locale=fr : display_name=chinois #simplifié#
|
||||
disp_locale=de : display_name=Chinesisch #Vereinfacht#
|
||||
-----------------
|
||||
locale='sr-Cyrl'
|
||||
disp_locale=en : display_name=Serbian #Cyrillic#
|
||||
disp_locale=fr : display_name=serbe #cyrillique#
|
||||
disp_locale=de : display_name=Serbisch #Kyrillisch#
|
||||
-----------------
|
||||
locale='sr-Latn'
|
||||
disp_locale=en : display_name=Serbian #Latin#
|
||||
disp_locale=fr : display_name=serbe #latin#
|
||||
disp_locale=de : display_name=Serbisch #Lateinisch#
|
||||
-----------------
|
||||
locale='zh-Hans-CN'
|
||||
disp_locale=en : display_name=Chinese #Simplified, China#
|
||||
disp_locale=fr : display_name=chinois #simplifié, Chine#
|
||||
disp_locale=de : display_name=Chinesisch #Vereinfacht, China#
|
||||
-----------------
|
||||
locale='sr-Latn-CS'
|
||||
disp_locale=en : display_name=Serbian #Latin, Serbia#
|
||||
disp_locale=fr : display_name=serbe #latin, Serbie#
|
||||
disp_locale=de : display_name=Serbisch #Lateinisch, Serbien#
|
||||
-----------------
|
||||
locale='sl-rozaj'
|
||||
disp_locale=en : display_name=Slovenian #Resian#
|
||||
disp_locale=fr : display_name=slovène #dialecte de Resia#
|
||||
disp_locale=de : display_name=Slowenisch( #(ROZAJ|Resianisch)#)?
|
||||
-----------------
|
||||
locale='sl-nedis'
|
||||
disp_locale=en : display_name=Slovenian #Natisone dialect#
|
||||
disp_locale=fr : display_name=slovène #dialecte de Natisone#
|
||||
disp_locale=de : display_name=Slowenisch #Natisone-Dialekt#
|
||||
-----------------
|
||||
locale='de-CH-1901'
|
||||
disp_locale=en : display_name=German #Switzerland, Traditional German orthography#
|
||||
disp_locale=fr : display_name=allemand #Suisse, orthographe allemande traditionnelle#
|
||||
disp_locale=de : display_name=Deutsch #Schweiz, (1901|[aA]lte deutsche Rechtschreibung)#
|
||||
-----------------
|
||||
locale='sl-IT-nedis'
|
||||
disp_locale=en : display_name=Slovenian #Italy, Natisone dialect#
|
||||
disp_locale=fr : display_name=slovène #Italie, dialecte de Natisone#
|
||||
disp_locale=de : display_name=Slowenisch #Italien, (NEDIS|Natisone-Dialekt)#
|
||||
-----------------
|
||||
locale='sl-Latn-IT-nedis'
|
||||
disp_locale=en : display_name=Slovenian #Latin, Italy, Natisone dialect#
|
||||
disp_locale=fr : display_name=slovène #latin, Italie, dialecte de Natisone#
|
||||
disp_locale=de : display_name=Slowenisch #Lateinisch, Italien, (NEDIS|Natisone-Dialekt)#
|
||||
-----------------
|
||||
locale='de-DE'
|
||||
disp_locale=en : display_name=German #Germany#
|
||||
disp_locale=fr : display_name=allemand #Allemagne#
|
||||
disp_locale=de : display_name=Deutsch #Deutschland#
|
||||
-----------------
|
||||
locale='en-US'
|
||||
disp_locale=en : display_name=English #United States#
|
||||
disp_locale=fr : display_name=anglais #États-Unis#
|
||||
disp_locale=de : display_name=Englisch #Vereinigte Staaten#
|
||||
-----------------
|
||||
locale='es-419'
|
||||
disp_locale=en : display_name=Spanish #Latin America#
|
||||
disp_locale=fr : display_name=espagnol #Amérique latine#
|
||||
disp_locale=de : display_name=Spanisch #Lateinamerika#
|
||||
-----------------
|
||||
locale='de-CH-x-phonebk'
|
||||
disp_locale=en : display_name=German #Switzerland, Private-Use=phonebk#
|
||||
disp_locale=fr : display_name=allemand #Suisse, Usage privé=phonebk#
|
||||
disp_locale=de : display_name=Deutsch #Schweiz, Privatnutzung=phonebk#
|
||||
-----------------
|
||||
locale='az-Arab-x-AZE-derbend'
|
||||
disp_locale=en : display_name=Azerbaijani #Arabic, Private-Use=aze-derbend#
|
||||
disp_locale=fr : display_name=azéri #arabe, Usage privé=aze-derbend#
|
||||
disp_locale=de : display_name=Aserbaidschanisch #Arabisch, Privatnutzung=aze-derbend#
|
||||
-----------------
|
||||
locale='zh-min'
|
||||
disp_locale=en : display_name=Chinese #MIN#
|
||||
disp_locale=fr : display_name=chinois #MIN#
|
||||
disp_locale=de : display_name=Chinesisch #MIN#
|
||||
-----------------
|
||||
locale='zh-min-nan-Hant-CN'
|
||||
disp_locale=en : display_name=Chinese #MIN, NAN_HANT_CN#
|
||||
disp_locale=fr : display_name=chinois #MIN, NAN_HANT_CN#
|
||||
disp_locale=de : display_name=Chinesisch #MIN, NAN_HANT_CN#
|
||||
-----------------
|
||||
locale='x-whatever'
|
||||
disp_locale=en : display_name=x-whatever #Private-Use=whatever#
|
||||
disp_locale=fr : display_name=x-whatever #Usage privé=whatever#
|
||||
disp_locale=de : display_name=x-whatever #Privatnutzung=whatever#
|
||||
-----------------
|
||||
locale='qaa-Qaaa-QM-x-southern'
|
||||
disp_locale=en : display_name=qaa #Qaaa, QM, Private-Use=southern#
|
||||
disp_locale=fr : display_name=qaa #Qaaa, QM, Usage privé=southern#
|
||||
disp_locale=de : display_name=qaa #Qaaa, QM, Privatnutzung=southern#
|
||||
-----------------
|
||||
locale='sr-Latn-QM'
|
||||
disp_locale=en : display_name=Serbian #Latin, QM#
|
||||
disp_locale=fr : display_name=serbe #latin, QM#
|
||||
disp_locale=de : display_name=Serbisch #Lateinisch, QM#
|
||||
-----------------
|
||||
locale='sr-Qaaa-CS'
|
||||
disp_locale=en : display_name=Serbian #Qaaa, Serbia#
|
||||
disp_locale=fr : display_name=serbe #Qaaa, Serbie#
|
||||
disp_locale=de : display_name=Serbisch #Qaaa, Serbien#
|
||||
-----------------
|
||||
locale='en-US-u-islamCal'
|
||||
disp_locale=en : display_name=English #United States, attribute=islamcal#
|
||||
disp_locale=fr : display_name=anglais #États-Unis, attribute=islamcal#
|
||||
disp_locale=de : display_name=Englisch #Vereinigte Staaten, attribute=islamcal#
|
||||
-----------------
|
||||
locale='zh-CN-a-myExt-x-private'
|
||||
disp_locale=en : display_name=Chinese #China, a=myext, Private-Use=private#
|
||||
disp_locale=fr : display_name=chinois #Chine, a=myext, Usage privé=private#
|
||||
disp_locale=de : display_name=Chinesisch #China, a=myext, Privatnutzung=private#
|
||||
-----------------
|
||||
locale='en-a-myExt-b-another'
|
||||
disp_locale=en : display_name=English #a=myext, b=another#
|
||||
disp_locale=fr : display_name=anglais #a=myext, b=another#
|
||||
disp_locale=de : display_name=Englisch #a=myext, b=another#
|
||||
-----------------
|
||||
locale='de-419-DE'
|
||||
disp_locale=en : display_name=German #Latin America, DE#
|
||||
disp_locale=fr : display_name=allemand #Amérique latine, DE#
|
||||
disp_locale=de : display_name=Deutsch #Lateinamerika, DE#
|
||||
-----------------
|
||||
locale='a-DE'
|
||||
disp_locale=en : display_name=a #Germany#
|
||||
disp_locale=fr : display_name=a #Allemagne#
|
||||
disp_locale=de : display_name=a #Deutschland#
|
||||
-----------------
|
||||
locale='ar-a-aaa-b-bbb-a-ccc'
|
||||
disp_locale=en : display_name=Arabic #a=aaa, b=bbb#
|
||||
disp_locale=fr : display_name=arabe #a=aaa, b=bbb#
|
||||
disp_locale=de : display_name=Arabisch #a=aaa, b=bbb#
|
||||
-----------------
|
||||
@@ -1,9 +1,8 @@
|
||||
--TEST--
|
||||
IntlTimeZone::getCanonicalID(): second argument
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('intl'))
|
||||
die('skip intl extension not enabled');
|
||||
<?php if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') >= 0) die('skip for ICU < 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set("intl.error_level", E_WARNING);
|
||||
@@ -21,4 +20,4 @@ string(13) "Europe/Lisbon"
|
||||
bool(true)
|
||||
string(0) ""
|
||||
bool(false)
|
||||
==DONE==
|
||||
==DONE==
|
||||
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
IntlTimeZone::getCanonicalID(): second argument
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
|
||||
<?php if (version_compare(INTL_ICU_VERSION, '53.1') < 0) die('skip for ICU >= 53.1'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set("intl.error_level", E_WARNING);
|
||||
|
||||
var_dump(IntlTimeZone::getCanonicalID('Portugal', $isSystemId));
|
||||
var_dump($isSystemId);
|
||||
|
||||
/* A valid custom time zone ID has the following syntax: GMT[+|-]hh[[:]mm] */
|
||||
var_dump(IntlTimeZone::getCanonicalID('GMT +01:25', $isSystemId));
|
||||
var_dump($isSystemId);
|
||||
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECTF--
|
||||
string(13) "Europe/Lisbon"
|
||||
bool(true)
|
||||
|
||||
Warning: IntlTimeZone::getCanonicalID(): intltz_get_canonical_id: error obtaining canonical ID in %stimezone_getCanonicalID_variant1_2.php on line %d
|
||||
bool(false)
|
||||
bool(true)
|
||||
==DONE==
|
||||
+10
-8
@@ -230,7 +230,7 @@ static inline void json_pretty_print_indent(smart_str *buf, php_int_t options TS
|
||||
|
||||
static void json_encode_array(smart_str *buf, zval **val, php_int_t options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
int i, r;
|
||||
int i, r, need_comma = 0;
|
||||
HashTable *myht;
|
||||
|
||||
if (Z_TYPE_PP(val) == IS_ARRAY) {
|
||||
@@ -253,7 +253,6 @@ static void json_encode_array(smart_str *buf, zval **val, php_int_t options TSRM
|
||||
smart_str_appendc(buf, '{');
|
||||
}
|
||||
|
||||
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
|
||||
++JSON_G(encoder_depth);
|
||||
|
||||
i = myht ? zend_hash_num_elements(myht) : 0;
|
||||
@@ -266,7 +265,6 @@ static void json_encode_array(smart_str *buf, zval **val, php_int_t options TSRM
|
||||
php_size_t key_len;
|
||||
HashPosition pos;
|
||||
HashTable *tmp_ht;
|
||||
int need_comma = 0;
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(myht, &pos);
|
||||
for (;; zend_hash_move_forward_ex(myht, &pos)) {
|
||||
@@ -283,11 +281,11 @@ static void json_encode_array(smart_str *buf, zval **val, php_int_t options TSRM
|
||||
if (r == PHP_JSON_OUTPUT_ARRAY) {
|
||||
if (need_comma) {
|
||||
smart_str_appendc(buf, ',');
|
||||
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
|
||||
} else {
|
||||
need_comma = 1;
|
||||
}
|
||||
|
||||
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
|
||||
json_pretty_print_indent(buf, options TSRMLS_CC);
|
||||
php_json_encode(buf, *data, options TSRMLS_CC);
|
||||
} else if (r == PHP_JSON_OUTPUT_OBJECT) {
|
||||
@@ -302,11 +300,11 @@ static void json_encode_array(smart_str *buf, zval **val, php_int_t options TSRM
|
||||
|
||||
if (need_comma) {
|
||||
smart_str_appendc(buf, ',');
|
||||
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
|
||||
} else {
|
||||
need_comma = 1;
|
||||
}
|
||||
|
||||
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
|
||||
json_pretty_print_indent(buf, options TSRMLS_CC);
|
||||
|
||||
json_escape_string(buf, key, key_len - 1, options & ~PHP_JSON_NUMERIC_CHECK TSRMLS_CC);
|
||||
@@ -318,11 +316,11 @@ static void json_encode_array(smart_str *buf, zval **val, php_int_t options TSRM
|
||||
} else {
|
||||
if (need_comma) {
|
||||
smart_str_appendc(buf, ',');
|
||||
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
|
||||
} else {
|
||||
need_comma = 1;
|
||||
}
|
||||
|
||||
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
|
||||
json_pretty_print_indent(buf, options TSRMLS_CC);
|
||||
|
||||
smart_str_appendc(buf, '"');
|
||||
@@ -347,8 +345,12 @@ static void json_encode_array(smart_str *buf, zval **val, php_int_t options TSRM
|
||||
JSON_G(error_code) = PHP_JSON_ERROR_DEPTH;
|
||||
}
|
||||
--JSON_G(encoder_depth);
|
||||
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
|
||||
json_pretty_print_indent(buf, options TSRMLS_CC);
|
||||
|
||||
/* Only keep closing bracket on same line for empty arrays/objects */
|
||||
if (need_comma) {
|
||||
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
|
||||
json_pretty_print_indent(buf, options TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (r == PHP_JSON_OUTPUT_ARRAY) {
|
||||
smart_str_appendc(buf, ']');
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Bug #66021 (Blank line inside empty array/object when JSON_PRETTY_PRINT is set)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("json")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
private $bar = 'baz';
|
||||
}
|
||||
|
||||
echo json_encode([[], (object)[], new Foo], JSON_PRETTY_PRINT), "\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
[
|
||||
[],
|
||||
{},
|
||||
{}
|
||||
]
|
||||
@@ -878,7 +878,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
#ifndef MYSQL_USE_MYSQLND
|
||||
mysql->conn = mysql_init(NULL);
|
||||
#else
|
||||
mysql->conn = mysql_init(persistent);
|
||||
mysql->conn = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent);
|
||||
#endif
|
||||
|
||||
if (connect_timeout != -1) {
|
||||
@@ -887,7 +887,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
#ifndef MYSQL_USE_MYSQLND
|
||||
if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
|
||||
#else
|
||||
if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
|
||||
if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
|
||||
#endif
|
||||
{
|
||||
/* Populate connect error globals so that the error functions can read them */
|
||||
@@ -935,7 +935,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
#ifndef MYSQL_USE_MYSQLND
|
||||
if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
|
||||
#else
|
||||
if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
|
||||
if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
|
||||
#endif
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect");
|
||||
@@ -997,7 +997,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
#ifndef MYSQL_USE_MYSQLND
|
||||
mysql->conn = mysql_init(NULL);
|
||||
#else
|
||||
mysql->conn = mysql_init(persistent);
|
||||
mysql->conn = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent);
|
||||
#endif
|
||||
if (!mysql->conn) {
|
||||
MySG(connect_error) = estrdup("OOM");
|
||||
@@ -1014,7 +1014,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
#ifndef MYSQL_USE_MYSQLND
|
||||
if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
|
||||
#else
|
||||
if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags TSRMLS_CC) == NULL)
|
||||
if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
|
||||
#endif
|
||||
{
|
||||
/* Populate connect error globals so that the error functions can read them */
|
||||
|
||||
@@ -721,6 +721,7 @@ PHP_MINIT_FUNCTION(mysqli)
|
||||
REGISTER_INT_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT);
|
||||
#if defined (MYSQLI_USE_MYSQLND)
|
||||
REGISTER_INT_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_INT_CONSTANT("MYSQLI_STORE_RESULT_COPY_DATA", MYSQLI_STORE_RESULT_COPY_DATA, CONST_CS | CONST_PERSISTENT);
|
||||
#endif
|
||||
|
||||
/* for mysqli_fetch_assoc */
|
||||
|
||||
+11
-5
@@ -1525,7 +1525,7 @@ void php_mysqli_init(INTERNAL_FUNCTION_PARAMETERS)
|
||||
We create always persistent, as if the user want to connecto
|
||||
to p:somehost, we can't convert the handle then
|
||||
*/
|
||||
if (!(mysql->mysql = mysql_init(TRUE)))
|
||||
if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, TRUE)))
|
||||
#endif
|
||||
{
|
||||
efree(mysql);
|
||||
@@ -2617,7 +2617,7 @@ PHP_FUNCTION(mysqli_stmt_sqlstate)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto object mysqli_store_result(object link)
|
||||
/* {{{ proto object mysqli_store_result(object link [, flags])
|
||||
Buffer result set on client */
|
||||
PHP_FUNCTION(mysqli_store_result)
|
||||
{
|
||||
@@ -2625,13 +2625,19 @@ PHP_FUNCTION(mysqli_store_result)
|
||||
MYSQL_RES *result;
|
||||
zval *mysql_link;
|
||||
MYSQLI_RESOURCE *mysqli_resource;
|
||||
long flags = 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|l", &mysql_link, mysqli_link_class_entry, &flags) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
|
||||
|
||||
if (!(result = mysql_store_result(mysql->mysql))) {
|
||||
#if MYSQLI_USE_MYSQLND
|
||||
result = flags & MYSQLI_STORE_RESULT_COPY_DATA? mysqlnd_store_result_ofs(mysql->mysql) : mysqlnd_store_result(mysql->mysql);
|
||||
#else
|
||||
result = mysql_store_result(mysql->mysql);
|
||||
#endif
|
||||
if (!result) {
|
||||
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
+13
-2
@@ -142,6 +142,17 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_rollback, 0, 0, 0)
|
||||
ZEND_ARG_INFO(0, name)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_store_result, 0, 0, 1)
|
||||
MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
|
||||
ZEND_ARG_INFO(0, flags)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_store_result, 0, 0, 0)
|
||||
ZEND_ARG_INFO(0, flags)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_change_user, 0, 0, 4)
|
||||
MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
|
||||
ZEND_ARG_INFO(0, user)
|
||||
@@ -498,7 +509,7 @@ const zend_function_entry mysqli_functions[] = {
|
||||
PHP_FE(mysqli_sqlstate, arginfo_mysqli_only_link)
|
||||
PHP_FE(mysqli_ssl_set, arginfo_mysqli_ssl_set)
|
||||
PHP_FE(mysqli_stat, arginfo_mysqli_only_link)
|
||||
PHP_FE(mysqli_store_result, arginfo_mysqli_only_link)
|
||||
PHP_FE(mysqli_store_result, arginfo_mysqli_store_result)
|
||||
PHP_FE(mysqli_thread_id, arginfo_mysqli_only_link)
|
||||
PHP_FE(mysqli_thread_safe, arginfo_mysqli_no_params)
|
||||
PHP_FE(mysqli_use_result, arginfo_mysqli_only_link)
|
||||
@@ -568,7 +579,7 @@ const zend_function_entry mysqli_link_methods[] = {
|
||||
PHP_FALIAS(ssl_set, mysqli_ssl_set, arginfo_class_mysqli_ssl_set)
|
||||
PHP_FALIAS(stat, mysqli_stat, arginfo_mysqli_no_params)
|
||||
PHP_FALIAS(stmt_init, mysqli_stmt_init, arginfo_mysqli_no_params)
|
||||
PHP_FALIAS(store_result, mysqli_store_result, arginfo_mysqli_no_params)
|
||||
PHP_FALIAS(store_result, mysqli_store_result, arginfo_class_store_result)
|
||||
PHP_FALIAS(thread_safe, mysqli_thread_safe, arginfo_mysqli_no_params)
|
||||
PHP_FALIAS(use_result, mysqli_use_result, arginfo_mysqli_no_params)
|
||||
PHP_FALIAS(refresh,mysqli_refresh, arginfo_class_mysqli_refresh)
|
||||
|
||||
@@ -217,7 +217,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne
|
||||
#if !defined(MYSQLI_USE_MYSQLND)
|
||||
if (!(mysql->mysql = mysql_init(NULL))) {
|
||||
#else
|
||||
if (!(mysql->mysql = mysqlnd_init(persistent))) {
|
||||
if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent))) {
|
||||
#endif
|
||||
goto err;
|
||||
}
|
||||
@@ -240,7 +240,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne
|
||||
if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname, port, socket, flags) == NULL)
|
||||
#else
|
||||
if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
|
||||
port, socket, flags TSRMLS_CC) == NULL)
|
||||
port, socket, flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
|
||||
#endif
|
||||
{
|
||||
/* Save error messages - for mysqli_connect_error() & mysqli_connect_errno() */
|
||||
@@ -575,7 +575,7 @@ PHP_FUNCTION(mysqli_query)
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty query");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) {
|
||||
if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) != MYSQLI_STORE_RESULT) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -609,9 +609,14 @@ PHP_FUNCTION(mysqli_query)
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
switch (resultmode) {
|
||||
switch (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) {
|
||||
case MYSQLI_STORE_RESULT:
|
||||
result = mysql_store_result(mysql->mysql);
|
||||
#ifdef MYSQLI_USE_MYSQLND
|
||||
if (resultmode & MYSQLI_STORE_RESULT_COPY_DATA) {
|
||||
result = mysqlnd_store_result_ofs(mysql->mysql);
|
||||
} else
|
||||
#endif
|
||||
result = mysql_store_result(mysql->mysql);
|
||||
break;
|
||||
case MYSQLI_USE_RESULT:
|
||||
result = mysql_use_result(mysql->mysql);
|
||||
|
||||
@@ -114,9 +114,11 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRML
|
||||
#define MYSQLI_USE_RESULT 1
|
||||
#ifdef MYSQLI_USE_MYSQLND
|
||||
#define MYSQLI_ASYNC 8
|
||||
#define MYSQLI_STORE_RESULT_COPY_DATA 16
|
||||
#else
|
||||
/* libmysql */
|
||||
#define MYSQLI_ASYNC 0
|
||||
#define MYSQLI_STORE_RESULT_OFS 0
|
||||
#endif
|
||||
|
||||
/* for mysqli_fetch_assoc */
|
||||
|
||||
@@ -12,7 +12,9 @@ require_once('skipifconnectfailure.inc');
|
||||
--FILE--
|
||||
<?php
|
||||
require 'connect.inc';
|
||||
$db = new mysqli($host, $user, $passwd, 'mysql');
|
||||
if (!$db = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
|
||||
}
|
||||
|
||||
$stmt = $db->stmt_init();
|
||||
$stmt->prepare("SELECT User FROM user WHERE password=\"\"");
|
||||
|
||||
@@ -9,7 +9,9 @@ require_once('skipifconnectfailure.inc');
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
|
||||
$mysqli = new mysqli($host, $user, $passwd, $db);
|
||||
if (!$mysqli = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
|
||||
}
|
||||
|
||||
$read_stmt = $mysqli->prepare("SELECT 1");
|
||||
|
||||
@@ -17,7 +19,6 @@ require_once('skipifconnectfailure.inc');
|
||||
|
||||
unset($mysqli);
|
||||
var_dump($read_stmt->bind_result($data));
|
||||
|
||||
?>
|
||||
done!
|
||||
--EXPECT--
|
||||
|
||||
@@ -32,65 +32,73 @@ require_once('skipifconnectfailure.inc');
|
||||
printf("[006] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
|
||||
if (false !== ($tmp = mysqli_change_user($link, $user . '_unknown_really', $passwd . 'non_empty', $db)))
|
||||
if (false !== ($tmp = @mysqli_change_user($link, $user . '_unknown_really', $passwd . 'non_empty', $db)))
|
||||
printf("[007] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (false !== ($tmp = mysqli_change_user($link, $user, $passwd . '_unknown_really', $db)))
|
||||
printf("[008] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
printf("[008] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
|
||||
if (false !== ($tmp = mysqli_change_user($link, $user, $passwd, $db . '_unknown_really')))
|
||||
if (false !== ($tmp = @mysqli_change_user($link, $user, $passwd . '_unknown_really', $db)))
|
||||
printf("[009] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!mysqli_query($link, 'SET @mysqli_change_user_test_var=1'))
|
||||
printf("[010] Failed to set test variable: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
printf("[010] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT @mysqli_change_user_test_var AS test_var'))
|
||||
printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
mysqli_free_result($res);
|
||||
if (1 != $tmp['test_var'])
|
||||
printf("[012] Cannot set test variable\n");
|
||||
|
||||
if (true !== ($tmp = mysqli_change_user($link, $user, $passwd, $db)))
|
||||
printf("[013] Expecting true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT database() AS dbname, user() AS user'))
|
||||
printf("[014] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
mysqli_free_result($res);
|
||||
|
||||
if (substr($tmp['user'], 0, strlen($user)) !== $user)
|
||||
printf("[015] Expecting user %s, got user() %s\n", $user, $tmp['user']);
|
||||
if ($tmp['dbname'] != $db)
|
||||
printf("[016] Expecting database %s, got database() %s\n", $db, $tmp['dbname']);
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT @mysqli_change_user_test_var AS test_var'))
|
||||
printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
mysqli_free_result($res);
|
||||
if (NULL !== $tmp['test_var'])
|
||||
printf("[019] Test variable is still set!\n");
|
||||
if (false !== ($tmp = @mysqli_change_user($link, $user, $passwd, $db . '_unknown_really')))
|
||||
printf("[011] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
mysqli_close($link);
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[020] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
printf("[012] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
}
|
||||
|
||||
if (false !== ($tmp = mysqli_change_user($link, str_repeat('user', 16384), str_repeat('pass', 16384), str_repeat('dbase', 16384))))
|
||||
printf("[021] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
if (false !== ($tmp = @mysqli_change_user($link, str_repeat('user', 16384), str_repeat('pass', 16384), str_repeat('dbase', 16384))))
|
||||
printf("[013] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
mysqli_close($link);
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[022] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
printf("[014] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
}
|
||||
|
||||
/* silent protocol change if no db which requires workaround in mysqlnd/libmysql
|
||||
(empty db = no db send with COM_CHANGE_USER) */
|
||||
if (true !== ($tmp = mysqli_change_user($link, $user, $passwd, "")))
|
||||
printf("[015] Expecting true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT database() AS dbname, user() AS user'))
|
||||
printf("[016] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
mysqli_free_result($res);
|
||||
|
||||
if ($tmp['dbname'] != "")
|
||||
printf("[017] Expecting database '', got database() '%s'\n", $tmp['dbname']);
|
||||
|
||||
mysqli_close($link);
|
||||
|
||||
if (NULL !== ($tmp = @mysqli_change_user($link, $user, $passwd, $db)))
|
||||
printf("[018] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
printf("[019] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
|
||||
if (!mysqli_query($link, 'SET @mysqli_change_user_test_var=1'))
|
||||
printf("[020] Failed to set test variable: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT @mysqli_change_user_test_var AS test_var'))
|
||||
printf("[021] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
mysqli_free_result($res);
|
||||
if (1 != $tmp['test_var'])
|
||||
printf("[022] Cannot set test variable\n");
|
||||
|
||||
if (true !== ($tmp = mysqli_change_user($link, $user, $passwd, $db)))
|
||||
printf("[023] Expecting true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT database() AS dbname, user() AS user'))
|
||||
@@ -98,13 +106,17 @@ require_once('skipifconnectfailure.inc');
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
mysqli_free_result($res);
|
||||
|
||||
if ($tmp['dbname'] != "")
|
||||
printf("[025] Expecting database '', got database() '%s'\n", $tmp['dbname']);
|
||||
if (substr($tmp['user'], 0, strlen($user)) !== $user)
|
||||
printf("[025] Expecting user %s, got user() %s\n", $user, $tmp['user']);
|
||||
if ($tmp['dbname'] != $db)
|
||||
printf("[026] Expecting database %s, got database() %s\n", $db, $tmp['dbname']);
|
||||
|
||||
mysqli_close($link);
|
||||
|
||||
if (NULL !== ($tmp = @mysqli_change_user($link, $user, $passwd, $db)))
|
||||
printf("[026] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
if (!$res = mysqli_query($link, 'SELECT @mysqli_change_user_test_var AS test_var'))
|
||||
printf("[027] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
mysqli_free_result($res);
|
||||
if (NULL !== $tmp['test_var'])
|
||||
printf("[028] Test variable is still set!\n");
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
mysqli_change_user(), MySQL 5.6+
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
die(sprintf("SKIP Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket));
|
||||
|
||||
if (mysqli_get_server_version($link) < 50600)
|
||||
die("SKIP For MySQL >= 5.6.0");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
|
||||
$tmp = NULL;
|
||||
$link = NULL;
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
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);
|
||||
|
||||
/* Pre 5.6: link remains useable */
|
||||
if (false !== ($tmp = @mysqli_change_user($link, $user . '_unknown_really', $passwd . 'non_empty', $db)))
|
||||
printf("[002] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT 1 AS _one'))
|
||||
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
var_dump($res->fetch_assoc());
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: mysqli_query(): MySQL server has gone away in %s on line %d
|
||||
|
||||
Warning: mysqli_query(): Error reading result set's header in %s on line %d
|
||||
[003] [2006] MySQL server has gone away
|
||||
|
||||
Fatal error: Call to a member function fetch_assoc() on a non-object in %s on line %d
|
||||
@@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
mysqli_change_user(), MySQL < 5.6
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
die(sprintf("SKIP Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket));
|
||||
|
||||
if (mysqli_get_server_version($link) >= 50600)
|
||||
die("SKIP For MySQL < 5.6.0");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
|
||||
$tmp = NULL;
|
||||
$link = NULL;
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
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);
|
||||
|
||||
/* Pre 5.6: link remains useable */
|
||||
if (false !== ($tmp = mysqli_change_user($link, $user . '_unknown_really', $passwd . 'non_empty', $db)))
|
||||
printf("[011] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$res = mysqli_query($link, 'SELECT 1 AS _one'))
|
||||
printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
var_dump($res->fetch_assoc());
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
done!
|
||||
@@ -10,6 +10,9 @@ require_once('table.inc');
|
||||
if (!$IS_MYSQLND && (mysqli_get_server_version($link) < 50118 && mysqli_get_server_version($link) > 50100)) {
|
||||
die("skip Your MySQL Server version has a known bug that will cause a crash");
|
||||
}
|
||||
|
||||
if (mysqli_get_server_version($link) >= 50600)
|
||||
die("SKIP For MySQL < 5.6.0");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@@ -1140,9 +1140,16 @@ isInternal: yes
|
||||
isUserDefined: no
|
||||
returnsReference: no
|
||||
Modifiers: 256
|
||||
Number of Parameters: 0
|
||||
Number of Parameters: 1
|
||||
Number of Required Parameters: 0
|
||||
|
||||
Inspecting parameter 'flags' of method 'store_result'
|
||||
isArray: no
|
||||
allowsNull: no
|
||||
isPassedByReference: no
|
||||
isOptional: yes
|
||||
isDefaultValueAvailable: no
|
||||
|
||||
Inspecting method 'thread_safe'
|
||||
isFinal: no
|
||||
isAbstract: no
|
||||
|
||||
@@ -108,6 +108,10 @@ require_once('skipifconnectfailure.inc');
|
||||
$expected_constants['MYSQLI_OPT_INT_AND_FLOAT_NATIVE'] = true;
|
||||
}
|
||||
|
||||
if ($IS_MYSQLND && defined('MYSQLI_STORE_RESULT_COPY_DATA')) {
|
||||
$expected_constants['MYSQLI_STORE_RESULT_COPY_DATA'] = true;
|
||||
}
|
||||
|
||||
if ($IS_MYSQLND || defined('MYSQLI_REFRESH_BACKUP_LOG')) {
|
||||
$expected_constants['MYSQLI_REFRESH_BACKUP_LOG'] = true;
|
||||
}
|
||||
|
||||
@@ -299,6 +299,26 @@ if (!function_exists('mysqli_fetch_all'))
|
||||
if (null !== ($tmp = mysqli_fetch_array($res, MYSQLI_ASSOC)))
|
||||
printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[016] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
}
|
||||
|
||||
if (!$res = mysqli_real_query($link, "SELECT 1 AS _one"))
|
||||
printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
/* on mysqlnd level this would not be allowed */
|
||||
if (!is_object($res = mysqli_use_result($link)))
|
||||
printf("[018] Expecting object, got %s/%s. [%d] %s\n",
|
||||
gettype($res), $res, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
$rows = mysqli_fetch_all($res, MYSQLI_ASSOC);
|
||||
if (!is_array($rows) || (count($rows) > 1) || !isset($rows[0]['_one']) || ($rows[0]['_one'] != 1)) {
|
||||
printf("[019] Results seem wrong, dumping\n");
|
||||
var_dump($rows);
|
||||
}
|
||||
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--CLEAN--
|
||||
|
||||
@@ -10,8 +10,10 @@ require_once('skipifconnectfailure.inc');
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
|
||||
if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket))
|
||||
printf("[001] Cannot connect\n");
|
||||
if (!$mysqli = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
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_fetch_lengths()))
|
||||
printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
@@ -52,6 +52,13 @@ if (!$IS_MYSQLND)
|
||||
if (0 !== ($tmp = (mysqli_poll($read, $error, $reject, 0, 1))))
|
||||
printf("[009] Expecting int/0 got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
||||
|
||||
$read = $error = $reject = array($link);
|
||||
if (false !== ($tmp = (mysqli_poll($read, $error, $reject, -1, 1))))
|
||||
printf("[010] Expecting false got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
||||
|
||||
$read = $error = $reject = array($link);
|
||||
if (false !== ($tmp = (mysqli_poll($read, $error, $reject, 0, -1))))
|
||||
printf("[011] Expecting false got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
||||
|
||||
function poll_async($offset, $link, $links, $errors, $reject, $exp_ready, $use_oo_syntax) {
|
||||
|
||||
@@ -90,14 +97,14 @@ if (!$IS_MYSQLND)
|
||||
$links = array($link);
|
||||
$errors = array($link);
|
||||
$reject = array($link);
|
||||
poll_async(10, $link, $links, $errors, $reject, 0, false);
|
||||
poll_async(12, $link, $links, $errors, $reject, 0, false);
|
||||
mysqli_close($link);
|
||||
|
||||
$link = get_connection();
|
||||
$links = array($link);
|
||||
$errors = array($link);
|
||||
$reject = array($link);
|
||||
poll_async(11, $link, $links, $errors, $reject, 0, true);
|
||||
poll_async(13, $link, $links, $errors, $reject, 0, true);
|
||||
mysqli_close($link);
|
||||
|
||||
// Connections on which no query has been send - 2
|
||||
@@ -106,7 +113,7 @@ if (!$IS_MYSQLND)
|
||||
$links = array($link, $link);
|
||||
$errors = array($link, $link);
|
||||
$reject = array();
|
||||
poll_async(12, $link, $links, $errors, $reject, 0, false);
|
||||
poll_async(14, $link, $links, $errors, $reject, 0, false);
|
||||
|
||||
// Connections on which no query has been send - 3
|
||||
// Difference: pass two connections
|
||||
@@ -114,7 +121,7 @@ if (!$IS_MYSQLND)
|
||||
$links = array($link, get_connection());
|
||||
$errors = array($link, $link);
|
||||
$reject = array();
|
||||
poll_async(13, $link, $links, $errors, $reject, 0, false);
|
||||
poll_async(15, $link, $links, $errors, $reject, 0, false);
|
||||
|
||||
// Reference mess...
|
||||
$link = get_connection();
|
||||
@@ -122,16 +129,20 @@ if (!$IS_MYSQLND)
|
||||
$errors = array($link);
|
||||
$ref_errors =& $errors;
|
||||
$reject = array();
|
||||
poll_async(14, $link, $links, $ref_errors, $reject, 0, false);
|
||||
poll_async(16, $link, $links, $ref_errors, $reject, 0, false);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
[010 + 6] Rejecting thread %d: 0/
|
||||
[011 + 6] Rejecting thread %d: 0/
|
||||
|
||||
Warning: mysqli_poll(): Negative values passed for sec and/or usec in %s on line %d
|
||||
|
||||
Warning: mysqli_poll(): Negative values passed for sec and/or usec in %s on line %d
|
||||
[012 + 6] Rejecting thread %d: 0/
|
||||
[012 + 6] Rejecting thread %d: 0/
|
||||
[013 + 6] Rejecting thread %d: 0/
|
||||
[013 + 6] Rejecting thread %d: 0/
|
||||
[014 + 6] Rejecting thread %d: 0/
|
||||
done!
|
||||
[014 + 6] Rejecting thread %d: 0/
|
||||
[015 + 6] Rejecting thread %d: 0/
|
||||
[015 + 6] Rejecting thread %d: 0/
|
||||
[016 + 6] Rejecting thread %d: 0/
|
||||
done!
|
||||
@@ -90,6 +90,7 @@ if (!$IS_MYSQLND)
|
||||
|
||||
// Yes, 1 - fetch OK packet of kill!
|
||||
$processed = 0;
|
||||
$begin = microtime(true);
|
||||
do {
|
||||
$links = array($link, $link);
|
||||
$errors = array($link, $link);
|
||||
@@ -106,9 +107,14 @@ if (!$IS_MYSQLND)
|
||||
break;
|
||||
}
|
||||
|
||||
if (FALSE === $ready) {
|
||||
printf("[013] MySQLi indicates some error\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!empty($reject)) {
|
||||
foreach ($reject as $mysqli) {
|
||||
printf("[013] Rejecting thread %d: %s/%s\n",
|
||||
printf("[014] Rejecting thread %d: %s/%s\n",
|
||||
mysqli_thread_id($mysqli),
|
||||
mysqli_errno($mysqli),
|
||||
mysqli_error($mysqli));
|
||||
@@ -121,11 +127,16 @@ if (!$IS_MYSQLND)
|
||||
printf("Fetching from thread %d...\n", mysqli_thread_id($mysqli));
|
||||
var_dump(mysqli_fetch_assoc($res));
|
||||
} else if (mysqli_errno($mysqli) > 0) {
|
||||
printf("[014] %d/%s\n", mysqli_errno($mysqli), mysqli_error($mysqli));
|
||||
printf("[015] %d/%s\n", mysqli_errno($mysqli), mysqli_error($mysqli));
|
||||
}
|
||||
$processed++;
|
||||
}
|
||||
|
||||
if ((microtime(true) - $begin) > 5) {
|
||||
printf("[016] Pulling the emergency break after 5s, something is wrong...\n");
|
||||
break;
|
||||
}
|
||||
|
||||
} while ($processed < 2);
|
||||
|
||||
|
||||
@@ -137,17 +148,17 @@ if (!$IS_MYSQLND)
|
||||
// Sleep 0.1s to ensure the KILL gets recognized
|
||||
usleep(100000);
|
||||
if (false !== ($tmp = mysqli_query($link, "SELECT 1 AS 'processed before killed'", MYSQLI_ASYNC | MYSQLI_USE_RESULT)))
|
||||
printf("[015] Expecting boolean/false got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
||||
printf("[017] Expecting boolean/false got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
||||
|
||||
$links = array($link);
|
||||
$errors = array($link);
|
||||
$reject = array($link);
|
||||
|
||||
if (0 !== ($tmp = (mysqli_poll($links, $errors, $reject, 0, 10000))))
|
||||
printf("[016] Expecting int/0 got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
||||
printf("[018] Expecting int/0 got %s/%s\n", gettype($tmp), var_export($tmp, true));
|
||||
|
||||
if (!is_array($links) || empty($links))
|
||||
printf("[017] Expecting non-empty array got %s/%s\n", gettype($links), var_export($links, true));
|
||||
printf("[019] Expecting non-empty array got %s/%s\n", gettype($links), var_export($links, true));
|
||||
else
|
||||
foreach ($links as $link) {
|
||||
if (is_object($res = mysqli_reap_async_query($link))) {
|
||||
@@ -156,16 +167,16 @@ if (!$IS_MYSQLND)
|
||||
mysqli_free_result($res);
|
||||
} else if ($link->errno > 0) {
|
||||
// But you are supposed to handle the error the way its shown here!
|
||||
printf("[018] Error: %d/%s\n", $link->errno, $link->error);
|
||||
printf("[020] Error: %d/%s\n", $link->errno, $link->error);
|
||||
}
|
||||
}
|
||||
|
||||
// None of these will indicate an error, check errno on the list of returned connections!
|
||||
if (!is_array($errors) || !empty($errors))
|
||||
printf("[019] Expecting non-empty array got %s/%s\n", gettype($errors), var_export($errors, true));
|
||||
printf("[021] Expecting non-empty array got %s/%s\n", gettype($errors), var_export($errors, true));
|
||||
|
||||
if (!is_array($reject) || !empty($reject))
|
||||
printf("[020] Expecting empty array got %s/%s\n", gettype($reject), var_export($reject, true));
|
||||
printf("[021] Expecting empty array got %s/%s\n", gettype($reject), var_export($reject, true));
|
||||
|
||||
|
||||
mysqli_close($link);
|
||||
|
||||
@@ -80,13 +80,17 @@ if (!$IS_MYSQLND)
|
||||
if (0 == count($poll_links))
|
||||
break;
|
||||
|
||||
if (0 == ($num_ready = mysqli_poll($poll_links, $poll_errors, $poll_reject, 0, 200000)))
|
||||
if (0 === ($num_ready = mysqli_poll($poll_links, $poll_errors, $poll_reject, 0, 200000)))
|
||||
continue;
|
||||
|
||||
if (!empty($poll_errors)) {
|
||||
die(var_dump($poll_errors));
|
||||
}
|
||||
|
||||
if (FALSE === $num_ready) {
|
||||
die("Some mysqli indicated error");
|
||||
}
|
||||
|
||||
foreach ($poll_links as $link) {
|
||||
$thread_id = mysqli_thread_id($link);
|
||||
$links[$thread_id]['processed'] = true;
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
--TEST--
|
||||
mysqli_reap_async_query()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('connect.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
|
||||
if (!$IS_MYSQLND)
|
||||
die("skip mysqlnd only feature, compile PHP using --with-mysqli=mysqlnd");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once('connect.inc');
|
||||
|
||||
function get_connection() {
|
||||
global $host, $user, $passwd, $db, $port, $socket;
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
|
||||
return $link;
|
||||
}
|
||||
|
||||
if (!$link = get_connection())
|
||||
printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
|
||||
|
||||
if (NULL !== ($tmp = @mysqli_reap_async_query()))
|
||||
printf("[002] Expecting NULL got %s\n", var_export($tmp, true));
|
||||
|
||||
$l = array($link);
|
||||
if (NULL !== ($tmp = @mysqli_reap_async_query($l)))
|
||||
printf("[003] Expecting NULL got %s\n", var_export($tmp, true));
|
||||
|
||||
if (NULL !== ($tmp = @mysqli_reap_async_query($link, $link)))
|
||||
printf("[004] Expecting NULL got %s\n", var_export($tmp, true));
|
||||
|
||||
|
||||
function poll_async($offset, $link, $links, $errors, $reject, $exp_ready, $use_oo_syntax) {
|
||||
|
||||
if ($exp_ready !== ($tmp = mysqli_poll($links, $errors, $reject, 0, 1000)))
|
||||
printf("[%03d + 1] There should be %d links ready to read from, %d ready\n",
|
||||
$offset, $exp_ready, $tmp);
|
||||
|
||||
foreach ($links as $mysqli) {
|
||||
if ($use_oo_syntax) {
|
||||
$res = $mysqli->reap_async_query();
|
||||
} else {
|
||||
$res = mysqli_reap_async_query($mysqli);
|
||||
}
|
||||
if (is_object($res)) {
|
||||
printf("[%03d + 2] %s\n", $offset, var_export($res->fetch_assoc(), true));
|
||||
} else if (mysqli_errno($mysqli) > 0) {
|
||||
printf("[%03d + 3] Error indicated through links array: %d/%s",
|
||||
$offset, mysqli_errno($mysqli), mysqli_error($mysqli));
|
||||
} else {
|
||||
printf("[%03d + 4] Cannot fetch and no error set - non resultset query (no SELECT)!\n", $offset);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($errors as $mysqli)
|
||||
printf("[%03d + 5] Error on %d: %d/%s\n",
|
||||
$offset, mysqli_thread_id($mysqli), mysqli_errno($mysqli), mysqli_error($mysqli));
|
||||
|
||||
foreach ($reject as $mysqli)
|
||||
printf("[%03d + 6] Rejecting thread %d: %d/%s\n",
|
||||
$offset, mysqli_thread_id($mysqli), mysqli_errno($mysqli), mysqli_error($mysqli));
|
||||
|
||||
}
|
||||
|
||||
// Connections on which no query has been send - 1
|
||||
$link = get_connection();
|
||||
$link->query("SELECT 1 AS _one", MYSQLI_ASYNC | MYSQLI_STORE_RESULT);
|
||||
$links = array($link);
|
||||
$errors = array($link);
|
||||
$reject = array($link);
|
||||
poll_async(12, $link, $links, $errors, $reject, 1, false);
|
||||
mysqli_close($link);
|
||||
|
||||
$link = get_connection();
|
||||
$link->query("SELECT 2 AS _two", MYSQLI_ASYNC | MYSQLI_USE_RESULT);
|
||||
$links = array($link);
|
||||
$errors = array($link);
|
||||
$reject = array($link);
|
||||
poll_async(13, $link, $links, $errors, $reject, 1, true);
|
||||
mysqli_close($link);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--EXPECTF--
|
||||
[012 + 2] array (
|
||||
'_one' => '1',
|
||||
)
|
||||
[013 + 2] array (
|
||||
'_two' => '2',
|
||||
)
|
||||
done!
|
||||
@@ -0,0 +1,84 @@
|
||||
--TEST--
|
||||
mysqli_release_savepoint()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
|
||||
require_once('connect.inc');
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
die(sprintf("Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
|
||||
|
||||
if (!have_innodb($link))
|
||||
die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error));
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
/* {{{ proto bool mysqli_release_savepoint(object link, string name) */
|
||||
$tmp = NULL;
|
||||
$link = NULL;
|
||||
|
||||
if (!is_null($tmp = @mysqli_release_savepoint()))
|
||||
printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!is_null($tmp = @mysqli_release_savepoint($link)))
|
||||
printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
|
||||
$name = array();
|
||||
if (!is_null($tmp = @mysqli_release_savepoint($link, $name)))
|
||||
printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!is_null($tmp = @mysqli_release_savepoint($link, 'foo', $link)))
|
||||
printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (false !== ($tmp = mysqli_release_savepoint($link, '')))
|
||||
printf("[006] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!mysqli_query($link, 'DROP TABLE IF EXISTS test'))
|
||||
printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!mysqli_query($link, 'CREATE TABLE test(id INT) ENGINE = InnoDB'))
|
||||
printf("[008] Cannot create test table, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (true !== ($tmp = mysqli_autocommit($link, false)))
|
||||
printf("[009] Cannot turn off autocommit, expecting true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
/* note that there is no savepoint my... */
|
||||
if (true !== ($tmp = mysqli_release_savepoint($link, 'my')))
|
||||
printf("[010] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)'))
|
||||
printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
$tmp = mysqli_commit($link);
|
||||
if ($tmp !== true)
|
||||
printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (true !== ($tmp = mysqli_savepoint($link, 'my')))
|
||||
printf("[013] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
$res = mysqli_query($link, "SELECT * FROM test");
|
||||
var_dump($res->fetch_assoc());
|
||||
|
||||
if (true !== ($tmp = mysqli_release_savepoint($link, 'my')))
|
||||
printf("[014] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once("clean_table.inc");
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: mysqli_release_savepoint(): Savepoint name cannot be empty in %s on line %d
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(1) "1"
|
||||
}
|
||||
done!
|
||||
@@ -43,8 +43,6 @@ require_once('skipifconnectfailure.inc');
|
||||
|
||||
mysqli_multi_query($link, "BAR; FOO;");
|
||||
mysqli_query($link, "FOO");
|
||||
/* This might work if you accept anonymous users in your setup */
|
||||
mysqli_change_user($link, "0123456789-10-456789-20-456789-30-456789-40-456789-50-456789-60-456789-70-456789-80-456789-90-456789", "password", $db);
|
||||
mysqli_kill($link, -1);
|
||||
|
||||
// mysqli_ping() cannot be tested, because one would need to cause an error inside the C function to test it
|
||||
@@ -61,7 +59,6 @@ require_once('skipifconnectfailure.inc');
|
||||
|
||||
mysqli_multi_query($link, "BAR; FOO;");
|
||||
mysqli_query($link, "FOO");
|
||||
mysqli_change_user($link, "This might work if you accept anonymous users in your setup", "password", $db);
|
||||
mysqli_kill($link, -1);
|
||||
mysqli_prepare($link, "FOO");
|
||||
mysqli_real_query($link, "FOO");
|
||||
@@ -291,8 +288,6 @@ Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; ch
|
||||
|
||||
Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
|
||||
|
||||
Warning: mysqli_change_user(): (%d/%d): Access denied for user '%s'@'%s' (using password: %s) in %s on line %d
|
||||
|
||||
Warning: mysqli_kill(): processid should have positive value in %s on line %d
|
||||
|
||||
Warning: mysqli_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
--TEST--
|
||||
mysqli_report(), change user, MySQL 5.6+
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
die(sprintf("SKIP Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket));
|
||||
|
||||
if (mysqli_get_server_version($link) < 50600)
|
||||
die("SKIP For MySQL >= 5.6.0");
|
||||
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
|
||||
$tmp = NULL;
|
||||
$link = NULL;
|
||||
|
||||
require('table.inc');
|
||||
|
||||
/*
|
||||
Internal macro MYSQL_REPORT_ERROR
|
||||
*/
|
||||
mysqli_report(MYSQLI_REPORT_ERROR);
|
||||
|
||||
mysqli_change_user($link, "0123456789-10-456789-20-456789-30-456789-40-456789-50-456789-60-456789-70-456789-80-456789-90-456789", "password", $db);
|
||||
|
||||
mysqli_report(MYSQLI_REPORT_OFF);
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
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);
|
||||
|
||||
mysqli_change_user($link, "This might work if you accept anonymous users in your setup", "password", $db);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once("clean_table.inc");
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
Warning: mysqli_change_user(): (%d/%d): Access denied for user '%s'@'%s' (using password: %s) in %s on line %d
|
||||
done!
|
||||
@@ -1,10 +1,17 @@
|
||||
--TEST--
|
||||
mysqli_report()
|
||||
mysqli_report(), MySQL < 5.6
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
die(sprintf("SKIP Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket));
|
||||
|
||||
if (mysqli_get_server_version($link) >= 50600)
|
||||
die("SKIP For MySQL < 5.6.0");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
--TEST--
|
||||
mysqli_savepoint()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
|
||||
require_once('connect.inc');
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
die(sprintf("Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
|
||||
|
||||
if (!have_innodb($link))
|
||||
die(sprintf("Needs InnoDB support, [%d] %s", $link->errno, $link->error));
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
/* {{{ proto bool mysqli_savepoint(object link, string name) */
|
||||
$tmp = NULL;
|
||||
$link = NULL;
|
||||
|
||||
if (!is_null($tmp = @mysqli_savepoint()))
|
||||
printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!is_null($tmp = @mysqli_savepoint($link)))
|
||||
printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
|
||||
printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
|
||||
$name = array();
|
||||
if (!is_null($tmp = @mysqli_savepoint($link, $name)))
|
||||
printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!is_null($tmp = @mysqli_savepoint($link, 'foo', $link)))
|
||||
printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (false !== ($tmp = mysqli_savepoint($link, '')))
|
||||
printf("[006] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!mysqli_query($link, 'DROP TABLE IF EXISTS test'))
|
||||
printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!mysqli_query($link, 'CREATE TABLE test(id INT) ENGINE = InnoDB'))
|
||||
printf("[008] Cannot create test table, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (true !== ($tmp = mysqli_autocommit($link, false)))
|
||||
printf("[009] Cannot turn off autocommit, expecting true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
/* overrule autocommit */
|
||||
if (true !== ($tmp = mysqli_savepoint($link, 'my')))
|
||||
printf("[010] Got %s - [%d] %s\n", var_dump($tmp, true), mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!mysqli_query($link, 'INSERT INTO test(id) VALUES (1)'))
|
||||
printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
$tmp = mysqli_rollback($link);
|
||||
if ($tmp !== true)
|
||||
printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once("clean_table.inc");
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
Warning: mysqli_savepoint(): Savepoint name cannot be empty in %s on line %d
|
||||
done!
|
||||
@@ -17,7 +17,7 @@ if (!mysqli_query($link, "DROP TABLE IF EXISTS test") ||
|
||||
!mysqli_query($link, "CREATE TABLE test(id SMALLINT)"))
|
||||
die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
|
||||
|
||||
if (!@mysqli_query("INSERT INTO test(id) VALUES (100001)"))
|
||||
if (!@mysqli_query($link, "SET sql_mode=''") || !@mysqli_query($link, "INSERT INTO test(id) VALUES (100001)"))
|
||||
die("skip Strict sql mode seems to be active. We won't get a warning to check for.");
|
||||
|
||||
mysqli_query($link, "DROP TABLE IF EXISTS test");
|
||||
@@ -43,54 +43,57 @@ mysqli_query($link, "DROP TABLE IF EXISTS test");
|
||||
if (NULL !== ($tmp = mysqli_stmt_get_warnings($stmt)))
|
||||
printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!mysqli_stmt_prepare($stmt, "DROP TABLE IF EXISTS test") || !mysqli_stmt_execute($stmt))
|
||||
if (!mysqli_stmt_prepare($stmt, "SET sql_mode=''") || !mysqli_stmt_execute($stmt))
|
||||
printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
if (!mysqli_stmt_prepare($stmt, "DROP TABLE IF EXISTS test") || !mysqli_stmt_execute($stmt))
|
||||
printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
if (false !== ($tmp = mysqli_stmt_get_warnings($stmt)))
|
||||
printf("[006] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!mysqli_stmt_prepare($stmt, "CREATE TABLE test(id SMALLINT, label CHAR(1))") || !mysqli_stmt_execute($stmt))
|
||||
printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
if (false !== ($tmp = mysqli_stmt_get_warnings($stmt)))
|
||||
printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (100000, 'a'), (100001, 'b')") ||
|
||||
!mysqli_stmt_execute($stmt))
|
||||
printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
if (!is_object($warning = mysqli_stmt_get_warnings($stmt)))
|
||||
printf("[010] Expecting mysqli_warning object, got %s/%s\n", gettype($warning), $warning);
|
||||
printf("[011] Expecting mysqli_warning object, got %s/%s\n", gettype($warning), $warning);
|
||||
|
||||
if ('mysqli_warning' !== get_class($warning))
|
||||
printf("[011] Expecting object of type mysqli_warning got type '%s'", get_class($warning));
|
||||
printf("[012] Expecting object of type mysqli_warning got type '%s'", get_class($warning));
|
||||
|
||||
if (!method_exists($warning, 'next'))
|
||||
printf("[012] Object mysqli_warning seems to lack method next()\n");
|
||||
printf("[013] Object mysqli_warning seems to lack method next()\n");
|
||||
|
||||
$i = 0;
|
||||
do {
|
||||
|
||||
if ('' == $warning->message)
|
||||
printf("[013 - %d] Message should not be empty\n", $i);
|
||||
printf("[014 - %d] Message should not be empty\n", $i);
|
||||
|
||||
if ('' == $warning->sqlstate)
|
||||
printf("[014 - %d] SQL State should not be empty\n", $i);
|
||||
printf("[015 - %d] SQL State should not be empty\n", $i);
|
||||
|
||||
if (0 == $warning->errno)
|
||||
printf("[015 - %d] Error number should not be zero\n", $i);
|
||||
printf("[016 - %d] Error number should not be zero\n", $i);
|
||||
|
||||
$i++;
|
||||
|
||||
} while ($warning->next());
|
||||
|
||||
if (2 != $i)
|
||||
printf("[016] Expected 2 warnings, got %d warnings\n", $i);
|
||||
printf("[017] Expected 2 warnings, got %d warnings\n", $i);
|
||||
|
||||
mysqli_stmt_close($stmt);
|
||||
|
||||
if (NULL !== ($tmp = mysqli_stmt_get_warnings($stmt)))
|
||||
printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
printf("[018] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
|
||||
|
||||
mysqli_close($link);
|
||||
print "done!";
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
mysqli_store_result()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
?>
|
||||
--INI--
|
||||
mysqlnd.debug=d:t:O,/tmp/mysqlnd.trace
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
|
||||
$tmp = NULL;
|
||||
$link = NULL;
|
||||
|
||||
|
||||
require('table.inc');
|
||||
|
||||
if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
|
||||
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
|
||||
printf("[004] Expecting object, got %s/%s. [%d] %s\n",
|
||||
gettype($res), $res, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (true !== ($tmp = mysqli_data_seek($res, 2)))
|
||||
printf("[005] Expecting boolean/true, got %s/%s. [%d] %s\n",
|
||||
gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
mysqli_free_result($res);
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once("clean_table.inc");
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: mysqli_store_result(): Couldn't fetch mysqli in %s on line %d
|
||||
done!
|
||||
@@ -0,0 +1,285 @@
|
||||
--TEST--
|
||||
mysqli_store_result()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifemb.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
if (!$IS_MYSQLND) {
|
||||
die("SKIP mysqlnd only test");
|
||||
}
|
||||
?>
|
||||
--INI--
|
||||
mysqlnd.debug=d:t:O,/tmp/mysqlnd.trace
|
||||
mysqlnd.net_read_buffer_size=1
|
||||
mysqlnd.mempool_default_size=1
|
||||
mysqlnd.fetch_data_copy=0
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
|
||||
$tmp = NULL;
|
||||
$link = NULL;
|
||||
|
||||
require('table.inc');
|
||||
|
||||
if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
|
||||
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
|
||||
printf("[004] Expecting object, got %s/%s. [%d] %s\n",
|
||||
gettype($res), $res, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (true !== ($tmp = mysqli_data_seek($res, 2)))
|
||||
printf("[005] Expecting boolean/true, got %s/%s. [%d] %s\n",
|
||||
gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
var_dump($res->fetch_assoc());
|
||||
|
||||
if (true !== ($tmp = mysqli_data_seek($res, 0)))
|
||||
printf("[006] Expecting boolean/true, got %s/%s. [%d] %s\n",
|
||||
gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
while ($row = $res->fetch_assoc()) {
|
||||
printf("id = %d, label = %s\n", $row['id'], $row['label']);
|
||||
}
|
||||
|
||||
mysqli_free_result($res);
|
||||
mysqli_close($link);
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[007] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
}
|
||||
|
||||
|
||||
if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
|
||||
printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
|
||||
printf("[009] Expecting object, got %s/%s. [%d] %s\n",
|
||||
gettype($res), $res, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
$no_result = 0;
|
||||
for ($i = 0; $i < 1000; $i++) {
|
||||
$idx = mt_rand(-100, 100);
|
||||
if (true === @mysqli_data_seek($res, $idx)) {
|
||||
$row = $res->fetch_assoc();
|
||||
if (!isset($row['id']) || !isset($row['label'])) {
|
||||
printf("[010] Brute force seek %d returned %d\n", $idx, var_export($row, true));
|
||||
}
|
||||
} else {
|
||||
$no_result++;
|
||||
}
|
||||
}
|
||||
printf("No result: %d\n", $no_result);
|
||||
|
||||
/* implicit free, implicit store */
|
||||
/* meta and fetch lenghts code */
|
||||
if (!$res = mysqli_query($link, "SELECT CONCAT(id, id) AS _c, label FROM test ORDER BY id DESC LIMIT 2"))
|
||||
printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
printf("Default\n");
|
||||
var_dump(mysqli_fetch_lengths($res));
|
||||
$fields = $res->fetch_fields();
|
||||
while ($row = $res->fetch_assoc()) {
|
||||
var_dump(mysqli_fetch_lengths($res));
|
||||
}
|
||||
var_dump(mysqli_fetch_lengths($res));
|
||||
|
||||
if (!$res = mysqli_real_query($link, "SELECT CONCAT(id, id) AS _c, label FROM test ORDER BY id DESC LIMIT 2"))
|
||||
printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
|
||||
printf("[013] Expecting object, got %s/%s. [%d] %s\n",
|
||||
gettype($res), $res, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
printf("Copy\n");
|
||||
var_dump(mysqli_fetch_lengths($res));
|
||||
$fields_copy = $res->fetch_fields();
|
||||
while ($row = $res->fetch_assoc()) {
|
||||
var_dump(mysqli_fetch_lengths($res));
|
||||
}
|
||||
var_dump(mysqli_fetch_lengths($res));
|
||||
|
||||
/* There's no need for in-depth testing here. If you want in-depth switch mysqlnd
|
||||
globally to copy mode and run all the tests */
|
||||
foreach ($fields as $k => $field_info) {
|
||||
if ($fields_copy[$k] != $field_info) {
|
||||
printf("[014] Metadata seems to differ, dumping\n");
|
||||
var_dump($field_info);
|
||||
var_dump($fields_copy[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
/* fetch all */
|
||||
|
||||
if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2"))
|
||||
printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
|
||||
printf("[016] Expecting object, got %s/%s. [%d] %s\n",
|
||||
gettype($res), $res, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
foreach (mysqli_fetch_all($res, MYSQLI_ASSOC) as $row) {
|
||||
printf("id = %d label = %s\n", $row['id'], $row['label']);
|
||||
}
|
||||
|
||||
if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2"))
|
||||
printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
|
||||
printf("[018] Expecting object, got %s/%s. [%d] %s\n",
|
||||
gettype($res), $res, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
/* provoke out of sync */
|
||||
if (!mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2"))
|
||||
printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
var_dump($res->fetch_assoc());
|
||||
|
||||
if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2"))
|
||||
printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
|
||||
printf("[021] Expecting object, got %s/%s. [%d] %s\n",
|
||||
gettype($res), $res, mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
/* user conn killed, res associated with conn, fetch from res */
|
||||
unset($link);
|
||||
var_dump($res->fetch_assoc());
|
||||
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[022] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
}
|
||||
|
||||
if (!$res = mysqli_real_query($link, "INSERT INTO test(id, label) VALUES (100, 'z')"))
|
||||
printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA);
|
||||
|
||||
if (mysqli_get_server_version($link) > 50000) {
|
||||
// let's try to play with stored procedures
|
||||
mysqli_real_query($link, 'DROP PROCEDURE IF EXISTS p');
|
||||
if (mysqli_real_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) READS SQL DATA BEGIN SELECT id FROM test WHERE id >= 100 ORDER BY id; SELECT id + 1, label FROM test WHERE id > 0 AND id < 3 ORDER BY id; SELECT VERSION() INTO ver_param;
|
||||
END;')) {
|
||||
mysqli_multi_query($link, "CALL p(@version)");
|
||||
do {
|
||||
if ($res = $link->store_result(MYSQLI_STORE_RESULT_COPY_DATA)) {
|
||||
printf("---\n");
|
||||
var_dump($res->fetch_all());
|
||||
$res->free();
|
||||
} else {
|
||||
if ($link->errno) {
|
||||
echo "Store failed: (" . $link->errno . ") " . $link->error;
|
||||
}
|
||||
}
|
||||
} while ($link->more_results() && $link->next_result());
|
||||
mysqli_real_query($link, 'SELECT @version AS p_version');
|
||||
$res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA);
|
||||
|
||||
$tmp = mysqli_fetch_assoc($res);
|
||||
if (!is_array($tmp) || empty($tmp) || !isset($tmp['p_version']) || ('' == $tmp['p_version'])) {
|
||||
printf("[024] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
var_dump($tmp);
|
||||
}
|
||||
|
||||
mysqli_free_result($res);
|
||||
} else {
|
||||
printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
}
|
||||
}
|
||||
|
||||
print "done!";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once("clean_table.inc");
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "3"
|
||||
["label"]=>
|
||||
string(1) "c"
|
||||
}
|
||||
id = 1, label = a
|
||||
id = 2, label = b
|
||||
id = 3, label = c
|
||||
id = 4, label = d
|
||||
id = 5, label = e
|
||||
id = 6, label = f
|
||||
No result: %d
|
||||
Default
|
||||
bool(false)
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
int(1)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
int(1)
|
||||
}
|
||||
bool(false)
|
||||
Copy
|
||||
bool(false)
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
int(1)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(2)
|
||||
[1]=>
|
||||
int(1)
|
||||
}
|
||||
bool(false)
|
||||
id = 6 label = f
|
||||
id = 5 label = e
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "6"
|
||||
["label"]=>
|
||||
string(1) "f"
|
||||
}
|
||||
[020] [2014] %s
|
||||
array(2) {
|
||||
["id"]=>
|
||||
string(1) "6"
|
||||
["label"]=>
|
||||
string(1) "f"
|
||||
}
|
||||
---
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(3) "100"
|
||||
}
|
||||
}
|
||||
---
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(1) "2"
|
||||
[1]=>
|
||||
string(1) "a"
|
||||
}
|
||||
[1]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(1) "3"
|
||||
[1]=>
|
||||
string(1) "b"
|
||||
}
|
||||
}
|
||||
done!
|
||||
+56
-5
@@ -1111,7 +1111,8 @@ PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn_handle,
|
||||
const char * db, php_size_t db_len,
|
||||
php_uint_t port,
|
||||
const char * socket_or_pipe,
|
||||
php_uint_t mysql_flags
|
||||
php_uint_t mysql_flags,
|
||||
php_uint_t client_api_flags
|
||||
TSRMLS_DC)
|
||||
{
|
||||
enum_func_status ret = FAIL;
|
||||
@@ -1122,7 +1123,7 @@ PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn_handle,
|
||||
|
||||
if (!conn_handle) {
|
||||
self_alloced = TRUE;
|
||||
if (!(conn_handle = mysqlnd_init(FALSE))) {
|
||||
if (!(conn_handle = mysqlnd_init(client_api_flags, FALSE))) {
|
||||
/* OOM */
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
@@ -2570,6 +2571,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn,
|
||||
|
||||
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
|
||||
do {
|
||||
unsigned int f = flags;
|
||||
if (!conn->current_result) {
|
||||
break;
|
||||
}
|
||||
@@ -2583,7 +2585,24 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn,
|
||||
|
||||
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_BUFFERED_SETS);
|
||||
|
||||
result = conn->current_result->m.store_result(conn->current_result, conn, 0 TSRMLS_CC);
|
||||
/* overwrite */
|
||||
if ((conn->m->get_client_api_capabilities(conn TSRMLS_CC) & MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA)) {
|
||||
if (MYSQLND_G(fetch_data_copy)) {
|
||||
f &= ~MYSQLND_STORE_NO_COPY;
|
||||
f |= MYSQLND_STORE_COPY;
|
||||
}
|
||||
} else {
|
||||
/* if for some reason PDO borks something */
|
||||
if (!(f & (MYSQLND_STORE_NO_COPY | MYSQLND_STORE_COPY))) {
|
||||
f |= MYSQLND_STORE_COPY;
|
||||
}
|
||||
}
|
||||
if (!(f & (MYSQLND_STORE_NO_COPY | MYSQLND_STORE_COPY))) {
|
||||
SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Unknown fetch mode");
|
||||
DBG_ERR("Unknown fetch mode");
|
||||
break;
|
||||
}
|
||||
result = conn->current_result->m.store_result(conn->current_result, conn, f TSRMLS_CC);
|
||||
if (!result) {
|
||||
conn->current_result->m.free_result(conn->current_result, TRUE TSRMLS_CC);
|
||||
}
|
||||
@@ -2890,6 +2909,32 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_savepoint_release)(MYSQLND_CONN_DATA * conn
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_conn_data::negotiate_client_api_capabilities */
|
||||
static unsigned int
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, negotiate_client_api_capabilities)(MYSQLND_CONN_DATA * const conn, const unsigned int flags TSRMLS_DC)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
DBG_ENTER("mysqlnd_conn_data::negotiate_client_api_capabilities");
|
||||
if (conn) {
|
||||
ret = conn->client_api_capabilities;
|
||||
conn->client_api_capabilities = flags;
|
||||
}
|
||||
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_conn_data::get_client_api_capabilities */
|
||||
static unsigned int
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, get_client_api_capabilities)(const MYSQLND_CONN_DATA * const conn TSRMLS_DC)
|
||||
{
|
||||
DBG_ENTER("mysqlnd_conn_data::get_client_api_capabilities");
|
||||
DBG_RETURN(conn? conn->client_api_capabilities : 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_conn_data::local_tx_start */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, local_tx_start)(MYSQLND_CONN_DATA * conn, size_t this_func TSRMLS_DC)
|
||||
@@ -3018,7 +3063,10 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn_data)
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request),
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, fetch_auth_plugin_by_name),
|
||||
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d),
|
||||
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, negotiate_client_api_capabilities),
|
||||
MYSQLND_METHOD(mysqlnd_conn_data, get_client_api_capabilities)
|
||||
MYSQLND_CLASS_METHODS_END;
|
||||
|
||||
|
||||
@@ -3097,11 +3145,14 @@ MYSQLND_CLASS_METHODS_END;
|
||||
|
||||
/* {{{ _mysqlnd_init */
|
||||
PHPAPI MYSQLND *
|
||||
_mysqlnd_init(zend_bool persistent TSRMLS_DC)
|
||||
_mysqlnd_init(unsigned int flags, zend_bool persistent TSRMLS_DC)
|
||||
{
|
||||
MYSQLND * ret;
|
||||
DBG_ENTER("mysqlnd_init");
|
||||
ret = MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_object_factory).get_connection(persistent TSRMLS_CC);
|
||||
if (ret && ret->data) {
|
||||
ret->data->m->negotiate_client_api_capabilities(ret->data, flags TSRMLS_CC);
|
||||
}
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -85,15 +85,16 @@ PHPAPI const MYSQLND_CHARSET * mysqlnd_find_charset_name(const char * const char
|
||||
|
||||
|
||||
/* Connect */
|
||||
#define mysqlnd_init(persistent) _mysqlnd_init((persistent) TSRMLS_CC)
|
||||
PHPAPI MYSQLND * _mysqlnd_init(zend_bool persistent TSRMLS_DC);
|
||||
#define mysqlnd_init(client_flags, persistent) _mysqlnd_init((client_flags), (persistent) TSRMLS_CC)
|
||||
PHPAPI MYSQLND * _mysqlnd_init(unsigned int client_flags, zend_bool persistent TSRMLS_DC);
|
||||
PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn,
|
||||
const char * host, const char * user,
|
||||
const char * passwd, php_size_t passwd_len,
|
||||
const char * db, php_size_t db_len,
|
||||
php_uint_t port,
|
||||
const char * socket_or_pipe,
|
||||
php_uint_t mysql_flags
|
||||
php_uint_t mysql_flags,
|
||||
php_uint_t client_api_flags
|
||||
TSRMLS_DC);
|
||||
|
||||
#define mysqlnd_change_user(conn, user, passwd, db, silent) ((conn)->data)->m->change_user((conn)->data, (user), (passwd), (db), (silent), strlen((passwd)) TSRMLS_CC)
|
||||
@@ -282,6 +283,7 @@ ZEND_BEGIN_MODULE_GLOBALS(mysqlnd)
|
||||
php_int_t debug_calloc_fail_threshold;
|
||||
php_int_t debug_realloc_fail_threshold;
|
||||
char * sha256_server_public_key;
|
||||
zend_bool fetch_data_copy;
|
||||
ZEND_END_MODULE_GLOBALS(mysqlnd)
|
||||
|
||||
PHPAPI ZEND_EXTERN_MODULE_GLOBALS(mysqlnd)
|
||||
|
||||
@@ -620,6 +620,16 @@ enum php_mysqlnd_server_command
|
||||
#define MYSQLND_STORE_NO_COPY 2
|
||||
#define MYSQLND_STORE_COPY 4
|
||||
|
||||
enum mysqlnd_buffered_type
|
||||
{
|
||||
MYSQLND_BUFFERED_TYPE_ZVAL = 1,
|
||||
MYSQLND_BUFFERED_TYPE_C
|
||||
};
|
||||
|
||||
|
||||
#define MYSQLND_CLIENT_NO_FLAG 0
|
||||
#define MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA 1
|
||||
|
||||
#endif /* MYSQLND_ENUM_N_DEF_H */
|
||||
|
||||
|
||||
|
||||
@@ -84,14 +84,26 @@ PHPAPI void ** _mysqlnd_plugin_get_plugin_result_unbuffered_data(const MYSQLND_R
|
||||
|
||||
|
||||
/* {{{ _mysqlnd_plugin_get_plugin_result_buffered_data */
|
||||
PHPAPI void ** _mysqlnd_plugin_get_plugin_result_buffered_data(const MYSQLND_RES_BUFFERED * result, unsigned int plugin_id TSRMLS_DC)
|
||||
PHPAPI void ** _mysqlnd_plugin_get_plugin_result_buffered_data_zval(const MYSQLND_RES_BUFFERED_ZVAL * result, unsigned int plugin_id TSRMLS_DC)
|
||||
{
|
||||
DBG_ENTER("_mysqlnd_plugin_get_plugin_result_data");
|
||||
DBG_INF_FMT("plugin_id=%u", plugin_id);
|
||||
if (!result || plugin_id >= mysqlnd_plugin_count()) {
|
||||
return NULL;
|
||||
}
|
||||
DBG_RETURN((void *)((char *)result + sizeof(MYSQLND_RES_BUFFERED) + plugin_id * sizeof(void *)));
|
||||
DBG_RETURN((void *)((char *)result + sizeof(MYSQLND_RES_BUFFERED_ZVAL) + plugin_id * sizeof(void *)));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ _mysqlnd_plugin_get_plugin_result_buffered_data */
|
||||
PHPAPI void ** _mysqlnd_plugin_get_plugin_result_buffered_data_c(const MYSQLND_RES_BUFFERED_C * result, unsigned int plugin_id TSRMLS_DC)
|
||||
{
|
||||
DBG_ENTER("_mysqlnd_plugin_get_plugin_result_data");
|
||||
DBG_INF_FMT("plugin_id=%u", plugin_id);
|
||||
if (!result || plugin_id >= mysqlnd_plugin_count()) {
|
||||
return NULL;
|
||||
}
|
||||
DBG_RETURN((void *)((char *)result + sizeof(MYSQLND_RES_BUFFERED_C) + plugin_id * sizeof(void *)));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -34,9 +34,11 @@ PHPAPI void ** _mysqlnd_plugin_get_plugin_result_data(const MYSQLND_RES * result
|
||||
PHPAPI void ** _mysqlnd_plugin_get_plugin_result_unbuffered_data(const MYSQLND_RES_UNBUFFERED * result, unsigned int plugin_id TSRMLS_DC);
|
||||
#define mysqlnd_plugin_get_plugin_result_unbuffered_data(r, p_id) _mysqlnd_plugin_get_plugin_result_unbuffered_data((r), (p_id) TSRMLS_CC)
|
||||
|
||||
PHPAPI void ** _mysqlnd_plugin_get_plugin_result_buffered_data(const MYSQLND_RES_BUFFERED * result, unsigned int plugin_id TSRMLS_DC);
|
||||
#define mysqlnd_plugin_get_plugin_result_buffered_data(r, p_id) _mysqlnd_plugin_get_plugin_result_buffered_data((r), (p_id) TSRMLS_CC)
|
||||
PHPAPI void ** _mysqlnd_plugin_get_plugin_result_buffered_data_zval(const MYSQLND_RES_BUFFERED_ZVAL * result, unsigned int plugin_id TSRMLS_DC);
|
||||
#define mysqlnd_plugin_get_plugin_result_buffered_data_zval(r, p_id) _mysqlnd_plugin_get_plugin_result_buffered_data_zval((r), (p_id) TSRMLS_CC)
|
||||
|
||||
PHPAPI void ** _mysqlnd_plugin_get_plugin_result_buffered_data_c(const MYSQLND_RES_BUFFERED_C * result, unsigned int plugin_id TSRMLS_DC);
|
||||
#define mysqlnd_plugin_get_plugin_result_buffered_data_c(r, p_id) _mysqlnd_plugin_get_plugin_result_buffered_data_c((r), (p_id) TSRMLS_CC)
|
||||
|
||||
PHPAPI void ** _mysqlnd_plugin_get_plugin_stmt_data(const MYSQLND_STMT * stmt, unsigned int plugin_id TSRMLS_DC);
|
||||
#define mysqlnd_plugin_get_plugin_stmt_data(s, p_id) _mysqlnd_plugin_get_plugin_stmt_data((s), (p_id) TSRMLS_CC)
|
||||
|
||||
+87
-80
@@ -89,36 +89,39 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||
result->type = MYSQLND_RES_PS_BUF;
|
||||
/* result->m.row_decoder = php_mysqlnd_rowp_read_binary_protocol; */
|
||||
|
||||
result->stored_data = mysqlnd_result_buffered_init(result->field_count, TRUE, result->persistent TSRMLS_CC);
|
||||
result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_zval_init(result->field_count, TRUE, result->persistent TSRMLS_CC);
|
||||
if (!result->stored_data) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
|
||||
ret = result->m.store_result_fetch_data(conn, result, result->meta, TRUE TSRMLS_CC);
|
||||
ret = result->m.store_result_fetch_data(conn, result, result->meta, &result->stored_data->row_buffers, TRUE TSRMLS_CC);
|
||||
|
||||
result->stored_data->m.fetch_row = mysqlnd_stmt_fetch_row_buffered;
|
||||
|
||||
if (PASS == ret) {
|
||||
/* Overflow ? */
|
||||
MYSQLND_RES_BUFFERED * set = result->stored_data;
|
||||
if (set->row_count) {
|
||||
/* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */
|
||||
if (set->row_count * result->meta->field_count * sizeof(zval *) > SIZE_MAX) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_ZVAL) {
|
||||
MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data;
|
||||
if (result->stored_data->row_count) {
|
||||
/* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */
|
||||
if (result->stored_data->row_count * result->meta->field_count * sizeof(zval *) > SIZE_MAX) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
/* if pecalloc is used valgrind barks gcc version 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux) */
|
||||
set->data = mnd_emalloc((size_t)(result->stored_data->row_count * result->meta->field_count * sizeof(zval *)));
|
||||
if (!set->data) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
memset(set->data, 0, (size_t)(result->stored_data->row_count * result->meta->field_count * sizeof(zval *)));
|
||||
}
|
||||
/* if pecalloc is used valgrind barks gcc version 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux) */
|
||||
set->data = mnd_emalloc((size_t)(set->row_count * result->meta->field_count * sizeof(zval *)));
|
||||
if (!set->data) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
memset(set->data, 0, (size_t)(set->row_count * result->meta->field_count * sizeof(zval *)));
|
||||
/* Position at the first row */
|
||||
set->data_cursor = set->data;
|
||||
} else if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_ZVAL) {
|
||||
/*TODO*/
|
||||
}
|
||||
/* Position at the first row */
|
||||
set->data_cursor = set->data;
|
||||
|
||||
|
||||
/* libmysql API docs say it should be so for SELECT statements */
|
||||
stmt->upsert_status->affected_rows = stmt->result->stored_data->row_count;
|
||||
@@ -187,7 +190,7 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s TSRMLS_DC)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((result = result->m.store_result(result, conn, TRUE TSRMLS_CC))) {
|
||||
if ((result = result->m.store_result(result, conn, MYSQLND_STORE_PS | MYSQLND_STORE_NO_COPY TSRMLS_CC))) {
|
||||
stmt->upsert_status->affected_rows = result->stored_data->row_count;
|
||||
stmt->state = MYSQLND_STMT_PREPARED;
|
||||
result->type = MYSQLND_RES_PS_BUF;
|
||||
@@ -733,7 +736,6 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, php_uint_t f
|
||||
{
|
||||
MYSQLND_STMT * s = (MYSQLND_STMT *) param;
|
||||
MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
|
||||
MYSQLND_RES_BUFFERED *set = result->stored_data;
|
||||
const MYSQLND_RES_METADATA * const meta = result->meta;
|
||||
php_uint_t field_count = meta->field_count;
|
||||
|
||||
@@ -742,81 +744,86 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, php_uint_t f
|
||||
DBG_INF_FMT("stmt=%lu", stmt != NULL ? stmt->stmt_id : 0L);
|
||||
|
||||
/* If we haven't read everything */
|
||||
if (set->data_cursor &&
|
||||
(set->data_cursor - set->data) < (set->row_count * field_count))
|
||||
{
|
||||
/* The user could have skipped binding - don't crash*/
|
||||
if (stmt->result_bind) {
|
||||
php_uint_t i;
|
||||
zval **current_row = set->data_cursor;
|
||||
if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_ZVAL) {
|
||||
MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data;
|
||||
if (set->data_cursor &&
|
||||
(set->data_cursor - set->data) < (result->stored_data->row_count * field_count))
|
||||
{
|
||||
/* The user could have skipped binding - don't crash*/
|
||||
if (stmt->result_bind) {
|
||||
php_uint_t i;
|
||||
zval **current_row = set->data_cursor;
|
||||
|
||||
if (NULL == current_row[0]) {
|
||||
uint64_t row_num = (set->data_cursor - set->data) / field_count;
|
||||
enum_func_status rc = result->stored_data->m.row_decoder(set->row_buffers[row_num],
|
||||
current_row,
|
||||
meta->field_count,
|
||||
meta->fields,
|
||||
result->conn->options->int_and_float_native,
|
||||
result->conn->stats TSRMLS_CC);
|
||||
if (PASS != rc) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
set->initialized_rows++;
|
||||
if (stmt->update_max_length) {
|
||||
for (i = 0; i < result->field_count; i++) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
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) {
|
||||
php_uint_t len = Z_STRSIZE_P(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
if (NULL == current_row[0]) {
|
||||
uint64_t row_num = (set->data_cursor - set->data) / field_count;
|
||||
enum_func_status rc = result->stored_data->m.row_decoder(result->stored_data->row_buffers[row_num],
|
||||
current_row,
|
||||
meta->field_count,
|
||||
meta->fields,
|
||||
result->conn->options->int_and_float_native,
|
||||
result->conn->stats TSRMLS_CC);
|
||||
if (PASS != rc) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
result->stored_data->initialized_rows++;
|
||||
if (stmt->update_max_length) {
|
||||
for (i = 0; i < result->field_count; i++) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
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) {
|
||||
php_size_t len = Z_STRSIZE_P(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < result->field_count; i++) {
|
||||
/* Clean what we copied last time */
|
||||
for (i = 0; i < result->field_count; i++) {
|
||||
/* Clean what we copied last time */
|
||||
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
|
||||
if (stmt->result_bind[i].zv) {
|
||||
zval_dtor(stmt->result_bind[i].zv);
|
||||
}
|
||||
if (stmt->result_bind[i].zv) {
|
||||
zval_dtor(stmt->result_bind[i].zv);
|
||||
}
|
||||
#endif
|
||||
/* copy the type */
|
||||
if (stmt->result_bind[i].bound == TRUE) {
|
||||
DBG_INF_FMT("i=%u type=%u", i, Z_TYPE_P(current_row[i]));
|
||||
if (Z_TYPE_P(current_row[i]) != IS_NULL) {
|
||||
/*
|
||||
Copy the value.
|
||||
Pre-condition is that the zvals in the result_bind buffer
|
||||
have been ZVAL_NULL()-ed or to another simple type
|
||||
(int, double, bool but not string). Because of the reference
|
||||
counting the user can't delete the strings the variables point to.
|
||||
*/
|
||||
/* copy the type */
|
||||
if (stmt->result_bind[i].bound == TRUE) {
|
||||
DBG_INF_FMT("i=%u type=%u", i, Z_TYPE_P(current_row[i]));
|
||||
if (Z_TYPE_P(current_row[i]) != IS_NULL) {
|
||||
/*
|
||||
Copy the value.
|
||||
Pre-condition is that the zvals in the result_bind buffer
|
||||
have been ZVAL_NULL()-ed or to another simple type
|
||||
(int, double, bool but not string). Because of the reference
|
||||
counting the user can't delete the strings the variables point to.
|
||||
*/
|
||||
|
||||
Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(current_row[i]);
|
||||
stmt->result_bind[i].zv->value = current_row[i]->value;
|
||||
Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(current_row[i]);
|
||||
stmt->result_bind[i].zv->value = current_row[i]->value;
|
||||
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
|
||||
zval_copy_ctor(stmt->result_bind[i].zv);
|
||||
zval_copy_ctor(stmt->result_bind[i].zv);
|
||||
#endif
|
||||
} else {
|
||||
ZVAL_NULL(stmt->result_bind[i].zv);
|
||||
} else {
|
||||
ZVAL_NULL(stmt->result_bind[i].zv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
set->data_cursor += field_count;
|
||||
*fetched_anything = TRUE;
|
||||
/* buffered result sets don't have a connection */
|
||||
MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_PS_BUF);
|
||||
DBG_INF("row fetched");
|
||||
} else {
|
||||
set->data_cursor = NULL;
|
||||
DBG_INF("no more data");
|
||||
}
|
||||
set->data_cursor += field_count;
|
||||
*fetched_anything = TRUE;
|
||||
/* buffered result sets don't have a connection */
|
||||
MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_PS_BUF);
|
||||
DBG_INF("row fetched");
|
||||
} else {
|
||||
set->data_cursor = NULL;
|
||||
DBG_INF("no more data");
|
||||
} else if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_C) {
|
||||
/*TODO*/
|
||||
}
|
||||
DBG_INF("PASS");
|
||||
DBG_RETURN(PASS);
|
||||
|
||||
+473
-157
@@ -32,29 +32,30 @@
|
||||
|
||||
#define MYSQLND_SILENT
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered::initialize_result_set_rest */
|
||||
/* {{{ mysqlnd_result_buffered_zval::initialize_result_set_rest */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta,
|
||||
MYSQLND_STATS * stats, zend_bool int_and_float_native TSRMLS_DC)
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta,
|
||||
MYSQLND_STATS * stats, zend_bool int_and_float_native TSRMLS_DC)
|
||||
{
|
||||
php_uint_t i;
|
||||
zval **data_cursor = result->data;
|
||||
zval **data_begin = result->data;
|
||||
php_uint_t field_count = meta->field_count;
|
||||
uint64_t row_count = result->row_count;
|
||||
enum_func_status ret = PASS;
|
||||
DBG_ENTER("mysqlnd_result_buffered::initialize_result_set_rest");
|
||||
const unsigned int field_count = meta->field_count;
|
||||
const uint64_t row_count = result->row_count;
|
||||
enum_func_status rc;
|
||||
|
||||
zval **data_begin = ((MYSQLND_RES_BUFFERED_ZVAL *) result)->data;
|
||||
zval **data_cursor = data_begin;
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered_zval::initialize_result_set_rest");
|
||||
|
||||
if (!data_cursor || row_count == result->initialized_rows) {
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
while ((data_cursor - data_begin) < (ptrdiff_t)(row_count * field_count)) {
|
||||
if (NULL == data_cursor[0]) {
|
||||
enum_func_status rc = result->m.row_decoder(
|
||||
result->row_buffers[(data_cursor - data_begin) / field_count],
|
||||
rc = result->m.row_decoder(result->row_buffers[(data_cursor - data_begin) / field_count],
|
||||
data_cursor,
|
||||
meta->field_count,
|
||||
field_count,
|
||||
meta->fields,
|
||||
int_and_float_native,
|
||||
stats TSRMLS_CC);
|
||||
@@ -63,7 +64,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered, initialize_result_set_rest)(MYSQLND_RES_
|
||||
break;
|
||||
}
|
||||
result->initialized_rows++;
|
||||
for (i = 0; i < meta->field_count; i++) {
|
||||
for (i = 0; i < field_count; i++) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
String of zero size, definitely can't be the next max_length.
|
||||
@@ -84,6 +85,62 @@ MYSQLND_METHOD(mysqlnd_result_buffered, initialize_result_set_rest)(MYSQLND_RES_
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered_c::initialize_result_set_rest */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta,
|
||||
MYSQLND_STATS * stats, zend_bool int_and_float_native TSRMLS_DC)
|
||||
{
|
||||
unsigned int i;
|
||||
enum_func_status ret = PASS;
|
||||
const unsigned int field_count = meta->field_count;
|
||||
const uint64_t row_count = result->row_count;
|
||||
enum_func_status rc;
|
||||
DBG_ENTER("mysqlnd_result_buffered_c::initialize_result_set_rest");
|
||||
|
||||
if (result->initialized_rows < row_count) {
|
||||
zend_uchar * initialized = ((MYSQLND_RES_BUFFERED_C *) result)->initialized;
|
||||
zval ** current_row = mnd_emalloc(field_count * sizeof(zval *));
|
||||
|
||||
if (!current_row) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
|
||||
for (i = 0; i < result->row_count; i++) {
|
||||
/* (i / 8) & the_bit_for_i*/
|
||||
if (initialized[i >> 3] & (1 << (i & 7))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = result->m.row_decoder(result->row_buffers[i], current_row, field_count, meta->fields, int_and_float_native, stats TSRMLS_CC);
|
||||
|
||||
if (rc != PASS) {
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
result->initialized_rows++;
|
||||
initialized[i >> 3] |= (1 << (i & 7));
|
||||
for (i = 0; i < field_count; i++) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
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) {
|
||||
unsigned long len = Z_STRSIZE_P(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
zval_ptr_dtor(¤t_row[i]);
|
||||
}
|
||||
}
|
||||
mnd_efree(current_row);
|
||||
}
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ 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)
|
||||
@@ -205,25 +262,23 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, free_result)(MYSQLND_RES_UNBUFFERED *
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered::free_result */
|
||||
/* {{{ mysqlnd_result_buffered_zval::free_result */
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * const set TSRMLS_DC)
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_zval, free_result)(MYSQLND_RES_BUFFERED_ZVAL * const set TSRMLS_DC)
|
||||
{
|
||||
php_uint_t field_count = set->field_count;
|
||||
int64_t row;
|
||||
zval ** data = set->data;
|
||||
|
||||
DBG_ENTER("mysqlnd_res::free_buffered_data");
|
||||
DBG_INF_FMT("Freeing "MYSQLND_LLU_SPEC" row(s)", set->row_count);
|
||||
DBG_ENTER("mysqlnd_result_buffered_zval::free_result");
|
||||
|
||||
if (set->data) {
|
||||
set->data = NULL; /* prevent double free if following loop is interrupted */
|
||||
if (data) {
|
||||
php_uint_t copy_on_write_performed = 0;
|
||||
php_uint_t copy_on_write_saved = 0;
|
||||
zval **data = set->data;
|
||||
set->data = NULL; /* prevent double free if following loop is interrupted */
|
||||
|
||||
php_uint_t field_count = set->field_count;
|
||||
int64_t row;
|
||||
|
||||
for (row = set->row_count - 1; row >= 0; row--) {
|
||||
zval **current_row = data + row * field_count;
|
||||
MYSQLND_MEMORY_POOL_CHUNK *current_buffer = set->row_buffers[row];
|
||||
int64_t col;
|
||||
|
||||
if (current_row != NULL) {
|
||||
@@ -239,13 +294,48 @@ MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * cons
|
||||
}
|
||||
}
|
||||
}
|
||||
current_buffer->free_chunk(current_buffer TSRMLS_CC);
|
||||
}
|
||||
|
||||
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_COPY_ON_WRITE_PERFORMED, copy_on_write_performed,
|
||||
STAT_COPY_ON_WRITE_SAVED, copy_on_write_saved);
|
||||
mnd_efree(data);
|
||||
}
|
||||
set->data_cursor = NULL;
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered_c::free_result */
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_c, free_result)(MYSQLND_RES_BUFFERED_C * const set TSRMLS_DC)
|
||||
{
|
||||
DBG_ENTER("mysqlnd_result_buffered_c::free_result");
|
||||
mnd_pefree(set->initialized, set->persistent);
|
||||
set->initialized = NULL;
|
||||
DBG_VOID_RETURN;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered::free_result */
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * const set TSRMLS_DC)
|
||||
{
|
||||
int64_t row;
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered::free_result");
|
||||
DBG_INF_FMT("Freeing "MYSQLND_LLU_SPEC" row(s)", set->row_count);
|
||||
|
||||
if (set->type == MYSQLND_BUFFERED_TYPE_ZVAL) {
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_zval, free_result)((MYSQLND_RES_BUFFERED_ZVAL *) set TSRMLS_CC);
|
||||
} if (set->type == MYSQLND_BUFFERED_TYPE_C) {
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_c, free_result)((MYSQLND_RES_BUFFERED_C *) set TSRMLS_CC);
|
||||
}
|
||||
|
||||
for (row = set->row_count - 1; row >= 0; row--) {
|
||||
MYSQLND_MEMORY_POOL_CHUNK *current_buffer = set->row_buffers[row];
|
||||
current_buffer->free_chunk(current_buffer TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (set->lengths) {
|
||||
mnd_pefree(set->lengths, set->persistent);
|
||||
@@ -253,8 +343,8 @@ MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * cons
|
||||
}
|
||||
|
||||
if (set->row_buffers) {
|
||||
mnd_efree(set->row_buffers);
|
||||
set->row_buffers = NULL;
|
||||
mnd_pefree(set->row_buffers, 0);
|
||||
set->row_buffers = NULL;
|
||||
}
|
||||
|
||||
if (set->result_set_memory_pool) {
|
||||
@@ -263,7 +353,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * cons
|
||||
}
|
||||
|
||||
|
||||
set->data_cursor = NULL;
|
||||
set->row_count = 0;
|
||||
|
||||
mnd_pefree(set, set->persistent);
|
||||
@@ -590,31 +679,49 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s
|
||||
completeness.
|
||||
*/
|
||||
static php_uint_t *
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, fetch_lengths)(MYSQLND_RES_BUFFERED * const result TSRMLS_DC)
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_lengths)(MYSQLND_RES_BUFFERED * const result TSRMLS_DC)
|
||||
{
|
||||
php_uint_t i;
|
||||
zval **previous_row;
|
||||
MYSQLND_RES_BUFFERED *set = result;
|
||||
|
||||
const MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result;
|
||||
/*
|
||||
If:
|
||||
- unbuffered result
|
||||
- first row has not been read
|
||||
- last_row has been read
|
||||
*/
|
||||
DBG_ENTER("mysqlnd_result_buffered_zval::fetch_lengths");
|
||||
|
||||
if (set->data_cursor == NULL ||
|
||||
set->data_cursor == set->data ||
|
||||
((set->data_cursor - set->data) > (set->row_count * result->field_count) ))
|
||||
((set->data_cursor - set->data) > (result->row_count * result->field_count) ))
|
||||
{
|
||||
return NULL;/* No rows or no more rows */
|
||||
DBG_INF("EOF");
|
||||
DBG_RETURN(NULL);/* No rows or no more rows */
|
||||
}
|
||||
DBG_INF("non NULL");
|
||||
DBG_RETURN(result->lengths);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
previous_row = set->data_cursor - result->field_count;
|
||||
for (i = 0; i < result->field_count; i++) {
|
||||
result->lengths[i] = (Z_TYPE_P(previous_row[i]) == IS_NULL)? 0:Z_STRSIZE_P(previous_row[i]);
|
||||
|
||||
/* {{{ mysqlnd_result_buffered_c::fetch_lengths */
|
||||
/*
|
||||
Do lazy initialization for buffered results. As PHP strings have
|
||||
length inside, this function makes not much sense in the context
|
||||
of PHP, to be called as separate function. But let's have it for
|
||||
completeness.
|
||||
*/
|
||||
static unsigned long *
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_lengths)(MYSQLND_RES_BUFFERED * const result TSRMLS_DC)
|
||||
{
|
||||
const MYSQLND_RES_BUFFERED_C * set = (MYSQLND_RES_BUFFERED_C *) result;
|
||||
DBG_ENTER("mysqlnd_result_buffered_c::fetch_lengths");
|
||||
|
||||
if (set->current_row > set->row_count || set->current_row == 0) {
|
||||
DBG_INF("EOF");
|
||||
DBG_RETURN(NULL); /* No more rows, or no fetched row */
|
||||
}
|
||||
|
||||
return result->lengths;
|
||||
DBG_INF("non NULL");
|
||||
DBG_RETURN(result->lengths);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -767,7 +874,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
|
||||
|
||||
/* {{{ mysqlnd_result_unbuffered::fetch_row */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC)
|
||||
MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void * param, const php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC)
|
||||
{
|
||||
enum_func_status ret;
|
||||
zval *row = (zval *) param;
|
||||
@@ -944,74 +1051,86 @@ static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC)
|
||||
{
|
||||
MYSQLND_ROW_C * row = (MYSQLND_ROW_C *) param;
|
||||
MYSQLND_RES_BUFFERED * set = result->stored_data;
|
||||
const MYSQLND_RES_METADATA * const meta = result->meta;
|
||||
php_uint_t field_count = meta->field_count;
|
||||
enum_func_status ret = FAIL;
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered::fetch_row_c");
|
||||
|
||||
/* If we haven't read everything */
|
||||
if (set->data_cursor &&
|
||||
(set->data_cursor - set->data) < (set->row_count * field_count))
|
||||
{
|
||||
zval **current_row = set->data_cursor;
|
||||
MYSQLND_FIELD * field = meta->fields;
|
||||
php_uint_t i;
|
||||
if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_ZVAL) {
|
||||
MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data;
|
||||
|
||||
if (NULL == current_row[0]) {
|
||||
uint64_t row_num = (set->data_cursor - set->data) / field_count;
|
||||
enum_func_status rc = set->m.row_decoder(set->row_buffers[row_num],
|
||||
current_row,
|
||||
field_count,
|
||||
meta->fields,
|
||||
result->conn->options->int_and_float_native,
|
||||
result->conn->stats TSRMLS_CC);
|
||||
if (rc != PASS) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
set->initialized_rows++;
|
||||
for (i = 0; i < field_count; i++) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
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) {
|
||||
php_uint_t len = Z_STRSIZE_P(current_row[i]);
|
||||
if (field->max_length < len) {
|
||||
field->max_length = len;
|
||||
/* If we haven't read everything */
|
||||
if (set->data_cursor &&
|
||||
(set->data_cursor - set->data) < (result->stored_data->row_count * field_count))
|
||||
{
|
||||
zval **current_row = set->data_cursor;
|
||||
unsigned int i;
|
||||
|
||||
if (NULL == current_row[0]) {
|
||||
uint64_t row_num = (set->data_cursor - set->data) / field_count;
|
||||
enum_func_status rc = set->m.row_decoder(set->row_buffers[row_num],
|
||||
current_row,
|
||||
field_count,
|
||||
meta->fields,
|
||||
result->conn->options->int_and_float_native,
|
||||
result->conn->stats TSRMLS_CC);
|
||||
if (rc != PASS) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
set->initialized_rows++;
|
||||
for (i = 0; i < field_count; i++) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
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) {
|
||||
unsigned long len = Z_STRSIZE_P(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* BEGIN difference between normal normal fetch and _c */
|
||||
/* there is no conn handle in this function thus we can't set OOM in error_info */
|
||||
*row = mnd_malloc(field_count * sizeof(char *));
|
||||
if (ret) {
|
||||
for (i = 0; i < field_count; i++) {
|
||||
zval * data = current_row[i];
|
||||
/* there is no conn handle in this function thus we can't set OOM in error_info */
|
||||
*row = mnd_malloc(field_count * sizeof(char *));
|
||||
if (*row) {
|
||||
for (i = 0; i < field_count; i++) {
|
||||
zval * data = current_row[i];
|
||||
|
||||
if (Z_TYPE_P(data) != IS_NULL) {
|
||||
convert_to_string(data);
|
||||
(*row)[i] = Z_STRVAL_P(data);
|
||||
} else {
|
||||
(*row)[i] = NULL;
|
||||
set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRSIZE_P(data);
|
||||
|
||||
if (Z_TYPE_P(data) != IS_NULL) {
|
||||
convert_to_string(data);
|
||||
(*row)[i] = Z_STRVAL_P(data);
|
||||
} else {
|
||||
(*row)[i] = NULL;
|
||||
}
|
||||
}
|
||||
set->data_cursor += field_count;
|
||||
MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF);
|
||||
} else {
|
||||
SET_OOM_ERROR(*result->conn->error_info);
|
||||
}
|
||||
}
|
||||
/* END difference between normal normal fetch and _c */
|
||||
|
||||
set->data_cursor += field_count;
|
||||
MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF);
|
||||
*fetched_anything = TRUE;
|
||||
ret = PASS;
|
||||
} else {
|
||||
set->data_cursor = NULL;
|
||||
DBG_INF("EOF reached");
|
||||
*fetched_anything = *row? TRUE:FALSE;
|
||||
ret = *row? PASS:FAIL;
|
||||
} else {
|
||||
set->data_cursor = NULL;
|
||||
DBG_INF("EOF reached");
|
||||
*fetched_anything = FALSE;
|
||||
ret = PASS;
|
||||
}
|
||||
} else if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_C) {
|
||||
/*
|
||||
We don't support _C with pdo because it uses the data in a different way - just references it.
|
||||
We will either leak or give nirvana pointers
|
||||
*/
|
||||
*fetched_anything = FALSE;
|
||||
ret = PASS;
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
DBG_INF_FMT("ret=PASS fetched=%u", *fetched_anything);
|
||||
DBG_RETURN(ret);
|
||||
@@ -1019,25 +1138,24 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered::fetch_row */
|
||||
/* {{{ mysqlnd_result_buffered_zval::fetch_row */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC)
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool * fetched_anything TSRMLS_DC)
|
||||
{
|
||||
zval * row = (zval *) param;
|
||||
MYSQLND_RES_BUFFERED * set = result->stored_data;
|
||||
const MYSQLND_RES_METADATA * const meta = result->meta;
|
||||
php_uint_t field_count = meta->field_count;
|
||||
enum_func_status ret = FAIL;
|
||||
MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data;
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered::fetch_row");
|
||||
DBG_ENTER("mysqlnd_result_buffered_zval::fetch_row");
|
||||
|
||||
/* If we haven't read everything */
|
||||
if (set->data_cursor &&
|
||||
(set->data_cursor - set->data) < (set->row_count * field_count))
|
||||
{
|
||||
zval **current_row = set->data_cursor;
|
||||
MYSQLND_FIELD * field = meta->fields;
|
||||
php_uint_t i;
|
||||
zval **current_row = set->data_cursor;
|
||||
|
||||
if (NULL == current_row[0]) {
|
||||
uint64_t row_num = (set->data_cursor - set->data) / field_count;
|
||||
@@ -1058,17 +1176,19 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row)(MYSQLND_RES * result, void *
|
||||
Thus for NULL and zero-length we are quite efficient.
|
||||
*/
|
||||
if (Z_TYPE_P(current_row[i]) >= IS_STRING) {
|
||||
php_uint_t len = Z_STRSIZE_P(current_row[i]);
|
||||
if (field->max_length < len) {
|
||||
field->max_length = len;
|
||||
php_size_t len = Z_STRSIZE_P(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < field_count; i++, field++) {
|
||||
for (i = 0; i < field_count; i++) {
|
||||
zval * data = current_row[i];
|
||||
|
||||
set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRSIZE_P(data);
|
||||
|
||||
if (flags & MYSQLND_FETCH_NUM) {
|
||||
Z_ADDREF_P(data);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL);
|
||||
@@ -1084,12 +1204,12 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row)(MYSQLND_RES * result, void *
|
||||
Z_ADDREF_P(data);
|
||||
if (meta->zend_hash_keys[i].is_numeric == FALSE) {
|
||||
zend_hash_quick_update(Z_ARRVAL_P(row),
|
||||
field->name,
|
||||
field->name_length + 1,
|
||||
meta->fields[i].name,
|
||||
meta->fields[i].name_length + 1,
|
||||
meta->zend_hash_keys[i].key,
|
||||
(void *) &data, sizeof(zval *), NULL);
|
||||
} else {
|
||||
zend_hash_index_update(Z_ARRVAL_P(row),
|
||||
zend_hash_index_update(Z_ARRVAL_P(row),
|
||||
meta->zend_hash_keys[i].key,
|
||||
(void *) &data, sizeof(zval *), NULL);
|
||||
}
|
||||
@@ -1111,9 +1231,121 @@ MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row)(MYSQLND_RES * result, void *
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered_c::fetch_row */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void * param, const php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC)
|
||||
{
|
||||
zval * row = (zval *) param;
|
||||
const MYSQLND_RES_METADATA * const meta = result->meta;
|
||||
php_uint_t field_count = meta->field_count;
|
||||
enum_func_status ret = FAIL;
|
||||
|
||||
MYSQLND_RES_BUFFERED_C * set = (MYSQLND_RES_BUFFERED_C *) result->stored_data;
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered_c::fetch_row");
|
||||
|
||||
/* If we haven't read everything */
|
||||
if (set->current_row < set->row_count) {
|
||||
zval **current_row;
|
||||
enum_func_status rc;
|
||||
php_uint_t i;
|
||||
|
||||
current_row = mnd_emalloc(field_count * sizeof(zval *));
|
||||
if (!current_row) {
|
||||
SET_OOM_ERROR(*result->conn->error_info);
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
|
||||
rc = result->stored_data->m.row_decoder(result->stored_data->row_buffers[set->current_row],
|
||||
current_row,
|
||||
field_count,
|
||||
meta->fields,
|
||||
result->conn->options->int_and_float_native,
|
||||
result->conn->stats TSRMLS_CC);
|
||||
if (rc != PASS) {
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
if (!(set->initialized[set->current_row >> 3] & (1 << (set->current_row & 7)))) {
|
||||
set->initialized[set->current_row >> 3] |= (1 << (set->current_row & 7)); /* mark initialized */
|
||||
|
||||
set->initialized_rows++;
|
||||
|
||||
for (i = 0; i < field_count; i++) {
|
||||
/*
|
||||
NULL fields are 0 length, 0 is not more than 0
|
||||
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) {
|
||||
php_size_t len = Z_STRSIZE_P(current_row[i]);
|
||||
if (meta->fields[i].max_length < len) {
|
||||
meta->fields[i].max_length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < field_count; i++) {
|
||||
zval * data = current_row[i];
|
||||
|
||||
set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRSIZE_P(data);
|
||||
|
||||
if (flags & MYSQLND_FETCH_NUM) {
|
||||
Z_ADDREF_P(data);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL);
|
||||
}
|
||||
if (flags & MYSQLND_FETCH_ASSOC) {
|
||||
/* zend_hash_quick_update needs length + trailing zero */
|
||||
/* QQ: Error handling ? */
|
||||
/*
|
||||
zend_hash_quick_update does not check, as add_assoc_zval_ex do, whether
|
||||
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.
|
||||
*/
|
||||
Z_ADDREF_P(data);
|
||||
if (meta->zend_hash_keys[i].is_numeric == FALSE) {
|
||||
zend_hash_quick_update(Z_ARRVAL_P(row),
|
||||
meta->fields[i].name,
|
||||
meta->fields[i].name_length + 1,
|
||||
meta->zend_hash_keys[i].key,
|
||||
(void *) &data, sizeof(zval *), NULL);
|
||||
} else {
|
||||
zend_hash_index_update(Z_ARRVAL_P(row),
|
||||
meta->zend_hash_keys[i].key,
|
||||
(void *) &data, sizeof(zval *), NULL);
|
||||
}
|
||||
}
|
||||
/*
|
||||
This will usually not destroy anything but decref.
|
||||
However, if neither NUM nor ASSOC is set we will free memory cleanly and won't leak.
|
||||
It also simplifies the handling of Z_ADDREF_P because we don't need to check if only
|
||||
either NUM or ASSOC is set but not both.
|
||||
*/
|
||||
zval_ptr_dtor(&data);
|
||||
}
|
||||
mnd_efree(current_row);
|
||||
set->current_row++;
|
||||
MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF);
|
||||
*fetched_anything = TRUE;
|
||||
ret = PASS;
|
||||
} else {
|
||||
if (set->current_row == set->row_count) {
|
||||
set->current_row = set->row_count + 1;
|
||||
}
|
||||
DBG_INF_FMT("EOF reached. current_row=%llu", (unsigned long long) set->current_row);
|
||||
*fetched_anything = FALSE;
|
||||
ret = PASS;
|
||||
}
|
||||
|
||||
DBG_INF_FMT("ret=PASS fetched=%u", *fetched_anything);
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_res::fetch_row */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_res, fetch_row)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool *fetched_anything TSRMLS_DC)
|
||||
MYSQLND_METHOD(mysqlnd_res, fetch_row)(MYSQLND_RES * result, void * param, const php_uint_t flags, zend_bool *fetched_anything TSRMLS_DC)
|
||||
{
|
||||
const mysqlnd_fetch_row_func f = result->stored_data? result->stored_data->m.fetch_row:(result->unbuf? result->unbuf->m.fetch_row:NULL);
|
||||
if (f) {
|
||||
@@ -1131,6 +1363,7 @@ MYSQLND_METHOD(mysqlnd_res, fetch_row)(MYSQLND_RES * result, void * param, php_u
|
||||
enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const conn, MYSQLND_RES * result,
|
||||
MYSQLND_RES_METADATA * meta,
|
||||
MYSQLND_MEMORY_POOL_CHUNK ***row_buffers,
|
||||
zend_bool binary_protocol TSRMLS_DC)
|
||||
{
|
||||
enum_func_status ret;
|
||||
@@ -1142,13 +1375,13 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
|
||||
|
||||
set = result->stored_data;
|
||||
|
||||
if (!set) {
|
||||
if (!set || !row_buffers) {
|
||||
ret = FAIL;
|
||||
goto end;
|
||||
}
|
||||
if (free_rows) {
|
||||
set->row_buffers = mnd_emalloc((size_t)(free_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)));
|
||||
if (!set->row_buffers) {
|
||||
*row_buffers = mnd_pemalloc((size_t)(free_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)), 0);
|
||||
if (!*row_buffers) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
ret = FAIL;
|
||||
goto end;
|
||||
@@ -1184,16 +1417,16 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
|
||||
ret = FAIL;
|
||||
goto end;
|
||||
}
|
||||
new_row_buffers = mnd_erealloc(set->row_buffers, (size_t)(total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)));
|
||||
new_row_buffers = mnd_perealloc(*row_buffers, (size_t)(total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)), 0);
|
||||
if (!new_row_buffers) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
ret = FAIL;
|
||||
goto end;
|
||||
}
|
||||
set->row_buffers = new_row_buffers;
|
||||
*row_buffers = new_row_buffers;
|
||||
}
|
||||
free_rows--;
|
||||
set->row_buffers[set->row_count] = row_packet->row_buffer;
|
||||
(*row_buffers)[set->row_count] = row_packet->row_buffer;
|
||||
|
||||
set->row_count++;
|
||||
|
||||
@@ -1228,7 +1461,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
|
||||
ret = FAIL;
|
||||
goto end;
|
||||
}
|
||||
set->row_buffers = mnd_erealloc(set->row_buffers, (size_t) (set->row_count * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)));
|
||||
*row_buffers = mnd_perealloc(*row_buffers, (size_t) (set->row_count * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)), 0);
|
||||
}
|
||||
|
||||
if (conn->upsert_status->server_status & SERVER_MORE_RESULTS_EXISTS) {
|
||||
@@ -1247,7 +1480,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
|
||||
ret == PASS? "PASS":"FAIL", (uint) set->row_count, conn->upsert_status->warning_count, conn->upsert_status->server_status);
|
||||
end:
|
||||
PACKET_FREE(row_packet);
|
||||
|
||||
DBG_INF_FMT("rows=%llu", (unsigned long long)result->stored_data->row_count);
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -1260,6 +1493,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
|
||||
const unsigned int flags TSRMLS_DC)
|
||||
{
|
||||
enum_func_status ret;
|
||||
MYSQLND_MEMORY_POOL_CHUNK ***row_buffers = NULL;
|
||||
|
||||
DBG_ENTER("mysqlnd_res::store_result");
|
||||
|
||||
@@ -1270,13 +1504,23 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
|
||||
|
||||
CONN_SET_STATE(conn, CONN_FETCHING_DATA);
|
||||
|
||||
result->stored_data = mysqlnd_result_buffered_init(result->field_count, flags & MYSQLND_STORE_PS, result->persistent TSRMLS_CC);
|
||||
if (!result->stored_data) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
if (flags & MYSQLND_STORE_NO_COPY) {
|
||||
result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_zval_init(result->field_count, flags & MYSQLND_STORE_PS, result->persistent TSRMLS_CC);
|
||||
if (!result->stored_data) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
row_buffers = &result->stored_data->row_buffers;
|
||||
} else if (flags & MYSQLND_STORE_COPY) {
|
||||
result->stored_data = (MYSQLND_RES_BUFFERED *) mysqlnd_result_buffered_c_init(result->field_count, flags & MYSQLND_STORE_PS, result->persistent TSRMLS_CC);
|
||||
if (!result->stored_data) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
row_buffers = &result->stored_data->row_buffers;
|
||||
}
|
||||
ret = result->m.store_result_fetch_data(conn, result, result->meta, row_buffers, flags & MYSQLND_STORE_PS TSRMLS_CC);
|
||||
|
||||
ret = result->m.store_result_fetch_data(conn, result, result->meta, flags & MYSQLND_STORE_PS TSRMLS_CC);
|
||||
if (FAIL == ret) {
|
||||
if (result->stored_data) {
|
||||
COPY_CLIENT_ERROR(*conn->error_info, result->stored_data->error_info);
|
||||
@@ -1286,24 +1530,30 @@ MYSQLND_METHOD(mysqlnd_res, store_result)(MYSQLND_RES * result,
|
||||
DBG_RETURN(NULL);
|
||||
} else {
|
||||
/* Overflow ? */
|
||||
MYSQLND_RES_METADATA * meta = result->meta;
|
||||
MYSQLND_RES_BUFFERED * set = result->stored_data;
|
||||
if (set->row_count) {
|
||||
/* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */
|
||||
if (set->row_count * meta->field_count * sizeof(zval *) > SIZE_MAX) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
if (flags & MYSQLND_STORE_NO_COPY) {
|
||||
MYSQLND_RES_METADATA * meta = result->meta;
|
||||
MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data;
|
||||
if (set->row_count) {
|
||||
/* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */
|
||||
if (set->row_count * meta->field_count * sizeof(zval *) > SIZE_MAX) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
/* if pecalloc is used valgrind barks gcc version 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux) */
|
||||
set->data = mnd_emalloc((size_t)(set->row_count * meta->field_count * sizeof(zval *)));
|
||||
if (!set->data) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
memset(set->data, 0, (size_t)(set->row_count * meta->field_count * sizeof(zval *)));
|
||||
}
|
||||
/* if pecalloc is used valgrind barks gcc version 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux) */
|
||||
set->data = mnd_emalloc((size_t)(set->row_count * meta->field_count * sizeof(zval *)));
|
||||
if (!set->data) {
|
||||
SET_OOM_ERROR(*conn->error_info);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
memset(set->data, 0, (size_t)(set->row_count * meta->field_count * sizeof(zval *)));
|
||||
/* Position at the first row */
|
||||
set->data_cursor = set->data;
|
||||
} else if (flags & MYSQLND_STORE_COPY) {
|
||||
MYSQLND_RES_BUFFERED_C * set = (MYSQLND_RES_BUFFERED_C *) result->stored_data;
|
||||
set->current_row = 0;
|
||||
set->initialized = mnd_pecalloc((set->row_count / 8) + 1, sizeof(zend_uchar), set->persistent); /* +1 for safety */
|
||||
}
|
||||
/* Position at the first row */
|
||||
set->data_cursor = set->data;
|
||||
}
|
||||
|
||||
/* libmysql's documentation says it should be so for SELECT statements */
|
||||
@@ -1370,19 +1620,37 @@ MYSQLND_METHOD(mysqlnd_res, data_seek)(MYSQLND_RES * const result, const uint64_
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered::data_seek */
|
||||
/* {{{ mysqlnd_result_buffered_zval::data_seek */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, data_seek)(MYSQLND_RES_BUFFERED * const result, const uint64_t row TSRMLS_DC)
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_zval, data_seek)(MYSQLND_RES_BUFFERED * const result, const uint64_t row TSRMLS_DC)
|
||||
{
|
||||
DBG_ENTER("mysqlnd_result_buffered::data_seek");
|
||||
MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result;
|
||||
DBG_ENTER("mysqlnd_result_buffered_zval::data_seek");
|
||||
|
||||
/* libmysql just moves to the end, it does traversing of a linked list */
|
||||
if (row >= result->row_count) {
|
||||
result->data_cursor = NULL;
|
||||
if (row >= set->row_count) {
|
||||
set->data_cursor = NULL;
|
||||
} else {
|
||||
result->data_cursor = result->data + row * result->field_count;
|
||||
set->data_cursor = set->data + row * result->field_count;
|
||||
}
|
||||
DBG_RETURN(PASS);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered_c::data_seek */
|
||||
static enum_func_status
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered_c, data_seek)(MYSQLND_RES_BUFFERED * const result, const uint64_t row TSRMLS_DC)
|
||||
{
|
||||
MYSQLND_RES_BUFFERED_C * set = (MYSQLND_RES_BUFFERED_C *) result;
|
||||
DBG_ENTER("mysqlnd_result_buffered_c::data_seek");
|
||||
|
||||
/* libmysql just moves to the end, it does traversing of a linked list */
|
||||
if (row >= set->row_count) {
|
||||
set->current_row = set->row_count;
|
||||
} else {
|
||||
set->current_row = row;
|
||||
}
|
||||
DBG_RETURN(PASS);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -1539,7 +1807,7 @@ MYSQLND_METHOD(mysqlnd_res, field_tell)(const MYSQLND_RES * const result TSRMLS_
|
||||
|
||||
/* {{{ mysqlnd_res::fetch_into */
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, php_uint_t flags,
|
||||
MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const php_uint_t flags,
|
||||
zval *return_value,
|
||||
enum_mysqlnd_extension extension TSRMLS_DC ZEND_FILE_LINE_DC)
|
||||
{
|
||||
@@ -1585,7 +1853,7 @@ 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->stored_data && result->stored_data->m.fetch_row == MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row)) {
|
||||
if (result->stored_data && result->stored_data->m.fetch_row == MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)) {
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(result, (void *) &ret, 0, &fetched_anything TSRMLS_CC);
|
||||
} else if (result->unbuf && result->unbuf->m.fetch_row == MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)) {
|
||||
MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(result, (void *) &ret, 0, &fetched_anything TSRMLS_CC);
|
||||
@@ -1600,7 +1868,7 @@ MYSQLND_METHOD(mysqlnd_res, fetch_row_c)(MYSQLND_RES * result TSRMLS_DC)
|
||||
|
||||
/* {{{ mysqlnd_res::fetch_all */
|
||||
static void
|
||||
MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC)
|
||||
MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, const php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC)
|
||||
{
|
||||
zval *row;
|
||||
php_uint_t i = 0;
|
||||
@@ -1713,12 +1981,12 @@ MYSQLND_CLASS_METHODS_END;
|
||||
|
||||
|
||||
MYSQLND_CLASS_METHODS_START(mysqlnd_result_buffered)
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row),
|
||||
NULL, /* fetch_row */
|
||||
NULL, /* row_decoder */
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, num_rows),
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, fetch_lengths),
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, data_seek),
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, initialize_result_set_rest),
|
||||
NULL, /* fetch_lengths */
|
||||
NULL, /* data_seek */
|
||||
NULL, /* initialize_result_set_rest */
|
||||
MYSQLND_METHOD(mysqlnd_result_buffered, free_result)
|
||||
MYSQLND_CLASS_METHODS_END;
|
||||
|
||||
@@ -1778,7 +2046,7 @@ mysqlnd_result_unbuffered_init(php_uint_t field_count, zend_bool ps, zend_bool p
|
||||
ret->m.fetch_lengths = NULL; /* makes no sense */
|
||||
ret->m.row_decoder = php_mysqlnd_rowp_read_binary_protocol;
|
||||
} else {
|
||||
ret->m.row_decoder = php_mysqlnd_rowp_read_text_protocol;
|
||||
ret->m.row_decoder = php_mysqlnd_rowp_read_text_protocol_zval;
|
||||
}
|
||||
|
||||
DBG_RETURN(ret);
|
||||
@@ -1786,14 +2054,14 @@ mysqlnd_result_unbuffered_init(php_uint_t field_count, zend_bool ps, zend_bool p
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered_init */
|
||||
PHPAPI MYSQLND_RES_BUFFERED *
|
||||
mysqlnd_result_buffered_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC)
|
||||
/* {{{ mysqlnd_result_buffered_zval_init */
|
||||
PHPAPI MYSQLND_RES_BUFFERED_ZVAL *
|
||||
mysqlnd_result_buffered_zval_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC)
|
||||
{
|
||||
size_t alloc_size = sizeof(MYSQLND_RES_BUFFERED) + mysqlnd_plugin_count() * sizeof(void *);
|
||||
MYSQLND_RES_BUFFERED * ret = mnd_pecalloc(1, alloc_size, persistent);
|
||||
size_t alloc_size = sizeof(MYSQLND_RES_BUFFERED_ZVAL) + mysqlnd_plugin_count() * sizeof(void *);
|
||||
MYSQLND_RES_BUFFERED_ZVAL * ret = mnd_pecalloc(1, alloc_size, persistent);
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered_init");
|
||||
DBG_ENTER("mysqlnd_result_buffered_zval_init");
|
||||
|
||||
if (!ret) {
|
||||
DBG_RETURN(NULL);
|
||||
@@ -1812,13 +2080,61 @@ mysqlnd_result_buffered_init(php_uint_t field_count, zend_bool ps, zend_bool per
|
||||
ret->field_count= field_count;
|
||||
ret->ps = ps;
|
||||
ret->m = *mysqlnd_result_buffered_get_methods();
|
||||
ret->type = MYSQLND_BUFFERED_TYPE_ZVAL;
|
||||
|
||||
if (ps) {
|
||||
ret->m.fetch_lengths = NULL; /* makes no sense */
|
||||
ret->m.row_decoder = php_mysqlnd_rowp_read_binary_protocol;
|
||||
} else {
|
||||
ret->m.row_decoder = php_mysqlnd_rowp_read_text_protocol;
|
||||
ret->m.row_decoder = php_mysqlnd_rowp_read_text_protocol_zval;
|
||||
}
|
||||
ret->m.fetch_row = MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row);
|
||||
ret->m.fetch_lengths = MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_lengths);
|
||||
ret->m.data_seek = MYSQLND_METHOD(mysqlnd_result_buffered_zval, data_seek);
|
||||
ret->m.initialize_result_set_rest = MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest);
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ mysqlnd_result_buffered_c_init */
|
||||
PHPAPI MYSQLND_RES_BUFFERED_C *
|
||||
mysqlnd_result_buffered_c_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC)
|
||||
{
|
||||
size_t alloc_size = sizeof(MYSQLND_RES_BUFFERED_C) + mysqlnd_plugin_count() * sizeof(void *);
|
||||
MYSQLND_RES_BUFFERED_C * ret = mnd_pecalloc(1, alloc_size, persistent);
|
||||
|
||||
DBG_ENTER("mysqlnd_result_buffered_c_init");
|
||||
|
||||
if (!ret) {
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
if (!(ret->lengths = mnd_pecalloc(field_count, sizeof(php_uint_t), persistent))) {
|
||||
mnd_pefree(ret, persistent);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
if (!(ret->result_set_memory_pool = mysqlnd_mempool_create(MYSQLND_G(mempool_default_size) TSRMLS_CC))) {
|
||||
mnd_efree(ret->lengths);
|
||||
mnd_pefree(ret, persistent);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
|
||||
ret->persistent = persistent;
|
||||
ret->field_count= field_count;
|
||||
ret->ps = ps;
|
||||
ret->m = *mysqlnd_result_buffered_get_methods();
|
||||
ret->type = MYSQLND_BUFFERED_TYPE_C;
|
||||
|
||||
if (ps) {
|
||||
ret->m.fetch_lengths = NULL; /* makes no sense */
|
||||
ret->m.row_decoder = php_mysqlnd_rowp_read_binary_protocol;
|
||||
} else {
|
||||
ret->m.row_decoder = php_mysqlnd_rowp_read_text_protocol_c;
|
||||
}
|
||||
ret->m.fetch_row = MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row);
|
||||
ret->m.fetch_lengths = MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_lengths);
|
||||
ret->m.data_seek = MYSQLND_METHOD(mysqlnd_result_buffered_c, data_seek);
|
||||
ret->m.initialize_result_set_rest = MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest);
|
||||
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
|
||||
PHPAPI MYSQLND_RES * mysqlnd_result_init(php_uint_t field_count, zend_bool persistent TSRMLS_DC);
|
||||
PHPAPI MYSQLND_RES_UNBUFFERED * mysqlnd_result_unbuffered_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC);
|
||||
PHPAPI MYSQLND_RES_BUFFERED * mysqlnd_result_buffered_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC);
|
||||
PHPAPI MYSQLND_RES_BUFFERED_ZVAL * mysqlnd_result_buffered_zval_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC);
|
||||
PHPAPI MYSQLND_RES_BUFFERED_C * mysqlnd_result_buffered_c_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC);
|
||||
|
||||
enum_func_status mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * stmt TSRMLS_DC);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ mysqlnd_reverse_api_register_api(MYSQLND_REVERSE_API * apiext TSRMLS_DC)
|
||||
|
||||
/* {{{ zval_to_mysqlnd */
|
||||
PHPAPI MYSQLND *
|
||||
zval_to_mysqlnd(zval * zv TSRMLS_DC)
|
||||
zval_to_mysqlnd(zval * zv, const unsigned int client_api_capabilities, unsigned int * save_client_api_capabilities TSRMLS_DC)
|
||||
{
|
||||
MYSQLND * retval;
|
||||
MYSQLND_REVERSE_API ** elem;
|
||||
@@ -80,6 +80,9 @@ zval_to_mysqlnd(zval * zv TSRMLS_DC)
|
||||
if ((*elem)->conversion_cb) {
|
||||
retval = (*elem)->conversion_cb(zv TSRMLS_CC);
|
||||
if (retval) {
|
||||
if (retval->data) {
|
||||
*save_client_api_capabilities = retval->data->m->negotiate_client_api_capabilities(retval->data, client_api_capabilities TSRMLS_CC);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,7 @@ PHPAPI void mysqlnd_reverse_api_end(TSRMLS_D);
|
||||
PHPAPI HashTable * mysqlnd_reverse_api_get_api_list(TSRMLS_D);
|
||||
|
||||
PHPAPI void mysqlnd_reverse_api_register_api(MYSQLND_REVERSE_API * apiext TSRMLS_DC);
|
||||
|
||||
PHPAPI MYSQLND * zval_to_mysqlnd(zval * zv TSRMLS_DC);
|
||||
PHPAPI MYSQLND * zval_to_mysqlnd(zval * zv, const unsigned int client_api_capabilities, unsigned int * save_client_api_capabilities TSRMLS_DC);
|
||||
|
||||
#endif /* MYSQLND_REVERSE_API_H */
|
||||
|
||||
|
||||
@@ -235,7 +235,9 @@ typedef struct st_mysqlnd_param_bind MYSQLND_PARAM_BIND;
|
||||
typedef struct st_mysqlnd_result_bind MYSQLND_RESULT_BIND;
|
||||
|
||||
typedef struct st_mysqlnd_result_metadata MYSQLND_RES_METADATA;
|
||||
typedef struct st_mysqlnd_buffered_result MYSQLND_RES_BUFFERED;
|
||||
typedef struct st_mysqlnd_buffered_result_parent MYSQLND_RES_BUFFERED;
|
||||
typedef struct st_mysqlnd_buffered_result_zval MYSQLND_RES_BUFFERED_ZVAL;
|
||||
typedef struct st_mysqlnd_buffered_result_c MYSQLND_RES_BUFFERED_C;
|
||||
typedef struct st_mysqlnd_unbuffered_result MYSQLND_RES_UNBUFFERED;
|
||||
|
||||
typedef struct st_mysqlnd_debug MYSQLND_DEBUG;
|
||||
@@ -244,7 +246,7 @@ typedef struct st_mysqlnd_debug MYSQLND_DEBUG;
|
||||
typedef MYSQLND_RES* (*mysqlnd_stmt_use_or_store_func)(MYSQLND_STMT * const TSRMLS_DC);
|
||||
typedef enum_func_status (*mysqlnd_fetch_row_func)(MYSQLND_RES *result,
|
||||
void * param,
|
||||
php_uint_t flags,
|
||||
const php_uint_t flags,
|
||||
zend_bool * fetched_anything
|
||||
TSRMLS_DC);
|
||||
|
||||
@@ -500,6 +502,11 @@ typedef struct st_mysqlnd_authentication_plugin * (*func_mysqlnd_conn_data__fetc
|
||||
|
||||
typedef enum_func_status (*func_mysqlnd_conn_data__set_client_option_2d)(MYSQLND_CONN_DATA * const conn, enum mysqlnd_option option, const char * const key, const char * const value TSRMLS_DC);
|
||||
|
||||
|
||||
typedef unsigned int (*func_mysqlnd_conn_data__negotiate_client_api_capabilities)(MYSQLND_CONN_DATA * const conn, const unsigned int flags TSRMLS_DC);
|
||||
typedef unsigned int (*func_mysqlnd_conn_data__get_client_api_capabilities)(const MYSQLND_CONN_DATA * const conn TSRMLS_DC);
|
||||
|
||||
|
||||
struct st_mysqlnd_conn_data_methods
|
||||
{
|
||||
func_mysqlnd_conn_data__init init;
|
||||
@@ -591,6 +598,9 @@ struct st_mysqlnd_conn_data_methods
|
||||
func_mysqlnd_conn_data__fetch_auth_plugin_by_name fetch_auth_plugin_by_name;
|
||||
|
||||
func_mysqlnd_conn_data__set_client_option_2d set_client_option_2d;
|
||||
|
||||
func_mysqlnd_conn_data__negotiate_client_api_capabilities negotiate_client_api_capabilities;
|
||||
func_mysqlnd_conn_data__get_client_api_capabilities get_client_api_capabilities;
|
||||
};
|
||||
|
||||
|
||||
@@ -615,9 +625,9 @@ typedef enum_func_status (*func_mysqlnd_res__row_decoder)(MYSQLND_MEMORY_POOL_CH
|
||||
|
||||
typedef MYSQLND_RES * (*func_mysqlnd_res__use_result)(MYSQLND_RES * const result, zend_bool ps_protocol TSRMLS_DC);
|
||||
typedef MYSQLND_RES * (*func_mysqlnd_res__store_result)(MYSQLND_RES * result, MYSQLND_CONN_DATA * const conn, const php_uint_t flags TSRMLS_DC);
|
||||
typedef void (*func_mysqlnd_res__fetch_into)(MYSQLND_RES *result, php_uint_t flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC);
|
||||
typedef void (*func_mysqlnd_res__fetch_into)(MYSQLND_RES *result, const php_uint_t flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC);
|
||||
typedef MYSQLND_ROW_C (*func_mysqlnd_res__fetch_row_c)(MYSQLND_RES *result TSRMLS_DC);
|
||||
typedef void (*func_mysqlnd_res__fetch_all)(MYSQLND_RES *result, php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC);
|
||||
typedef void (*func_mysqlnd_res__fetch_all)(MYSQLND_RES *result, const php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC);
|
||||
typedef void (*func_mysqlnd_res__fetch_field_data)(MYSQLND_RES *result, php_uint_t offset, zval *return_value TSRMLS_DC);
|
||||
typedef uint64_t (*func_mysqlnd_res__num_rows)(const MYSQLND_RES * const result TSRMLS_DC);
|
||||
typedef php_uint_t (*func_mysqlnd_res__num_fields)(const MYSQLND_RES * const result TSRMLS_DC);
|
||||
@@ -631,7 +641,7 @@ typedef const MYSQLND_FIELD *(*func_mysqlnd_res__fetch_fields)(MYSQLND_RES * con
|
||||
|
||||
typedef enum_func_status (*func_mysqlnd_res__read_result_metadata)(MYSQLND_RES * result, MYSQLND_CONN_DATA * conn TSRMLS_DC);
|
||||
typedef php_uint_t * (*func_mysqlnd_res__fetch_lengths)(MYSQLND_RES * const result TSRMLS_DC);
|
||||
typedef enum_func_status (*func_mysqlnd_res__store_result_fetch_data)(MYSQLND_CONN_DATA * const conn, MYSQLND_RES * result, MYSQLND_RES_METADATA *meta, zend_bool binary_protocol TSRMLS_DC);
|
||||
typedef enum_func_status (*func_mysqlnd_res__store_result_fetch_data)(MYSQLND_CONN_DATA * const conn, MYSQLND_RES * result, MYSQLND_RES_METADATA * meta, MYSQLND_MEMORY_POOL_CHUNK *** row_buffers, zend_bool binary_protocol TSRMLS_DC);
|
||||
|
||||
typedef void (*func_mysqlnd_res__free_result_buffers)(MYSQLND_RES * result TSRMLS_DC); /* private */
|
||||
typedef enum_func_status (*func_mysqlnd_res__free_result)(MYSQLND_RES * result, zend_bool implicit TSRMLS_DC);
|
||||
@@ -947,9 +957,6 @@ struct st_mysqlnd_connection_data
|
||||
/* Temporal storage for mysql_query */
|
||||
php_uint_t field_count;
|
||||
|
||||
/* persistent connection */
|
||||
zend_bool persistent;
|
||||
|
||||
/* options */
|
||||
MYSQLND_OPTIONS * options;
|
||||
MYSQLND_OPTIONS options_impl;
|
||||
@@ -957,7 +964,12 @@ struct st_mysqlnd_connection_data
|
||||
/* stats */
|
||||
MYSQLND_STATS * stats;
|
||||
|
||||
unsigned int client_api_capabilities;
|
||||
|
||||
struct st_mysqlnd_conn_data_methods * m;
|
||||
|
||||
/* persistent connection */
|
||||
zend_bool persistent;
|
||||
};
|
||||
|
||||
|
||||
@@ -991,31 +1003,50 @@ struct st_mysqlnd_result_metadata
|
||||
};
|
||||
|
||||
|
||||
struct st_mysqlnd_buffered_result
|
||||
#define def_mysqlnd_buffered_result_parent \
|
||||
MYSQLND_MEMORY_POOL_CHUNK **row_buffers; \
|
||||
uint64_t row_count; \
|
||||
uint64_t initialized_rows; \
|
||||
\
|
||||
/* Column lengths of current row - both buffered and unbuffered. For buffered results it duplicates the data found in **data */ \
|
||||
unsigned long *lengths; \
|
||||
\
|
||||
MYSQLND_MEMORY_POOL *result_set_memory_pool; \
|
||||
\
|
||||
unsigned int references; \
|
||||
\
|
||||
MYSQLND_ERROR_INFO error_info; \
|
||||
\
|
||||
unsigned int field_count; \
|
||||
zend_bool ps; \
|
||||
zend_bool persistent; \
|
||||
struct st_mysqlnd_result_buffered_methods m; \
|
||||
enum mysqlnd_buffered_type type; \
|
||||
void * unused1; \
|
||||
void * unused2; \
|
||||
void * unused3
|
||||
|
||||
|
||||
struct st_mysqlnd_buffered_result_parent
|
||||
{
|
||||
zval **data;
|
||||
zval **data_cursor;
|
||||
MYSQLND_MEMORY_POOL_CHUNK **row_buffers;
|
||||
uint64_t row_count;
|
||||
uint64_t initialized_rows;
|
||||
def_mysqlnd_buffered_result_parent;
|
||||
};
|
||||
|
||||
/*
|
||||
Column lengths of current row - both buffered and unbuffered.
|
||||
For buffered results it duplicates the data found in **data
|
||||
*/
|
||||
php_uint_t *lengths;
|
||||
struct st_mysqlnd_buffered_result_zval
|
||||
{
|
||||
def_mysqlnd_buffered_result_parent;
|
||||
|
||||
MYSQLND_MEMORY_POOL *result_set_memory_pool;
|
||||
zval **data;
|
||||
zval **data_cursor;
|
||||
};
|
||||
|
||||
php_uint_t references;
|
||||
|
||||
MYSQLND_ERROR_INFO error_info;
|
||||
struct st_mysqlnd_buffered_result_c
|
||||
{
|
||||
def_mysqlnd_buffered_result_parent;
|
||||
|
||||
php_uint_t field_count;
|
||||
zend_bool ps;
|
||||
zend_bool persistent;
|
||||
|
||||
struct st_mysqlnd_result_buffered_methods m;
|
||||
zend_uchar *initialized; /* every row is a single bit */
|
||||
uint64_t current_row;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1572,13 +1572,13 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ php_mysqlnd_rowp_read_text_protocol */
|
||||
enum_func_status
|
||||
php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
php_uint_t field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC)
|
||||
zend_bool as_int_or_float, zend_bool copy_data, MYSQLND_STATS * stats TSRMLS_DC)
|
||||
{
|
||||
|
||||
php_uint_t i;
|
||||
zend_bool last_field_was_string = FALSE;
|
||||
zval **current_field, **end_field, **start_field;
|
||||
@@ -1586,7 +1586,7 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval
|
||||
size_t data_size = row_buffer->app;
|
||||
zend_uchar * bit_area = (zend_uchar*) row_buffer->ptr + data_size + 1; /* we allocate from here */
|
||||
|
||||
DBG_ENTER("php_mysqlnd_rowp_read_text_protocol");
|
||||
DBG_ENTER("php_mysqlnd_rowp_read_text_protocol_aux");
|
||||
|
||||
if (!fields) {
|
||||
DBG_RETURN(FAIL);
|
||||
@@ -1608,7 +1608,7 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval
|
||||
/* php_mysqlnd_net_field_length() call should be after *this_field_len_pos = p; */
|
||||
php_uint_t len = php_mysqlnd_net_field_length(&p);
|
||||
|
||||
if (current_field > start_field && last_field_was_string) {
|
||||
if (copy_data == FALSE && current_field > start_field && last_field_was_string) {
|
||||
/*
|
||||
Normal queries:
|
||||
We have to put \0 now to the end of the previous field, if it was
|
||||
@@ -1733,22 +1733,22 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval
|
||||
p -= len;
|
||||
if (Z_TYPE_PP(current_field) == IS_INT) {
|
||||
bit_area += 1 + sprintf((char *)start, ZEND_INT_FMT, Z_IVAL_PP(current_field));
|
||||
ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0);
|
||||
ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, copy_data);
|
||||
} else if (Z_TYPE_PP(current_field) == IS_STRING){
|
||||
memcpy(bit_area, Z_STRVAL_PP(current_field), Z_STRSIZE_PP(current_field));
|
||||
bit_area += Z_STRSIZE_PP(current_field);
|
||||
*bit_area++ = '\0';
|
||||
zval_dtor(*current_field);
|
||||
ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0);
|
||||
ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, copy_data);
|
||||
}
|
||||
} else {
|
||||
ZVAL_STRINGL(*current_field, (char *)p, len, 0);
|
||||
ZVAL_STRINGL(*current_field, (char *)p, len, copy_data);
|
||||
}
|
||||
p += len;
|
||||
last_field_was_string = TRUE;
|
||||
}
|
||||
}
|
||||
if (last_field_was_string) {
|
||||
if (copy_data == FALSE && last_field_was_string) {
|
||||
/* Normal queries: The buffer has one more byte at the end, because we need it */
|
||||
row_buffer->ptr[data_size] = '\0';
|
||||
}
|
||||
@@ -1758,6 +1758,36 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ php_mysqlnd_rowp_read_text_protocol_zval */
|
||||
enum_func_status
|
||||
php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC)
|
||||
{
|
||||
enum_func_status ret;
|
||||
DBG_ENTER("php_mysqlnd_rowp_read_text_protocol_zval");
|
||||
ret = php_mysqlnd_rowp_read_text_protocol_aux(row_buffer, fields, field_count, fields_metadata, as_int_or_float, FALSE, stats TSRMLS_CC);
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ php_mysqlnd_rowp_read_text_protocol_c */
|
||||
enum_func_status
|
||||
php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC)
|
||||
{
|
||||
enum_func_status ret;
|
||||
DBG_ENTER("php_mysqlnd_rowp_read_text_protocol_c");
|
||||
ret = php_mysqlnd_rowp_read_text_protocol_aux(row_buffer, fields, field_count, fields_metadata, as_int_or_float, TRUE, stats TSRMLS_CC);
|
||||
DBG_RETURN(ret);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
|
||||
|
||||
/* {{{ php_mysqlnd_rowp_read */
|
||||
/*
|
||||
if normal statements => packet->fields is created by this function,
|
||||
|
||||
@@ -312,7 +312,11 @@ enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
|
||||
|
||||
|
||||
enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
enum_func_status php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
php_uint_t field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
|
||||
|
||||
enum_func_status php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
|
||||
php_uint_t field_count, const MYSQLND_FIELD * fields_metadata,
|
||||
zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ mysqlnd_minfo_dump_api_plugins(smart_str * buffer TSRMLS_DC)
|
||||
MYSQLND_REVERSE_API **ext;
|
||||
|
||||
for (zend_hash_internal_pointer_reset_ex(ht, &pos);
|
||||
zend_hash_get_current_data_ex(ht, (void **) &ext, &pos);
|
||||
zend_hash_get_current_data_ex(ht, (void **) &ext, &pos) == SUCCESS;
|
||||
zend_hash_move_forward_ex(ht, &pos)
|
||||
) {
|
||||
if (buffer->len) {
|
||||
@@ -209,6 +209,7 @@ static PHP_GINIT_FUNCTION(mysqlnd)
|
||||
mysqlnd_globals->debug_calloc_fail_threshold = -1;
|
||||
mysqlnd_globals->debug_realloc_fail_threshold = -1;
|
||||
mysqlnd_globals->sha256_server_public_key = NULL;
|
||||
mysqlnd_globals->fetch_data_copy = FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -229,8 +230,8 @@ static PHP_INI_MH(OnUpdateNetCmdBufferSize)
|
||||
/* {{{ PHP_INI_BEGIN
|
||||
*/
|
||||
PHP_INI_BEGIN()
|
||||
STD_PHP_INI_BOOLEAN("mysqlnd.collect_statistics", "1", PHP_INI_ALL, OnUpdateBool, collect_statistics, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
STD_PHP_INI_BOOLEAN("mysqlnd.collect_memory_statistics", "0", PHP_INI_SYSTEM, OnUpdateBool, collect_memory_statistics, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
STD_PHP_INI_BOOLEAN("mysqlnd.collect_statistics", "1", PHP_INI_ALL, OnUpdateBool, collect_statistics, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
STD_PHP_INI_BOOLEAN("mysqlnd.collect_memory_statistics","0",PHP_INI_SYSTEM, OnUpdateBool, collect_memory_statistics, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
STD_PHP_INI_ENTRY("mysqlnd.debug", NULL, PHP_INI_SYSTEM, OnUpdateString, debug, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
STD_PHP_INI_ENTRY("mysqlnd.trace_alloc", NULL, PHP_INI_SYSTEM, OnUpdateString, trace_alloc_settings, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
STD_PHP_INI_ENTRY("mysqlnd.net_cmd_buffer_size", MYSQLND_NET_CMD_BUFFER_MIN_SIZE_STR, PHP_INI_ALL, OnUpdateNetCmdBufferSize, net_cmd_buffer_size, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
@@ -239,7 +240,7 @@ PHP_INI_BEGIN()
|
||||
STD_PHP_INI_ENTRY("mysqlnd.log_mask", "0", PHP_INI_ALL, OnUpdateLong, log_mask, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
STD_PHP_INI_ENTRY("mysqlnd.mempool_default_size","16000", PHP_INI_ALL, OnUpdateLong, mempool_default_size, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
STD_PHP_INI_ENTRY("mysqlnd.sha256_server_public_key",NULL, PHP_INI_PERDIR, OnUpdateString, sha256_server_public_key, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
|
||||
STD_PHP_INI_BOOLEAN("mysqlnd.fetch_data_copy", "0", PHP_INI_ALL, OnUpdateBool, fetch_data_copy, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
#if PHP_DEBUG
|
||||
STD_PHP_INI_ENTRY("mysqlnd.debug_emalloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_emalloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
STD_PHP_INI_ENTRY("mysqlnd.debug_ecalloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_ecalloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals)
|
||||
|
||||
@@ -2211,8 +2211,10 @@ static void accel_fast_zval_ptr_dtor(zval **zval_ptr)
|
||||
#else
|
||||
switch (Z_TYPE_P(zvalue) & ~IS_CONSTANT_INDEX) {
|
||||
#endif
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY: {
|
||||
#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
|
||||
case IS_CONSTANT_ARRAY:
|
||||
#endif
|
||||
case IS_ARRAY: {
|
||||
TSRMLS_FETCH();
|
||||
|
||||
#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
|
||||
|
||||
@@ -779,7 +779,7 @@ static ZEND_FUNCTION(opcache_compile_file)
|
||||
op_array = persistent_compile_file(&handle, ZEND_INCLUDE TSRMLS_CC);
|
||||
} zend_catch {
|
||||
EG(current_execute_data) = orig_execute_data;
|
||||
zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s" TSRMLS_CC, handle.filename);
|
||||
zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s", handle.filename);
|
||||
} zend_end_try();
|
||||
|
||||
if(op_array != NULL) {
|
||||
|
||||
@@ -237,19 +237,21 @@ static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC)
|
||||
if ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) {
|
||||
switch ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK)) {
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
case IS_CONSTANT:
|
||||
Z_STRVAL_P(node->u.val) = (char *) interned_estrndup(Z_STRVAL_P(ast->u.val), Z_STRSIZE_P(ast->u.val));
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY:
|
||||
#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
|
||||
case IS_CONSTANT_ARRAY:
|
||||
#endif
|
||||
if (ast->u.val->value.ht && ast->u.val->value.ht != &EG(symbol_table)) {
|
||||
ALLOC_HASHTABLE(node->u.val->value.ht);
|
||||
zend_hash_clone_zval(node->u.val->value.ht, ast->u.val->value.ht, 0);
|
||||
}
|
||||
break;
|
||||
case IS_CONSTANT_AST:
|
||||
Z_AST_P(node->u.val) = zend_ast_clone(Z_AST_P(ast->u.val) TSRMLS_CC);
|
||||
break;
|
||||
case IS_CONSTANT_AST:
|
||||
Z_AST_P(node->u.val) = zend_ast_clone(Z_AST_P(ast->u.val) TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -295,20 +297,22 @@ static inline zval* zend_clone_zval(zval *src, int bind TSRMLS_DC)
|
||||
switch ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX)) {
|
||||
#endif
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
case IS_CONSTANT:
|
||||
Z_STRVAL_P(ret) = (char *) interned_estrndup(Z_STRVAL_P(ret), Z_STRSIZE_P(ret));
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY:
|
||||
#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
|
||||
case IS_CONSTANT_ARRAY:
|
||||
#endif
|
||||
if (ret->value.ht && ret->value.ht != &EG(symbol_table)) {
|
||||
ALLOC_HASHTABLE(ret->value.ht);
|
||||
zend_hash_clone_zval(ret->value.ht, src->value.ht, 0);
|
||||
}
|
||||
break;
|
||||
#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
|
||||
case IS_CONSTANT_AST:
|
||||
Z_AST_P(ret) = zend_ast_clone(Z_AST_P(ret) TSRMLS_CC);
|
||||
break;
|
||||
case IS_CONSTANT_AST:
|
||||
Z_AST_P(ret) = zend_ast_clone(Z_AST_P(ret) TSRMLS_CC);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -417,20 +421,22 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind)
|
||||
switch ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX)) {
|
||||
#endif
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
case IS_CONSTANT:
|
||||
Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->pDataPtr), Z_STRSIZE_P((zval*)p->pDataPtr));
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY:
|
||||
#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
|
||||
case IS_CONSTANT_ARRAY:
|
||||
#endif
|
||||
if (((zval*)p->pDataPtr)->value.ht && ((zval*)p->pDataPtr)->value.ht != &EG(symbol_table)) {
|
||||
ALLOC_HASHTABLE(ppz->value.ht);
|
||||
zend_hash_clone_zval(ppz->value.ht, ((zval*)p->pDataPtr)->value.ht, 0);
|
||||
}
|
||||
break;
|
||||
#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
|
||||
case IS_CONSTANT_AST:
|
||||
Z_AST_P(ppz) = zend_ast_clone(Z_AST_P(ppz) TSRMLS_CC);
|
||||
break;
|
||||
case IS_CONSTANT_AST:
|
||||
Z_AST_P(ppz) = zend_ast_clone(Z_AST_P(ppz) TSRMLS_CC);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Loaded 100 of 139 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user