コード例 #1
0
void test_phalcon_init_var(void)
{
	startup_php(__func__);
	zend_first_try {
		zval* x;
		zval* y;

		PHALCON_MM_GROW();
			PHALCON_INIT_VAR(x);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);
			CU_ASSERT_EQUAL(Z_TYPE_P(x), IS_NULL);

			PHALCON_INIT_VAR(y);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(y), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(y), 0);
			CU_ASSERT_EQUAL(Z_TYPE_P(y), IS_NULL);
			Z_ADDREF_P(y);
		PHALCON_MM_RESTORE();

		/* y has two references => should not be freed */
		CU_ASSERT_EQUAL(_mem_block_check(y, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
		CU_ASSERT_EQUAL(Z_REFCOUNT_P(y), 1);
		zval_ptr_dtor(&y);
	}
	zend_catch {
		CU_ASSERT(0);
	}
	zend_end_try();

	shutdown_php();
	CU_ASSERT_EQUAL(leaks, 0);
}
コード例 #2
0
void test_phalcon_init_nvar(void)
{
	startup_php(__func__);
	zend_first_try {
		zval* x = NULL;

		PHALCON_MM_GROW();
			PHALCON_INIT_NVAR(x);

			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);
			CU_ASSERT_EQUAL(Z_TYPE_P(x), IS_NULL);

			ZVAL_LONG(x, 0x12345678ul);

			PHALCON_INIT_NVAR(x);

			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);
			CU_ASSERT_EQUAL(Z_TYPE_P(x), IS_NULL);
		PHALCON_MM_RESTORE();
	}
	zend_catch {
		CU_ASSERT(0);
	}
	zend_end_try();

	shutdown_php();
	CU_ASSERT_EQUAL(leaks, 0);
}
コード例 #3
0
void test_phalcon_obs_nvar(void)
{
	startup_php(__func__);
	zend_first_try {
		zval* x = NULL;

		PHALCON_MM_GROW();
			PHALCON_OBS_NVAR(x);
			ALLOC_INIT_ZVAL(x);

			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);

			PHALCON_OBS_NVAR(x);
			ALLOC_INIT_ZVAL(x);

			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);
		PHALCON_MM_RESTORE();
	}
	zend_catch {
		CU_ASSERT(0);
	}
	zend_end_try();

	shutdown_php();
	CU_ASSERT_EQUAL(leaks, 0);
}
コード例 #4
0
void test_phalcon_separate_param(void)
{
	startup_php(__func__);
	zend_first_try {
		zval* x;
		zval* orig;

		PHALCON_MM_GROW();
			MAKE_STD_ZVAL(x);
			ZVAL_LONG(x, 0xB61964F6l);
			Z_ADDREF_P(x);
			Z_ADDREF_P(x);
			Z_ADDREF_P(x);
			orig = x;

			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 4);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);

			PHALCON_SEPARATE_PARAM(x);

			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);
			CU_ASSERT_PTR_NOT_EQUAL(x, orig);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(orig), 4);
			CU_ASSERT_EQUAL(Z_ISREF_P(orig), 0);

			CU_ASSERT_EQUAL(Z_TYPE_P(x), IS_LONG);
			CU_ASSERT_EQUAL(Z_LVAL_P(x), 0xB61964F6l);

			CU_ASSERT_EQUAL(Z_TYPE_P(x), Z_TYPE_P(orig));
			CU_ASSERT_EQUAL(Z_LVAL_P(x), Z_LVAL_P(orig));

			zval_ptr_dtor(&orig);
			CU_ASSERT_EQUAL(_mem_block_check(x, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
			CU_ASSERT_EQUAL(_mem_block_check(orig, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(orig), 3);

			zval_ptr_dtor(&orig);
			CU_ASSERT_EQUAL(_mem_block_check(x, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
			CU_ASSERT_EQUAL(_mem_block_check(orig, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(orig), 2);

			zval_ptr_dtor(&orig);
			CU_ASSERT_EQUAL(_mem_block_check(x, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
			CU_ASSERT_EQUAL(_mem_block_check(orig, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(orig), 1);

			zval_ptr_dtor(&orig);
			CU_ASSERT_EQUAL(_mem_block_check(x, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
		PHALCON_MM_RESTORE();
	}
	zend_catch {
		CU_ASSERT(0);
	}
	zend_end_try();

	shutdown_php();
	CU_ASSERT_EQUAL(leaks, 0);
}
コード例 #5
0
void test_phalcon_cpy_wrt_ctor(void)
{
	startup_php(__func__);
	zend_first_try {
		zval* dest;
		zval* src;

		PHALCON_MM_GROW();
		/* dest is not observed by Phalcon */
			MAKE_STD_ZVAL(dest);
			ZVAL_STRING(dest, "R^itaM cha svAdhyAyapravachane cha", 1);

			PHALCON_INIT_VAR(src);
			ZVAL_STRING(src, "satyaM cha svAdhyAyapravachane cha", 1);

			PHALCON_CPY_WRT_CTOR(dest, src);

			CU_ASSERT_PTR_NOT_EQUAL(dest, src);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(src), 1);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(dest), 1);
			CU_ASSERT_EQUAL(Z_TYPE_P(src), IS_STRING);
			CU_ASSERT_EQUAL(Z_ISREF_P(src), 0);
			CU_ASSERT_EQUAL(Z_ISREF_P(dest), 0);
		PHALCON_MM_RESTORE();

		CU_ASSERT_EQUAL(_mem_block_check(dest, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
		CU_ASSERT_PTR_NOT_EQUAL(dest, src);
		CU_ASSERT_EQUAL(Z_REFCOUNT_P(dest), 1);
		CU_ASSERT_STRING_EQUAL(Z_STRVAL_P(dest), "satyaM cha svAdhyAyapravachane cha");
		zval_ptr_dtor(&dest);

		PHALCON_MM_GROW();
		/* dest will be observed by Phalcon */
			dest = NULL;

			PHALCON_INIT_VAR(src);
			ZVAL_STRING(src, "satyaM cha svAdhyAyapravachane cha", 1);

			PHALCON_CPY_WRT_CTOR(dest, src);

			CU_ASSERT_PTR_NOT_EQUAL(dest, src);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(src), 1);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(dest), 1);
			CU_ASSERT_EQUAL(Z_TYPE_P(src), IS_STRING);
			CU_ASSERT_EQUAL(Z_ISREF_P(src), 0);
			CU_ASSERT_EQUAL(Z_ISREF_P(dest), 0);
		PHALCON_MM_RESTORE();
		/* At this point dest will be destroyed */

	}
	zend_catch {
		CU_ASSERT(0);
	}
	zend_end_try();

	shutdown_php();
	CU_ASSERT_EQUAL(leaks, 0);
}
コード例 #6
0
ZEND_METHOD(Closure, __invoke) /* {{{ */
{
	zend_function *func = EG(current_execute_data)->function_state.function;
	zval ***arguments;
	zval *closure_result_ptr = NULL;

	arguments = emalloc(sizeof(zval**) * ZEND_NUM_ARGS());
	if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
		efree(arguments);
		zend_error(E_RECOVERABLE_ERROR, "Cannot get arguments for calling closure");
		RETVAL_FALSE;
	} else if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
		RETVAL_FALSE;
	} else if (closure_result_ptr) {
		if (Z_ISREF_P(closure_result_ptr) && return_value_ptr) {
			if (return_value) {
				zval_ptr_dtor(&return_value);
			}
			*return_value_ptr = closure_result_ptr;
		} else {
			RETVAL_ZVAL(closure_result_ptr, 1, 1);
		}
	}
	efree(arguments);

	/* destruct the function also, then - we have allocated it in get_method */
	efree(func->internal_function.function_name);
	efree(func);
}
コード例 #7
0
ファイル: object.c プロジェクト: phalcon/zephir
static int zephir_update_static_property_ex(zend_class_entry *scope, const char *name, int name_length, zval *value, zend_property_info **property_info)
{
	zval garbage;
	zval *property;
	zend_class_entry *old_scope;

#if PHP_VERSION_ID >= 70100
	old_scope = EG(fake_scope);
	EG(fake_scope) = scope;
#else
	old_scope = EG(scope);
	EG(scope) = scope;
#endif
	property = zephir_std_get_static_property(scope, name, name_length, 0, property_info);
#if PHP_VERSION_ID >= 70100
	EG(fake_scope) = old_scope;
#else
	EG(scope) = old_scope;
#endif

	if (!property) {
		return FAILURE;
	} else {
		ZVAL_COPY_VALUE(&garbage, property);
		if (Z_ISREF_P(value)) {
			SEPARATE_ZVAL(value);
		}
		ZVAL_COPY(property, value);
		zval_ptr_dtor(&garbage);
		return SUCCESS;
	}
}
コード例 #8
0
void test_phalcon_alloc_zval(void)
{
	startup_php(__func__);
	zend_first_try {
		zval* x;

		PHALCON_MM_GROW();
			PHALCON_ALLOC_ZVAL(x);

			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);
			CU_ASSERT_EQUAL(Z_TYPE_P(x), IS_NULL);
		PHALCON_MM_RESTORE();

		/* zvals allocated by PHALCON_ALLOC_ZVAL() should not be affected by PHALCON_MM_RESTORE() */
		CU_ASSERT_EQUAL(_mem_block_check(x, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
		CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);

		zval_ptr_dtor(&x);
	}
	zend_catch {
		CU_ASSERT(0);
	}
	zend_end_try();

	shutdown_php();
	CU_ASSERT_EQUAL(leaks, 0);
}
コード例 #9
0
void test_phalcon_init_nvar_pnull(void)
{
	startup_php(__func__);
	zend_first_try {
		zval* x   = NULL;
		char* str = NULL;

		PHALCON_MM_GROW();
			PHALCON_INIT_NVAR(x);

			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);
			CU_ASSERT_EQUAL(Z_TYPE_P(x), IS_NULL);

			str = (char*)estrdup("satyaM vada dharmaM chara svAdhyAyAnmA pramadaH");
			ZVAL_STRING(x, str, 0);

			PHALCON_INIT_NVAR_PNULL(x);
			CU_ASSERT_EQUAL(_mem_block_check(str, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
			CU_ASSERT_EQUAL(Z_REFCOUNT_P(x), 1);
			CU_ASSERT_EQUAL(Z_ISREF_P(x), 0);
			CU_ASSERT_EQUAL(Z_TYPE_P(x), IS_NULL);
		PHALCON_MM_RESTORE();

		CU_ASSERT_EQUAL(_mem_block_check(str, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
		efree(str);

		x   = NULL;
		str = NULL;

		PHALCON_MM_GROW();
			PHALCON_INIT_NVAR_PNULL(x);
			str = (char*)estrdup("satyaM vada dharmaM chara svAdhyAyAnmA pramadaH");
			ZVAL_STRING(x, str, 0);
		PHALCON_MM_RESTORE();

		CU_ASSERT_EQUAL(_mem_block_check(str, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC), 1);
		efree(str);
	}
	zend_catch {
		CU_ASSERT(0);
	}
	zend_end_try();

	shutdown_php();
	CU_ASSERT_EQUAL(leaks, 0);
}
コード例 #10
0
ファイル: zend_variables.c プロジェクト: Irker/php-src
/* This function should only be used as a copy constructor, i.e. it
 * should only be called AFTER a zval has been copied to another
 * location using ZVAL_COPY_VALUE. Do not call it before copying,
 * otherwise a reference may be leaked. */
ZEND_API void zval_add_ref(zval *p)
{
	if (Z_REFCOUNTED_P(p)) {
		if (Z_ISREF_P(p) && Z_REFCOUNT_P(p) == 1) {
			ZVAL_COPY(p, Z_REFVAL_P(p));
		} else {
			Z_ADDREF_P(p);
		}
	}
}
コード例 #11
0
ファイル: apc_cache.c プロジェクト: Cum6upck/apcu
static zend_always_inline int apc_array_dup_element(apc_context_t *ctxt, HashTable *source, HashTable *target, uint32_t idx, Bucket *p, Bucket *q, int packed, int static_keys, int with_holes)
{
	zval *data = &p->val;

	if (with_holes) {
		if (!packed && Z_TYPE_INFO_P(data) == IS_INDIRECT) {
			data = Z_INDIRECT_P(data);
		}
		if (UNEXPECTED(Z_TYPE_INFO_P(data) == IS_UNDEF)) {
			return 0;
		}
	} else if (!packed) {
		/* INDIRECT element may point to UNDEF-ined slots */
		if (Z_TYPE_INFO_P(data) == IS_INDIRECT) {
			data = Z_INDIRECT_P(data);
			if (UNEXPECTED(Z_TYPE_INFO_P(data) == IS_UNDEF)) {
				return 0;
			}
		}
	}

	do {
		if (Z_OPT_REFCOUNTED_P(data)) {
			if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1 &&
				(Z_TYPE_P(Z_REFVAL_P(data)) != IS_ARRAY ||
				  Z_ARRVAL_P(Z_REFVAL_P(data)) != source)) {
				data = Z_REFVAL_P(data);
				if (!Z_OPT_REFCOUNTED_P(data)) {
					break;
				}
			}
		}
	} while (0);

	my_copy_zval(&q->val, data, ctxt);

	q->h = p->h;
	if (packed) {
		q->key = NULL;
	} else {
		uint32_t nIndex;

		q->key = p->key;
		if (!static_keys && q->key) {
			if (ctxt->copy == APC_COPY_IN) {
				q->key = apc_pstrcpy(q->key, ctxt->pool);
			} else q->key = p->key;
		}

		nIndex = q->h | target->nTableMask;
		Z_NEXT(q->val) = HT_HASH(target, nIndex);
		HT_HASH(target, nIndex) = HT_IDX_TO_HASH(idx);
	}
	return 1;
}
コード例 #12
0
static int coro_exit_handler(zend_execute_data *execute_data)
{
    zval ex;
    zend_object *obj;
    zend_long flags = 0;
    if (sw_get_current_cid() != -1)
    {
        flags |= SW_EXIT_IN_COROUTINE;
    }
    if (SwooleG.serv && SwooleG.serv->gs->start)
    {
        flags |= SW_EXIT_IN_SERVER;
    }
    if (flags)
    {
        const zend_op *opline = EX(opline);
        zval _exit_status;
        zval *exit_status = NULL;

        if (opline->op1_type != IS_UNUSED)
        {
            if (opline->op1_type == IS_CONST)
            {
                // see: https://github.com/php/php-src/commit/e70618aff6f447a298605d07648f2ce9e5a284f5
#ifdef EX_CONSTANT
                exit_status = EX_CONSTANT(opline->op1);
#else
                exit_status = RT_CONSTANT(opline, opline->op1);
#endif
            }
            else
            {
                exit_status = EX_VAR(opline->op1.var);
            }
            if (Z_ISREF_P(exit_status))
            {
                exit_status = Z_REFVAL_P(exit_status);
            }
        }
        else
        {
            exit_status = &_exit_status;
            ZVAL_NULL(exit_status);
        }
        obj = zend_throw_error_exception(swoole_exit_exception_class_entry_ptr, "swoole exit.", 0, E_ERROR TSRMLS_CC);
        ZVAL_OBJ(&ex, obj);
        zend_update_property_long(swoole_exit_exception_class_entry_ptr, &ex, ZEND_STRL("flags"), flags);
        Z_TRY_ADDREF_P(exit_status);
        zend_update_property(swoole_exit_exception_class_entry_ptr, &ex, ZEND_STRL("status"), exit_status);
    }

    return ZEND_USER_OPCODE_DISPATCH;
}
コード例 #13
0
ファイル: zend_execute.c プロジェクト: ARYANJASHWAL/php7
static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free, int unref TSRMLS_DC)
{
	if (!Z_DELREF_P(z)) {
		Z_SET_REFCOUNT_P(z, 1);
		Z_UNSET_ISREF_P(z);
		should_free->var = z;
/*		should_free->is_var = 1; */
	} else {
		should_free->var = 0;
		if (unref && Z_ISREF_P(z) && Z_REFCOUNT_P(z) == 1) {
			Z_UNSET_ISREF_P(z);
		}
		GC_ZVAL_CHECK_POSSIBLE_ROOT(z);
	}
}
コード例 #14
0
ファイル: methods.c プロジェクト: TheSin-/phc
/* Dont pass-by-ref */
static zval *
fetch_var_arg (zval * arg, int *is_arg_new)
{
  if (Z_ISREF_P(arg))
    {
      // We dont separate since we don't own one of ARG's references.
      arg = zvp_clone_ex (arg);
      *is_arg_new = 1;

      // It seems we get incorrect refcounts without this.
      // TODO This decreases the refcount to zero, which seems wrong,
      // but gives the right answer. We should look at how zend does
      // this.

      Z_DELREF_P(arg);
    }
  return arg;
}
コード例 #15
0
ファイル: string.c プロジェクト: wuthering-bytes/vroom
/*===========================================================================================================

    NAME
	string_append - Fast string concatenation.
	
    PROTOTYPE
	string_append ( &$value, ... ) ;
	
    DESCRIPTION
	Appends series of values to the specified string.
	
    PARAMETERS
	$value (string) -
		String where to append values.
		
	$... (mixed) -
		Any argument that can be converted to a string and appended to $value.
	
    NOTE 
	This code is theorically faster than the inline string-catenation operator, except that calling a
	PHP_FUNCTION() has a cost.
	When catenating 100 000 times a set of value takes 170ms using the catenation operator, it takes 615ms
	for string_append(), 535 of them being consumed just by calling the PHP_FUNCTION().
	
 *===========================================================================================================*/
THRAK_API zend_bool 	internal_string_append ( zval *  z_string, int  argc, zval **  argv, char **  result, int *  result_length )
    {
	char *		data,
	     *		p ;
	int  		size 		=  Z_STRLEN_P ( z_string ) ;
	int  		i ;
	
	// Compute the size needed to hold all the appended strings
	for (  i = 0 ; i  <  argc ; i ++ )
	   {
		if  ( Z_ISREF_P ( argv [i] ) )
			SEPARATE_ZVAL ( & argv [i] ) ;
			
		convert_to_string ( argv [i] ) ;
		size 	+=  Z_STRLEN_P ( argv [i] ) ;
	    }
	    
	// Allocate enough memory for it (just reallocate existing data, this will avoid to copy the appended variable
	// initial value)
	data = p = erealloc ( Z_STRVAL_P ( z_string ), size + 1 ) ;
	
	if  ( data  ==  NULL )
		return ( 0 ) ;
		
	// Point at the end of initial value
	p += Z_STRLEN_P ( z_string ) ;
	
	for  ( i = 0 ; i  <  argc ; i ++, argv ++ )
	   {
		memcpy ( p, Z_STRVAL_PP ( argv ), Z_STRLEN_PP ( argv ) ) ;
		p += Z_STRLEN_PP ( argv ) ;
	    }
	 
	/* Useless but makes me happy */
	* p = 0 ;
	
	// Give the resulting string to the caller
	* result 		=  data ;
	* result_length 	=  size ;
	
	return ( 1 ) ;
     }
コード例 #16
0
int uopz_no_exit_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
	if (UOPZ(exit)) {
		if (uopz_exit_handler)
			return uopz_exit_handler(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU);

		return ZEND_USER_OPCODE_DISPATCH;
	}

	if (EX(opline)->op1_type != IS_UNUSED) {
		zval *estatus;

		if (EX(opline)->op1_type == IS_CONST) {
			estatus = EX_CONSTANT(EX(opline)->op1);
		} else estatus = EX_VAR(EX(opline)->op1.var);

		if (Z_ISREF_P(estatus)) {
			estatus = Z_REFVAL_P(estatus);
		}

		if (Z_TYPE_P(estatus) == IS_LONG) {
			EG(exit_status) = Z_LVAL_P(estatus);
		} else EG(exit_status) = 0;

		ZVAL_COPY(&UOPZ(estatus), estatus);
	}

	if (EX(opline) < &EX(func)->op_array.opcodes[EX(func)->op_array.last - 1]) {
		EX(opline)++;

		while (EX(opline)->opcode == ZEND_EXT_STMT) {
			EX(opline)++;
		}

		return ZEND_USER_OPCODE_CONTINUE;
	} else {
		return ZEND_USER_OPCODE_RETURN;
	}
} /* }}} */
コード例 #17
0
PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER)
{
	const unsigned char *cursor, *limit, *marker, *start;
	zval *rval_ref;

	limit = max;
	cursor = *p;

	if (YYCURSOR >= YYLIMIT) {
		return 0;
	}

	if (var_hash && (*p)[0] != 'R') {
		var_push(var_hash, rval);
	}

	start = cursor;


#line 518 "ext/standard/var_unserializer.c"
{
	YYCTYPE yych;
	static const unsigned char yybm[] = {
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
	};

	if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
	yych = *YYCURSOR;
	switch (yych) {
	case 'C':
	case 'O':	goto yy13;
	case 'N':	goto yy5;
	case 'R':	goto yy2;
	case 'S':	goto yy10;
	case 'a':	goto yy11;
	case 'b':	goto yy6;
	case 'd':	goto yy8;
	case 'i':	goto yy7;
	case 'o':	goto yy12;
	case 'r':	goto yy4;
	case 's':	goto yy9;
	case '}':	goto yy14;
	default:	goto yy16;
	}
yy2:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy95;
yy3:
#line 873 "ext/standard/var_unserializer.re"
	{ return 0; }
#line 580 "ext/standard/var_unserializer.c"
yy4:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy89;
	goto yy3;
yy5:
	yych = *++YYCURSOR;
	if (yych == ';') goto yy87;
	goto yy3;
yy6:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy83;
	goto yy3;
yy7:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy77;
	goto yy3;
yy8:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy53;
	goto yy3;
yy9:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy46;
	goto yy3;
yy10:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy39;
	goto yy3;
yy11:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy32;
	goto yy3;
yy12:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy25;
	goto yy3;
yy13:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy17;
	goto yy3;
yy14:
	++YYCURSOR;
#line 867 "ext/standard/var_unserializer.re"
	{
	/* this is the case where we have less data than planned */
	php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");
	return 0; /* not sure if it should be 0 or 1 here? */
}
#line 629 "ext/standard/var_unserializer.c"
yy16:
	yych = *++YYCURSOR;
	goto yy3;
yy17:
	yych = *++YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy20;
	}
	if (yych == '+') goto yy19;
yy18:
	YYCURSOR = YYMARKER;
	goto yy3;
yy19:
	yych = *++YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy20;
	}
	goto yy18;
yy20:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy20;
	}
	if (yych <= '/') goto yy18;
	if (yych >= ';') goto yy18;
	yych = *++YYCURSOR;
	if (yych != '"') goto yy18;
	++YYCURSOR;
#line 722 "ext/standard/var_unserializer.re"
	{
	size_t len, len2, len3, maxlen;
	zend_long elements;
	char *str;
	zend_string *class_name;
	zend_class_entry *ce;
	int incomplete_class = 0;

	int custom_object = 0;

	zval user_func;
	zval retval;
	zval args[1];

    if (!var_hash) return 0;
	if (*start == 'C') {
		custom_object = 1;
	}

	len2 = len = parse_uiv(start + 2);
	maxlen = max - YYCURSOR;
	if (maxlen < len || len == 0) {
		*p = start + 2;
		return 0;
	}

	str = (char*)YYCURSOR;

	YYCURSOR += len;

	if (*(YYCURSOR) != '"') {
		*p = YYCURSOR;
		return 0;
	}
	if (*(YYCURSOR+1) != ':') {
		*p = YYCURSOR+1;
		return 0;
	}

	len3 = strspn(str, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\");
	if (len3 != len)
	{
		*p = YYCURSOR + len3 - len;
		return 0;
	}

	class_name = zend_string_init(str, len, 0);

	do {
		if(!unserialize_allowed_class(class_name, classes)) {
			incomplete_class = 1;
			ce = PHP_IC_ENTRY;
			break;
		}

		/* Try to find class directly */
		BG(serialize_lock)++;
		ce = zend_lookup_class(class_name);
		if (ce) {
			BG(serialize_lock)--;
			if (EG(exception)) {
				zend_string_release(class_name);
				return 0;
			}
			break;
		}
		BG(serialize_lock)--;

		if (EG(exception)) {
			zend_string_release(class_name);
			return 0;
		}

		/* Check for unserialize callback */
		if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
			incomplete_class = 1;
			ce = PHP_IC_ENTRY;
			break;
		}

		/* Call unserialize callback */
		ZVAL_STRING(&user_func, PG(unserialize_callback_func));

		ZVAL_STR_COPY(&args[0], class_name);
		BG(serialize_lock)++;
		if (call_user_function_ex(CG(function_table), NULL, &user_func, &retval, 1, args, 0, NULL) != SUCCESS) {
			BG(serialize_lock)--;
			if (EG(exception)) {
				zend_string_release(class_name);
				zval_ptr_dtor(&user_func);
				zval_ptr_dtor(&args[0]);
				return 0;
			}
			php_error_docref(NULL, E_WARNING, "defined (%s) but not found", Z_STRVAL(user_func));
			incomplete_class = 1;
			ce = PHP_IC_ENTRY;
			zval_ptr_dtor(&user_func);
			zval_ptr_dtor(&args[0]);
			break;
		}
		BG(serialize_lock)--;
		zval_ptr_dtor(&retval);
		if (EG(exception)) {
			zend_string_release(class_name);
			zval_ptr_dtor(&user_func);
			zval_ptr_dtor(&args[0]);
			return 0;
		}

		/* The callback function may have defined the class */
		if ((ce = zend_lookup_class(class_name)) == NULL) {
			php_error_docref(NULL, E_WARNING, "Function %s() hasn't defined the class it was called for", Z_STRVAL(user_func));
			incomplete_class = 1;
			ce = PHP_IC_ENTRY;
		}

		zval_ptr_dtor(&user_func);
		zval_ptr_dtor(&args[0]);
		break;
	} while (1);

	*p = YYCURSOR;

	if (custom_object) {
		int ret;

		ret = object_custom(UNSERIALIZE_PASSTHRU, ce);

		if (ret && incomplete_class) {
			php_store_class_name(rval, ZSTR_VAL(class_name), len2);
		}
		zend_string_release(class_name);
		return ret;
	}

	elements = object_common1(UNSERIALIZE_PASSTHRU, ce);

	if (incomplete_class) {
		php_store_class_name(rval, ZSTR_VAL(class_name), len2);
	}
	zend_string_release(class_name);

	return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
#line 805 "ext/standard/var_unserializer.c"
yy25:
	yych = *++YYCURSOR;
	if (yych <= ',') {
		if (yych != '+') goto yy18;
	} else {
		if (yych <= '-') goto yy26;
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy27;
		goto yy18;
	}
yy26:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy27:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy27;
	if (yych >= ';') goto yy18;
	yych = *++YYCURSOR;
	if (yych != '"') goto yy18;
	++YYCURSOR;
#line 715 "ext/standard/var_unserializer.re"
	{
    if (!var_hash) return 0;

	return object_common2(UNSERIALIZE_PASSTHRU,
			object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
}
#line 837 "ext/standard/var_unserializer.c"
yy32:
	yych = *++YYCURSOR;
	if (yych == '+') goto yy33;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy34;
	goto yy18;
yy33:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy34:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy34;
	if (yych >= ';') goto yy18;
	yych = *++YYCURSOR;
	if (yych != '{') goto yy18;
	++YYCURSOR;
#line 691 "ext/standard/var_unserializer.re"
	{
	zend_long elements = parse_iv(start + 2);
	/* use iv() not uiv() in order to check data range */
	*p = YYCURSOR;
    if (!var_hash) return 0;

	if (elements < 0) {
		return 0;
	}

	array_init_size(rval, elements);
//??? we can't convert from packed to hash during unserialization, because
//??? reference to some zvals might be keept in var_hash (to support references)
	if (elements) {
		zend_hash_real_init(Z_ARRVAL_P(rval), 0);
	}

	if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) {
		return 0;
	}

	return finish_nested_data(UNSERIALIZE_PASSTHRU);
}
#line 882 "ext/standard/var_unserializer.c"
yy39:
	yych = *++YYCURSOR;
	if (yych == '+') goto yy40;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy41;
	goto yy18;
yy40:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy41:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy41;
	if (yych >= ';') goto yy18;
	yych = *++YYCURSOR;
	if (yych != '"') goto yy18;
	++YYCURSOR;
#line 663 "ext/standard/var_unserializer.re"
	{
	size_t len, maxlen;
	zend_string *str;

	len = parse_uiv(start + 2);
	maxlen = max - YYCURSOR;
	if (maxlen < len) {
		*p = start + 2;
		return 0;
	}

	if ((str = unserialize_str(&YYCURSOR, len, maxlen)) == NULL) {
		return 0;
	}

	if (*(YYCURSOR) != '"') {
		zend_string_free(str);
		*p = YYCURSOR;
		return 0;
	}

	YYCURSOR += 2;
	*p = YYCURSOR;

	ZVAL_STR(rval, str);
	return 1;
}
#line 931 "ext/standard/var_unserializer.c"
yy46:
	yych = *++YYCURSOR;
	if (yych == '+') goto yy47;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy48;
	goto yy18;
yy47:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy48:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy48;
	if (yych >= ';') goto yy18;
	yych = *++YYCURSOR;
	if (yych != '"') goto yy18;
	++YYCURSOR;
#line 636 "ext/standard/var_unserializer.re"
	{
	size_t len, maxlen;
	char *str;

	len = parse_uiv(start + 2);
	maxlen = max - YYCURSOR;
	if (maxlen < len) {
		*p = start + 2;
		return 0;
	}

	str = (char*)YYCURSOR;

	YYCURSOR += len;

	if (*(YYCURSOR) != '"') {
		*p = YYCURSOR;
		return 0;
	}

	YYCURSOR += 2;
	*p = YYCURSOR;

	ZVAL_STRINGL(rval, str, len);
	return 1;
}
#line 979 "ext/standard/var_unserializer.c"
yy53:
	yych = *++YYCURSOR;
	if (yych <= '/') {
		if (yych <= ',') {
			if (yych == '+') goto yy57;
			goto yy18;
		} else {
			if (yych <= '-') goto yy55;
			if (yych <= '.') goto yy60;
			goto yy18;
		}
	} else {
		if (yych <= 'I') {
			if (yych <= '9') goto yy58;
			if (yych <= 'H') goto yy18;
			goto yy56;
		} else {
			if (yych != 'N') goto yy18;
		}
	}
	yych = *++YYCURSOR;
	if (yych == 'A') goto yy76;
	goto yy18;
yy55:
	yych = *++YYCURSOR;
	if (yych <= '/') {
		if (yych == '.') goto yy60;
		goto yy18;
	} else {
		if (yych <= '9') goto yy58;
		if (yych != 'I') goto yy18;
	}
yy56:
	yych = *++YYCURSOR;
	if (yych == 'N') goto yy72;
	goto yy18;
yy57:
	yych = *++YYCURSOR;
	if (yych == '.') goto yy60;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy58:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
	yych = *YYCURSOR;
	if (yych <= ':') {
		if (yych <= '.') {
			if (yych <= '-') goto yy18;
			goto yy70;
		} else {
			if (yych <= '/') goto yy18;
			if (yych <= '9') goto yy58;
			goto yy18;
		}
	} else {
		if (yych <= 'E') {
			if (yych <= ';') goto yy63;
			if (yych <= 'D') goto yy18;
			goto yy65;
		} else {
			if (yych == 'e') goto yy65;
			goto yy18;
		}
	}
yy60:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy61:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
	yych = *YYCURSOR;
	if (yych <= ';') {
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy61;
		if (yych <= ':') goto yy18;
	} else {
		if (yych <= 'E') {
			if (yych <= 'D') goto yy18;
			goto yy65;
		} else {
			if (yych == 'e') goto yy65;
			goto yy18;
		}
	}
yy63:
	++YYCURSOR;
#line 627 "ext/standard/var_unserializer.re"
	{
#if SIZEOF_ZEND_LONG == 4
use_double:
#endif
	*p = YYCURSOR;
	ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
	return 1;
}
#line 1076 "ext/standard/var_unserializer.c"
yy65:
	yych = *++YYCURSOR;
	if (yych <= ',') {
		if (yych != '+') goto yy18;
	} else {
		if (yych <= '-') goto yy66;
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy67;
		goto yy18;
	}
yy66:
	yych = *++YYCURSOR;
	if (yych <= ',') {
		if (yych == '+') goto yy69;
		goto yy18;
	} else {
		if (yych <= '-') goto yy69;
		if (yych <= '/') goto yy18;
		if (yych >= ':') goto yy18;
	}
yy67:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy67;
	if (yych == ';') goto yy63;
	goto yy18;
yy69:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy67;
	goto yy18;
yy70:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
	yych = *YYCURSOR;
	if (yych <= ';') {
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy70;
		if (yych <= ':') goto yy18;
		goto yy63;
	} else {
		if (yych <= 'E') {
			if (yych <= 'D') goto yy18;
			goto yy65;
		} else {
			if (yych == 'e') goto yy65;
			goto yy18;
		}
	}
yy72:
	yych = *++YYCURSOR;
	if (yych != 'F') goto yy18;
yy73:
	yych = *++YYCURSOR;
	if (yych != ';') goto yy18;
	++YYCURSOR;
#line 611 "ext/standard/var_unserializer.re"
	{
	*p = YYCURSOR;

	if (!strncmp((char*)start + 2, "NAN", 3)) {
		ZVAL_DOUBLE(rval, php_get_nan());
	} else if (!strncmp((char*)start + 2, "INF", 3)) {
		ZVAL_DOUBLE(rval, php_get_inf());
	} else if (!strncmp((char*)start + 2, "-INF", 4)) {
		ZVAL_DOUBLE(rval, -php_get_inf());
	} else {
		ZVAL_NULL(rval);
	}

	return 1;
}
#line 1151 "ext/standard/var_unserializer.c"
yy76:
	yych = *++YYCURSOR;
	if (yych == 'N') goto yy73;
	goto yy18;
yy77:
	yych = *++YYCURSOR;
	if (yych <= ',') {
		if (yych != '+') goto yy18;
	} else {
		if (yych <= '-') goto yy78;
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy79;
		goto yy18;
	}
yy78:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy79:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy79;
	if (yych != ';') goto yy18;
	++YYCURSOR;
#line 585 "ext/standard/var_unserializer.re"
	{
#if SIZEOF_ZEND_LONG == 4
	int digits = YYCURSOR - start - 3;

	if (start[2] == '-' || start[2] == '+') {
		digits--;
	}

	/* Use double for large zend_long values that were serialized on a 64-bit system */
	if (digits >= MAX_LENGTH_OF_LONG - 1) {
		if (digits == MAX_LENGTH_OF_LONG - 1) {
			int cmp = strncmp((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);

			if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
				goto use_double;
			}
		} else {
			goto use_double;
		}
	}
#endif
	*p = YYCURSOR;
	ZVAL_LONG(rval, parse_iv(start + 2));
	return 1;
}
#line 1204 "ext/standard/var_unserializer.c"
yy83:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= '2') goto yy18;
	yych = *++YYCURSOR;
	if (yych != ';') goto yy18;
	++YYCURSOR;
#line 579 "ext/standard/var_unserializer.re"
	{
	*p = YYCURSOR;
	ZVAL_BOOL(rval, parse_iv(start + 2));
	return 1;
}
#line 1218 "ext/standard/var_unserializer.c"
yy87:
	++YYCURSOR;
#line 573 "ext/standard/var_unserializer.re"
	{
	*p = YYCURSOR;
	ZVAL_NULL(rval);
	return 1;
}
#line 1227 "ext/standard/var_unserializer.c"
yy89:
	yych = *++YYCURSOR;
	if (yych <= ',') {
		if (yych != '+') goto yy18;
	} else {
		if (yych <= '-') goto yy90;
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy91;
		goto yy18;
	}
yy90:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy91:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy91;
	if (yych != ';') goto yy18;
	++YYCURSOR;
#line 548 "ext/standard/var_unserializer.re"
	{
	zend_long id;

 	*p = YYCURSOR;
	if (!var_hash) return 0;

	id = parse_iv(start + 2) - 1;
	if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
		return 0;
	}

	if (rval_ref == rval) {
		return 0;
	}

	if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
		ZVAL_UNDEF(rval);
		return 1;
	}

	ZVAL_COPY(rval, rval_ref);

	return 1;
}
#line 1275 "ext/standard/var_unserializer.c"
yy95:
	yych = *++YYCURSOR;
	if (yych <= ',') {
		if (yych != '+') goto yy18;
	} else {
		if (yych <= '-') goto yy96;
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy97;
		goto yy18;
	}
yy96:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy97:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy97;
	if (yych != ';') goto yy18;
	++YYCURSOR;
#line 522 "ext/standard/var_unserializer.re"
	{
	zend_long id;

 	*p = YYCURSOR;
	if (!var_hash) return 0;

	id = parse_iv(start + 2) - 1;
	if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
		return 0;
	}

	zval_ptr_dtor(rval);
	if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
		ZVAL_UNDEF(rval);
		return 1;
	}
	if (Z_ISREF_P(rval_ref)) {
		ZVAL_COPY(rval, rval_ref);
	} else {
		ZVAL_NEW_REF(rval_ref, rval_ref);
		ZVAL_COPY(rval, rval_ref);
	}

	return 1;
}
#line 1324 "ext/standard/var_unserializer.c"
}
#line 875 "ext/standard/var_unserializer.re"


	return 0;
}
コード例 #18
0
ファイル: zend_constants.c プロジェクト: 0xhacking/php-src
ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, zend_ulong flags)
{
	zend_constant *c;
	const char *colon;
	zend_class_entry *ce = NULL;
	zend_string *class_name;
	const char *name = cname->val;
	size_t name_len = cname->len;

	/* Skip leading \\ */
	if (name[0] == '\\') {
		name += 1;
		name_len -= 1;
		cname = NULL;
	}

	if ((colon = zend_memrchr(name, ':', name_len)) &&
	    colon > name && (*(colon - 1) == ':')) {
		int class_name_len = colon - name - 1;
		size_t const_name_len = name_len - class_name_len - 2;
		zend_string *constant_name = zend_string_init(colon + 1, const_name_len, 0);
		char *lcname;
		zval *ret_constant = NULL;
		ALLOCA_FLAG(use_heap)

		class_name = zend_string_init(name, class_name_len, 0);
		lcname = do_alloca(class_name_len + 1, use_heap);
		zend_str_tolower_copy(lcname, name, class_name_len);
		if (!scope) {
			if (EG(current_execute_data)) {
				scope = EG(scope);
			} else {
				scope = CG(active_class_entry);
			}
		}

		if (class_name_len == sizeof("self")-1 &&
		    !memcmp(lcname, "self", sizeof("self")-1)) {
			if (UNEXPECTED(!scope)) {
				zend_error(E_EXCEPTION | E_ERROR, "Cannot access self:: when no class scope is active");
				return NULL;
			}
			ce = scope;
		} else if (class_name_len == sizeof("parent")-1 &&
		           !memcmp(lcname, "parent", sizeof("parent")-1)) {
			if (UNEXPECTED(!scope)) {
				zend_error(E_EXCEPTION | E_ERROR, "Cannot access parent:: when no class scope is active");
				return NULL;
			} else if (UNEXPECTED(!scope->parent)) {
				zend_error(E_EXCEPTION | E_ERROR, "Cannot access parent:: when current class scope has no parent");
				return NULL;
			} else {
				ce = scope->parent;
			}
		} else if (class_name_len == sizeof("static")-1 &&
		           !memcmp(lcname, "static", sizeof("static")-1)) {
			ce = zend_get_called_scope(EG(current_execute_data));
			if (UNEXPECTED(!ce)) {
				zend_error(E_EXCEPTION | E_ERROR, "Cannot access static:: when no class scope is active");
				return NULL;
			}
		} else {
			ce = zend_fetch_class(class_name, flags);
		}
		free_alloca(lcname, use_heap);
		if (ce) {
			ret_constant = zend_hash_find(&ce->constants_table, constant_name);
			if (ret_constant == NULL) {
				if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
					zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s::%s'", class_name->val, constant_name->val);
					zend_string_release(class_name);
					zend_string_free(constant_name);
					return NULL;
				}
			} else if (Z_ISREF_P(ret_constant)) {
				ret_constant = Z_REFVAL_P(ret_constant);
			}
		}
		zend_string_release(class_name);
		zend_string_free(constant_name);
		if (ret_constant && Z_CONSTANT_P(ret_constant)) {
			if (UNEXPECTED(zval_update_constant_ex(ret_constant, 1, ce) != SUCCESS)) {
				return NULL;
			}
		}
		return ret_constant;
	}

	/* non-class constant */
	if ((colon = zend_memrchr(name, '\\', name_len)) != NULL) {
		/* compound constant name */
		int prefix_len = colon - name;
		size_t const_name_len = name_len - prefix_len - 1;
		const char *constant_name = colon + 1;
		char *lcname;
		size_t lcname_len;
		ALLOCA_FLAG(use_heap)

		lcname_len = prefix_len + 1 + const_name_len;
		lcname = do_alloca(lcname_len + 1, use_heap);
		zend_str_tolower_copy(lcname, name, prefix_len);
		/* Check for namespace constant */

		lcname[prefix_len] = '\\';
		memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1);

		if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) == NULL) {
			/* try lowercase */
			zend_str_tolower(lcname + prefix_len + 1, const_name_len);
			if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) != NULL) {
				if ((c->flags & CONST_CS) != 0) {
					c = NULL;
				}
			}
		}
		free_alloca(lcname, use_heap);
		if (c) {
			return &c->value;
		}
		/* name requires runtime resolution, need to check non-namespaced name */
		if ((flags & IS_CONSTANT_UNQUALIFIED) != 0) {
			return zend_get_constant_str(constant_name, const_name_len);
		}
		return NULL;
	}

	if (cname) {
		return zend_get_constant(cname);
	} else {
		return zend_get_constant_str(name, name_len);
	}
}
コード例 #19
0
/**
 * Copies of internal methods from Zend/zend_execute_API.c
 * These are used to call internal methods (not in the function table) from the external method.
 * TODO: See if xdebug works
 */
int runkit_forward_call_user_function(zend_function *fbc, zend_function *fbc_inner, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
{
	uint32_t i;
	zend_execute_data *call, dummy_execute_data;
	zend_fcall_info_cache fci_cache_local = {0};
	zend_function *func;
	/* {{{ patch for runkit */
	zend_fcall_info fci = {0};
	zend_fcall_info_cache *fci_cache = NULL;

	fci.size = sizeof(fci);
	fci.object = NULL; // FIXME for methods? // object ? Z_OBJ_P(object) : NULL;
	ZVAL_STR(&fci.function_name, fbc_inner->common.function_name);
	zend_string_addref(fbc_inner->common.function_name);
	fci.retval = return_value;
	fci.param_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
	fci.params = ZEND_CALL_ARG(EG(current_execute_data), 1);  // params and param_count From zend_API.c
	fci.no_separation = (zend_bool)1;			  // ???
	/* end patch for runkit }}} */

	ZVAL_UNDEF(fci.retval);

	if (!EG(active)) {
		return FAILURE; /* executor is already inactive */
	}

	if (EG(exception)) {
		return FAILURE; /* we would result in an unstable executor otherwise */
	}

	/* Initialize execute_data */
	if (!EG(current_execute_data)) {
		/* This only happens when we're called outside any execute()'s
		 * It shouldn't be strictly necessary to NULL execute_data out,
		 * but it may make bugs easier to spot
		 */
		memset(&dummy_execute_data, 0, sizeof(zend_execute_data));
		EG(current_execute_data) = &dummy_execute_data;
	} else if (EG(current_execute_data)->func &&
	           ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
	           EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL &&
	           EG(current_execute_data)->opline->opcode != ZEND_DO_ICALL &&
	           EG(current_execute_data)->opline->opcode != ZEND_DO_UCALL &&
	           EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL_BY_NAME) {
		/* Insert fake frame in case of include or magic calls */
		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.opline = NULL;
		dummy_execute_data.func = NULL;
		EG(current_execute_data) = &dummy_execute_data;
	}

	if (!fci_cache || !RUNKIT_IS_FCI_CACHE_INITIALIZED(fci_cache)) {
		zend_string *callable_name;
		char *error = NULL;

		if (!fci_cache) {
			fci_cache = &fci_cache_local;
		}

		if (!zend_is_callable_ex(&fci.function_name, fci.object, IS_CALLABLE_CHECK_SILENT, &callable_name, fci_cache, &error)) {
			if (error) {
				zend_error(E_WARNING, "Invalid callback %s, %s", ZSTR_VAL(callable_name), error);
				efree(error);
			}
			if (callable_name) {
				zend_string_release(callable_name);
			}
			if (EG(current_execute_data) == &dummy_execute_data) {
				EG(current_execute_data) = dummy_execute_data.prev_execute_data;
			}
			return FAILURE;
		} else if (error) {
			/* Capitalize the first latter of the error message */
			if (error[0] >= 'a' && error[0] <= 'z') {
				error[0] += ('A' - 'a');
			}
			zend_error(E_DEPRECATED, "%s", error);
			efree(error);
		}
		zend_string_release(callable_name);
	}

	func = fbc_inner;
    fci.object = (func->common.fn_flags & ZEND_ACC_STATIC) ?
	   NULL : fci_cache->object;

    call = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC,
	   func, fci.param_count, fci_cache->called_scope, fci.object);
	if (fci.object &&
	    (!EG(objects_store).object_buckets ||
	     !IS_OBJ_VALID(EG(objects_store).object_buckets[fci.object->handle]))) {
		if (EG(current_execute_data) == &dummy_execute_data) {
			EG(current_execute_data) = dummy_execute_data.prev_execute_data;
		}
		return FAILURE;
	}

	if (func->common.fn_flags & (ZEND_ACC_ABSTRACT | ZEND_ACC_DEPRECATED)) {
		if (func->common.fn_flags & ZEND_ACC_ABSTRACT) {
			zend_throw_error(NULL, "Cannot call abstract method %s::%s()", ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
			if (EG(current_execute_data) == &dummy_execute_data) {
				EG(current_execute_data) = dummy_execute_data.prev_execute_data;
			}
			return FAILURE;
		}
		if (func->common.fn_flags & ZEND_ACC_DEPRECATED) {
 			zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
				func->common.scope ? ZSTR_VAL(func->common.scope->name) : "",
				func->common.scope ? "::" : "",
				ZSTR_VAL(func->common.function_name));
		}
	}

	for (i = 0; i < fci.param_count; i++) {
		zval *param;
		zval *arg = &fci.params[i];

		if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) {
			if (UNEXPECTED(!Z_ISREF_P(arg))) {
				if (!fci.no_separation) {
					/* Separation is enabled -- create a ref */
					ZVAL_NEW_REF(arg, arg);
				} else if (!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
					/* By-value send is not allowed -- emit a warning,
					 * but still perform the call with a by-value send. */
					zend_error(E_WARNING,
						"Parameter %d to %s%s%s() expected to be a reference, value given", i + 1,
						func->common.scope ? ZSTR_VAL(func->common.scope->name) : "",
						func->common.scope ? "::" : "",
						ZSTR_VAL(func->common.function_name));
				}
			}
		} else {
			if (Z_ISREF_P(arg) &&
			    !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
				/* don't separate references for __call */
				arg = Z_REFVAL_P(arg);
			}
		}
		param = ZEND_CALL_ARG(call, i + 1);
		ZVAL_COPY(param, arg);
	}

	if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
		ZEND_ASSERT(GC_TYPE((zend_object *)func->op_array.prototype) == IS_OBJECT);
		GC_ADDREF((zend_object *)func->op_array.prototype);
		ZEND_ADD_CALL_FLAG(call, ZEND_CALL_CLOSURE);
	}

	if (func->type == ZEND_USER_FUNCTION) {
		int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
		zend_init_execute_data(call, &func->op_array, fci.retval);
		zend_execute_ex(call);
		if (call_via_handler) {
			/* We must re-initialize function again */
			RUNKIT_CLEAR_FCI_CACHE(fci_cache);
		}
	} else if (func->type == ZEND_INTERNAL_FUNCTION) {
		int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
		ZVAL_NULL(fci.retval);
		call->prev_execute_data = EG(current_execute_data);
		call->return_value = NULL; /* this is not a constructor call */
		EG(current_execute_data) = call;
		if (EXPECTED(zend_execute_internal == NULL)) {
			/* saves one function call if zend_execute_internal is not used */
			func->internal_function.handler(call, fci.retval);
		} else {
			zend_execute_internal(call, fci.retval);
		}
		EG(current_execute_data) = call->prev_execute_data;
		zend_vm_stack_free_args(call);

		/*  We shouldn't fix bad extensions here,
			because it can break proper ones (Bug #34045)
		if (!EX(function_state).function->common.return_reference)
		{
			INIT_PZVAL(f->retval);
		}*/
		if (EG(exception)) {
			zval_ptr_dtor(fci.retval);
			ZVAL_UNDEF(fci.retval);
		}

		if (call_via_handler) {
			/* We must re-initialize function again */
			RUNKIT_CLEAR_FCI_CACHE(fci_cache);
		}
	} else { /* ZEND_OVERLOADED_FUNCTION */
		ZVAL_NULL(fci.retval);

		/* Not sure what should be done here if it's a static method */
		if (fci.object) {
			call->prev_execute_data = EG(current_execute_data);
			EG(current_execute_data) = call;
			fci.object->handlers->call_method(func->common.function_name, fci.object, call, fci.retval);
			EG(current_execute_data) = call->prev_execute_data;
		} else {
			zend_throw_error(NULL, "Cannot call overloaded function for non-object");
		}

		zend_vm_stack_free_args(call);

		if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
			zend_string_release(func->common.function_name);
		}
		efree(func);

		if (EG(exception)) {
			zval_ptr_dtor(fci.retval);
			ZVAL_UNDEF(fci.retval);
		}
	}

	zend_vm_stack_free_call_frame(call);

	if (EG(current_execute_data) == &dummy_execute_data) {
		EG(current_execute_data) = dummy_execute_data.prev_execute_data;
	}

	if (EG(exception)) {
		zend_throw_exception_internal(NULL);
	}
	return SUCCESS;
}
コード例 #20
0
ファイル: zend_interfaces.c プロジェクト: 0xhacking/php-src
/* {{{ zend_call_method
 Only returns the returned zval if retval_ptr != NULL */
ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, size_t function_name_len, zval *retval_ptr, int param_count, zval* arg1, zval* arg2)
{
	int result;
	zend_fcall_info fci;
	zval retval;
	HashTable *function_table;

	zval params[2];

	if (param_count > 0) {
		ZVAL_COPY_VALUE(&params[0], arg1);
	}
	if (param_count > 1) {
		ZVAL_COPY_VALUE(&params[1], arg2);
	}

	fci.size = sizeof(fci);
	/*fci.function_table = NULL; will be read form zend_class_entry of object if needed */
	fci.object = (object && Z_TYPE_P(object) == IS_OBJECT) ? Z_OBJ_P(object) : NULL;
	ZVAL_STRINGL(&fci.function_name, function_name, function_name_len);
	fci.retval = retval_ptr ? retval_ptr : &retval;
	fci.param_count = param_count;
	fci.params = params;
	fci.no_separation = 1;
	fci.symbol_table = NULL;

	if (!fn_proxy && !obj_ce) {
		/* no interest in caching and no information already present that is
		 * needed later inside zend_call_function. */
		fci.function_table = !object ? EG(function_table) : NULL;
		result = zend_call_function(&fci, NULL);
		zval_ptr_dtor(&fci.function_name);
	} else {
		zend_fcall_info_cache fcic;

		fcic.initialized = 1;
		if (!obj_ce) {
			obj_ce = object ? Z_OBJCE_P(object) : NULL;
		}
		if (obj_ce) {
			function_table = &obj_ce->function_table;
		} else {
			function_table = EG(function_table);
		}
		if (!fn_proxy || !*fn_proxy) {
			if ((fcic.function_handler = zend_hash_find_ptr(function_table, Z_STR(fci.function_name))) == NULL) {
				/* error at c-level */
				zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? obj_ce->name->val : "", obj_ce ? "::" : "", function_name);
			}
			if (fn_proxy) {
				*fn_proxy = fcic.function_handler;
			}
		} else {
			fcic.function_handler = *fn_proxy;
		}
		fcic.calling_scope = obj_ce;
		if (object) {
			fcic.called_scope = Z_OBJCE_P(object);
		} else {
			zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));

			if (obj_ce &&
			    (!called_scope ||
			     !instanceof_function(called_scope, obj_ce))) {
				fcic.called_scope = obj_ce;
			} else {
				fcic.called_scope = called_scope;
			}
		}
		fcic.object = object ? Z_OBJ_P(object) : NULL;
		result = zend_call_function(&fci, &fcic);
		zval_ptr_dtor(&fci.function_name);
	}
	if (result == FAILURE) {
		/* error at c-level */
		if (!obj_ce) {
			obj_ce = object ? Z_OBJCE_P(object) : NULL;
		}
		if (!EG(exception)) {
			zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name->val : "", obj_ce ? "::" : "", function_name);
		}
	}
	/* copy arguments back, they might be changed by references */
	if (param_count > 0 && Z_ISREF(params[0]) && !Z_ISREF_P(arg1)) {
		ZVAL_COPY_VALUE(arg1, &params[0]);
	}
	if (param_count > 1 && Z_ISREF(params[1]) && !Z_ISREF_P(arg2)) {
		ZVAL_COPY_VALUE(arg2, &params[1]);
	}
	if (!retval_ptr) {
		zval_ptr_dtor(&retval);
		return NULL;
	}
	return retval_ptr;
}
コード例 #21
0
ファイル: fcall.c プロジェクト: Mrhjx2/zephir
int zephir_call_func_aparams_fast(zval *return_value_ptr, zephir_fcall_cache_entry **cache_entry, zend_uint param_count, zval *params[])
{
	uint32_t i;
	zend_class_entry *calling_scope = NULL;
	zend_execute_data *call, dummy_execute_data;
	zval retval_local;
	zval *retval_ptr = return_value_ptr ? return_value_ptr : &retval_local;
	zend_class_entry *orig_scope;
	zend_function *func;

	if (return_value_ptr) {
		zval_ptr_dtor(return_value_ptr);
		ZVAL_UNDEF(return_value_ptr);
	} else {
		ZVAL_UNDEF(&retval_local);
	}

	if (!EG(active)) {
		return FAILURE; /* executor is already inactive */
	}

	if (EG(exception)) {
		return FAILURE; /* we would result in an instable executor otherwise */
	}

	orig_scope = EG(scope);

	/* Initialize execute_data */
	if (!EG(current_execute_data)) {
		/* This only happens when we're called outside any execute()'s
		 * It shouldn't be strictly necessary to NULL execute_data out,
		 * but it may make bugs easier to spot
		 */
		memset(&dummy_execute_data, 0, sizeof(zend_execute_data));
		EG(current_execute_data) = &dummy_execute_data;
	} else if (EG(current_execute_data)->func &&
	           ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
	           EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL &&
	           EG(current_execute_data)->opline->opcode != ZEND_DO_ICALL &&
	           EG(current_execute_data)->opline->opcode != ZEND_DO_UCALL &&
	           EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL_BY_NAME) {
		/* Insert fake frame in case of include or magic calls */
		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.opline = NULL;
		dummy_execute_data.func = NULL;
		EG(current_execute_data) = &dummy_execute_data;
	}

#ifndef ZEPHIR_RELEASE
	func = (*cache_entry)->f;
	++(*cache_entry)->times;
#else
	func = *cache_entry;
#endif

	calling_scope = NULL;
	call = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_FUNCTION, func, param_count, NULL, NULL);

	for (i = 0; i < param_count; i++) {
		zval *param;
		zval *arg = params[i];

		if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) {
			if (!Z_ISREF_P(arg)) {
				/*if (!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
					if (i) {
						// hack to clean up the stack
						ZEND_CALL_NUM_ARGS(call) = i;
						zend_vm_stack_free_args(call);
					}
					zend_vm_stack_free_call_frame(call);

					zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
						i+1,
						func->common.scope ? ZSTR_VAL(func->common.scope->name) : "",
						func->common.scope ? "::" : "",
						ZSTR_VAL(func->common.function_name));
					if (EG(current_execute_data) == &dummy_execute_data) {
						EG(current_execute_data) = dummy_execute_data.prev_execute_data;
					}
					return FAILURE;
				}*/

				ZVAL_NEW_REF(arg, arg);
			}
			Z_ADDREF_P(arg);
		} else {
			if (Z_ISREF_P(arg) &&
			    !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
				/* don't separate references for __call */
				arg = Z_REFVAL_P(arg);
			}
			if (Z_OPT_REFCOUNTED_P(arg)) {
				Z_ADDREF_P(arg);
			}
		}
		param = ZEND_CALL_ARG(call, i+1);
		ZVAL_COPY_VALUE(param, arg);
	}

	EG(scope) = calling_scope;
	Z_OBJ(call->This) = NULL;

	if (func->type == ZEND_USER_FUNCTION) {
		int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
		EG(scope) = func->common.scope;
		call->symbol_table = NULL;
		if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
			ZEND_ASSERT(GC_TYPE((zend_object*)func->op_array.prototype) == IS_OBJECT);
			GC_REFCOUNT((zend_object*)func->op_array.prototype)++;
			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_CLOSURE);
		}
		if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) {
			zend_init_execute_data(call, &func->op_array, retval_ptr);
			zend_execute_ex(call);
		} else {
			zend_generator_create_zval(call, &func->op_array, retval_ptr);
		}
		if (call_via_handler) {
			/* We must re-initialize function again */
			*cache_entry = NULL;
		}
	} else if (func->type == ZEND_INTERNAL_FUNCTION) {
		int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
		if (func->common.scope) {
			EG(scope) = func->common.scope;
		}
		call->prev_execute_data = EG(current_execute_data);
		call->return_value = NULL; /* this is not a constructor call */
		EG(current_execute_data) = call;
		if (EXPECTED(zend_execute_internal == NULL)) {
			/* saves one function call if zend_execute_internal is not used */
			func->internal_function.handler(call, retval_ptr);
		} else {
			zend_execute_internal(call, retval_ptr);
		}
		EG(current_execute_data) = call->prev_execute_data;
		zend_vm_stack_free_args(call);

		/*  We shouldn't fix bad extensions here,
			because it can break proper ones (Bug #34045)
		if (!EX(function_state).function->common.return_reference)
		{
			INIT_PZVAL(f->retval);
		}*/
		if (EG(exception)) {
			zval_ptr_dtor(retval_ptr);
			ZVAL_UNDEF(retval_ptr);
		}

		if (call_via_handler) {
			/* We must re-initialize function again */
			*cache_entry = NULL;
		}
	} else { /* ZEND_OVERLOADED_FUNCTION */
		ZVAL_NULL(retval_ptr);

		zend_throw_error(NULL, "Cannot call overloaded function for non-object");
		zend_vm_stack_free_args(call);

		if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
			zend_string_release(func->common.function_name);
		}
		efree(func);

		if (EG(exception)) {
			zval_ptr_dtor(retval_ptr);
			ZVAL_UNDEF(retval_ptr);
		}
	}

	EG(scope) = orig_scope;
	zend_vm_stack_free_call_frame(call);

	if (EG(current_execute_data) == &dummy_execute_data) {
		EG(current_execute_data) = dummy_execute_data.prev_execute_data;
	}

	if (EG(exception)) {
		zend_throw_exception_internal(NULL);
	}
	return SUCCESS;
}
コード例 #22
0
ファイル: phpdbg_watch.c プロジェクト: MessyHack/php-src
static phpdbg_watchpoint_t *phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch) {
	phpdbg_watchpoint_t *ret = watch;

	/* exclude references & refcounted */
	if (!watch->parent || watch->parent->type != WATCH_ON_ZVAL || watch->type == WATCH_ON_HASHTABLE) {
		phpdbg_watchpoint_t *old_watch = zend_hash_find_ptr(&PHPDBG_G(watchpoints), watch->str);

		if (old_watch) {
#define return_and_free_watch(x) { \
	phpdbg_watchpoint_t *ref = phpdbg_get_refcount_watch(old_watch); \
	if (ref) { \
		phpdbg_add_watch_collision(ref); \
	} \
	if (watch != old_watch) { \
		phpdbg_free_watch(watch); \
		efree(watch); \
	} \
	return (x); \
}
			if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
				if (old_watch->flags & PHPDBG_WATCH_RECURSIVE) {
					return_and_free_watch(NULL);
				} else {
					old_watch->flags &= ~(PHPDBG_WATCH_SIMPLE | PHPDBG_WATCH_IMPLICIT);
					old_watch->flags |= PHPDBG_WATCH_RECURSIVE;
					return_and_free_watch(old_watch);
				}
			} else {
				if (!(old_watch->flags & PHPDBG_WATCH_RECURSIVE)) {
					old_watch->flags |= watch->flags & (PHPDBG_WATCH_IMPLICIT | PHPDBG_WATCH_SIMPLE);
				}
				return_and_free_watch(NULL);
			}
		} else {
			if (watch->parent && watch->parent->type == WATCH_ON_HASHTABLE) {
				watch->parent->implicit_ht_count++;
			}
			zend_hash_add_ptr(&PHPDBG_G(watchpoints), watch->str, watch);
		}
	}

	phpdbg_store_watchpoint(watch);

	if (watch->parent && watch->parent->type == WATCH_ON_ZVAL && Z_REFCOUNTED_P(watch->parent->addr.zv)) {
		phpdbg_add_watch_collision(phpdbg_create_refcounted_watchpoint(watch, Z_COUNTED_P(watch->parent->addr.zv)));
	}

	if (watch->type == WATCH_ON_ZVAL) {
		if (watch->parent_container) {
			HashTable *ht_watches;
			phpdbg_btree_result *find;
			if (!(find = phpdbg_btree_find(&PHPDBG_G(watch_HashTables), (zend_ulong) watch->parent_container))) {
				phpdbg_watch_ht_info *hti = emalloc(sizeof(*hti));
				hti->dtor = watch->parent_container->pDestructor;
				ht_watches = &hti->watches;
				zend_hash_init(ht_watches, 0, grrrrr, ZVAL_PTR_DTOR, 0);
				phpdbg_btree_insert(&PHPDBG_G(watch_HashTables), (zend_ulong) watch->parent_container, hti);
				watch->parent_container->pDestructor = (dtor_func_t) phpdbg_watch_HashTable_dtor;
			} else {
				ht_watches = &((phpdbg_watch_ht_info *) find->ptr)->watches;
			}
			zend_hash_add_ptr(ht_watches, watch->name_in_parent, watch);
		}

		if (Z_ISREF_P(watch->addr.zv)) {
			ret = phpdbg_create_reference_watch(watch);
		}
	}

	phpdbg_activate_watchpoint(watch);

	return ret;
}
コード例 #23
0
ファイル: var_unserializer.c プロジェクト: flaupretre/php-src
static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
{
	const unsigned char *cursor, *limit, *marker, *start;
	zval *rval_ref;

	limit = max;
	cursor = *p;

	if (YYCURSOR >= YYLIMIT) {
		return 0;
	}

	if (var_hash && (*p)[0] != 'R') {
		var_push(var_hash, rval);
	}

	start = cursor;


#line 656 "ext/standard/var_unserializer.c"
{
	YYCTYPE yych;
	static const unsigned char yybm[] = {
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
	};
	if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
	yych = *YYCURSOR;
	switch (yych) {
	case 'C':
	case 'O':	goto yy4;
	case 'N':	goto yy5;
	case 'R':	goto yy6;
	case 'S':	goto yy7;
	case 'a':	goto yy8;
	case 'b':	goto yy9;
	case 'd':	goto yy10;
	case 'i':	goto yy11;
	case 'o':	goto yy12;
	case 'r':	goto yy13;
	case 's':	goto yy14;
	case '}':	goto yy15;
	default:	goto yy2;
	}
yy2:
	++YYCURSOR;
yy3:
#line 1043 "ext/standard/var_unserializer.re"
	{ return 0; }
#line 716 "ext/standard/var_unserializer.c"
yy4:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy17;
	goto yy3;
yy5:
	yych = *++YYCURSOR;
	if (yych == ';') goto yy19;
	goto yy3;
yy6:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy21;
	goto yy3;
yy7:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy22;
	goto yy3;
yy8:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy23;
	goto yy3;
yy9:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy24;
	goto yy3;
yy10:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy25;
	goto yy3;
yy11:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy26;
	goto yy3;
yy12:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy27;
	goto yy3;
yy13:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy28;
	goto yy3;
yy14:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ':') goto yy29;
	goto yy3;
yy15:
	++YYCURSOR;
#line 1037 "ext/standard/var_unserializer.re"
	{
	/* this is the case where we have less data than planned */
	php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");
	return 0; /* not sure if it should be 0 or 1 here? */
}
#line 769 "ext/standard/var_unserializer.c"
yy17:
	yych = *++YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy30;
	}
yy18:
	YYCURSOR = YYMARKER;
	goto yy3;
yy19:
	++YYCURSOR;
#line 709 "ext/standard/var_unserializer.re"
	{
	*p = YYCURSOR;
	ZVAL_NULL(rval);
	return 1;
}
#line 786 "ext/standard/var_unserializer.c"
yy21:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy32;
	goto yy18;
yy22:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy34;
	goto yy18;
yy23:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy36;
	goto yy18;
yy24:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '1') goto yy38;
	goto yy18;
yy25:
	yych = *++YYCURSOR;
	if (yych <= '/') {
		if (yych <= ',') {
			if (yych == '+') goto yy39;
			goto yy18;
		} else {
			if (yych <= '-') goto yy40;
			if (yych <= '.') goto yy41;
			goto yy18;
		}
	} else {
		if (yych <= 'I') {
			if (yych <= '9') goto yy42;
			if (yych <= 'H') goto yy18;
			goto yy44;
		} else {
			if (yych == 'N') goto yy45;
			goto yy18;
		}
	}
yy26:
	yych = *++YYCURSOR;
	if (yych <= ',') {
		if (yych == '+') goto yy46;
		goto yy18;
	} else {
		if (yych <= '-') goto yy46;
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy47;
		goto yy18;
	}
yy27:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy49;
	goto yy18;
yy28:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy51;
	goto yy18;
yy29:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy53;
	goto yy18;
yy30:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy30;
	}
	if (yych <= '/') goto yy18;
	if (yych <= ':') goto yy55;
	goto yy18;
yy32:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy32;
	if (yych == ';') goto yy56;
	goto yy18;
yy34:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy34;
	if (yych <= ':') goto yy58;
	goto yy18;
yy36:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy36;
	if (yych <= ':') goto yy59;
	goto yy18;
yy38:
	yych = *++YYCURSOR;
	if (yych == ';') goto yy60;
	goto yy18;
yy39:
	yych = *++YYCURSOR;
	if (yych == '.') goto yy41;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy42;
	goto yy18;
yy40:
	yych = *++YYCURSOR;
	if (yych <= '/') {
		if (yych != '.') goto yy18;
	} else {
		if (yych <= '9') goto yy42;
		if (yych == 'I') goto yy44;
		goto yy18;
	}
yy41:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy62;
	goto yy18;
yy42:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
	yych = *YYCURSOR;
	if (yych <= ':') {
		if (yych <= '.') {
			if (yych <= '-') goto yy18;
			goto yy62;
		} else {
			if (yych <= '/') goto yy18;
			if (yych <= '9') goto yy42;
			goto yy18;
		}
	} else {
		if (yych <= 'E') {
			if (yych <= ';') goto yy64;
			if (yych <= 'D') goto yy18;
			goto yy66;
		} else {
			if (yych == 'e') goto yy66;
			goto yy18;
		}
	}
yy44:
	yych = *++YYCURSOR;
	if (yych == 'N') goto yy67;
	goto yy18;
yy45:
	yych = *++YYCURSOR;
	if (yych == 'A') goto yy68;
	goto yy18;
yy46:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy47:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy47;
	if (yych == ';') goto yy69;
	goto yy18;
yy49:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy49;
	if (yych <= ':') goto yy71;
	goto yy18;
yy51:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy51;
	if (yych == ';') goto yy72;
	goto yy18;
yy53:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy53;
	if (yych <= ':') goto yy74;
	goto yy18;
yy55:
	yych = *++YYCURSOR;
	if (yych == '"') goto yy75;
	goto yy18;
yy56:
	++YYCURSOR;
#line 660 "ext/standard/var_unserializer.re"
	{
	zend_long id;

 	*p = YYCURSOR;
	if (!var_hash) return 0;

	id = parse_uiv(start + 2) - 1;
	if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
		return 0;
	}

	if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
		return 0;
	}

	if (Z_ISREF_P(rval_ref)) {
		ZVAL_COPY(rval, rval_ref);
	} else {
		ZVAL_NEW_REF(rval_ref, rval_ref);
		ZVAL_COPY(rval, rval_ref);
	}

	return 1;
}
#line 1010 "ext/standard/var_unserializer.c"
yy58:
	yych = *++YYCURSOR;
	if (yych == '"') goto yy77;
	goto yy18;
yy59:
	yych = *++YYCURSOR;
	if (yych == '{') goto yy79;
	goto yy18;
yy60:
	++YYCURSOR;
#line 715 "ext/standard/var_unserializer.re"
	{
	*p = YYCURSOR;
	ZVAL_BOOL(rval, parse_iv(start + 2));
	return 1;
}
#line 1027 "ext/standard/var_unserializer.c"
yy62:
	++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
	yych = *YYCURSOR;
	if (yych <= ';') {
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy62;
		if (yych <= ':') goto yy18;
	} else {
		if (yych <= 'E') {
			if (yych <= 'D') goto yy18;
			goto yy66;
		} else {
			if (yych == 'e') goto yy66;
			goto yy18;
		}
	}
yy64:
	++YYCURSOR;
#line 763 "ext/standard/var_unserializer.re"
	{
#if SIZEOF_ZEND_LONG == 4
use_double:
#endif
	*p = YYCURSOR;
	ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
	return 1;
}
#line 1056 "ext/standard/var_unserializer.c"
yy66:
	yych = *++YYCURSOR;
	if (yych <= ',') {
		if (yych == '+') goto yy81;
		goto yy18;
	} else {
		if (yych <= '-') goto yy81;
		if (yych <= '/') goto yy18;
		if (yych <= '9') goto yy82;
		goto yy18;
	}
yy67:
	yych = *++YYCURSOR;
	if (yych == 'F') goto yy84;
	goto yy18;
yy68:
	yych = *++YYCURSOR;
	if (yych == 'N') goto yy84;
	goto yy18;
yy69:
	++YYCURSOR;
#line 721 "ext/standard/var_unserializer.re"
	{
#if SIZEOF_ZEND_LONG == 4
	int digits = YYCURSOR - start - 3;

	if (start[2] == '-' || start[2] == '+') {
		digits--;
	}

	/* Use double for large zend_long values that were serialized on a 64-bit system */
	if (digits >= MAX_LENGTH_OF_LONG - 1) {
		if (digits == MAX_LENGTH_OF_LONG - 1) {
			int cmp = strncmp((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);

			if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
				goto use_double;
			}
		} else {
			goto use_double;
		}
	}
#endif
	*p = YYCURSOR;
	ZVAL_LONG(rval, parse_iv(start + 2));
	return 1;
}
#line 1104 "ext/standard/var_unserializer.c"
yy71:
	yych = *++YYCURSOR;
	if (yych == '"') goto yy85;
	goto yy18;
yy72:
	++YYCURSOR;
#line 685 "ext/standard/var_unserializer.re"
	{
	zend_long id;

 	*p = YYCURSOR;
	if (!var_hash) return 0;

	id = parse_uiv(start + 2) - 1;
	if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
		return 0;
	}

	if (rval_ref == rval) {
		return 0;
	}

	if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
		return 0;
	}

	ZVAL_COPY(rval, rval_ref);

	return 1;
}
#line 1135 "ext/standard/var_unserializer.c"
yy74:
	yych = *++YYCURSOR;
	if (yych == '"') goto yy87;
	goto yy18;
yy75:
	++YYCURSOR;
#line 885 "ext/standard/var_unserializer.re"
	{
	size_t len, len2, len3, maxlen;
	zend_long elements;
	char *str;
	zend_string *class_name;
	zend_class_entry *ce;
	int incomplete_class = 0;

	int custom_object = 0;

	zval user_func;
	zval retval;
	zval args[1];

    if (!var_hash) return 0;
	if (*start == 'C') {
		custom_object = 1;
	}

	len2 = len = parse_uiv(start + 2);
	maxlen = max - YYCURSOR;
	if (maxlen < len || len == 0) {
		*p = start + 2;
		return 0;
	}

	str = (char*)YYCURSOR;

	YYCURSOR += len;

	if (*(YYCURSOR) != '"') {
		*p = YYCURSOR;
		return 0;
	}
	if (*(YYCURSOR+1) != ':') {
		*p = YYCURSOR+1;
		return 0;
	}

	len3 = strspn(str, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\");
	if (len3 != len)
	{
		*p = YYCURSOR + len3 - len;
		return 0;
	}

	class_name = zend_string_init(str, len, 0);

	do {
		if(!unserialize_allowed_class(class_name, var_hash)) {
			incomplete_class = 1;
			ce = PHP_IC_ENTRY;
			break;
		}

		/* Try to find class directly */
		BG(serialize_lock)++;
		ce = zend_lookup_class(class_name);
		if (ce) {
			BG(serialize_lock)--;
			if (EG(exception)) {
				zend_string_release(class_name);
				return 0;
			}
			break;
		}
		BG(serialize_lock)--;

		if (EG(exception)) {
			zend_string_release(class_name);
			return 0;
		}

		/* Check for unserialize callback */
		if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
			incomplete_class = 1;
			ce = PHP_IC_ENTRY;
			break;
		}

		/* Call unserialize callback */
		ZVAL_STRING(&user_func, PG(unserialize_callback_func));

		ZVAL_STR_COPY(&args[0], class_name);
		BG(serialize_lock)++;
		if (call_user_function_ex(CG(function_table), NULL, &user_func, &retval, 1, args, 0, NULL) != SUCCESS) {
			BG(serialize_lock)--;
			if (EG(exception)) {
				zend_string_release(class_name);
				zval_ptr_dtor(&user_func);
				zval_ptr_dtor(&args[0]);
				return 0;
			}
			php_error_docref(NULL, E_WARNING, "defined (%s) but not found", Z_STRVAL(user_func));
			incomplete_class = 1;
			ce = PHP_IC_ENTRY;
			zval_ptr_dtor(&user_func);
			zval_ptr_dtor(&args[0]);
			break;
		}
		BG(serialize_lock)--;
		zval_ptr_dtor(&retval);
		if (EG(exception)) {
			zend_string_release(class_name);
			zval_ptr_dtor(&user_func);
			zval_ptr_dtor(&args[0]);
			return 0;
		}

		/* The callback function may have defined the class */
		BG(serialize_lock)++;
		if ((ce = zend_lookup_class(class_name)) == NULL) {
			php_error_docref(NULL, E_WARNING, "Function %s() hasn't defined the class it was called for", Z_STRVAL(user_func));
			incomplete_class = 1;
			ce = PHP_IC_ENTRY;
		}
		BG(serialize_lock)--;

		zval_ptr_dtor(&user_func);
		zval_ptr_dtor(&args[0]);
		break;
	} while (1);

	*p = YYCURSOR;

	if (custom_object) {
		int ret;

		ret = object_custom(UNSERIALIZE_PASSTHRU, ce);

		if (ret && incomplete_class) {
			php_store_class_name(rval, ZSTR_VAL(class_name), len2);
		}
		zend_string_release(class_name);
		return ret;
	}

	elements = object_common1(UNSERIALIZE_PASSTHRU, ce);

	if (elements < 0) {
	   zend_string_release(class_name);
	   return 0;
	}

	if (incomplete_class) {
		php_store_class_name(rval, ZSTR_VAL(class_name), len2);
	}
	zend_string_release(class_name);

	return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
#line 1294 "ext/standard/var_unserializer.c"
yy77:
	++YYCURSOR;
#line 810 "ext/standard/var_unserializer.re"
	{
	size_t len, maxlen;
	zend_string *str;

	len = parse_uiv(start + 2);
	maxlen = max - YYCURSOR;
	if (maxlen < len) {
		*p = start + 2;
		return 0;
	}

	if ((str = unserialize_str(&YYCURSOR, len, maxlen)) == NULL) {
		return 0;
	}

	if (*(YYCURSOR) != '"') {
		zend_string_free(str);
		*p = YYCURSOR;
		return 0;
	}

	if (*(YYCURSOR + 1) != ';') {
		efree(str);
		*p = YYCURSOR + 1;
		return 0;
	}

	YYCURSOR += 2;
	*p = YYCURSOR;

	ZVAL_STR(rval, str);
	return 1;
}
#line 1331 "ext/standard/var_unserializer.c"
yy79:
	++YYCURSOR;
#line 844 "ext/standard/var_unserializer.re"
	{
	zend_long elements = parse_iv(start + 2);
	/* use iv() not uiv() in order to check data range */
	*p = YYCURSOR;
    if (!var_hash) return 0;

	if (elements < 0 || elements >= HT_MAX_SIZE) {
		return 0;
	}

	array_init_size(rval, elements);
	if (elements) {
		/* we can't convert from packed to hash during unserialization, because
		   reference to some zvals might be keept in var_hash (to support references) */
		zend_hash_real_init(Z_ARRVAL_P(rval), 0);
	}

	/* The array may contain references to itself, in which case we'll be modifying an
	 * rc>1 array. This is okay, since the array is, ostensibly, only visible to
	 * unserialize (in practice unserialization handlers also see it). Ideally we should
	 * prohibit "r:" references to non-objects, as we only generate them for objects. */
	HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(rval));

	if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) {
		return 0;
	}

	return finish_nested_data(UNSERIALIZE_PASSTHRU);
}
#line 1364 "ext/standard/var_unserializer.c"
yy81:
	yych = *++YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych >= ':') goto yy18;
yy82:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yych <= '/') goto yy18;
	if (yych <= '9') goto yy82;
	if (yych == ';') goto yy64;
	goto yy18;
yy84:
	yych = *++YYCURSOR;
	if (yych == ';') goto yy89;
	goto yy18;
yy85:
	++YYCURSOR;
#line 874 "ext/standard/var_unserializer.re"
	{
	zend_long elements;
    if (!var_hash) return 0;

	elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
	if (elements < 0 || elements >= HT_MAX_SIZE) {
		return 0;
	}
	return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
#line 1394 "ext/standard/var_unserializer.c"
yy87:
	++YYCURSOR;
#line 772 "ext/standard/var_unserializer.re"
	{
	size_t len, maxlen;
	char *str;

	len = parse_uiv(start + 2);
	maxlen = max - YYCURSOR;
	if (maxlen < len) {
		*p = start + 2;
		return 0;
	}

	str = (char*)YYCURSOR;

	YYCURSOR += len;

	if (*(YYCURSOR) != '"') {
		*p = YYCURSOR;
		return 0;
	}

	if (*(YYCURSOR + 1) != ';') {
		*p = YYCURSOR + 1;
		return 0;
	}

	YYCURSOR += 2;
	*p = YYCURSOR;

	if (len == 0) {
		ZVAL_EMPTY_STRING(rval);
	} else if (len == 1) {
		ZVAL_INTERNED_STR(rval, ZSTR_CHAR((zend_uchar)*str));
	} else {
		ZVAL_STRINGL(rval, str, len);
	}
	return 1;
}
#line 1435 "ext/standard/var_unserializer.c"
yy89:
	++YYCURSOR;
#line 747 "ext/standard/var_unserializer.re"
	{
	*p = YYCURSOR;

	if (!strncmp((char*)start + 2, "NAN", 3)) {
		ZVAL_DOUBLE(rval, ZEND_NAN);
	} else if (!strncmp((char*)start + 2, "INF", 3)) {
		ZVAL_DOUBLE(rval, ZEND_INFINITY);
	} else if (!strncmp((char*)start + 2, "-INF", 4)) {
		ZVAL_DOUBLE(rval, -ZEND_INFINITY);
	} else {
		ZVAL_NULL(rval);
	}

	return 1;
}
#line 1454 "ext/standard/var_unserializer.c"
}
#line 1045 "ext/standard/var_unserializer.re"


	return 0;
}
コード例 #24
0
ファイル: mysqlnd_ps_codec.c プロジェクト: Sobak/php-src
/* {{{ mysqlnd_stmt_execute_calculate_param_values_size */
static enum_func_status
mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval ** copies_param, size_t * data_size)
{
	unsigned int i;
	DBG_ENTER("mysqlnd_stmt_execute_calculate_param_values_size");
	for (i = 0; i < stmt->param_count; i++) {
		unsigned short is_longlong = 0;
		unsigned int j;
		zval *bind_var, *the_var = &stmt->param_bind[i].zv;

		bind_var = the_var;
		ZVAL_DEREF(the_var);
		if ((stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB && Z_TYPE_P(the_var) == IS_NULL)) {
			continue;
		}

		if (Z_ISREF_P(bind_var)) {
			for (j = i + 1; j < stmt->param_count; j++) {
				if (Z_ISREF(stmt->param_bind[j].zv) && Z_REFVAL(stmt->param_bind[j].zv) == the_var) {
					/* Double binding of the same zval, make a copy */
					if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
						if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) {
							SET_OOM_ERROR(*stmt->error_info);
							goto end;
						}
					}
					break;
				}
			}
		}

		switch (stmt->param_bind[i].type) {
			case MYSQL_TYPE_DOUBLE:
				*data_size += 8;
				if (Z_TYPE_P(the_var) != IS_DOUBLE) {
					if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
						if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) {
							SET_OOM_ERROR(*stmt->error_info);
							goto end;
						}
					}
				}
				break;
			case MYSQL_TYPE_LONGLONG:
				is_longlong = 4;
				/* fall-through */
			case MYSQL_TYPE_LONG:
				{
					zval *tmp_data = (*copies_param && !Z_ISUNDEF((*copies_param)[i]))? &(*copies_param)[i]: the_var;
					if (Z_TYPE_P(tmp_data) == IS_STRING) {
						goto use_string;
					}
					convert_to_long_ex(tmp_data);
				}
				*data_size += 4 + is_longlong;
				break;
			case MYSQL_TYPE_LONG_BLOB:
				if (!(stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED)) {
					/*
					  User hasn't sent anything, we will send empty string.
					  Empty string has length of 0, encoded in 1 byte. No real
					  data will follows after it.
					*/
					(*data_size)++;
				}
				break;
			case MYSQL_TYPE_VAR_STRING:
use_string:
				*data_size += 8; /* max 8 bytes for size */
				if (Z_TYPE_P(the_var) != IS_STRING) {
					if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
						if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) {
							SET_OOM_ERROR(*stmt->error_info);
							goto end;
						}
					}
					the_var = &((*copies_param)[i]);
				}
				convert_to_string_ex(the_var);
				*data_size += Z_STRLEN_P(the_var);
				break;
		}
	}
	DBG_RETURN(PASS);
end:
	DBG_RETURN(FAIL);
}
コード例 #25
0
ファイル: ScriptEngine.cpp プロジェクト: pauxus/Homegear
bool ScriptEngine::checkSessionId(const std::string& sessionId)
{
	if(_disposing) return false;
	std::unique_ptr<BaseLib::HTTP> request(new BaseLib::HTTP());
	ts_resource_ex(0, NULL); //Replaces TSRMLS_FETCH()
	try
	{
		zend_homegear_globals* globals = php_homegear_get_globals();
		if(!globals)
		{
			ts_free_thread();
			return false;
		}
		globals->http = request.get();

		if(!tsrm_get_ls_cache() || !((sapi_globals_struct *) (*((void ***) tsrm_get_ls_cache()))[((sapi_globals_id)-1)]))
		{
			GD::out.printCritical("Critical: Error in PHP: No thread safe resource exists.");
			ts_free_thread();
			return false;
		}
		SG(server_context) = (void*)request.get(); //Must be defined! Otherwise POST data is not processed.
		SG(sapi_headers).http_response_code = 200;
		SG(default_mimetype) = nullptr;
		SG(default_charset) = nullptr;
		SG(request_info).content_length = 0;
		SG(request_info).request_method = "GET";
		SG(request_info).proto_num = 1001;
		request->getHeader()->cookie = "PHPSESSID=" + sessionId;

		if (php_request_startup(TSRMLS_C) == FAILURE) {
			GD::bl->out.printError("Error calling php_request_startup...");
			ts_free_thread();
			return false;
		}

		zval returnValue;
		zval function;

		ZVAL_STRING(&function, "session_start");
		call_user_function(EG(function_table), NULL, &function, &returnValue, 0, nullptr);

		bool result = false;
		zval* reference = zend_hash_str_find(&EG(symbol_table), "_SESSION", sizeof("_SESSION") - 1);
		if(reference != NULL)
		{
			if(Z_ISREF_P(reference) && Z_RES_P(reference)->ptr && Z_TYPE_P(Z_REFVAL_P(reference)) == IS_ARRAY)
			{
				zval* token = zend_hash_str_find(Z_ARRVAL_P(Z_REFVAL_P(reference)), "authorized", sizeof("authorized") - 1);
				if(token != NULL)
				{
					result = (Z_TYPE_P(token) == IS_TRUE);
				}
			}
        }

		php_request_shutdown(NULL);

		ts_free_thread();
		return result;
	}
	catch(const std::exception& ex)
	{
		GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(BaseLib::Exception& ex)
	{
		GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
	}
	catch(...)
	{
		GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
	}
	std::string error("Error executing script. Check Homegear log for more details.");
	ts_free_thread();
	return false;
}
コード例 #26
0
ファイル: operators.c プロジェクト: banketree/cphalcon
				ZVAL_BOOL(&op2_tmp, op2);
				is_equal_function(&result, op1, &op2_tmp TSRMLS_CC);
				bool_result = Z_BVAL(result);
				return bool_result;
			}
	}

	return 0;
}
/**
 * Do add function keeping ref_count and is_ref
 */
int phalcon_add_function_ex(zval *result, zval *op1, zval *op2 TSRMLS_DC){
	int status;
	int ref_count = Z_REFCOUNT_P(result);
	int is_ref = Z_ISREF_P(result);
	status = add_function(result, op1, op2 TSRMLS_CC);
	Z_SET_REFCOUNT_P(result, ref_count);
	Z_SET_ISREF_TO_P(result, is_ref);
	return status;
}

void phalcon_negate(zval *z TSRMLS_DC) {
	while (1) {
		switch (Z_TYPE_P(z)) {
			case IS_LONG:
			case IS_BOOL:
				ZVAL_LONG(z, -Z_LVAL_P(z));
				return;

			case IS_DOUBLE: