summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/tests/bug69568.phpt25
-rw-r--r--Zend/tests/parent_class_name_without_parent.phpt21
-rw-r--r--Zend/zend_API.c17
-rw-r--r--Zend/zend_API.h1
-rw-r--r--Zend/zend_closures.c34
-rw-r--r--Zend/zend_closures.h2
-rw-r--r--Zend/zend_compile.c30
-rw-r--r--Zend/zend_vm_def.h91
-rw-r--r--Zend/zend_vm_execute.h250
-rw-r--r--ext/pdo/pdo_stmt.c56
-rw-r--r--ext/pdo/php_pdo_driver.h3
-rw-r--r--ext/pdo_dblib/dblib_stmt.c9
-rw-r--r--ext/pdo_firebird/firebird_statement.c4
-rw-r--r--ext/pdo_mysql/mysql_statement.c7
-rw-r--r--ext/pdo_oci/oci_statement.c3
-rw-r--r--ext/pdo_odbc/odbc_stmt.c3
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c7
-rw-r--r--ext/pdo_sqlite/sqlite_statement.c5
-rw-r--r--ext/reflection/php_reflection.c6
-rw-r--r--ext/simplexml/simplexml.c110
-rw-r--r--ext/standard/formatted_print.c22
-rw-r--r--ext/standard/string.c22
22 files changed, 400 insertions, 328 deletions
diff --git a/Zend/tests/bug69568.phpt b/Zend/tests/bug69568.phpt
new file mode 100644
index 0000000000..18ec941d0b
--- /dev/null
+++ b/Zend/tests/bug69568.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #69568: call a private function in closure failed
+--FILE--
+<?php
+class A {
+
+ private static function testprivate() {
+ return 1;
+ }
+ public static function test() {
+ return function() {
+ return self::testprivate();
+ };
+ }
+}
+
+class B extends A {
+}
+
+$fn = B::test();
+echo $fn();
+
+?>
+--EXPECT--
+1
diff --git a/Zend/tests/parent_class_name_without_parent.phpt b/Zend/tests/parent_class_name_without_parent.phpt
new file mode 100644
index 0000000000..0e67173f87
--- /dev/null
+++ b/Zend/tests/parent_class_name_without_parent.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Getting parent class name when there is no parent generates an error
+--FILE--
+<?php
+
+trait T {
+ public function f() {
+ var_dump(parent::class);
+ }
+}
+
+class C {
+ use T;
+}
+
+(new C)->f();
+
+?>
+--EXPECTF--
+Fatal error: Cannot use "parent" when current class scope has no parent in %s on line 5
+
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index e55ec45af6..7f8587ab4f 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -3828,6 +3828,23 @@ ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char
}
/* }}} */
+ZEND_API void zend_update_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zval *value) /* {{{ */
+{
+ zval property;
+ zend_class_entry *old_scope = EG(scope);
+
+ EG(scope) = scope;
+
+ if (!Z_OBJ_HT_P(object)->write_property) {
+ zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, Z_OBJCE_P(object)->name->val);
+ }
+ ZVAL_STR(&property, name);
+ Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL);
+
+ EG(scope) = old_scope;
+}
+/* }}} */
+
ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value) /* {{{ */
{
zval property;
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index e0860a45f4..f61091ae72 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -329,6 +329,7 @@ ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char
ZEND_API int zend_update_class_constants(zend_class_entry *class_type);
+ZEND_API void zend_update_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zval *value);
ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value);
ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, size_t name_length);
ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value);
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index 952e4ed1e0..97f0cbf57a 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -35,9 +35,10 @@
zend_error(E_EXCEPTION | E_ERROR, "Closure object cannot have properties")
typedef struct _zend_closure {
- zend_object std;
- zend_function func;
- zval this_ptr;
+ zend_object std;
+ zend_function func;
+ zval this_ptr;
+ zend_class_entry *called_scope;
} zend_closure;
/* non-static since it needs to be referenced */
@@ -129,7 +130,7 @@ ZEND_METHOD(Closure, bind)
{
zval *newthis, *zclosure, *scope_arg = NULL;
zend_closure *closure;
- zend_class_entry *ce;
+ zend_class_entry *ce, *called_scope;
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oo!|z", &zclosure, zend_ce_closure, &newthis, &scope_arg) == FAILURE) {
RETURN_NULL();
@@ -161,7 +162,13 @@ ZEND_METHOD(Closure, bind)
ce = closure->func.common.scope;
}
- zend_create_closure(return_value, &closure->func, ce, newthis);
+ if (newthis) {
+ called_scope = Z_OBJCE_P(newthis);
+ } else {
+ called_scope = ce;
+ }
+
+ zend_create_closure(return_value, &closure->func, ce, called_scope, newthis);
}
/* }}} */
@@ -296,7 +303,8 @@ static zend_object *zend_closure_clone(zval *zobject) /* {{{ */
zend_closure *closure = (zend_closure *)Z_OBJ_P(zobject);
zval result;
- zend_create_closure(&result, &closure->func, closure->func.common.scope, &closure->this_ptr);
+ zend_create_closure(&result, &closure->func,
+ closure->func.common.scope, closure->called_scope, &closure->this_ptr);
return Z_OBJ(result);
}
/* }}} */
@@ -311,17 +319,14 @@ int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function
closure = (zend_closure *)Z_OBJ_P(obj);
*fptr_ptr = &closure->func;
+ *ce_ptr = closure->called_scope;
- if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
- if (obj_ptr) {
+ if (obj_ptr) {
+ if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
*obj_ptr = Z_OBJ(closure->this_ptr);
- }
- *ce_ptr = Z_OBJCE(closure->this_ptr);
- } else {
- if (obj_ptr) {
+ } else {
*obj_ptr = NULL;
}
- *ce_ptr = closure->func.common.scope;
}
return SUCCESS;
}
@@ -457,7 +462,7 @@ void zend_register_closure_ce(void) /* {{{ */
}
/* }}} */
-ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zval *this_ptr) /* {{{ */
+ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) /* {{{ */
{
zend_closure *closure;
@@ -512,6 +517,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
* If the closure is unscoped, it has no bound object.
* The the closure is scoped, it's either static or it's bound */
closure->func.common.scope = scope;
+ closure->called_scope = called_scope;
if (scope) {
closure->func.common.fn_flags |= ZEND_ACC_PUBLIC;
if (this_ptr && Z_TYPE_P(this_ptr) == IS_OBJECT && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) {
diff --git a/Zend/zend_closures.h b/Zend/zend_closures.h
index 9862bc07cf..8d0963ec17 100644
--- a/Zend/zend_closures.h
+++ b/Zend/zend_closures.h
@@ -28,7 +28,7 @@ void zend_register_closure_ce(void);
extern ZEND_API zend_class_entry *zend_ce_closure;
-ZEND_API void zend_create_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zval *this_ptr);
+ZEND_API void zend_create_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr);
ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *obj);
ZEND_API const zend_function *zend_get_closure_method_def(zval *obj);
ZEND_API zval* zend_get_closure_this_ptr(zval *obj);
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index c92a25a705..2e05b35966 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -6349,16 +6349,8 @@ void zend_compile_resolve_class_name(znode *result, zend_ast *ast) /* {{{ */
switch (fetch_type) {
case ZEND_FETCH_CLASS_SELF:
if (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) {
- zval class_str_zv;
- zend_ast *class_str_ast, *class_const_ast;
-
- ZVAL_STRING(&class_str_zv, "class");
- class_str_ast = zend_ast_create_zval(&class_str_zv);
- class_const_ast = zend_ast_create(ZEND_AST_CLASS_CONST, name_ast, class_str_ast);
-
- zend_compile_expr(result, class_const_ast);
-
- zval_ptr_dtor(&class_str_zv);
+ zend_op *opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
+ opline->extended_value = fetch_type;
} else {
result->op_type = IS_CONST;
ZVAL_STR_COPY(&result->u.constant, CG(active_class_entry)->name);
@@ -6367,17 +6359,8 @@ void zend_compile_resolve_class_name(znode *result, zend_ast *ast) /* {{{ */
case ZEND_FETCH_CLASS_STATIC:
case ZEND_FETCH_CLASS_PARENT:
{
- zval class_str_zv;
- zend_ast *class_str_ast, *class_const_ast;
-
- ZVAL_STRING(&class_str_zv, "class");
- class_str_ast = zend_ast_create_zval(&class_str_zv);
- class_const_ast = zend_ast_create(
- ZEND_AST_CLASS_CONST, name_ast, class_str_ast);
-
- zend_compile_expr(result, class_const_ast);
-
- zval_ptr_dtor(&class_str_zv);
+ zend_op *opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
+ opline->extended_value = fetch_type;
}
break;
case ZEND_FETCH_CLASS_DEFAULT:
@@ -6518,6 +6501,8 @@ static void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */
void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */
{
+ zend_op *opline;
+
if (zend_try_ct_eval_magic_const(&result->u.constant, ast)) {
result->op_type = IS_CONST;
return;
@@ -6527,7 +6512,8 @@ void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */
CG(active_class_entry) &&
(CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
- zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
+ opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
+ opline->extended_value = ZEND_FETCH_CLASS_SELF;
}
/* }}} */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 282844df10..e00ee07d84 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5076,9 +5076,6 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
}
ZVAL_DUP(EX_VAR(opline->result.var), value);
- } else if (Z_STRLEN_P(EX_CONSTANT(opline->op2)) == sizeof("class")-1 && memcmp(Z_STRVAL_P(EX_CONSTANT(opline->op2)), "class", sizeof("class") - 1) == 0) {
- /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
- ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
} else {
zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
}
@@ -7304,9 +7301,11 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||
(EX(func)->common.fn_flags & ZEND_ACC_STATIC))) {
- zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(called_scope), NULL);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc),
+ EG(scope), EX(called_scope), NULL);
} else {
- zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EG(scope), Z_OBJ(EX(This)) ? &EX(This) : NULL);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc),
+ EG(scope), EX(called_scope), Z_OBJ(EX(This)) ? &EX(This) : NULL);
}
CHECK_EXCEPTION();
@@ -7773,44 +7772,31 @@ ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY)
{
USE_OPLINE
zval *value;
- int result;
+ int result = 0;
zend_free_op free_op1;
SAVE_OPLINE();
value = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
- switch (opline->extended_value) {
- case IS_NULL:
- case IS_LONG:
- case IS_DOUBLE:
- case IS_STRING:
- case IS_ARRAY:
- result = (Z_TYPE_P(value) == opline->extended_value);
- break;
- case _IS_BOOL:
- result = (Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE);
- break;
- case IS_OBJECT:
- if (Z_TYPE_P(value) == opline->extended_value) {
- zend_class_entry *ce = Z_OBJCE_P(value);
- if (ce->name->len == sizeof("__PHP_Incomplete_Class") - 1
- && !memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1)) {
- result = 0;
- } else {
- result = 1;
- }
- } else {
- result = 0;
+ if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
+ if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ zend_class_entry *ce = Z_OBJCE_P(value);
+
+ if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
+ EXPECTED(memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
+ result = 1;
}
- break;
- case IS_RESOURCE:
- if (Z_TYPE_P(value) == opline->extended_value) {
- const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
- result = (type_name != NULL);
- } else {
- result = 0;
+ } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) {
+ const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
+
+ if (EXPECTED(type_name != NULL)) {
+ result = 1;
}
- break;
- EMPTY_SWITCH_DEFAULT_CASE()
+ } else {
+ result = 1;
+ }
+ } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) &&
+ EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) {
+ result = 1;
}
FREE_OP1();
ZEND_VM_SMART_BRANCH(result, 1);
@@ -7857,12 +7843,35 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ANY)
ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY)
{
+ uint32_t fetch_type;
USE_OPLINE
- if (EG(scope) && EG(scope)->name) {
- ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
- } else {
- ZVAL_EMPTY_STRING(EX_VAR(opline->result.var));
+ SAVE_OPLINE();
+ fetch_type = opline->extended_value;
+
+ if (UNEXPECTED(EG(scope) == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use \"%s\" when no class scope is active",
+ fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
+ fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
+ HANDLE_EXCEPTION();
+ }
+
+ switch (fetch_type) {
+ case ZEND_FETCH_CLASS_SELF:
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
+ break;
+ case ZEND_FETCH_CLASS_PARENT:
+ if (UNEXPECTED(EG(scope)->parent == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR,
+ "Cannot use \"parent\" when current class scope has no parent");
+ HANDLE_EXCEPTION();
+ }
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->parent->name);
+ break;
+ case ZEND_FETCH_CLASS_STATIC:
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(called_scope)->name);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
}
ZEND_VM_NEXT_OPCODE();
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 89e95a4463..85075af2a6 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1790,12 +1790,35 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
+ uint32_t fetch_type;
USE_OPLINE
- if (EG(scope) && EG(scope)->name) {
- ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
- } else {
- ZVAL_EMPTY_STRING(EX_VAR(opline->result.var));
+ SAVE_OPLINE();
+ fetch_type = opline->extended_value;
+
+ if (UNEXPECTED(EG(scope) == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Cannot use \"%s\" when no class scope is active",
+ fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
+ fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
+ HANDLE_EXCEPTION();
+ }
+
+ switch (fetch_type) {
+ case ZEND_FETCH_CLASS_SELF:
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
+ break;
+ case ZEND_FETCH_CLASS_PARENT:
+ if (UNEXPECTED(EG(scope)->parent == NULL)) {
+ zend_error(E_EXCEPTION | E_ERROR,
+ "Cannot use \"parent\" when current class scope has no parent");
+ HANDLE_EXCEPTION();
+ }
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->parent->name);
+ break;
+ case ZEND_FETCH_CLASS_STATIC:
+ ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(called_scope)->name);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
}
ZEND_VM_NEXT_OPCODE();
}
@@ -4199,44 +4222,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CONST_HANDLER(
{
USE_OPLINE
zval *value;
- int result;
+ int result = 0;
SAVE_OPLINE();
value = EX_CONSTANT(opline->op1);
- switch (opline->extended_value) {
- case IS_NULL:
- case IS_LONG:
- case IS_DOUBLE:
- case IS_STRING:
- case IS_ARRAY:
- result = (Z_TYPE_P(value) == opline->extended_value);
- break;
- case _IS_BOOL:
- result = (Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE);
- break;
- case IS_OBJECT:
- if (Z_TYPE_P(value) == opline->extended_value) {
- zend_class_entry *ce = Z_OBJCE_P(value);
- if (ce->name->len == sizeof("__PHP_Incomplete_Class") - 1
- && !memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1)) {
- result = 0;
- } else {
- result = 1;
- }
- } else {
- result = 0;
+ if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
+ if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ zend_class_entry *ce = Z_OBJCE_P(value);
+
+ if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
+ EXPECTED(memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
+ result = 1;
}
- break;
- case IS_RESOURCE:
- if (Z_TYPE_P(value) == opline->extended_value) {
- const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
- result = (type_name != NULL);
- } else {
- result = 0;
+ } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) {
+ const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
+
+ if (EXPECTED(type_name != NULL)) {
+ result = 1;
}
- break;
- EMPTY_SWITCH_DEFAULT_CASE()
+ } else {
+ result = 1;
+ }
+ } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) &&
+ EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) {
+ result = 1;
}
ZEND_VM_SMART_BRANCH(result, 1);
@@ -5832,9 +5842,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONS
CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
}
ZVAL_DUP(EX_VAR(opline->result.var), value);
- } else if (Z_STRLEN_P(EX_CONSTANT(opline->op2)) == sizeof("class")-1 && memcmp(Z_STRVAL_P(EX_CONSTANT(opline->op2)), "class", sizeof("class") - 1) == 0) {
- /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
- ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
} else {
zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
}
@@ -7983,9 +7990,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C
if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||
(EX(func)->common.fn_flags & ZEND_ACC_STATIC))) {
- zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(called_scope), NULL);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc),
+ EG(scope), EX(called_scope), NULL);
} else {
- zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EG(scope), Z_OBJ(EX(This)) ? &EX(This) : NULL);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc),
+ EG(scope), EX(called_scope), Z_OBJ(EX(This)) ? &EX(This) : NULL);
}
CHECK_EXCEPTION();
@@ -12262,44 +12271,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZE
{
USE_OPLINE
zval *value;
- int result;
+ int result = 0;
zend_free_op free_op1;
SAVE_OPLINE();
value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
- switch (opline->extended_value) {
- case IS_NULL:
- case IS_LONG:
- case IS_DOUBLE:
- case IS_STRING:
- case IS_ARRAY:
- result = (Z_TYPE_P(value) == opline->extended_value);
- break;
- case _IS_BOOL:
- result = (Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE);
- break;
- case IS_OBJECT:
- if (Z_TYPE_P(value) == opline->extended_value) {
- zend_class_entry *ce = Z_OBJCE_P(value);
- if (ce->name->len == sizeof("__PHP_Incomplete_Class") - 1
- && !memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1)) {
- result = 0;
- } else {
- result = 1;
- }
- } else {
- result = 0;
+ if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
+ if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ zend_class_entry *ce = Z_OBJCE_P(value);
+
+ if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
+ EXPECTED(memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
+ result = 1;
}
- break;
- case IS_RESOURCE:
- if (Z_TYPE_P(value) == opline->extended_value) {
- const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
- result = (type_name != NULL);
- } else {
- result = 0;
+ } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) {
+ const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
+
+ if (EXPECTED(type_name != NULL)) {
+ result = 1;
}
- break;
- EMPTY_SWITCH_DEFAULT_CASE()
+ } else {
+ result = 1;
+ }
+ } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) &&
+ EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) {
+ result = 1;
}
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, 1);
@@ -16017,44 +16013,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_VAR_HANDLER(ZE
{
USE_OPLINE
zval *value;
- int result;
+ int result = 0;
zend_free_op free_op1;
SAVE_OPLINE();
value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
- switch (opline->extended_value) {
- case IS_NULL:
- case IS_LONG:
- case IS_DOUBLE:
- case IS_STRING:
- case IS_ARRAY:
- result = (Z_TYPE_P(value) == opline->extended_value);
- break;
- case _IS_BOOL:
- result = (Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE);
- break;
- case IS_OBJECT:
- if (Z_TYPE_P(value) == opline->extended_value) {
- zend_class_entry *ce = Z_OBJCE_P(value);
- if (ce->name->len == sizeof("__PHP_Incomplete_Class") - 1
- && !memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1)) {
- result = 0;
- } else {
- result = 1;
- }
- } else {
- result = 0;
+ if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
+ if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ zend_class_entry *ce = Z_OBJCE_P(value);
+
+ if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
+ EXPECTED(memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
+ result = 1;
}
- break;
- case IS_RESOURCE:
- if (Z_TYPE_P(value) == opline->extended_value) {
- const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
- result = (type_name != NULL);
- } else {
- result = 0;
+ } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) {
+ const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
+
+ if (EXPECTED(type_name != NULL)) {
+ result = 1;
}
- break;
- EMPTY_SWITCH_DEFAULT_CASE()
+ } else {
+ result = 1;
+ }
+ } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) &&
+ EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) {
+ result = 1;
}
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_SMART_BRANCH(result, 1);
@@ -17447,9 +17430,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_
CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
}
ZVAL_DUP(EX_VAR(opline->result.var), value);
- } else if (Z_STRLEN_P(EX_CONSTANT(opline->op2)) == sizeof("class")-1 && memcmp(Z_STRVAL_P(EX_CONSTANT(opline->op2)), "class", sizeof("class") - 1) == 0) {
- /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
- ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
} else {
zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
}
@@ -23819,9 +23799,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON
CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
}
ZVAL_DUP(EX_VAR(opline->result.var), value);
- } else if (Z_STRLEN_P(EX_CONSTANT(opline->op2)) == sizeof("class")-1 && memcmp(Z_STRVAL_P(EX_CONSTANT(opline->op2)), "class", sizeof("class") - 1) == 0) {
- /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
- ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
} else {
zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
}
@@ -29701,44 +29678,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEN
{
USE_OPLINE
zval *value;
- int result;
+ int result = 0;
SAVE_OPLINE();
value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
- switch (opline->extended_value) {
- case IS_NULL:
- case IS_LONG:
- case IS_DOUBLE:
- case IS_STRING:
- case IS_ARRAY:
- result = (Z_TYPE_P(value) == opline->extended_value);
- break;
- case _IS_BOOL:
- result = (Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE);
- break;
- case IS_OBJECT:
- if (Z_TYPE_P(value) == opline->extended_value) {
- zend_class_entry *ce = Z_OBJCE_P(value);
- if (ce->name->len == sizeof("__PHP_Incomplete_Class") - 1
- && !memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1)) {
- result = 0;
- } else {
- result = 1;
- }
- } else {
- result = 0;
+ if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) {
+ if (UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+ zend_class_entry *ce = Z_OBJCE_P(value);
+
+ if (UNEXPECTED(ce->name->len != sizeof("__PHP_Incomplete_Class") - 1) ||
+ EXPECTED(memcmp(ce->name->val, "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
+ result = 1;
}
- break;
- case IS_RESOURCE:
- if (Z_TYPE_P(value) == opline->extended_value) {
- const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
- result = (type_name != NULL);
- } else {
- result = 0;
+ } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) {
+ const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value));
+
+ if (EXPECTED(type_name != NULL)) {
+ result = 1;
}
- break;
- EMPTY_SWITCH_DEFAULT_CASE()
+ } else {
+ result = 1;
+ }
+ } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) &&
+ EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) {
+ result = 1;
}
ZEND_VM_SMART_BRANCH(result, 1);
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 3387da0f2d..6383abb925 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -209,7 +209,7 @@ int pdo_stmt_describe_columns(pdo_stmt_t *stmt) /* {{{ */
/* if we are applying case conversions on column names, do so now */
if (stmt->dbh->native_case != stmt->dbh->desired_case && stmt->dbh->desired_case != PDO_CASE_NATURAL) {
- char *s = stmt->columns[col].name;
+ char *s = stmt->columns[col].name->val;
switch (stmt->dbh->desired_case) {
case PDO_CASE_UPPER:
@@ -243,8 +243,8 @@ int pdo_stmt_describe_columns(pdo_stmt_t *stmt) /* {{{ */
if (stmt->bound_columns) {
struct pdo_bound_param_data *param;
- if ((param = zend_hash_str_find_ptr(stmt->bound_columns,
- stmt->columns[col].name, stmt->columns[col].namelen)) != NULL) {
+ if ((param = zend_hash_find_ptr(stmt->bound_columns,
+ stmt->columns[col].name)) != NULL) {
param->paramno = col;
}
}
@@ -345,7 +345,8 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s
int i;
for (i = 0; i < stmt->column_count; i++) {
- if (strncmp(stmt->columns[i].name, param->name->val, param->name->len + 1) == 0) {
+ if (stmt->columns[i].name->len == param->name->len &&
+ strncmp(stmt->columns[i].name->val, param->name->val, param->name->len + 1) == 0) {
param->paramno = i;
break;
}
@@ -1025,7 +1026,7 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
switch (how) {
case PDO_FETCH_ASSOC:
- add_assoc_zval(return_value, stmt->columns[i].name, &val);
+ zend_symtable_update(Z_ARRVAL_P(return_value), stmt->columns[i].name, &val);
break;
case PDO_FETCH_KEY_PAIR:
@@ -1046,19 +1047,18 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
case PDO_FETCH_USE_DEFAULT:
case PDO_FETCH_BOTH:
- add_assoc_zval(return_value, stmt->columns[i].name, &val);
+ zend_symtable_update(Z_ARRVAL_P(return_value), stmt->columns[i].name, &val);
if (Z_REFCOUNTED(val)) {
Z_ADDREF(val);
}
- add_next_index_zval(return_value, &val);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &val);
break;
case PDO_FETCH_NAMED:
/* already have an item with this name? */
{
zval *curr_val;
- if ((curr_val = zend_hash_str_find(Z_ARRVAL_P(return_value), stmt->columns[i].name,
- strlen(stmt->columns[i].name)))) {
+ if ((curr_val = zend_hash_find(Z_ARRVAL_P(return_value), stmt->columns[i].name))) {
zval arr;
if (Z_TYPE_P(curr_val) != IS_ARRAY) {
/* a little bit of black magic here:
@@ -1077,33 +1077,33 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
ZVAL_COPY_VALUE(&cur, curr_val);
ZVAL_COPY_VALUE(curr_val, &arr);
- add_next_index_zval(&arr, &cur);
+ zend_hash_next_index_insert_new(Z_ARRVAL(arr), &cur);
} else {
ZVAL_COPY_VALUE(&arr, curr_val);
}
- add_next_index_zval(&arr, &val);
+ zend_hash_next_index_insert_new(Z_ARRVAL(arr), &val);
} else {
- add_assoc_zval(return_value, stmt->columns[i].name, &val);
+ zend_hash_update(Z_ARRVAL_P(return_value), stmt->columns[i].name, &val);
}
}
break;
case PDO_FETCH_NUM:
- add_next_index_zval(return_value, &val);
+ zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &val);
break;
case PDO_FETCH_OBJ:
case PDO_FETCH_INTO:
- zend_update_property(NULL, return_value,
- stmt->columns[i].name, stmt->columns[i].namelen,
+ zend_update_property_ex(NULL, return_value,
+ stmt->columns[i].name,
&val);
zval_ptr_dtor(&val);
break;
case PDO_FETCH_CLASS:
if ((flags & PDO_FETCH_SERIALIZE) == 0 || idx) {
- zend_update_property(ce, return_value,
- stmt->columns[i].name, stmt->columns[i].namelen,
+ zend_update_property_ex(ce, return_value,
+ stmt->columns[i].name,
&val);
zval_ptr_dtor(&val);
} else {
@@ -1194,16 +1194,16 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
if (return_all) {
if ((flags & PDO_FETCH_UNIQUE) == PDO_FETCH_UNIQUE) {
- add_assoc_zval(return_all, Z_STRVAL(grp_val), return_value);
+ zend_symtable_update(Z_ARRVAL_P(return_all), Z_STR(grp_val), return_value);
} else {
zval grp;
if ((pgrp = zend_symtable_find(Z_ARRVAL_P(return_all), Z_STR(grp_val))) == NULL) {
array_init(&grp);
- add_assoc_zval(return_all, Z_STRVAL(grp_val), &grp);
+ zend_symtable_update(Z_ARRVAL_P(return_all), Z_STR(grp_val), &grp);
} else {
ZVAL_COPY_VALUE(&grp, pgrp);
}
- add_next_index_zval(&grp, return_value);
+ zend_hash_next_index_insert(Z_ARRVAL(grp), return_value);
}
zval_dtor(&grp_val);
}
@@ -1518,7 +1518,7 @@ static PHP_METHOD(PDOStatement, fetchAll)
} else {
array_init(return_value);
do {
- add_next_index_zval(return_value, &data);
+ zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &data);
} while (do_fetch(stmt, 1, &data, how | flags, PDO_FETCH_ORI_NEXT, 0, 0));
}
}
@@ -1824,7 +1824,7 @@ static PHP_METHOD(PDOStatement, getColumnMeta)
/* add stock items */
col = &stmt->columns[colno];
- add_assoc_string(return_value, "name", col->name);
+ add_assoc_str(return_value, "name", zend_string_copy(col->name));
add_assoc_long(return_value, "len", col->maxlen); /* FIXME: unsigned ? */
add_assoc_long(return_value, "precision", col->precision);
if (col->param_type != PDO_PARAM_ZVAL) {
@@ -2027,7 +2027,7 @@ static int pdo_stmt_do_next_rowset(pdo_stmt_t *stmt)
struct pdo_column_data *cols = stmt->columns;
for (i = 0; i < stmt->column_count; i++) {
- efree(cols[i].name);
+ zend_string_release(cols[i].name);
}
efree(stmt->columns);
stmt->columns = NULL;
@@ -2329,7 +2329,7 @@ PDO_API void php_pdo_free_statement(pdo_stmt_t *stmt)
for (i = 0; i < stmt->column_count; i++) {
if (cols[i].name) {
- efree(cols[i].name);
+ zend_string_release(cols[i].name);
cols[i].name = NULL;
}
}
@@ -2506,7 +2506,8 @@ static zval *row_prop_read(zval *object, zval *member, int type, void **cache_sl
/* TODO: replace this with a hash of available column names to column
* numbers */
for (colno = 0; colno < stmt->column_count; colno++) {
- if (strcmp(stmt->columns[colno].name, Z_STRVAL_P(member)) == 0) {
+ if (stmt->columns[colno].name->len == Z_STRLEN_P(member) &&
+ strncmp(stmt->columns[colno].name->val, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0) {
fetch_value(stmt, rv, colno, NULL);
//???
//Z_SET_REFCOUNT_P(rv, 0);
@@ -2565,7 +2566,8 @@ static int row_prop_exists(zval *object, zval *member, int check_empty, void **c
/* TODO: replace this with a hash of available column names to column
* numbers */
for (colno = 0; colno < stmt->column_count; colno++) {
- if (strcmp(stmt->columns[colno].name, Z_STRVAL_P(member)) == 0) {
+ if (stmt->columns[colno].name->len == Z_STRLEN_P(member) &&
+ strncmp(stmt->columns[colno].name->val, Z_STRVAL_P(member), Z_STRLEN_P(member)) == 0) {
return 1;
}
}
@@ -2606,7 +2608,7 @@ static HashTable *row_get_properties(zval *object)
zval val;
fetch_value(stmt, &val, i, NULL);
- zend_hash_str_update(stmt->std.properties, stmt->columns[i].name, stmt->columns[i].namelen, &val);
+ zend_hash_update(stmt->std.properties, stmt->columns[i].name, &val);
}
return stmt->std.properties;
diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h
index 407d1baa82..efa21a4e14 100644
--- a/ext/pdo/php_pdo_driver.h
+++ b/ext/pdo/php_pdo_driver.h
@@ -527,11 +527,10 @@ static inline pdo_dbh_object_t *php_pdo_dbh_fetch_object(zend_object *obj) {
/* describes a column */
struct pdo_column_data {
- char *name;
+ zend_string *name;
size_t maxlen;
zend_ulong precision;
enum pdo_param_type param_type;
- size_t namelen;
/* don't touch this unless your name is dbdo */
void *dbdo_data;
diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c
index 4da5f71531..97776548b2 100644
--- a/ext/pdo_dblib/dblib_stmt.c
+++ b/ext/pdo_dblib/dblib_stmt.c
@@ -191,16 +191,17 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno)
{
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
pdo_dblib_db_handle *H = S->H;
+ struct pdo_column_data *col;
+ zend_string *str;
if(colno >= stmt->column_count || colno < 0) {
return FAILURE;
}
- struct pdo_column_data *col = &stmt->columns[colno];
-
- col->name = estrdup(dbcolname(H->link, colno+1));
+ col = &stmt->columns[colno];
+ str = dbcolname(H->link, colno+1);
+ col->name = zend_string_init(str, strlen(str), 0);
col->maxlen = dbcollen(H->link, colno+1);
- col->namelen = strlen(col->name);
col->param_type = PDO_PARAM_STR;
return 1;
diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c
index 50901841c8..337ce3fb66 100644
--- a/ext/pdo_firebird/firebird_statement.c
+++ b/ext/pdo_firebird/firebird_statement.c
@@ -197,8 +197,8 @@ static int firebird_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */
: (var->aliasname_length);
col->precision = -var->sqlscale;
col->maxlen = var->sqllen;
- col->namelen = colname_len;
- col->name = cp = emalloc(colname_len + 1);
+ col->name = zend_string_alloc(colname_len, 0);
+ cp = col->name->val;
if (colname_len > var->aliasname_length) {
memmove(cp, var->relname, var->relname_length);
cp += var->relname_length;
diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c
index 56728ed92d..551960560e 100644
--- a/ext/pdo_mysql/mysql_statement.c
+++ b/ext/pdo_mysql/mysql_statement.c
@@ -696,14 +696,11 @@ static int pdo_mysql_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */
PDO_DBG_RETURN(1);
}
for (i = 0; i < stmt->column_count; i++) {
- int namelen;
if (S->H->fetch_table_names) {
- namelen = spprintf(&cols[i].name, 0, "%s.%s", S->fields[i].table, S->fields[i].name);
- cols[i].namelen = namelen;
+ cols[i].name = strpprintf(0, "%s.%s", S->fields[i].table, S->fields[i].name);
} else {
- cols[i].namelen = S->fields[i].name_length;
- cols[i].name = estrndup(S->fields[i].name, S->fields[i].name_length);
+ cols[i].name = zend_string_init(S->fields[i].name, S->fields[i].name_length, 0);
}
cols[i].precision = S->fields[i].decimals;
diff --git a/ext/pdo_oci/oci_statement.c b/ext/pdo_oci/oci_statement.c
index e47fba513b..9efb371f6d 100644
--- a/ext/pdo_oci/oci_statement.c
+++ b/ext/pdo_oci/oci_statement.c
@@ -525,8 +525,7 @@ static int oci_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */
col->precision = scale;
col->maxlen = data_size;
- col->namelen = namelen;
- col->name = estrndup((char *)colname, namelen);
+ col->name = zend_string_init((char *)colname, namelen, 0);
S->cols[colno].dtype = dtype;
diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c
index 5d4ff3af96..6421cb6701 100644
--- a/ext/pdo_odbc/odbc_stmt.c
+++ b/ext/pdo_odbc/odbc_stmt.c
@@ -594,8 +594,7 @@ static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno)
colsize = displaysize;
col->maxlen = S->cols[colno].datalen = colsize;
- col->namelen = colnamelen;
- col->name = estrdup(S->cols[colno].colname);
+ col->name = zend_string_init(S->cols[colno].colname, colnamelen, 0);
S->cols[colno].is_unicode = pdo_odbc_sqltype_is_unicode(S, S->cols[colno].coltype);
/* returning data as a string */
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index 435781ecf1..60553b36ce 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -438,13 +438,14 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno)
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
struct pdo_column_data *cols = stmt->columns;
struct pdo_bound_param_data *param;
+ char *str;
if (!S->result) {
return 0;
}
- cols[colno].name = estrdup(PQfname(S->result, colno));
- cols[colno].namelen = strlen(cols[colno].name);
+ str = PQfname(S->result, colno);
+ cols[colno].name = zend_string_init(str, strlen(str), 0);
cols[colno].maxlen = PQfsize(S->result, colno);
cols[colno].precision = PQfmod(S->result, colno);
S->cols[colno].pgsql_type = PQftype(S->result, colno);
@@ -459,7 +460,7 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno)
/* did the user bind the column as a LOB ? */
if (stmt->bound_columns && (
(param = zend_hash_index_find_ptr(stmt->bound_columns, colno)) != NULL ||
- (param = zend_hash_str_find_ptr(stmt->bound_columns, cols[colno].name, cols[colno].namelen)) != NULL)) {
+ (param = zend_hash_find_ptr(stmt->bound_columns, cols[colno].name)) != NULL)) {
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
cols[colno].param_type = PDO_PARAM_LOB;
diff --git a/ext/pdo_sqlite/sqlite_statement.c b/ext/pdo_sqlite/sqlite_statement.c
index 29300c198a..f42ad05329 100644
--- a/ext/pdo_sqlite/sqlite_statement.c
+++ b/ext/pdo_sqlite/sqlite_statement.c
@@ -233,6 +233,7 @@ static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno)
{
pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
+ char *str;
if(colno >= sqlite3_column_count(S->stmt)) {
/* error invalid column */
@@ -240,8 +241,8 @@ static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno)
return 0;
}
- stmt->columns[colno].name = estrdup(sqlite3_column_name(S->stmt, colno));
- stmt->columns[colno].namelen = strlen(stmt->columns[colno].name);
+ str = sqlite3_column_name(S->stmt, colno);
+ stmt->columns[colno].name = zend_string_init(str, strlen(str), 0);
stmt->columns[colno].maxlen = 0xffffffff;
stmt->columns[colno].precision = 0;
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 76159479f2..f7dd5531d0 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -1717,7 +1717,7 @@ ZEND_METHOD(reflection_function, getClosure)
}
GET_REFLECTION_OBJECT_PTR(fptr);
- zend_create_closure(return_value, fptr, NULL, NULL);
+ zend_create_closure(return_value, fptr, NULL, NULL, NULL);
}
/* }}} */
@@ -2827,7 +2827,7 @@ ZEND_METHOD(reflection_method, getClosure)
GET_REFLECTION_OBJECT_PTR(mptr);
if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
- zend_create_closure(return_value, mptr, mptr->common.scope, NULL);
+ zend_create_closure(return_value, mptr, mptr->common.scope, mptr->common.scope, NULL);
} else {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &obj) == FAILURE) {
return;
@@ -2844,7 +2844,7 @@ ZEND_METHOD(reflection_method, getClosure)
{
RETURN_ZVAL(obj, 1, 0);
} else {
- zend_create_closure(return_value, mptr, mptr->common.scope, obj);
+ zend_create_closure(return_value, mptr, mptr->common.scope, Z_OBJCE_P(obj), obj);
}
}
}
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index d2ed7da008..7a9775b752 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -64,7 +64,7 @@ static void php_sxe_iterator_rewind(zend_object_iterator *iter);
/* {{{ _node_as_zval()
*/
-static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, SXE_ITER itertype, char *name, const xmlChar *nsprefix, int isprefix)
+static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, SXE_ITER itertype, char *name, const char *nsprefix, int isprefix)
{
php_sxe_object *subnode;
@@ -73,10 +73,10 @@ static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, SXE
subnode->document->refcount++;
subnode->iter.type = itertype;
if (name) {
- subnode->iter.name = xmlStrdup((xmlChar *)name);
+ subnode->iter.name = (xmlChar*)estrdup(name);
}
if (nsprefix && *nsprefix) {
- subnode->iter.nsprefix = xmlStrdup(nsprefix);
+ subnode->iter.nsprefix = (xmlChar*)estrdup(nsprefix);
subnode->iter.isprefix = isprefix;
}
@@ -978,7 +978,7 @@ static inline zend_string *sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr li
/* {{{ _get_base_node_value()
*/
-static void _get_base_node_value(php_sxe_object *sxe_ref, xmlNodePtr node, zval *value, xmlChar *nsprefix, int isprefix)
+static void _get_base_node_value(php_sxe_object *sxe_ref, xmlNodePtr node, zval *value, char *nsprefix, int isprefix)
{
php_sxe_object *subnode;
xmlChar *contents;
@@ -994,7 +994,7 @@ static void _get_base_node_value(php_sxe_object *sxe_ref, xmlNodePtr node, zval
subnode->document = sxe_ref->document;
subnode->document->refcount++;
if (nsprefix && *nsprefix) {
- subnode->iter.nsprefix = xmlStrdup((xmlChar *)nsprefix);
+ subnode->iter.nsprefix = (xmlChar*)estrdup(nsprefix);
subnode->iter.isprefix = isprefix;
}
php_libxml_increment_node_ptr((php_libxml_node_object *)subnode, node, NULL);
@@ -1007,26 +1007,24 @@ static void _get_base_node_value(php_sxe_object *sxe_ref, xmlNodePtr node, zval
static void sxe_properties_add(HashTable *rv, char *name, int namelen, zval *value) /* {{{ */
{
+ zend_string *key;
zval *data_ptr;
zval newptr;
- if ((data_ptr = zend_hash_str_find(rv, name, namelen)) != NULL) {
+ key = zend_string_init(name, namelen, 0);
+ if ((data_ptr = zend_hash_find(rv, key)) != NULL) {
if (Z_TYPE_P(data_ptr) == IS_ARRAY) {
- zend_hash_next_index_insert(Z_ARRVAL_P(data_ptr), value);
+ zend_hash_next_index_insert_new(Z_ARRVAL_P(data_ptr), value);
} else {
array_init(&newptr);
-
- if (Z_REFCOUNTED_P(data_ptr)) {
- Z_ADDREF_P(data_ptr);
- }
- zend_hash_next_index_insert(Z_ARRVAL(newptr), data_ptr);
- zend_hash_next_index_insert(Z_ARRVAL(newptr), value);
-
- zend_hash_str_update(rv, name, namelen, &newptr);
+ zend_hash_next_index_insert_new(Z_ARRVAL(newptr), data_ptr);
+ zend_hash_next_index_insert_new(Z_ARRVAL(newptr), value);
+ ZVAL_ARR(data_ptr, Z_ARR(newptr));
}
} else {
- zend_hash_str_update(rv, name, namelen, value);
+ zend_hash_add_new(rv, key, value);
}
+ zend_string_release(key);
}
/* }}} */
@@ -1499,9 +1497,14 @@ SXE_METHOD(asXML)
static inline void sxe_add_namespace_name(zval *return_value, xmlNsPtr ns) /* {{{ */
{
char *prefix = SXE_NS_PREFIX(ns);
- if (zend_hash_str_exists(Z_ARRVAL_P(return_value), prefix, strlen(prefix)) == 0) {
- add_assoc_string(return_value, prefix, (char*)ns->href);
+ zend_string *key = zend_string_init(prefix, strlen(prefix), 0);
+ zval zv;
+
+ if (!zend_hash_exists(Z_ARRVAL_P(return_value), key)) {
+ ZVAL_STRING(&zv, (char*)ns->href);
+ zend_hash_add_new(Z_ARRVAL_P(return_value), key, &zv);
}
+ zend_string_release(key);
}
/* }}} */
@@ -2061,10 +2064,10 @@ sxe_object_clone(zval *object)
clone->iter.isprefix = sxe->iter.isprefix;
if (sxe->iter.name != NULL) {
- clone->iter.name = xmlStrdup((xmlChar *)sxe->iter.name);
+ clone->iter.name = (xmlChar*)estrdup((char*)sxe->iter.name);
}
if (sxe->iter.nsprefix != NULL) {
- clone->iter.nsprefix = xmlStrdup((xmlChar *)sxe->iter.nsprefix);
+ clone->iter.nsprefix = (xmlChar*)estrdup((char*)sxe->iter.nsprefix);
}
clone->iter.type = sxe->iter.type;
@@ -2093,11 +2096,11 @@ static void sxe_object_dtor(zend_object *object)
}
if (sxe->iter.name) {
- xmlFree(sxe->iter.name);
+ efree(sxe->iter.name);
sxe->iter.name = NULL;
}
if (sxe->iter.nsprefix) {
- xmlFree(sxe->iter.nsprefix);
+ efree(sxe->iter.nsprefix);
sxe->iter.nsprefix = NULL;
}
if (!Z_ISUNDEF(sxe->tmp)) {
@@ -2136,17 +2139,21 @@ static zend_function* php_sxe_find_fptr_count(zend_class_entry *ce)
{
zend_function *fptr_count = NULL;
zend_class_entry *parent = ce;
+ int inherited = 0;
while (parent) {
if (parent == sxe_class_entry) {
break;
}
parent = parent->parent;
+ inherited = 1;
}
- fptr_count = zend_hash_str_find_ptr(&ce->function_table, "count", sizeof("count") - 1);
- if (fptr_count->common.scope == parent) {
- fptr_count = NULL;
+ if (inherited) {
+ fptr_count = zend_hash_str_find_ptr(&ce->function_table, "count", sizeof("count") - 1);
+ if (fptr_count->common.scope == parent) {
+ fptr_count = NULL;
+ }
}
return fptr_count;
@@ -2218,7 +2225,7 @@ PHP_FUNCTION(simplexml_load_file)
fptr_count = php_sxe_find_fptr_count(ce);
}
sxe = php_sxe_object_new(ce, fptr_count);
- sxe->iter.nsprefix = ns_len ? xmlStrdup((xmlChar *)ns) : NULL;
+ sxe->iter.nsprefix = ns_len ? (xmlChar*)estrdup(ns) : NULL;
sxe->iter.isprefix = isprefix;
php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp);
php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL);
@@ -2259,7 +2266,7 @@ PHP_FUNCTION(simplexml_load_string)
fptr_count = php_sxe_find_fptr_count(ce);
}
sxe = php_sxe_object_new(ce, fptr_count);
- sxe->iter.nsprefix = ns_len ? xmlStrdup((xmlChar *)ns) : NULL;
+ sxe->iter.nsprefix = ns_len ? (xmlChar*)estrdup(ns) : NULL;
sxe->iter.isprefix = isprefix;
php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp);
php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL);
@@ -2291,7 +2298,7 @@ SXE_METHOD(__construct)
return;
}
- sxe->iter.nsprefix = ns_len ? xmlStrdup((xmlChar *)ns) : NULL;
+ sxe->iter.nsprefix = ns_len ? (xmlChar*)estrdup(ns) : NULL;
sxe->iter.isprefix = isprefix;
php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp);
php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL);
@@ -2312,22 +2319,45 @@ static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, i
{
xmlChar *prefix = sxe->iter.nsprefix;
int isprefix = sxe->iter.isprefix;
- int test_elem = sxe->iter.type == SXE_ITER_ELEMENT && sxe->iter.name;
- int test_attr = sxe->iter.type == SXE_ITER_ATTRLIST && sxe->iter.name;
- while (node) {
- SKIP_TEXT(node);
- if (sxe->iter.type != SXE_ITER_ATTRLIST && node->type == XML_ELEMENT_NODE) {
- if ((!test_elem || !xmlStrcmp(node->name, sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) {
- break;
+ if (sxe->iter.type == SXE_ITER_ATTRLIST) {
+ if (sxe->iter.name) {
+ while (node) {
+ if (node->type == XML_ATTRIBUTE_NODE) {
+ if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, prefix, isprefix)) {
+ break;
+ }
+ }
+ node = node->next;
}
- } else if (node->type == XML_ATTRIBUTE_NODE) {
- if ((!test_attr || !xmlStrcmp(node->name, sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) {
- break;
+ } else {
+ while (node) {
+ if (node->type == XML_ATTRIBUTE_NODE) {
+ if (match_ns(sxe, node, prefix, isprefix)) {
+ break;
+ }
+ }
+ node = node->next;
}
}
-next_iter:
- node = node->next;
+ } else if (sxe->iter.type == SXE_ITER_ELEMENT && sxe->iter.name) {
+ while (node) {
+ if (node->type == XML_ELEMENT_NODE) {
+ if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, prefix, isprefix)) {
+ break;
+ }
+ }
+ node = node->next;
+ }
+ } else {
+ while (node) {
+ if (node->type == XML_ELEMENT_NODE) {
+ if (match_ns(sxe, node, prefix, isprefix)) {
+ break;
+ }
+ }
+ node = node->next;
+ }
}
if (node && use_data) {
diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c
index 4c0eeeebb9..1c381cdb00 100644
--- a/ext/standard/formatted_print.c
+++ b/ext/standard/formatted_print.c
@@ -383,7 +383,7 @@ php_sprintf_getnumber(char *buffer, size_t *pos)
*
*/
static zend_string *
-php_formatted_print(int param_count, int use_array, int format_offset)
+php_formatted_print(zend_execute_data *execute_data, int use_array, int format_offset)
{
zval *newargs = NULL;
zval *args, *z_format;
@@ -395,9 +395,15 @@ php_formatted_print(int param_count, int use_array, int format_offset)
int always_sign;
size_t format_len;
- if (zend_parse_parameters(param_count, "+", &args, &argc) == FAILURE) {
+#ifndef FAST_ZPP
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
return NULL;
}
+#else
+ ZEND_PARSE_PARAMETERS_START(1, -1)
+ Z_PARAM_VARIADIC('+', args, argc)
+ ZEND_PARSE_PARAMETERS_END_EX(return NULL);
+#endif
/* verify the number of args */
if ((use_array && argc != (2 + format_offset))
@@ -670,7 +676,7 @@ PHP_FUNCTION(user_sprintf)
{
zend_string *result;
- if ((result=php_formatted_print(ZEND_NUM_ARGS(), 0, 0))==NULL) {
+ if ((result=php_formatted_print(execute_data, 0, 0))==NULL) {
RETURN_FALSE;
}
RETVAL_STR(result);
@@ -683,7 +689,7 @@ PHP_FUNCTION(vsprintf)
{
zend_string *result;
- if ((result=php_formatted_print(ZEND_NUM_ARGS(), 1, 0))==NULL) {
+ if ((result=php_formatted_print(execute_data, 1, 0))==NULL) {
RETURN_FALSE;
}
RETVAL_STR(result);
@@ -697,7 +703,7 @@ PHP_FUNCTION(user_printf)
zend_string *result;
size_t rlen;
- if ((result=php_formatted_print(ZEND_NUM_ARGS(), 0, 0))==NULL) {
+ if ((result=php_formatted_print(execute_data, 0, 0))==NULL) {
RETURN_FALSE;
}
rlen = PHPWRITE(result->val, result->len);
@@ -713,7 +719,7 @@ PHP_FUNCTION(vprintf)
zend_string *result;
size_t rlen;
- if ((result=php_formatted_print(ZEND_NUM_ARGS(), 1, 0))==NULL) {
+ if ((result=php_formatted_print(execute_data, 1, 0))==NULL) {
RETURN_FALSE;
}
rlen = PHPWRITE(result->val, result->len);
@@ -740,7 +746,7 @@ PHP_FUNCTION(fprintf)
php_stream_from_zval(stream, arg1);
- if ((result=php_formatted_print(ZEND_NUM_ARGS(), 0, 1))==NULL) {
+ if ((result=php_formatted_print(execute_data, 0, 1))==NULL) {
RETURN_FALSE;
}
@@ -769,7 +775,7 @@ PHP_FUNCTION(vfprintf)
php_stream_from_zval(stream, arg1);
- if ((result=php_formatted_print(ZEND_NUM_ARGS(), 1, 1))==NULL) {
+ if ((result=php_formatted_print(execute_data, 1, 1))==NULL) {
RETURN_FALSE;
}
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 686fa19536..ee66e8a2af 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -1082,18 +1082,22 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return
char *p1 = str->val;
char *endp = str->val + str->len;
char *p2 = (char *) php_memnstr(str->val, delim->val, delim->len, endp);
+ zval tmp;
if (p2 == NULL) {
- add_next_index_str(return_value, zend_string_copy(str));
+ ZVAL_STR_COPY(&tmp, str);
+ zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
} else {
do {
- add_next_index_stringl(return_value, p1, p2 - p1);
+ ZVAL_STRINGL(&tmp, p1, p2 - p1);
+ zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
p1 = p2 + delim->len;
p2 = (char *) php_memnstr(p1, delim->val, delim->len, endp);
} while (p2 != NULL && --limit > 1);
if (p1 <= endp) {
- add_next_index_stringl(return_value, p1, endp - p1);
+ ZVAL_STRINGL(&tmp, p1, endp - p1);
+ zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
}
}
}
@@ -1107,6 +1111,7 @@ PHPAPI void php_explode_negative_limit(const zend_string *delim, zend_string *st
char *p1 = str->val;
char *endp = str->val + str->len;
char *p2 = (char *) php_memnstr(str->val, delim->val, delim->len, endp);
+ zval tmp;
if (p2 == NULL) {
/*
@@ -1131,8 +1136,8 @@ PHPAPI void php_explode_negative_limit(const zend_string *delim, zend_string *st
to_return = limit + found;
/* limit is at least -1 therefore no need of bounds checking : i will be always less than found */
for (i = 0; i < to_return; i++) { /* this checks also for to_return > 0 */
- add_next_index_stringl(return_value, positions[i],
- (positions[i+1] - delim->len) - positions[i]);
+ ZVAL_STRINGL(&tmp, positions[i], (positions[i+1] - delim->len) - positions[i]);
+ zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
}
efree(positions);
}
@@ -1146,6 +1151,7 @@ PHP_FUNCTION(explode)
{
zend_string *str, *delim;
zend_long limit = ZEND_LONG_MAX; /* No limit */
+ zval tmp;
#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|l", &delim, &str, &limit) == FAILURE) {
@@ -1169,7 +1175,8 @@ PHP_FUNCTION(explode)
if (str->len == 0) {
if (limit >= 0) {
- add_next_index_str(return_value, STR_EMPTY_ALLOC());
+ ZVAL_EMPTY_STRING(&tmp);
+ zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);
}
return;
}
@@ -1179,7 +1186,8 @@ PHP_FUNCTION(explode)
} else if (limit < 0) {
php_explode_negative_limit(delim, str, return_value, limit);
} else {
- add_index_stringl(return_value, 0, str->val, str->len);
+ ZVAL_STR_COPY(&tmp, str);
+ zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);
}
}
/* }}} */