1
0
mirror of https://github.com/php/php-src.git synced 2026-04-04 14:42:49 +02:00
This commit is contained in:
Xinchen Hui
2014-10-03 18:35:18 +08:00
38 changed files with 779 additions and 377 deletions

1
.gitignore vendored
View File

@@ -20,6 +20,7 @@
*.tgz
*.tar.gz
*.tar.bz2
*.tar.xz
.FBCIndex
.FBCLockFolder
.deps

View File

@@ -228,13 +228,6 @@ MAINTENANCE: Maintained
STATUS: Working
COMMENT: Use PostgreSQL 7.0.x or later. PostgreSQL 6.5.3 or less have fatal bug.
-------------------------------------------------------------------------------
EXTENSION: sqlite
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Wez Furlong <wez@php.net>, Ilia Alshanetsky <iliaa@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.0 (Since 4.3.2 in PECL)
COMMENT: Integrates SQLite 2 embeddable SQL database engine.
-------------------------------------------------------------------------------
EXTENSION: sqlite3
PRIMARY MAINTAINER: Scott MacVicar <scottmac@php.net>
MAINTENANCE: Maintained
@@ -385,6 +378,12 @@ MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.4
-------------------------------------------------------------------------------
EXTENSION: hash
PRIMARY MAINTAINER: Sara Golemon <pollita@php.net>, Mike Wallner <mike@php.net>, Anatol Belski <ab@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.1.2
-------------------------------------------------------------------------------
EXTENSION: iconv
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net>
MAINTENANCE: Maintained
@@ -422,22 +421,6 @@ PRIMARY MAINTAINER: Derick Rethans <derick@derickrethans.nl>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mhash
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>, Scott MacVicar <scottmac@php.net>
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mime_magic
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Deprecated
STATUS: Experimental
COMMENT: Use the fileinfo extension instead
-------------------------------------------------------------------------------
EXTENSION: ming
PRIMARY MAINTAINER: Frank M. Kromann
MAINTENANCE: Unknown
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: openssl
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>, Pierre-Alain Joye <pajoye@php.net>
MAINTENANCE: Maintained

View File

@@ -1761,7 +1761,7 @@ static int copy_function_name(zval *zv TSRMLS_DC, int num_args, va_list args, ze
Returns an array of all defined functions */
ZEND_FUNCTION(get_defined_functions)
{
zval internal, user, *ret;
zval internal, user;
if (zend_parse_parameters_none() == FAILURE) {
return;

View File

@@ -132,6 +132,19 @@ static zend_string *zend_build_runtime_definition_key(zend_string *name, unsigne
}
/* }}} */
static zend_bool zend_get_unqualified_name(const zend_string *name, const char **result, size_t *result_len) /* {{{ */
{
const char *ns_separator = zend_memrchr(name->val, '\\', name->len);
if (ns_separator != NULL) {
*result = ns_separator + 1;
*result_len = name->val + name->len - *result;
return 1;
}
return 0;
}
/* }}} */
static void init_compiler_declarables(TSRMLS_D) /* {{{ */
{
ZVAL_LONG(&CG(declarables).ticks, 0);
@@ -331,8 +344,10 @@ static inline int zend_add_literal_string(zend_op_array *op_array, zend_string *
static int zend_add_func_name_literal(zend_op_array *op_array, zend_string *name TSRMLS_DC) /* {{{ */
{
/* Original name */
int ret = zend_add_literal_string(op_array, &name TSRMLS_CC);
/* Lowercased name */
zend_string *lc_name = zend_string_alloc(name->len, 0);
zend_str_tolower_copy(lc_name->val, name->val, name->len);
zend_add_literal_string(op_array, &lc_name TSRMLS_CC);
@@ -343,19 +358,21 @@ static int zend_add_func_name_literal(zend_op_array *op_array, zend_string *name
static int zend_add_ns_func_name_literal(zend_op_array *op_array, zend_string *name TSRMLS_DC) /* {{{ */
{
const char *ns_separator;
const char *unqualified_name;
size_t unqualified_name_len;
/* Original name */
int ret = zend_add_literal_string(op_array, &name TSRMLS_CC);
/* Lowercased name */
zend_string *lc_name = zend_string_alloc(name->len, 0);
zend_str_tolower_copy(lc_name->val, name->val, name->len);
zend_add_literal_string(op_array, &lc_name TSRMLS_CC);
ns_separator = zend_memrchr(name->val, '\\', name->len);
if (ns_separator != NULL) {
size_t len = name->len - (ns_separator - name->val + 1);
lc_name = zend_string_alloc(len, 0);
zend_str_tolower_copy(lc_name->val, ns_separator + 1, len);
/* Lowercased unqualfied name */
if (zend_get_unqualified_name(name, &unqualified_name, &unqualified_name_len)) {
lc_name = zend_string_alloc(unqualified_name_len, 0);
zend_str_tolower_copy(lc_name->val, unqualified_name, unqualified_name_len);
zend_add_literal_string(op_array, &lc_name TSRMLS_CC);
}
@@ -365,8 +382,10 @@ static int zend_add_ns_func_name_literal(zend_op_array *op_array, zend_string *n
static int zend_add_class_name_literal(zend_op_array *op_array, zend_string *name TSRMLS_DC) /* {{{ */
{
/* Original name */
int ret = zend_add_literal_string(op_array, &name TSRMLS_CC);
/* Lowercased name */
zend_string *lc_name = zend_string_alloc(name->len, 0);
zend_str_tolower_copy(lc_name->val, name->val, name->len);
zend_add_literal_string(op_array, &lc_name TSRMLS_CC);
@@ -576,12 +595,16 @@ zend_string *zend_prefix_with_ns(zend_string *name TSRMLS_DC) {
}
}
void *zend_hash_find_ptr_lc(HashTable *ht, char *str, size_t len) {
void *zend_hash_find_ptr_lc(HashTable *ht, const char *str, size_t len) {
void *result;
zend_string *lcname = zend_string_alloc(len, 0);
zend_string *lcname;
ALLOCA_FLAG(use_heap);
STR_ALLOCA_ALLOC(lcname, len, use_heap);
zend_str_tolower_copy(lcname->val, str, len);
result = zend_hash_find_ptr(ht, lcname);
zend_string_free(lcname);
STR_ALLOCA_FREE(lcname, use_heap);
return result;
}
@@ -1131,55 +1154,45 @@ ZEND_API int zend_unmangle_property_name_ex(const zend_string *name, const char
}
/* }}} */
static zend_constant *zend_get_ct_const(zend_string *name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
static zend_constant *zend_lookup_reserved_const(const char *name, size_t len TSRMLS_DC) /* {{{ */
{
zend_constant *c = NULL;
char *lookup_name;
if (name->val[0] == '\\') {
c = zend_hash_str_find_ptr(EG(zend_constants), name->val + 1, name->len - 1);
if (!c) {
lookup_name = zend_str_tolower_dup(name->val + 1, name->len - 1);
c = zend_hash_str_find_ptr(EG(zend_constants), lookup_name, name->len - 1);
efree(lookup_name);
if (c && (c->flags & CONST_CT_SUBST) && !(c->flags & CONST_CS)) {
return c;
}
return NULL;
}
} else if ((c = zend_hash_find_ptr(EG(zend_constants), name)) == NULL) {
lookup_name = zend_str_tolower_dup(name->val, name->len);
c = zend_hash_str_find_ptr(EG(zend_constants), lookup_name, name->len);
efree(lookup_name);
if (c && (c->flags & CONST_CT_SUBST) && !(c->flags & CONST_CS)) {
return c;
}
return NULL;
}
if (c->flags & CONST_CT_SUBST) {
return c;
}
if (all_internal_constants_substitution &&
(c->flags & CONST_PERSISTENT) &&
!(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION) &&
!Z_CONSTANT(c->value)) {
zend_constant *c = zend_hash_find_ptr_lc(EG(zend_constants), name, len);
if (c && !(c->flags & CONST_CS) && (c->flags & CONST_CT_SUBST)) {
return c;
}
return NULL;
}
/* }}} */
static int zend_constant_ct_subst(zval *result, zend_string *name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool is_fully_qualified TSRMLS_DC) /* {{{ */
{
zend_constant *c = zend_get_ct_const(name, all_internal_constants_substitution TSRMLS_CC);
zend_constant *c;
if (c) {
ZVAL_DUP(result, &c->value);
return 1;
if (!(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
/* Substitute case-sensitive (or lowercase) persistent constants */
c = zend_hash_find_ptr(EG(zend_constants), name);
if (c && (c->flags & CONST_PERSISTENT)) {
ZVAL_DUP(zv, &c->value);
return 1;
}
}
{
/* Substitute true, false and null (including unqualified usage in namespaces) */
const char *lookup_name = name->val;
size_t lookup_len = name->len;
if (!is_fully_qualified) {
zend_get_unqualified_name(name, &lookup_name, &lookup_len);
}
c = zend_lookup_reserved_const(lookup_name, lookup_len TSRMLS_CC);
if (c) {
ZVAL_DUP(zv, &c->value);
return 1;
}
}
return 0;
}
/* }}} */
@@ -3922,8 +3935,6 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
}
if (op_array->fn_flags & ZEND_ACC_ABSTRACT) {
//zend_op *opline;
if (op_array->fn_flags & ZEND_ACC_PRIVATE) {
zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot be declared private",
in_interface ? "Interface" : "Abstract", ce->name->val, name->val);
@@ -3935,11 +3946,6 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
}
ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
/*opline = get_next_op(op_array TSRMLS_CC);
opline->opcode = ZEND_RAISE_ABSTRACT_ERROR;
SET_UNUSED(opline->op1);
SET_UNUSED(opline->op2);*/
} else if (!has_body) {
zend_error_noreturn(E_COMPILE_ERROR, "Non-abstract method %s::%s() must contain body",
ce->name->val, name->val);
@@ -4692,10 +4698,11 @@ void zend_compile_use(zend_ast *ast TSRMLS_DC) /* {{{ */
if (new_name_ast) {
new_name = zend_string_copy(zend_ast_get_str(new_name_ast));
} else {
/* The form "use A\B" is eqivalent to "use A\B as B" */
const char *p = zend_memrchr(old_name->val, '\\', old_name->len);
if (p) {
new_name = zend_string_init(p + 1, old_name->len - (p - old_name->val + 1), 0);
const char *unqualified_name;
size_t unqualified_name_len;
if (zend_get_unqualified_name(old_name, &unqualified_name, &unqualified_name_len)) {
/* The form "use A\B" is eqivalent to "use A\B as B" */
new_name = zend_string_init(unqualified_name, unqualified_name_len, 0);
} else {
new_name = zend_string_copy(old_name);
@@ -4799,7 +4806,7 @@ void zend_compile_const_decl(zend_ast *ast TSRMLS_DC) /* {{{ */
value_node.op_type = IS_CONST;
zend_const_expr_to_zval(value_zv, value_ast TSRMLS_CC);
if (zend_get_ct_const(name, 0 TSRMLS_CC)) {
if (zend_lookup_reserved_const(name->val, name->len TSRMLS_CC)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", name->val);
}
@@ -5552,7 +5559,7 @@ void zend_compile_array(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
zend_op *opline;
uint32_t i, opnum_init;
uint32_t i, opnum_init = -1;
zend_bool packed = 1;
if (zend_try_ct_eval_array(&result->u.constant, ast TSRMLS_CC)) {
@@ -5560,8 +5567,6 @@ void zend_compile_array(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
return;
}
opnum_init = get_next_op_number(CG(active_op_array));
for (i = 0; i < list->children; ++i) {
zend_ast *elem_ast = list->child[i];
zend_ast *value_ast = elem_ast->child[0];
@@ -5584,6 +5589,7 @@ void zend_compile_array(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
}
if (i == 0) {
opnum_init = get_next_op_number(CG(active_op_array));
opline = zend_emit_op_tmp(result, ZEND_INIT_ARRAY, &value_node, key_node_ptr TSRMLS_CC);
opline->extended_value = list->children << ZEND_ARRAY_SIZE_SHIFT;
} else {
@@ -5605,6 +5611,7 @@ void zend_compile_array(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
/* Add a flag to INIT_ARRAY if we know this array cannot be packed */
if (!packed) {
ZEND_ASSERT(opnum_init != -1);
opline = &CG(active_op_array)->opcodes[opnum_init];
opline->extended_value |= ZEND_ARRAY_NOT_PACKED;
}
@@ -5622,7 +5629,7 @@ void zend_compile_const(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
zend_string *resolved_name = zend_resolve_const_name(
orig_name, name_ast->attr, &is_fully_qualified TSRMLS_CC);
if (zend_constant_ct_subst(&result->u.constant, resolved_name, 1 TSRMLS_CC)) {
if (zend_try_ct_eval_const(&result->u.constant, resolved_name, is_fully_qualified TSRMLS_CC)) {
result->op_type = IS_CONST;
zend_string_release(resolved_name);
return;
@@ -5858,16 +5865,16 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr TSRMLS_DC) /* {{{ */
zend_bool is_fully_qualified;
zval result, resolved_name;
ZVAL_STR(&resolved_name, zend_resolve_const_name(
orig_name, name_ast->attr, &is_fully_qualified TSRMLS_CC));
if (zend_constant_ct_subst(&result, orig_name, 0 TSRMLS_CC)) {
if (zend_try_ct_eval_const(&result, Z_STR(resolved_name), is_fully_qualified TSRMLS_CC)) {
zend_string_release(Z_STR(resolved_name));
zend_ast_destroy(ast);
*ast_ptr = zend_ast_create_zval(&result);
return;
}
ZVAL_STR(&resolved_name, zend_resolve_const_name(
orig_name, name_ast->attr, &is_fully_qualified TSRMLS_CC));
Z_TYPE_INFO(resolved_name) = IS_CONSTANT_EX;
if (!is_fully_qualified) {
Z_CONST_FLAGS(resolved_name) = IS_CONSTANT_UNQUALIFIED;
@@ -6352,10 +6359,20 @@ void zend_eval_const_expr(zend_ast **ast_ptr TSRMLS_DC) /* {{{ */
}
break;
case ZEND_AST_CONST:
if (!zend_constant_ct_subst(&result, zend_ast_get_str(ast->child[0]), 0 TSRMLS_CC)) {
{
zend_ast *name_ast = ast->child[0];
zend_bool is_fully_qualified;
zend_string *resolved_name = zend_resolve_const_name(
zend_ast_get_str(name_ast), name_ast->attr, &is_fully_qualified TSRMLS_CC);
if (!zend_try_ct_eval_const(&result, resolved_name, is_fully_qualified TSRMLS_CC)) {
zend_string_release(resolved_name);
return;
}
zend_string_release(resolved_name);
break;
}
default:
return;
}

View File

@@ -367,7 +367,6 @@ struct _zend_execute_data {
zend_uchar frame_kind;
zend_class_entry *called_scope;
zend_object *object;
zend_execute_data *prev_nested_call;
zend_execute_data *prev_execute_data;
zval *return_value;
zend_class_entry *scope; /* function scope (self) */

View File

@@ -85,7 +85,7 @@ void zend_exception_restore(TSRMLS_D) /* {{{ */
}
/* }}} */
void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
ZEND_API void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
{
#ifdef HAVE_DTRACE
if (DTRACE_EXCEPTION_THROWN_ENABLED()) {

View File

@@ -30,7 +30,7 @@ ZEND_API void zend_exception_set_previous(zend_object *exception, zend_object *a
ZEND_API void zend_exception_save(TSRMLS_D);
ZEND_API void zend_exception_restore(TSRMLS_D);
void zend_throw_exception_internal(zval *exception TSRMLS_DC);
ZEND_API void zend_throw_exception_internal(zval *exception TSRMLS_DC);
void zend_register_default_exception(TSRMLS_D);

View File

@@ -1609,11 +1609,13 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data
*/
zend_execute_data *execute_data;
uint32_t num_args = call->num_args;
size_t stack_size = (ZEND_CALL_FRAME_SLOT + MAX(op_array->last_var + op_array->T, num_args)) * sizeof(zval);
EG(argument_stack) = zend_vm_stack_new_page(
MAX(ZEND_VM_STACK_PAGE_SIZE,
ZEND_CALL_FRAME_SLOT + MAX(op_array->last_var + op_array->T, num_args)));
EG(argument_stack)->prev = NULL;
EXPECTED(stack_size < ZEND_VM_STACK_FREE_PAGE_SIZE) ?
ZEND_VM_STACK_PAGE_SIZE :
ZEND_VM_STACK_PAGE_ALIGNED_SIZE(stack_size),
NULL);
execute_data = zend_vm_stack_push_call_frame(
(zend_function*)op_array,
@@ -1663,7 +1665,7 @@ static zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call,
int used_stack = (EG(argument_stack)->top - (zval*)call) + additional_args;
/* copy call frame into new stack segment */
zend_vm_stack_extend(used_stack TSRMLS_CC);
zend_vm_stack_extend(used_stack * sizeof(zval) TSRMLS_CC);
new_call = (zend_execute_data*)EG(argument_stack)->top;
EG(argument_stack)->top += used_stack;
*new_call = *call;

View File

@@ -137,7 +137,9 @@ ZEND_API int zval_update_constant_no_inline_change(zval *pp, zend_class_entry *s
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) /* should be a power of 2 */
#define ZEND_VM_STACK_PAGE_SLOTS (16 * 1024) /* should be a power of 2 */
#define ZEND_VM_STACK_PAGE_SIZE (ZEND_VM_STACK_PAGE_SLOTS * sizeof(zval))
struct _zend_vm_stack {
zval *top;
@@ -145,33 +147,30 @@ struct _zend_vm_stack {
zend_vm_stack prev;
};
#define ZEND_VM_STACK_HEADER_SLOT \
#define ZEND_VM_STACK_HEADER_SLOTS \
((ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval)))
#define ZEND_VM_STACK_FREE_PAGE_SIZE \
((ZEND_VM_STACK_PAGE_SLOTS - ZEND_VM_STACK_HEADER_SLOTS) * sizeof(zval))
#define ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size) \
(((size) + (ZEND_VM_STACK_FREE_PAGE_SIZE - 1)) & ~ZEND_VM_STACK_PAGE_SIZE)
#define ZEND_VM_STACK_ELEMETS(stack) \
(((zval*)(stack)) + ZEND_VM_STACK_HEADER_SLOT)
(((zval*)(stack)) + ZEND_VM_STACK_HEADER_SLOTS)
#define ZEND_VM_STACK_GROW_IF_NEEDED(count) \
do { \
if (UNEXPECTED(((count) * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) > \
(size_t)(((char*)EG(argument_stack)->end) - \
((char*)EG(argument_stack)->top)))) { \
zend_vm_stack_extend((count) TSRMLS_CC); \
} \
} while (0)
static zend_always_inline zend_vm_stack zend_vm_stack_new_page(int count) {
zend_vm_stack page = (zend_vm_stack)emalloc(count * ZEND_MM_ALIGNED_SIZE(sizeof(zval)));
static zend_always_inline zend_vm_stack zend_vm_stack_new_page(size_t size, zend_vm_stack prev) {
zend_vm_stack page = (zend_vm_stack)emalloc(size);
page->top = ZEND_VM_STACK_ELEMETS(page);
page->end = (zval*)page + count;
page->prev = NULL;
page->end = (zval*)((char*)page + size);
page->prev = prev;
return page;
}
static zend_always_inline void zend_vm_stack_init(TSRMLS_D)
{
EG(argument_stack) = zend_vm_stack_new_page(ZEND_VM_STACK_PAGE_SIZE);
EG(argument_stack) = zend_vm_stack_new_page(ZEND_VM_STACK_PAGE_SIZE, NULL);
EG(argument_stack)->top++;
}
@@ -186,16 +185,24 @@ static zend_always_inline void zend_vm_stack_destroy(TSRMLS_D)
}
}
static zend_always_inline void zend_vm_stack_extend(uint32_t count TSRMLS_DC)
static zend_always_inline void zend_vm_stack_extend(size_t size TSRMLS_DC)
{
uint32_t size = count * ZEND_MM_ALIGNED_SIZE(sizeof(zval));
zend_vm_stack p = zend_vm_stack_new_page(
(size >= (ZEND_VM_STACK_PAGE_SIZE - ZEND_VM_STACK_HEADER_SLOT) * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) ?
(size + ((ZEND_VM_STACK_HEADER_SLOT + ZEND_VM_STACK_PAGE_SIZE) * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) - 1) &
~((ZEND_VM_STACK_PAGE_SIZE * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) - 1) :
ZEND_VM_STACK_PAGE_SIZE);
p->prev = EG(argument_stack);
EG(argument_stack) = p;
EG(argument_stack) = zend_vm_stack_new_page(
EXPECTED(size < ZEND_VM_STACK_FREE_PAGE_SIZE) ?
ZEND_VM_STACK_PAGE_SIZE : ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size),
EG(argument_stack));
}
static zend_always_inline zval* zend_vm_stack_alloc(size_t size TSRMLS_DC)
{
char *top = (char*)EG(argument_stack)->top;
if (UNEXPECTED(size > (size_t)(((char*)EG(argument_stack)->end) - top))) {
zend_vm_stack_extend(size TSRMLS_CC);
top = (char*)EG(argument_stack)->top;
}
EG(argument_stack)->top = (zval*)(top + size);
return (zval*)top;
}
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_function *func, uint32_t num_args, zend_uchar flags, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
@@ -206,15 +213,13 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_
if (ZEND_USER_CODE(func->type)) {
used_stack += func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args);
}
ZEND_VM_STACK_GROW_IF_NEEDED(used_stack);
call = (zend_execute_data*)EG(argument_stack)->top;
EG(argument_stack)->top += used_stack;
call = (zend_execute_data*)zend_vm_stack_alloc(used_stack * sizeof(zval) TSRMLS_CC);
call->func = func;
call->num_args = 0;
call->flags = flags;
call->called_scope = called_scope;
call->object = object;
call->prev_nested_call = prev;
call->prev_execute_data = prev;
return call;
}
@@ -249,13 +254,12 @@ static zend_always_inline void zend_vm_stack_free_args(zend_execute_data *call T
static zend_always_inline void zend_vm_stack_free_call_frame(zend_execute_data *call TSRMLS_DC)
{
if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (zval*)call)) {
zend_vm_stack p = EG(argument_stack);
zend_vm_stack p = EG(argument_stack);
if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(p) == (zval*)call)) {
EG(argument_stack) = p->prev;
efree(p);
} else {
EG(argument_stack)->top = (zval*)call;
p->top = (zval*)call;
}
}

View File

@@ -703,7 +703,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
dummy_execute_data = *EG(current_execute_data);
dummy_execute_data.prev_execute_data = EG(current_execute_data);
dummy_execute_data.call = NULL;
dummy_execute_data.prev_nested_call = NULL;
dummy_execute_data.opline = NULL;
dummy_execute_data.func = NULL;
EG(current_execute_data) = &dummy_execute_data;

View File

@@ -71,7 +71,7 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
if (execute_data->call->object) {
OBJ_RELEASE(execute_data->call->object);
}
execute_data->call = execute_data->call->prev_nested_call;
execute_data->call = execute_data->call->prev_execute_data;
}
}
/* }}} */

View File

@@ -37,14 +37,7 @@
} while (0)
#define OBJ_RELEASE(obj) do { \
zend_object *_obj = (obj); \
if (--GC_REFCOUNT(_obj) == 0) { \
zend_objects_store_del(_obj TSRMLS_CC); \
} else { \
gc_possible_root(&_obj->gc TSRMLS_CC); \
} \
} while (0)
#define OBJ_RELEASE(obj) zend_object_release(obj TSRMLS_CC)
typedef struct _zend_objects_store {
zend_object **object_buckets;
@@ -78,6 +71,15 @@ ZEND_API zend_object *zend_object_create_proxy(zval *object, zval *member TSRMLS
ZEND_API zend_object_handlers *zend_get_std_object_handlers(void);
END_EXTERN_C()
static zend_always_inline void zend_object_release(zend_object *obj TSRMLS_DC)
{
if (--GC_REFCOUNT(obj) == 0) {
zend_objects_store_del(obj TSRMLS_CC);
} else if (UNEXPECTED(!GC_INFO(obj))) {
gc_possible_root(&obj->gc TSRMLS_CC);
}
}
#endif /* ZEND_OBJECTS_H */
/*

View File

@@ -294,7 +294,7 @@ CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){
CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat) /* {{{ */
{
WIN32_FILE_ATTRIBUTE_DATA data;
__int64 t;
LARGE_INTEGER t;
const size_t path_len = strlen(path);
ALLOCA_FLAG(use_heap_large);
@@ -393,10 +393,11 @@ CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat) /* {{
}
buf->st_nlink = 1;
t = data.nFileSizeHigh;
t = t << 32;
t |= data.nFileSizeLow;
buf->st_size = t;
t.HighPart = data.nFileSizeHigh;
t.LowPart = data.nFileSizeLow;
/* It's an overflow on 32 bit, however it won't fix as long
as zend_long is 32 bit. */
buf->st_size = (zend_long)t.QuadPart;
buf->st_atime = FileTimeToUnixTime(&data.ftLastAccessTime);
buf->st_ctime = FileTimeToUnixTime(&data.ftCreationTime);
buf->st_mtime = FileTimeToUnixTime(&data.ftLastWriteTime);

View File

@@ -1985,17 +1985,6 @@ ZEND_VM_HANDLER(70, ZEND_FREE, TMP|VAR, ANY)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(53, ZEND_INIT_STRING, ANY, ANY)
{
USE_OPLINE
zval *tmp = EX_VAR(opline->result.var);
SAVE_OPLINE();
ZVAL_EMPTY_STRING(tmp);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP|UNUSED, CONST)
{
USE_OPLINE
@@ -2545,7 +2534,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
zend_function *fbc = call->func;
SAVE_OPLINE();
EX(call) = call->prev_nested_call;
EX(call) = call->prev_execute_data;
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
@@ -2669,11 +2658,12 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
call->prev_execute_data = execute_data;
i_init_func_execute_data(call, &fbc->op_array, return_value, EXPECTED(zend_execute_ex == execute_ex) ? VM_FRAME_NESTED_FUNCTION : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
i_init_func_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
call->frame_kind = VM_FRAME_TOP_FUNCTION;
zend_execute_ex(call TSRMLS_CC);
}
}
@@ -2721,11 +2711,7 @@ ZEND_VM_C_LABEL(fcall_end_change_scope):
zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC);
}
}
if (!Z_DELREF(EG(This))) {
_zval_dtor_func_for_ptr(Z_COUNTED(EG(This)) ZEND_FILE_LINE_CC);
} else if (UNEXPECTED(!Z_GC_INFO(EG(This)))) {
gc_possible_root(Z_COUNTED(EG(This)) TSRMLS_CC);
}
OBJ_RELEASE(Z_OBJ(EG(This)));
}
Z_OBJ(EG(This)) = EX(object);
EG(scope) = EX(scope);
@@ -4145,10 +4131,11 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
}
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, EXPECTED(zend_execute_ex == execute_ex) ? VM_FRAME_NESTED_CODE : VM_FRAME_TOP_CODE TSRMLS_CC);
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
call->frame_kind = VM_FRAME_TOP_CODE;
zend_execute_ex(call TSRMLS_CC);
}
@@ -5082,13 +5069,6 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY)
{
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(scope)->name->val, EX(func)->op_array.function_name->val);
ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
{
USE_OPLINE
@@ -5427,7 +5407,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
}
OBJ_RELEASE(call->object);
}
EX(call) = call->prev_nested_call;
EX(call) = call->prev_execute_data;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
call = EX(call);
} while (call);

View File

@@ -488,17 +488,6 @@ static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_CONTINUE();
}
static int ZEND_FASTCALL ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *tmp = EX_VAR(opline->result.var);
SAVE_OPLINE();
ZVAL_EMPTY_STRING(tmp);
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -506,7 +495,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_function *fbc = call->func;
SAVE_OPLINE();
EX(call) = call->prev_nested_call;
EX(call) = call->prev_execute_data;
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
@@ -630,11 +619,12 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
call->prev_execute_data = execute_data;
i_init_func_execute_data(call, &fbc->op_array, return_value, EXPECTED(zend_execute_ex == execute_ex) ? VM_FRAME_NESTED_FUNCTION : VM_FRAME_TOP_FUNCTION TSRMLS_CC);
i_init_func_execute_data(call, &fbc->op_array, return_value, VM_FRAME_NESTED_FUNCTION TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
call->frame_kind = VM_FRAME_TOP_FUNCTION;
zend_execute_ex(call TSRMLS_CC);
}
}
@@ -682,11 +672,7 @@ fcall_end_change_scope:
zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC);
}
}
if (!Z_DELREF(EG(This))) {
_zval_dtor_func_for_ptr(Z_COUNTED(EG(This)) ZEND_FILE_LINE_CC);
} else if (UNEXPECTED(!Z_GC_INFO(EG(This)))) {
gc_possible_root(Z_COUNTED(EG(This)) TSRMLS_CC);
}
OBJ_RELEASE(Z_OBJ(EG(This)));
}
Z_OBJ(EG(This)) = EX(object);
EG(scope) = EX(scope);
@@ -1142,13 +1128,6 @@ static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(scope)->name->val, EX(func)->op_array.function_name->val);
ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
static int ZEND_FASTCALL ZEND_EXT_STMT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
SAVE_OPLINE();
@@ -1330,7 +1309,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
}
OBJ_RELEASE(call->object);
}
EX(call) = call->prev_nested_call;
EX(call) = call->prev_execute_data;
zend_vm_stack_free_call_frame(call TSRMLS_CC);
call = EX(call);
} while (call);
@@ -3023,10 +3002,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
}
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, EXPECTED(zend_execute_ex == execute_ex) ? VM_FRAME_NESTED_CODE : VM_FRAME_TOP_CODE TSRMLS_CC);
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
call->frame_kind = VM_FRAME_TOP_CODE;
zend_execute_ex(call TSRMLS_CC);
}
@@ -9761,10 +9741,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
}
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, EXPECTED(zend_execute_ex == execute_ex) ? VM_FRAME_NESTED_CODE : VM_FRAME_TOP_CODE TSRMLS_CC);
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
call->frame_kind = VM_FRAME_TOP_CODE;
zend_execute_ex(call TSRMLS_CC);
}
@@ -10070,12 +10051,12 @@ static int ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
} else if (IS_TMP_VAR == IS_VAR && is_ref) {
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
zval_dtor(free_op1.var);
zval_ptr_dtor_nogc(free_op1.var);
}
ZEND_VM_JMP(opline->op2.jmp_addr);
}
zval_dtor(free_op1.var);
zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -16349,10 +16330,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
}
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, EXPECTED(zend_execute_ex == execute_ex) ? VM_FRAME_NESTED_CODE : VM_FRAME_TOP_CODE TSRMLS_CC);
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
call->frame_kind = VM_FRAME_TOP_CODE;
zend_execute_ex(call TSRMLS_CC);
}
@@ -33630,10 +33612,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
}
call->prev_execute_data = execute_data;
i_init_code_execute_data(call, new_op_array, return_value, EXPECTED(zend_execute_ex == execute_ex) ? VM_FRAME_NESTED_CODE : VM_FRAME_TOP_CODE TSRMLS_CC);
i_init_code_execute_data(call, new_op_array, return_value, VM_FRAME_NESTED_CODE TSRMLS_CC);
if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
call->frame_kind = VM_FRAME_TOP_CODE;
zend_execute_ex(call TSRMLS_CC);
}
@@ -44626,31 +44609,31 @@ void zend_init_opcodes_handlers(void)
ZEND_BOOL_SPEC_CV_HANDLER,
ZEND_BOOL_SPEC_CV_HANDLER,
ZEND_BOOL_SPEC_CV_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_INIT_STRING_SPEC_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
@@ -46851,31 +46834,31 @@ void zend_init_opcodes_handlers(void)
ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_RAISE_ABSTRACT_ERROR_SPEC_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,

View File

@@ -75,7 +75,7 @@ const char *zend_vm_opcodes_map[170] = {
"ZEND_BRK",
"ZEND_CONT",
"ZEND_BOOL",
"ZEND_INIT_STRING",
NULL,
"ZEND_ADD_CHAR",
"ZEND_ADD_STRING",
"ZEND_ADD_VAR",
@@ -164,7 +164,7 @@ const char *zend_vm_opcodes_map[170] = {
"ZEND_DECLARE_CLASS",
"ZEND_DECLARE_INHERITED_CLASS",
"ZEND_DECLARE_FUNCTION",
"ZEND_RAISE_ABSTRACT_ERROR",
NULL,
"ZEND_DECLARE_CONST",
"ZEND_ADD_INTERFACE",
"ZEND_DECLARE_INHERITED_CLASS_DELAYED",

View File

@@ -75,7 +75,6 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
#define ZEND_BRK 50
#define ZEND_CONT 51
#define ZEND_BOOL 52
#define ZEND_INIT_STRING 53
#define ZEND_ADD_CHAR 54
#define ZEND_ADD_STRING 55
#define ZEND_ADD_VAR 56
@@ -155,7 +154,6 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
#define ZEND_DECLARE_CLASS 139
#define ZEND_DECLARE_INHERITED_CLASS 140
#define ZEND_DECLARE_FUNCTION 141
#define ZEND_RAISE_ABSTRACT_ERROR 142
#define ZEND_DECLARE_CONST 143
#define ZEND_ADD_INTERFACE 144
#define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145

View File

@@ -156,12 +156,12 @@ if test "\$PHP_$EXTNAME" != "no"; then
dnl PHP_CHECK_LIBRARY(\$LIBNAME,\$LIBSYMBOL,
dnl [
dnl PHP_ADD_LIBRARY_WITH_PATH(\$LIBNAME, \$${EXTNAME}_DIR/lib, ${EXTNAME}_SHARED_LIBADD)
dnl PHP_ADD_LIBRARY_WITH_PATH(\$LIBNAME, \$${EXTNAME}_DIR/\$PHP_LIBDIR, ${EXTNAME}_SHARED_LIBADD)
dnl AC_DEFINE(HAVE_${EXTNAME}LIB,1,[ ])
dnl ],[
dnl AC_MSG_ERROR([wrong $extname lib version or lib not found])
dnl ],[
dnl -L\$${EXTNAME}_DIR/lib -lm
dnl -L\$${EXTNAME}_DIR/\$PHP_LIBDIR -lm
dnl ])
dnl
dnl PHP_SUBST(${EXTNAME}_SHARED_LIBADD)

View File

@@ -1054,25 +1054,6 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
VAR_UNSET(opline->op1);
COPY_NODE(opline->op1, src->op1);
MAKE_NOP(src);
} else if ((opline->opcode == ZEND_ADD_STRING ||
opline->opcode == ZEND_ADD_CHAR) &&
ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
VAR_SOURCE(opline->op1) &&
VAR_SOURCE(opline->op1)->opcode == ZEND_INIT_STRING) {
/* convert T = INIT_STRING(), T = ADD_STRING(T, X) to T = QM_ASSIGN(X) */
/* CHECKME: Remove ZEND_ADD_VAR optimization, since some conversions -
namely, BOOL(false)->string - don't allocate memory but use empty_string
and ADD_CHAR fails */
zend_op *src = VAR_SOURCE(opline->op1);
VAR_UNSET(opline->op1);
COPY_NODE(opline->op1, opline->op2);
if (opline->opcode == ZEND_ADD_CHAR) {
char c = (char)Z_LVAL(ZEND_OP2_LITERAL(opline));
ZVAL_STRINGL(&ZEND_OP1_LITERAL(opline), &c, 1);
}
SET_UNUSED(opline->op2);
MAKE_NOP(src);
opline->opcode = ZEND_QM_ASSIGN;
} else if ((opline->opcode == ZEND_ADD_STRING ||
opline->opcode == ZEND_ADD_CHAR ||
opline->opcode == ZEND_ADD_VAR ||
@@ -1094,23 +1075,6 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
opline->opcode = ZEND_CONCAT;
literal_dtor(&ZEND_OP2_LITERAL(src)); /* will take care of empty_string too */
MAKE_NOP(src);
//??? This optimization can't work anymore because ADD_VAR returns IS_TMP_VAR
//??? and ZEND_CAST returns IS_VAR.
//??? BTW: it wan't used for long time, because we don't use INIT_STRING
#if 0
} else if (opline->opcode == ZEND_ADD_VAR &&
ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
VAR_SOURCE(opline->op1) &&
VAR_SOURCE(opline->op1)->opcode == ZEND_INIT_STRING) {
/* convert T = INIT_STRING(), T = ADD_VAR(T, X) to T = CAST(STRING, X) */
zend_op *src = VAR_SOURCE(opline->op1);
VAR_UNSET(opline->op1);
COPY_NODE(opline->op1, opline->op2);
SET_UNUSED(opline->op2);
MAKE_NOP(src);
opline->opcode = ZEND_CAST;
opline->extended_value = IS_STRING;
#endif
} else if ((opline->opcode == ZEND_ADD_STRING ||
opline->opcode == ZEND_ADD_CHAR ||
opline->opcode == ZEND_ADD_VAR ||

View File

@@ -5126,7 +5126,7 @@ PHP_FUNCTION(php_strip_whitespace)
char *filename;
size_t filename_len;
zend_lex_state original_lex_state;
zend_file_handle file_handle = {0};
zend_file_handle file_handle = {{0}};
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
RETURN_FALSE;

View File

@@ -221,7 +221,7 @@ static void php_browscap_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callb
static int browscap_read_file(char *filename, browser_data *browdata, int persistent TSRMLS_DC) /* {{{ */
{
zend_file_handle fh = {0};
zend_file_handle fh = {{0}};
if (filename == NULL || filename[0] == '\0') {
return FAILURE;
@@ -379,15 +379,13 @@ static int browser_reg_compare(zval *browser TSRMLS_DC, int num_args, va_list ar
number of characters changed in the user agent being checked versus
the previous match found and the current match. */
if (Z_TYPE_P(found_browser_entry) == IS_ARRAY) {
int i, prev_len = 0, curr_len = 0, ua_len;
zval *current_match;
size_t i, prev_len = 0, curr_len = 0;
zval *current_match = zend_hash_str_find(Z_ARRVAL_P(browser), "browser_name_pattern", sizeof("browser_name_pattern")-1);
if ((current_match = zend_hash_str_find(Z_ARRVAL_P(browser), "browser_name_pattern", sizeof("browser_name_pattern")-1)) == NULL) {
if (!current_match) {
return 0;
}
ua_len = lookup_browser_length;
for (i = 0; i < Z_STRLEN_P(previous_match); i++) {
switch (Z_STRVAL_P(previous_match)[i]) {
case '?':

View File

@@ -201,11 +201,11 @@ _cyr_mac = {
* d - x-cp866
* m - x-mac-cyrillic
*****************************************************************************/
static char * php_convert_cyr_string(unsigned char *str, int length, char from, char to TSRMLS_DC)
static char * php_convert_cyr_string(unsigned char *str, size_t length, char from, char to TSRMLS_DC)
{
const unsigned char *from_table, *to_table;
unsigned char tmp;
int i;
size_t i;
from_table = NULL;
to_table = NULL;
@@ -258,8 +258,7 @@ static char * php_convert_cyr_string(unsigned char *str, int length, char from,
if (!str)
return (char *)str;
for( i = 0; i<length; i++)
{
for (i = 0; i < length; i++) {
tmp = (from_table == NULL)? str[i] : from_table[ str[i] ];
str[i] = (to_table == NULL) ? tmp : to_table[tmp + 256];
}
@@ -281,7 +280,7 @@ PHP_FUNCTION(convert_cyr_string)
str = zend_string_init(input, input_len, 0);
php_convert_cyr_string(str->val, str->len, fr_cs[0], to_cs[0] TSRMLS_CC);
php_convert_cyr_string((unsigned char *) str->val, str->len, fr_cs[0], to_cs[0] TSRMLS_CC);
RETVAL_NEW_STR(str);
}
/* }}} */

View File

@@ -535,7 +535,7 @@ static u_char *php_parserr(u_char *cp, u_char *end, querybuf *answer, int type_t
}
if (n) {
memcpy(tp->val + l2 , cp + l1 + 1, n);
add_next_index_stringl(&entries, cp + l1 + 1, n);
add_next_index_stringl(&entries, (char *) cp + l1 + 1, n);
}
l1 = l1 + n + 1;
l2 = l2 + n;

View File

@@ -300,8 +300,8 @@ PHP_FUNCTION(iptcparse)
{
int inx = 0, len;
unsigned int tagsfound = 0;
unsigned char *buffer, recnum, dataset, key[ 16 ];
char *str;
unsigned char *buffer, recnum, dataset;
char *str, key[16];
size_t str_len;
zval values, *element;

View File

@@ -61,7 +61,7 @@ PHP_NAMED_FUNCTION(php_if_md5)
PHP_MD5Update(&context, arg->val, arg->len);
PHP_MD5Final(digest, &context);
if (raw_output) {
RETURN_STRINGL(digest, 16);
RETURN_STRINGL((char *) digest, 16);
} else {
make_digest_ex(md5str, digest, 16);
RETVAL_STRING(md5str);
@@ -112,7 +112,7 @@ PHP_NAMED_FUNCTION(php_if_md5_file)
PHP_MD5Final(digest, &context);
if (raw_output) {
RETURN_STRINGL(digest, 16);
RETURN_STRINGL((char *) digest, 16);
} else {
make_digest_ex(md5str, digest, 16);
RETVAL_STRING(md5str);

View File

@@ -46,10 +46,10 @@ PHP_FUNCTION(sha1)
sha1str[0] = '\0';
PHP_SHA1Init(&context);
PHP_SHA1Update(&context, arg->val, arg->len);
PHP_SHA1Update(&context, (unsigned char *) arg->val, arg->len);
PHP_SHA1Final(digest, &context);
if (raw_output) {
RETURN_STRINGL(digest, 20);
RETURN_STRINGL((char *) digest, 20);
} else {
make_digest_ex(sha1str, digest, 20);
RETVAL_STRING(sha1str);
@@ -71,7 +71,7 @@ PHP_FUNCTION(sha1_file)
unsigned char buf[1024];
unsigned char digest[20];
PHP_SHA1_CTX context;
int n;
size_t n;
php_stream *stream;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|b", &arg, &arg_len, &raw_output) == FAILURE) {
@@ -85,7 +85,7 @@ PHP_FUNCTION(sha1_file)
PHP_SHA1Init(&context);
while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
while ((n = php_stream_read(stream, (char *) buf, sizeof(buf))) > 0) {
PHP_SHA1Update(&context, buf, n);
}
@@ -93,12 +93,8 @@ PHP_FUNCTION(sha1_file)
php_stream_close(stream);
if (n<0) {
RETURN_FALSE;
}
if (raw_output) {
RETURN_STRINGL(digest, 20);
RETURN_STRINGL((char *) digest, 20);
} else {
make_digest_ex(sha1str, digest, 20);
RETVAL_STRING(sha1str);

View File

@@ -3983,7 +3983,7 @@ static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, int convert_newlines)
while (1) {
char_count=0;
while ((!max_chars || max_chars > 0 && char_count < max_chars) && begin > 0) {
while ((!max_chars || (max_chars > 0 && char_count < max_chars)) && begin > 0) {
char_count++;
begin--;
if (begin <= 0 || _isnewline(heb_str[begin])) {

View File

@@ -0,0 +1,95 @@
--TEST--
Bug #51800 proc_open on Windows hangs forever
--SKIPIF--
<?php
echo 'skip expected to fail or take too long';
if (getenv("SKIP_SLOW_TESTS")) {
die("skip slow test");
}
?>
--XFAIL--
pipes have to be read/written simultaneously
--FILE--
<?php
/* This is the wrong way to do it. The parent will block till it has read all the STDIN.
The smaller the pipe buffer is, the longer it will take. It might even pass at the end,
after taking inappropriately long. Pipes have to be read simultaneously in smaller chunks,
so then the pipe buffer is emptied more often and the child has chance to continue its
write. The behaviour might look some better if write/read in a separate thread, however
this is much more resource greedy and complexer to integrate into the user script. */
$callee = dirname(__FILE__) . "/process_proc_open_bug51800.php";
$php = PHP_BINARY;
$cmd = "$php $callee";
$status;
$stdout = "";
$stderr = "";
$pipes = array();
$descriptors = array(
0 => array("pipe", "rb"), // stdin
1 => array("pipe", "wb"), // stdout
2 => array("pipe", "wb") // stderr
);
/* create the proc file */
$r = file_put_contents($callee, '<?php
$how_much = 10000;
$data0 = str_repeat("a", $how_much);
$data1 = str_repeat("b", $how_much);
fwrite(STDOUT, $data0);
fwrite(STDERR, $data1);
exit(0);
');
if (!$r) {
die("couldn't create helper script '$callee'");
}
$process = proc_open($cmd, $descriptors, $pipes);
if (is_resource($process))
{
fclose($pipes[0]);
while (!feof($pipes[1]))
$stdout .= fread($pipes[1], 1024);
fclose($pipes[1]);
while (!feof($pipes[2]))
$stderr .= fread($pipes[2], 1024);
fclose($pipes[2]);
$status = proc_close($process);
}
var_dump(array(
"status" => $status,
"stdout" => $stdout,
"stderr" => $stderr,
), strlen($stdout), strlen($stderr));
?>
===DONE===
--CLEAN--
<?php
$callee = dirname(__FILE__) . "/process_proc_open_bug51800.php";
unlink($callee);
?>
--EXPECTF--
array(3) {
["status"]=>
int(0)
["stdout"]=>
string(10000) "a%s"
["stderr"]=>
string(10000) "b%s"
}
int(10000)
int(10000)
===DONE===

View File

@@ -0,0 +1,78 @@
--TEST--
Bug #51800 proc_open on Windows hangs forever, the right way to do it
--FILE--
<?php
$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right.php";
$php = PHP_BINARY;
$cmd = "$php $callee";
$status;
$stdout = "";
$stderr = "";
$pipes = array();
$descriptors = array(
0 => array("pipe", "rb"), // stdin
1 => array("pipe", "wb"), // stdout
2 => array("pipe", "wb") // stderr
);
/* create the proc file */
$r = file_put_contents($callee, '<?php
$how_much = 10000;
$data0 = str_repeat("a", $how_much);
$data1 = str_repeat("b", $how_much);
fwrite(STDOUT, $data0);
fwrite(STDERR, $data1);
exit(0);
');
if (!$r) {
die("couldn't create helper script '$callee'");
}
$process = proc_open($cmd, $descriptors, $pipes);
if (is_resource($process))
{
fclose($pipes[0]);
while (!feof($pipes[1]) || !feof($pipes[2])) {
$stdout .= fread($pipes[1], 1024);
$stderr .= fread($pipes[2], 1024);
}
fclose($pipes[1]);
fclose($pipes[2]);
$status = proc_close($process);
}
var_dump(array(
"status" => $status,
"stdout" => $stdout,
"stderr" => $stderr,
), strlen($stdout), strlen($stderr));
?>
===DONE===
--CLEAN--
<?php
$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right.php";
unlink($callee);
?>
--EXPECTF--
array(3) {
["status"]=>
int(0)
["stdout"]=>
string(10000) "a%s"
["stderr"]=>
string(10000) "b%s"
}
int(10000)
int(10000)
===DONE===

View File

@@ -0,0 +1,84 @@
--TEST--
Bug #51800 proc_open on Windows hangs forever, the right way to do it with more data
--FILE--
<?php
$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right2.php";
$php = PHP_BINARY;
$cmd = "$php $callee";
$status;
$stdout = "";
$stderr = "";
$pipes = array();
$descriptors = array(
0 => array("pipe", "rb"), // stdin
1 => array("pipe", "wb"), // stdout
2 => array("pipe", "wb") // stderr
);
/* create the proc file */
$r = file_put_contents($callee, '<?php
$how_much = 1000000;
$data0 = str_repeat("a", $how_much);
$data1 = str_repeat("b", $how_much);
$i0 = $i1 = 0;
$step = 1024;
while ($i0 < strlen($data0) && $i1 < strlen($data1)) {
fwrite(STDOUT, substr($data0, $i0, $step));
fwrite(STDERR, substr($data1, $i1, $step));
$i0 += $step;
$i1 += $step;
}
exit(0);
');
if (!$r) {
die("couldn't create helper script '$callee'");
}
$process = proc_open($cmd, $descriptors, $pipes);
if (is_resource($process))
{
fclose($pipes[0]);
while (!feof($pipes[1]) || !feof($pipes[2])) {
$stdout .= fread($pipes[1], 1024);
$stderr .= fread($pipes[2], 1024);
}
fclose($pipes[1]);
fclose($pipes[2]);
$status = proc_close($process);
}
var_dump(array(
"status" => $status,
"stdout" => $stdout,
"stderr" => $stderr,
), strlen($stdout), strlen($stderr));
?>
===DONE===
--CLEAN--
<?php
$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right2.php";
unlink($callee);
?>
--EXPECTF--
array(3) {
["status"]=>
int(0)
["stdout"]=>
string(1000000) "a%s"
["stderr"]=>
string(1000000) "b%s"
}
int(1000000)
int(1000000)
===DONE===

View File

@@ -0,0 +1,71 @@
--TEST--
Bug #60120 proc_open hangs with stdin/out with 2048+ bytes
--FILE--
<?php
error_reporting(E_ALL);
if (substr(PHP_OS, 0, 3) == 'WIN') {
$cmd = PHP_BINARY . ' -n -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"';
} else {
$cmd = PHP_BINARY . ' -n -r \'fwrite(STDOUT, $in = file_get_contents("php://stdin")); fwrite(STDERR, $in);\'';
}
$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
$stdin = str_repeat('*', 1024 * 16) . '!';
$stdin = str_repeat('*', 2049 );
$options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => false));
$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options);
foreach ($pipes as $pipe) {
stream_set_blocking($pipe, false);
}
$writePipes = array($pipes[0]);
$stdinLen = strlen($stdin);
$stdinOffset = 0;
unset($pipes[0]);
while ($pipes || $writePipes) {
$r = $pipes;
$w = $writePipes;
$e = null;
$n = stream_select($r, $w, $e, 60);
if (false === $n) {
break;
} elseif ($n === 0) {
proc_terminate($process);
}
if ($w) {
$written = fwrite($writePipes[0], (binary)substr($stdin, $stdinOffset), 8192);
if (false !== $written) {
$stdinOffset += $written;
}
if ($stdinOffset >= $stdinLen) {
fclose($writePipes[0]);
$writePipes = null;
}
}
foreach ($r as $pipe) {
$type = array_search($pipe, $pipes);
$data = fread($pipe, 8192);
var_dump($data);
if (false === $data || feof($pipe)) {
fclose($pipe);
unset($pipes[$type]);
}
}
}
?>
===DONE===
--EXPECTF--
string(2049) "%s"
string(2049) "%s"
string(0) ""
string(0) ""
===DONE===

View File

@@ -0,0 +1,70 @@
--TEST--
Bug #64438 proc_open hangs with stdin/out with 4097+ bytes
--FILE--
<?php
error_reporting(E_ALL);
if (substr(PHP_OS, 0, 3) == 'WIN') {
$cmd = PHP_BINARY . ' -n -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"';
} else {
$cmd = PHP_BINARY . ' -n -r \'fwrite(STDOUT, $in = file_get_contents("php://stdin")); fwrite(STDERR, $in);\'';
}
$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
$stdin = str_repeat('*', 4097);
$options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => false));
$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options);
foreach ($pipes as $pipe) {
stream_set_blocking($pipe, false);
}
$writePipes = array($pipes[0]);
$stdinLen = strlen($stdin);
$stdinOffset = 0;
unset($pipes[0]);
while ($pipes || $writePipes) {
$r = $pipes;
$w = $writePipes;
$e = null;
$n = stream_select($r, $w, $e, 60);
if (false === $n) {
break;
} elseif ($n === 0) {
proc_terminate($process);
}
if ($w) {
$written = fwrite($writePipes[0], (binary)substr($stdin, $stdinOffset), 8192);
if (false !== $written) {
$stdinOffset += $written;
}
if ($stdinOffset >= $stdinLen) {
fclose($writePipes[0]);
$writePipes = null;
}
}
foreach ($r as $pipe) {
$type = array_search($pipe, $pipes);
$data = fread($pipe, 8192);
var_dump($data);
if (false === $data || feof($pipe)) {
fclose($pipe);
unset($pipes[$type]);
}
}
}
?>
===DONE===
--EXPECTF--
string(4097) "%s"
string(4097) "%s"
string(0) ""
string(0) ""
===DONE===

View File

@@ -20,9 +20,9 @@ echo "*** Testing setlocale() : usage variations ***\n";
function good_locale($locale) {
/**
* Note: no_NO is a bogus locale and should not be used, see https://bugzilla.redhat.com/show_bug.cgi?id=532487
* Note: no_NO is a bogus locale and should not be used, see https://bugzilla.redhat.com/971416
**/
return $locale !== 'tt_RU@iqtelif.UTF-8' && substr($locale, 0, 5) !== "no_NO";
return $locale !== 'tt_RU@iqtelif.UTF-8' && $locale !== 'no_NO.ISO-8859-1';
}
/* Prototype : array list_system_locales( void )

View File

@@ -348,6 +348,34 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count TSRMLS
assert(data != NULL);
if (data->fd >= 0) {
#ifdef PHP_WIN32
php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract;
if (self->is_pipe || self->is_process_pipe) {
HANDLE ph = (HANDLE)_get_osfhandle(data->fd);
int retry = 0;
DWORD avail_read = 0;
do {
/* Look ahead to get the available data amount to read. Do the same
as read() does, however not blocking forever. In case it failed,
no data will be read (better than block). */
if (!PeekNamedPipe(ph, NULL, 0, NULL, &avail_read, NULL)) {
break;
}
/* If there's nothing to read, wait in 100ms periods. */
if (0 == avail_read) {
usleep(100000);
}
} while (0 == avail_read && retry++ < 320);
/* Reduce the required data amount to what is available, otherwise read()
will block.*/
if (avail_read < count) {
count = avail_read;
}
}
#endif
ret = read(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count));
if (ret == (size_t)-1 && errno == EINTR) {

View File

@@ -39,29 +39,6 @@ struct listening_socket_s {
static struct fpm_array_s sockets_list;
static int fpm_sockets_resolve_af_inet(char *node, char *service, struct sockaddr_in *addr) /* {{{ */
{
struct addrinfo *res;
struct addrinfo hints;
int ret;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
ret = getaddrinfo(node, service, &hints, &res);
if (ret != 0) {
zlog(ZLOG_ERROR, "can't resolve hostname '%s%s%s': getaddrinfo said: %s%s%s\n",
node, service ? ":" : "", service ? service : "",
gai_strerror(ret), ret == EAI_SYSTEM ? ", system error: " : "", ret == EAI_SYSTEM ? strerror(errno) : "");
return -1;
}
*addr = *(struct sockaddr_in *) res->ai_addr;
freeaddrinfo(res);
return 0;
}
/* }}} */
enum { FPM_GET_USE_SOCKET = 1, FPM_STORE_SOCKET = 2, FPM_STORE_USE_SOCKET = 3 };
static void fpm_sockets_cleanup(int which, void *arg) /* {{{ */
@@ -98,14 +75,23 @@ static void fpm_sockets_cleanup(int which, void *arg) /* {{{ */
}
/* }}} */
static void *fpm_get_in_addr(struct sockaddr *sa) /* {{{ */
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
/* }}} */
static int fpm_sockets_hash_op(int sock, struct sockaddr *sa, char *key, int type, int op) /* {{{ */
{
if (key == NULL) {
switch (type) {
case FPM_AF_INET : {
struct sockaddr_in *sa_in = (struct sockaddr_in *) sa;
key = alloca(sizeof("xxx.xxx.xxx.xxx:ppppp"));
sprintf(key, "%u.%u.%u.%u:%u", IPQUAD(&sa_in->sin_addr), (unsigned int) ntohs(sa_in->sin_port));
key = alloca(INET6_ADDRSTRLEN);
inet_ntop(sa->sa_family, fpm_get_in_addr(sa), key, sizeof key);
break;
}
@@ -254,11 +240,14 @@ enum fpm_address_domain fpm_sockets_domain_from_address(char *address) /* {{{ */
static int fpm_socket_af_inet_listening_socket(struct fpm_worker_pool_s *wp) /* {{{ */
{
struct sockaddr_in sa_in;
struct addrinfo hints, *servinfo, *p;
char *dup_address = strdup(wp->config->listen_address);
char *port_str = strchr(dup_address, ':');
char *port_str = strrchr(dup_address, ':');
char *addr = NULL;
int addr_len;
int port = 0;
int sock;
int status;
if (port_str) { /* this is host:port pair */
*port_str++ = '\0';
@@ -274,23 +263,35 @@ static int fpm_socket_af_inet_listening_socket(struct fpm_worker_pool_s *wp) /*
return -1;
}
memset(&sa_in, 0, sizeof(sa_in));
if (addr) {
sa_in.sin_addr.s_addr = inet_addr(addr);
if (sa_in.sin_addr.s_addr == INADDR_NONE) { /* do resolve */
if (0 > fpm_sockets_resolve_af_inet(addr, NULL, &sa_in)) {
return -1;
}
zlog(ZLOG_NOTICE, "address '%s' resolved as %u.%u.%u.%u", addr, IPQUAD(&sa_in.sin_addr));
// strip brackets from address for getaddrinfo
if (addr != NULL) {
addr_len = strlen(addr);
if (addr[0] == '[' && addr[addr_len - 1] == ']') {
addr[addr_len - 1] = '\0';
addr++;
}
} else {
sa_in.sin_addr.s_addr = htonl(INADDR_ANY);
}
sa_in.sin_family = AF_INET;
sa_in.sin_port = htons(port);
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(addr, port_str, &hints, &servinfo)) != 0) {
zlog(ZLOG_ERROR, "getaddrinfo: %s\n", gai_strerror(status));
return -1;
}
free(dup_address);
return fpm_sockets_get_listening_socket(wp, (struct sockaddr *) &sa_in, sizeof(struct sockaddr_in));
for (p = servinfo; p != NULL; p = p->ai_next) {
if ((sock = fpm_sockets_get_listening_socket(wp, p->ai_addr, p->ai_addrlen)) != -1) {
break;
}
}
freeaddrinfo(servinfo);
return sock;
}
/* }}} */

View File

@@ -45,10 +45,4 @@ static inline int fd_set_blocked(int fd, int blocked) /* {{{ */
}
/* }}} */
#define IPQUAD(sin_addr) \
(unsigned int) ((unsigned char *) &(sin_addr)->s_addr)[0], \
(unsigned int) ((unsigned char *) &(sin_addr)->s_addr)[1], \
(unsigned int) ((unsigned char *) &(sin_addr)->s_addr)[2], \
(unsigned int) ((unsigned char *) &(sin_addr)->s_addr)[3]
#endif

View File

@@ -152,6 +152,8 @@ group = @php_fpm_group@
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses on a
; specific port;
; '/path/to/unix/socket' - to listen on a unix socket.

53
sapi/fpm/tests/003.phpt Normal file
View File

@@ -0,0 +1,53 @@
--TEST--
FPM: Test IPv6 support
--SKIPIF--
<?php include "skipif.inc"; ?>
--FILE--
<?php
include "include.inc";
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
$cfg = <<<EOT
[global]
error_log = $logfile
[unconfined]
listen = [::1]:9000
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
EOT;
$fpm = run_fpm($cfg, $tail);
if (is_resource($fpm)) {
var_dump(fgets($tail));
var_dump(fgets($tail));
$i = 0;
while (($i++ < 30) && !($fp = fsockopen('[::1]', 9000))) {
usleep(10000);
}
if ($fp) {
echo "Done\n";
fclose($fp);
}
proc_terminate($fpm);
stream_get_contents($tail);
fclose($tail);
proc_close($fpm);
}
?>
--EXPECTF--
string(%d) "[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
"
string(%d) "[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
"
Done
--CLEAN--
<?php
$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
@unlink($logfile);
?>