Esempio n. 1
0
/* {{{ proto array SplDoublyLinkedList::__serialize() */
SPL_METHOD(SplDoublyLinkedList, __serialize)
{
	spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS);
	spl_ptr_llist_element *current = intern->llist->head;
	zval tmp;

	if (zend_parse_parameters_none_throw() == FAILURE) {
		return;
	}

	array_init(return_value);

	/* flags */
	ZVAL_LONG(&tmp, intern->flags);
	zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);

	/* elements */
	array_init_size(&tmp, intern->llist->count);
	while (current) {
		zend_hash_next_index_insert(Z_ARRVAL(tmp), &current->data);
		current = current->next;
	}
	zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);

	/* members */
	ZVAL_ARR(&tmp, zend_std_get_properties(&intern->std));
	Z_TRY_ADDREF(tmp);
	zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);
} /* }}} */
Esempio n. 2
0
static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{ */
{
	zend_closure *closure = (zend_closure *)Z_OBJ_P(object);
	zval val;
	struct _zend_arg_info *arg_info = closure->func.common.arg_info;

	*is_temp = 0;

	if (closure->debug_info == NULL) {
		ALLOC_HASHTABLE(closure->debug_info);
		zend_hash_init(closure->debug_info, 8, NULL, ZVAL_PTR_DTOR, 0);
	}
	if (closure->debug_info->u.v.nApplyCount == 0) {
		if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
			HashTable *static_variables = closure->func.op_array.static_variables;
			ZVAL_ARR(&val, zend_array_dup(static_variables));
			zend_hash_str_update(closure->debug_info, "static", sizeof("static")-1, &val);
		}

		if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
			Z_ADDREF(closure->this_ptr);
			zend_hash_str_update(closure->debug_info, "this", sizeof("this")-1, &closure->this_ptr);
		}

		if (arg_info &&
		    (closure->func.common.num_args ||
		     (closure->func.common.fn_flags & ZEND_ACC_VARIADIC))) {
			uint32_t i, num_args, required = closure->func.common.required_num_args;

			array_init(&val);

			num_args = closure->func.common.num_args;
			if (closure->func.common.fn_flags & ZEND_ACC_VARIADIC) {
				num_args++;
			}
			for (i = 0; i < num_args; i++) {
				zend_string *name;
				zval info;
				if (arg_info->name) {
					name = zend_strpprintf(0, "%s$%s",
							arg_info->pass_by_reference ? "&" : "",
							arg_info->name->val);
				} else {
					name = zend_strpprintf(0, "%s$param%d",
							arg_info->pass_by_reference ? "&" : "",
							i + 1);
				}
				ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
				zend_hash_update(Z_ARRVAL(val), name, &info);
				zend_string_release(name);
				arg_info++;
			}
			zend_hash_str_update(closure->debug_info, "parameter", sizeof("parameter")-1, &val);
		}
	}

	return closure->debug_info;
}
Esempio n. 3
0
static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
{
	zval globals;

	ZVAL_ARR(&globals, &EG(symbol_table));
	ZVAL_NEW_REF(&globals, &globals);
	zend_hash_update(&EG(symbol_table).ht, name, &globals);
	return 0;
}
Esempio n. 4
0
static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
{
	zval globals;

	ZVAL_ARR(&globals, &EG(symbol_table));
	Z_TYPE_INFO_P(&globals) = IS_ARRAY | (IS_TYPE_SYMBOLTABLE << Z_TYPE_FLAGS_SHIFT);
	ZVAL_NEW_REF(&globals, &globals);
	zend_hash_update(&EG(symbol_table), name, &globals);
	return 0;
}
Esempio n. 5
0
ZEND_API void ZEND_FASTCALL zval_copy_ctor_func(zval *zvalue)
{
	if (EXPECTED(Z_TYPE_P(zvalue) == IS_ARRAY)) {
		ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue)));
	} else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) {
		ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zvalue)));
		CHECK_ZVAL_STRING(Z_STR_P(zvalue));
		ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0));
	}
}
Esempio n. 6
0
static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
{
	zval globals;

	/* IS_ARRAY, but with ref-counter 1 and not IS_TYPE_REFCOUNTED */
	ZVAL_ARR(&globals, &EG(symbol_table));
	Z_TYPE_FLAGS_P(&globals) = 0;
	ZVAL_NEW_REF(&globals, &globals);
	zend_hash_update(&EG(symbol_table), name, &globals);
	return 0;
}
Esempio n. 7
0
static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
{
	char *cmd;
	size_t cmd_len;
	zval *ret_code=NULL, *ret_array=NULL;
	int ret;

	ZEND_PARSE_PARAMETERS_START(1, (mode ? 2 : 3))
		Z_PARAM_STRING(cmd, cmd_len)
		Z_PARAM_OPTIONAL
		if (!mode) {
			Z_PARAM_ZVAL_DEREF(ret_array)
		}
		Z_PARAM_ZVAL_DEREF(ret_code)
	ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

	if (!cmd_len) {
		php_error_docref(NULL, E_WARNING, "Cannot execute a blank command");
		RETURN_FALSE;
	}
	if (strlen(cmd) != cmd_len) {
		php_error_docref(NULL, E_WARNING, "NULL byte detected. Possible attack");
		RETURN_FALSE;
	}

	if (!ret_array) {
		ret = php_exec(mode, cmd, NULL, return_value);
	} else {
		if (Z_TYPE_P(ret_array) != IS_ARRAY) {
			zval_ptr_dtor(ret_array);
			array_init(ret_array);
		} else if (Z_REFCOUNT_P(ret_array) > 1) {
			zval_ptr_dtor(ret_array);
			ZVAL_ARR(ret_array, zend_array_dup(Z_ARR_P(ret_array)));
		}
		ret = php_exec(2, cmd, ret_array, return_value);
	}
	if (ret_code) {
		zval_ptr_dtor(ret_code);
		ZVAL_LONG(ret_code, ret);
	}
}
Esempio n. 8
0
static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{ */
{
	zend_closure *closure = (zend_closure *)Z_OBJ_P(object);
	zval val;
	struct _zend_arg_info *arg_info = closure->func.common.arg_info;
	HashTable *debug_info;
	zend_bool zstr_args = (closure->func.type == ZEND_USER_FUNCTION) || (closure->func.common.fn_flags & ZEND_ACC_USER_ARG_INFO);

	*is_temp = 1;

	debug_info = zend_new_array(8);

	if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
		HashTable *static_variables = closure->func.op_array.static_variables;
		ZVAL_ARR(&val, zend_array_dup(static_variables));
		zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_STATIC), &val);
	}

	if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
		Z_ADDREF(closure->this_ptr);
		zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_THIS), &closure->this_ptr);
	}

	if (arg_info &&
		(closure->func.common.num_args ||
		 (closure->func.common.fn_flags & ZEND_ACC_VARIADIC))) {
		uint32_t i, num_args, required = closure->func.common.required_num_args;

		array_init(&val);

		num_args = closure->func.common.num_args;
		if (closure->func.common.fn_flags & ZEND_ACC_VARIADIC) {
			num_args++;
		}
		for (i = 0; i < num_args; i++) {
			zend_string *name;
			zval info;
			if (arg_info->name) {
				if (zstr_args) {
					name = zend_strpprintf(0, "%s$%s",
							arg_info->pass_by_reference ? "&" : "",
							ZSTR_VAL(arg_info->name));
				} else {
					name = zend_strpprintf(0, "%s$%s",
							arg_info->pass_by_reference ? "&" : "",
							((zend_internal_arg_info*)arg_info)->name);
				}
			} else {
				name = zend_strpprintf(0, "%s$param%d",
						arg_info->pass_by_reference ? "&" : "",
						i + 1);
			}
			ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
			zend_hash_update(Z_ARRVAL(val), name, &info);
			zend_string_release_ex(name, 0);
			arg_info++;
		}
		zend_hash_str_update(debug_info, "parameter", sizeof("parameter")-1, &val);
	}

	return debug_info;
}
Esempio n. 9
0
int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
{
	zend_func_info *func_info = ZEND_FUNC_INFO(op_array);
	int removed_ops = 0;

	if (func_info->callee_info) {
		zend_call_info *call_info = func_info->callee_info;

		do {
			if (call_info->caller_call_opline->opcode == ZEND_DO_ICALL
			 && call_info->callee_func
			 && ZSTR_LEN(call_info->callee_func->common.function_name) == sizeof("in_array")-1
			 && memcmp(ZSTR_VAL(call_info->callee_func->common.function_name), "in_array", sizeof("in_array")-1) == 0
			 && (call_info->caller_init_opline->extended_value == 2
			  || (call_info->caller_init_opline->extended_value == 3
			   && (call_info->caller_call_opline - 1)->opcode == ZEND_SEND_VAL
			   && (call_info->caller_call_opline - 1)->op1_type == IS_CONST))) {

				zend_op *send_array;
				zend_op *send_needly;
				zend_bool strict = 0;

				if (call_info->caller_init_opline->extended_value == 2) {
					send_array = call_info->caller_call_opline - 1;
					send_needly = call_info->caller_call_opline - 2;
				} else {
					if (zend_is_true(CT_CONSTANT_EX(op_array, (call_info->caller_call_opline - 1)->op1.constant))) {
						strict = 1;
					}
					send_array = call_info->caller_call_opline - 2;
					send_needly = call_info->caller_call_opline - 3;
				}

				if (send_array->opcode == ZEND_SEND_VAL
				 && send_array->op1_type == IS_CONST
				 && Z_TYPE_P(CT_CONSTANT_EX(op_array, send_array->op1.constant)) == IS_ARRAY
				 && (send_needly->opcode == ZEND_SEND_VAL
				  || send_needly->opcode == ZEND_SEND_VAR)
			    ) {
					int ok = 1;

					HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, send_array->op1.constant));
					HashTable *dst;
					zval *val, tmp;
					zend_ulong idx;

					ZVAL_TRUE(&tmp);
					dst = zend_new_array(zend_hash_num_elements(src));
					if (strict) {
						ZEND_HASH_FOREACH_VAL(src, val) {
							if (Z_TYPE_P(val) == IS_STRING) {
								zend_hash_add(dst, Z_STR_P(val), &tmp);
							} else if (Z_TYPE_P(val) == IS_LONG) {
								zend_hash_index_add(dst, Z_LVAL_P(val), &tmp);
							} else {
								zend_array_destroy(dst);
								ok = 0;
								break;
							}
						} ZEND_HASH_FOREACH_END();
					} else {
						ZEND_HASH_FOREACH_VAL(src, val) {
							if (Z_TYPE_P(val) != IS_STRING || ZEND_HANDLE_NUMERIC(Z_STR_P(val), idx)) {
								zend_array_destroy(dst);
								ok = 0;
								break;
							}
							zend_hash_add(dst, Z_STR_P(val), &tmp);
						} ZEND_HASH_FOREACH_END();
					}

					if (ok) {
						uint32_t op_num = send_needly - op_array->opcodes;
						zend_ssa_op *ssa_op = ssa->ops + op_num;

						if (ssa_op->op1_use >= 0) {
							/* Reconstruct SSA */
							int var_num = ssa_op->op1_use;
							zend_ssa_var *var = ssa->vars + var_num;

							ZEND_ASSERT(ssa_op->op1_def < 0);
							zend_ssa_unlink_use_chain(ssa, op_num, ssa_op->op1_use);
							ssa_op->op1_use = -1;
							ssa_op->op1_use_chain = -1;
							op_num = call_info->caller_call_opline - op_array->opcodes;
							ssa_op = ssa->ops + op_num;
							ssa_op->op1_use = var_num;
							ssa_op->op1_use_chain = var->use_chain;
							var->use_chain = op_num;
						}

						ZVAL_ARR(&tmp, dst);

						/* Update opcode */
						call_info->caller_call_opline->opcode = ZEND_IN_ARRAY;
						call_info->caller_call_opline->extended_value = strict;
						call_info->caller_call_opline->op1_type = send_needly->op1_type;
						call_info->caller_call_opline->op1.num = send_needly->op1.num;
						call_info->caller_call_opline->op2_type = IS_CONST;
						call_info->caller_call_opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp);
						if (call_info->caller_init_opline->extended_value == 3) {
							MAKE_NOP(call_info->caller_call_opline - 1);
						}
						MAKE_NOP(call_info->caller_init_opline);
						MAKE_NOP(send_needly);
						MAKE_NOP(send_array);
						removed_ops++;

					}
				}