Ejemplo n.º 1
0
ZEND_API int zend_register_constant(zend_constant *c)
{
	zend_string *lowercase_name = NULL;
	zend_string *name;
	int ret = SUCCESS;

#if 0
	printf("Registering constant for module %d\n", c->module_number);
#endif

	if (!(c->flags & CONST_CS)) {
		lowercase_name = zend_string_tolower_ex(c->name, c->flags & CONST_PERSISTENT);
		lowercase_name = zend_new_interned_string(lowercase_name);
		name = lowercase_name;
	} else {
		char *slash = strrchr(ZSTR_VAL(c->name), '\\');
		if (slash) {
			lowercase_name = zend_string_init(ZSTR_VAL(c->name), ZSTR_LEN(c->name), c->flags & CONST_PERSISTENT);
			zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(c->name));
			lowercase_name = zend_new_interned_string(lowercase_name);
			name = lowercase_name;
		} else {
			name = c->name;
		}
	}

	/* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */
	if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__")
		|| zend_hash_add_constant(EG(zend_constants), name, c) == NULL) {

		/* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */
		if (ZSTR_VAL(c->name)[0] == '\0' && ZSTR_LEN(c->name) > sizeof("\0__COMPILER_HALT_OFFSET__")-1
			&& memcmp(ZSTR_VAL(name), "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {
		}
		zend_error(E_NOTICE,"Constant %s already defined", ZSTR_VAL(name));
		zend_string_release(c->name);
		if (!(c->flags & CONST_PERSISTENT)) {
			zval_ptr_dtor_nogc(&c->value);
		}
		ret = FAILURE;
	}
	if (lowercase_name) {
		zend_string_release(lowercase_name);
	}
	return ret;
}
Ejemplo n.º 2
0
/**
 * Returns a class name into a zval result
 */
void zephir_get_class(zval *result, zval *object, int lower)
{
	zend_class_entry *ce;
	zend_string *class_name;

	if (Z_TYPE_P(object) == IS_OBJECT) {

		ce = Z_OBJCE_P(object);
		//zval_ptr_dtor(result);
		class_name = zend_string_init(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), 0);
		ZVAL_STR(result, class_name);

		if (lower) {
			zend_str_tolower(Z_STRVAL_P(result), Z_STRLEN_P(result));
		}

	} else {
		ZVAL_NULL(result);
		php_error_docref(NULL, E_WARNING, "zephir_get_class expects an object");
	}
}
Ejemplo n.º 3
0
void zend_optimizer_update_op1_const(zend_op_array *op_array,
                                     zend_op       *opline,
                                     zval          *val)
{
	if (opline->opcode == ZEND_FREE) {
		MAKE_NOP(opline);
		zval_dtor(val);
	} else {
		ZEND_OP1_TYPE(opline) = IS_CONST;
		if (Z_TYPE_P(val) == IS_STRING) {
			switch (opline->opcode) {
				case ZEND_INIT_STATIC_METHOD_CALL:
				case ZEND_CATCH:
				case ZEND_FETCH_CONSTANT:
				case ZEND_FETCH_CLASS_CONSTANT:
				case ZEND_DEFINED:
				case ZEND_NEW:
					opline->op1.constant = zend_optimizer_add_literal(op_array, val);
					zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline)));
					Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size;
					op_array->cache_size += sizeof(void*);
					zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
					zend_optimizer_add_literal(op_array, val);
					zend_string_hash_val(Z_STR(op_array->literals[opline->op1.constant+1]));
					break;
				default:
					opline->op1.constant = zend_optimizer_add_literal(op_array, val);
					zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline)));
					break;
			}
		} else {
			if (opline->opcode == ZEND_CONCAT ||
			    opline->opcode == ZEND_FAST_CONCAT) {
				convert_to_string(val);
			}
			opline->op1.constant = zend_optimizer_add_literal(op_array, val);
		}
	}
}
Ejemplo n.º 4
0
ZEND_API int zend_register_constant(zend_constant *c)
{
	zend_string *lowercase_name = NULL;
	zend_string *name;
	int ret = SUCCESS;
	zend_bool persistent = (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) != 0;

#if 0
	printf("Registering constant for module %d\n", c->module_number);
#endif

	char *slash = strrchr(ZSTR_VAL(c->name), '\\');
	if (slash) {
		lowercase_name = zend_string_init(ZSTR_VAL(c->name), ZSTR_LEN(c->name), persistent);
		zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(c->name));
		lowercase_name = zend_new_interned_string(lowercase_name);
		name = lowercase_name;
	} else {
		name = c->name;
	}

	/* Check if the user is trying to define any special constant */
	if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__")
		|| (!persistent && zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name)))
		|| zend_hash_add_constant(EG(zend_constants), name, c) == NULL
	) {
		zend_error(E_NOTICE,"Constant %s already defined", ZSTR_VAL(name));
		zend_string_release(c->name);
		if (!persistent) {
			zval_ptr_dtor_nogc(&c->value);
		}
		ret = FAILURE;
	}
	if (lowercase_name) {
		zend_string_release(lowercase_name);
	}
	return ret;
}
Ejemplo n.º 5
0
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);
	}
}
Ejemplo n.º 6
0
ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags)
{
	zend_constant *c;
	const char *colon;
	zend_class_entry *ce = NULL;
	const char *name = ZSTR_VAL(cname);
	size_t name_len = ZSTR_LEN(cname);

	/* 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);
		zend_string *class_name = zend_string_init(name, class_name_len, 0);
		zval *ret_constant = NULL;

		if (zend_string_equals_literal_ci(class_name, "self")) {
			if (UNEXPECTED(!scope)) {
				zend_throw_error(NULL, "Cannot access self:: when no class scope is active");
				goto failure;
			}
			ce = scope;
		} else if (zend_string_equals_literal_ci(class_name, "parent")) {
			if (UNEXPECTED(!scope)) {
				zend_throw_error(NULL, "Cannot access parent:: when no class scope is active");
				goto failure;
			} else if (UNEXPECTED(!scope->parent)) {
				zend_throw_error(NULL, "Cannot access parent:: when current class scope has no parent");
				goto failure;
			} else {
				ce = scope->parent;
			}
		} else if (zend_string_equals_literal_ci(class_name, "static")) {
			ce = zend_get_called_scope(EG(current_execute_data));
			if (UNEXPECTED(!ce)) {
				zend_throw_error(NULL, "Cannot access static:: when no class scope is active");
				goto failure;
			}
		} else {
			ce = zend_fetch_class(class_name, flags);
		}
		if (ce) {
			zend_class_constant *c = zend_hash_find_ptr(&ce->constants_table, constant_name);
			if (c == NULL) {
				if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
					zend_throw_error(NULL, "Undefined class constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
					goto failure;
				}
				ret_constant = NULL;
			} else {
				if (!zend_verify_const_access(c, scope)) {
					zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
					goto failure;
				}
				ret_constant = &c->value;
			}
		}

		if (ret_constant && Z_CONSTANT_P(ret_constant)) {
			if (Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) {
				if (IS_CONSTANT_VISITED(ret_constant)) {
					zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
					ret_constant = NULL;
					goto failure;
				}
				MARK_CONSTANT_VISITED(ret_constant);
			}
			if (UNEXPECTED(zval_update_constant_ex(ret_constant, ce) != SUCCESS)) {
				RESET_CONSTANT_VISITED(ret_constant);
				ret_constant = NULL;
				goto failure;
			}
			RESET_CONSTANT_VISITED(ret_constant);
		}
failure:
		zend_string_release(class_name);
		zend_string_free(constant_name);
		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);
	}
}
Ejemplo n.º 7
0
void zend_optimizer_update_op2_const(zend_op_array *op_array,
                                     zend_op       *opline,
                                     zval          *val)
{
	ZEND_OP2_TYPE(opline) = IS_CONST;
	if (opline->opcode == ZEND_INIT_FCALL) {
		zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
		opline->op2.constant = zend_optimizer_add_literal(op_array, val);
		zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline)));
		Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
		op_array->cache_size += sizeof(void*);
		return;
	} else if (opline->opcode == ZEND_ROPE_INIT ||
			opline->opcode == ZEND_ROPE_ADD ||
			opline->opcode == ZEND_ROPE_END ||
			opline->opcode == ZEND_CONCAT ||
			opline->opcode == ZEND_FAST_CONCAT) {
		convert_to_string(val);
	}
	opline->op2.constant = zend_optimizer_add_literal(op_array, val);
	if (Z_TYPE_P(val) == IS_STRING) {
		zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline)));
		switch (opline->opcode) {
			case ZEND_FETCH_CLASS:
			case ZEND_INIT_FCALL_BY_NAME:
			/*case ZEND_INIT_NS_FCALL_BY_NAME:*/
			case ZEND_ADD_INTERFACE:
			case ZEND_ADD_TRAIT:
			case ZEND_INSTANCEOF:
			case ZEND_FETCH_STATIC_PROP_R:
			case ZEND_FETCH_STATIC_PROP_W:
			case ZEND_FETCH_STATIC_PROP_RW:
			case ZEND_FETCH_STATIC_PROP_IS:
			case ZEND_FETCH_STATIC_PROP_UNSET:
			case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
			case ZEND_UNSET_STATIC_PROP:
			case ZEND_ISSET_ISEMPTY_STATIC_PROP:
				Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
				op_array->cache_size += sizeof(void*);
				zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
				zend_optimizer_add_literal(op_array, val);
				zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
				break;
			case ZEND_INIT_DYNAMIC_CALL:
				opline->opcode = ZEND_INIT_FCALL_BY_NAME;
				Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
				op_array->cache_size += sizeof(void*);
				zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
				zend_optimizer_add_literal(op_array, val);
				zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
				break;
			case ZEND_INIT_METHOD_CALL:
			case ZEND_INIT_STATIC_METHOD_CALL:
				zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
				zend_optimizer_add_literal(op_array, val);
				zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
				/* break missing intentionally */
			/*case ZEND_FETCH_CLASS_CONSTANT:*/
			case ZEND_ASSIGN_OBJ:
			case ZEND_FETCH_OBJ_R:
			case ZEND_FETCH_OBJ_W:
			case ZEND_FETCH_OBJ_RW:
			case ZEND_FETCH_OBJ_IS:
			case ZEND_FETCH_OBJ_UNSET:
			case ZEND_FETCH_OBJ_FUNC_ARG:
			case ZEND_UNSET_OBJ:
			case ZEND_PRE_INC_OBJ:
			case ZEND_PRE_DEC_OBJ:
			case ZEND_POST_INC_OBJ:
			case ZEND_POST_DEC_OBJ:
			case ZEND_ISSET_ISEMPTY_PROP_OBJ:
				Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
				op_array->cache_size += 2 * sizeof(void*);
				break;
			case ZEND_ASSIGN_ADD:
			case ZEND_ASSIGN_SUB:
			case ZEND_ASSIGN_MUL:
			case ZEND_ASSIGN_DIV:
			case ZEND_ASSIGN_POW:
			case ZEND_ASSIGN_MOD:
			case ZEND_ASSIGN_SL:
			case ZEND_ASSIGN_SR:
			case ZEND_ASSIGN_CONCAT:
			case ZEND_ASSIGN_BW_OR:
			case ZEND_ASSIGN_BW_AND:
			case ZEND_ASSIGN_BW_XOR:
				if (opline->extended_value == ZEND_ASSIGN_OBJ) {
					Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
					op_array->cache_size += 2 * sizeof(void*);
				}
				break;
			case ZEND_OP_DATA:
				if ((opline-1)->opcode == ZEND_ASSIGN_DIM ||
				    ((opline-1)->extended_value == ZEND_ASSIGN_DIM &&
				     ((opline-1)->opcode == ZEND_ASSIGN_ADD ||
				     (opline-1)->opcode == ZEND_ASSIGN_SUB ||
				     (opline-1)->opcode == ZEND_ASSIGN_MUL ||
				     (opline-1)->opcode == ZEND_ASSIGN_DIV ||
				     (opline-1)->opcode == ZEND_ASSIGN_POW ||
				     (opline-1)->opcode == ZEND_ASSIGN_MOD ||
				     (opline-1)->opcode == ZEND_ASSIGN_SL ||
				     (opline-1)->opcode == ZEND_ASSIGN_SR ||
				     (opline-1)->opcode == ZEND_ASSIGN_CONCAT ||
				     (opline-1)->opcode == ZEND_ASSIGN_BW_OR ||
				     (opline-1)->opcode == ZEND_ASSIGN_BW_AND ||
				     (opline-1)->opcode == ZEND_ASSIGN_BW_XOR))) {
					goto check_numeric;
				}
				break;
			case ZEND_ISSET_ISEMPTY_DIM_OBJ:
			case ZEND_ADD_ARRAY_ELEMENT:
			case ZEND_INIT_ARRAY:
			case ZEND_ASSIGN_DIM:
			case ZEND_UNSET_DIM:
			case ZEND_FETCH_DIM_R:
			case ZEND_FETCH_DIM_W:
			case ZEND_FETCH_DIM_RW:
			case ZEND_FETCH_DIM_IS:
			case ZEND_FETCH_DIM_FUNC_ARG:
			case ZEND_FETCH_DIM_UNSET:
			case ZEND_FETCH_LIST:
check_numeric:
				{
					zend_ulong index;

					if (ZEND_HANDLE_NUMERIC(Z_STR_P(val), index)) {
						zval_dtor(val);
						ZVAL_LONG(val, index);
						op_array->literals[opline->op2.constant] = *val;
		        	}
				}
				break;
			default:
				break;
		}
	}
}
Ejemplo n.º 8
0
static int LoadDirectory(HashTable *directories, HKEY key, char *path, int path_len, HashTable *parent_ht)
{
	DWORD keys, values, max_key, max_name, max_value;
	int ret = 0;
	HashTable *ht = NULL;

	if (RegQueryInfoKey(key, NULL, NULL, NULL, &keys, &max_key, NULL, &values, &max_name, &max_value, NULL, NULL) == ERROR_SUCCESS) {

		if (values) {
			DWORD i;
			char *name = (char*)emalloc(max_name+1);
			char *value = (char*)emalloc(max_value+1);
			DWORD name_len, type, value_len;

			for (i = 0; i < values; i++) {
				name_len = max_name+1;
				value_len = max_value+1;

				memset(name, '\0', max_name+1);
				memset(value, '\0', max_value+1);

				if (RegEnumValue(key, i, name, &name_len, NULL, &type, value, &value_len) == ERROR_SUCCESS) {
					if ((type == REG_SZ) || (type == REG_EXPAND_SZ)) {
						zval data;

						if (!ht) {
							ht = (HashTable*)malloc(sizeof(HashTable));
							if (!ht) {
								return ret;
							}
							zend_hash_init(ht, 0, NULL, ZVAL_INTERNAL_PTR_DTOR, 1);
						}
						ZVAL_PSTRINGL(&data, value, value_len-1);
						zend_hash_str_update(ht, name, name_len, &data);
					}
				}
			}
			if (ht) {
				if (parent_ht) {
					zend_string *index;
					zend_ulong num;
					zval *tmpdata;

					ZEND_HASH_FOREACH_KEY_VAL(parent_ht, num, index, tmpdata) {
						zend_hash_add(ht, index, tmpdata);
					} ZEND_HASH_FOREACH_END();
				}
				zend_hash_str_update_mem(directories, path, path_len, ht, sizeof(HashTable));
				ret = 1;
			}

			efree(name);
			efree(value);
		}

		if (ht == NULL) {
			ht = parent_ht;
		}

		if (keys) {
			DWORD i;
			char *name = (char*)emalloc(max_key+1);
			char *new_path = (char*)emalloc(path_len+max_key+2);
			DWORD name_len;
			FILETIME t;
			HKEY subkey;

			for (i = 0; i < keys; i++) {
				name_len = max_key+1;
				if (RegEnumKeyEx(key, i, name, &name_len, NULL, NULL, NULL, &t) == ERROR_SUCCESS) {
					if (RegOpenKeyEx(key, name, 0, KEY_READ, &subkey) == ERROR_SUCCESS) {
						if (path_len) {
							memcpy(new_path, path, path_len);
							new_path[path_len] = '/';
							memcpy(new_path+path_len+1, name, name_len+1);
							zend_str_tolower(new_path, path_len+name_len+1);
							name_len += path_len+1;
						} else {
							memcpy(new_path, name, name_len+1);
							zend_str_tolower(new_path, name_len);
						}
						if (LoadDirectory(directories, subkey, new_path, name_len, ht)) {
							ret = 1;
						}
						RegCloseKey(subkey);
					}
				}
			}
			efree(new_path);
			efree(name);
		}
	}
Ejemplo n.º 9
0
/**
 * Returns a namespace from a class name
 */
void zephir_get_ns_class(zval *result, zval *object, int lower)
{
	zend_class_entry *ce;
	int found = 0;
	unsigned int i, j, class_length;
	char *cursor, *class_name;

	if (Z_TYPE_P(object) != IS_OBJECT) {
		if (Z_TYPE_P(object) != IS_STRING) {
			php_error_docref(NULL, E_WARNING, "zephir_get_ns_class expects an object");
			ZVAL_NULL(result);
			return;
		}
	}

	if (Z_TYPE_P(object) == IS_OBJECT) {
		ce = Z_OBJCE_P(object);
		class_name = ZSTR_VAL(ce->name);
		class_length = ZSTR_LEN(ce->name);
	} else {
		class_name = Z_STRVAL_P(object);
		class_length = Z_STRLEN_P(object);
	}

	if (!class_length) {
		ZVAL_NULL(result);
		return;
	}

	j = 0;
	i = class_length;
	cursor = (char *) (class_name + class_length - 1);

	while (i > 0) {
		if ((*cursor) == '\\') {
			found = 1;
			break;
		}
		cursor--;
		i--;
		j++;
	}

	if (j > 0) {

		if (found) {
			int cursor_length = class_length - j - 1;
			cursor = (char *) emalloc(cursor_length + 1);
			memcpy(cursor, class_name, cursor_length);
			cursor[cursor_length] = 0;
			ZVAL_STRING(result, cursor);
			efree(cursor);
		} else {
			ZVAL_EMPTY_STRING(result);
		}

		if (lower) {
			zend_str_tolower(Z_STRVAL_P(result), Z_STRLEN_P(result));
		}
	} else {
		ZVAL_NULL(result);
	}

}
Ejemplo n.º 10
0
static void php_browscap_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, void *arg) /* {{{ */
{
	browser_data *bdata = arg;
	int persistent = bdata->htab->u.flags & HASH_FLAG_PERSISTENT;
	
	if (!arg1) {
		return;
	}

	switch (callback_type) {
		case ZEND_INI_PARSER_ENTRY:
			if (Z_TYPE(bdata->current_section) != IS_UNDEF && arg2) {
				zval new_property;
				zend_string *new_key;

				/* parent entry can not be same as current section -> causes infinite loop! */
				if (!strcasecmp(Z_STRVAL_P(arg1), "parent") && 
					bdata->current_section_name != NULL &&
					!strcasecmp(bdata->current_section_name, Z_STRVAL_P(arg2))
				) {
					zend_error(E_CORE_ERROR, "Invalid browscap ini file: "
						"'Parent' value cannot be same as the section name: %s "
						"(in file %s)", bdata->current_section_name, INI_STR("browscap"));
					return;
				}

				/* Set proper value for true/false settings */
				if ((Z_STRLEN_P(arg2) == 2 && !strncasecmp(Z_STRVAL_P(arg2), "on", sizeof("on") - 1)) ||
					(Z_STRLEN_P(arg2) == 3 && !strncasecmp(Z_STRVAL_P(arg2), "yes", sizeof("yes") - 1)) ||
					(Z_STRLEN_P(arg2) == 4 && !strncasecmp(Z_STRVAL_P(arg2), "true", sizeof("true") - 1))
				) {
					ZVAL_NEW_STR(&new_property, zend_string_init("1", sizeof("1")-1, persistent));
				} else if (
					(Z_STRLEN_P(arg2) == 2 && !strncasecmp(Z_STRVAL_P(arg2), "no", sizeof("no") - 1)) ||
					(Z_STRLEN_P(arg2) == 3 && !strncasecmp(Z_STRVAL_P(arg2), "off", sizeof("off") - 1)) ||
					(Z_STRLEN_P(arg2) == 4 && !strncasecmp(Z_STRVAL_P(arg2), "none", sizeof("none") - 1)) ||
					(Z_STRLEN_P(arg2) == 5 && !strncasecmp(Z_STRVAL_P(arg2), "false", sizeof("false") - 1))
				) {
					// TODO: USE STR_EMPTY_ALLOC()?
					ZVAL_NEW_STR(&new_property, zend_string_init("", sizeof("")-1, persistent));
				} else { /* Other than true/false setting */
					ZVAL_STR(&new_property, zend_string_dup(Z_STR_P(arg2), persistent));
				}
				new_key = zend_string_dup(Z_STR_P(arg1), persistent);
				zend_str_tolower(new_key->val, new_key->len);
				zend_hash_update(Z_ARRVAL(bdata->current_section), new_key, &new_property);
				zend_string_release(new_key);
			}
			break;
		case ZEND_INI_PARSER_SECTION: {
				zval processed;
				zval unprocessed;

				/*printf("'%s' (%d)\n",$1.value.str.val,$1.value.str.len + 1);*/
				if (persistent) {
					ZVAL_NEW_PERSISTENT_ARR(&bdata->current_section);
				} else {
					ZVAL_NEW_ARR(&bdata->current_section);
				}
				zend_hash_init(Z_ARRVAL(bdata->current_section), 0, NULL,
						(dtor_func_t) (persistent?browscap_entry_dtor_persistent
												 :browscap_entry_dtor_request),
						persistent);
				if (bdata->current_section_name) {
					pefree(bdata->current_section_name, persistent);
				}
				bdata->current_section_name = pestrndup(Z_STRVAL_P(arg1),
						Z_STRLEN_P(arg1), persistent);

				zend_hash_update(bdata->htab, Z_STR_P(arg1), &bdata->current_section);

				ZVAL_STR(&processed, Z_STR_P(arg1));
				ZVAL_STR(&unprocessed, zend_string_dup(Z_STR_P(arg1), persistent));

				convert_browscap_pattern(&processed, persistent);
				zend_hash_str_update(Z_ARRVAL(bdata->current_section), "browser_name_regex", sizeof("browser_name_regex")-1, &processed);
				zend_hash_str_update(Z_ARRVAL(bdata->current_section), "browser_name_pattern", sizeof("browser_name_pattern")-1, &unprocessed);
			}
			break;
	}
}
Ejemplo n.º 11
0
int php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, int printdef, GUID *guid, int codepage)
{
	TYPEATTR *attr;
	FUNCDESC *func;
	int i;
	OLECHAR *olename;
	char *ansiname = NULL;
	size_t ansinamelen;
	int ret = 0;

	if (FAILED(ITypeInfo_GetTypeAttr(typeinfo, &attr))) {
		return 0;
	}

	/* verify that it is suitable */
	if (id_to_name == NULL || attr->typekind == TKIND_DISPATCH) {

		if (guid) {
			memcpy(guid, &attr->guid, sizeof(GUID));
		}

		if (printdef) {
			char *guidstring;

			ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &olename, NULL, NULL, NULL);
			ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage);
			SysFreeString(olename);

			guidstring = php_com_string_from_clsid(&attr->guid, codepage);
			php_printf("class %s { /* GUID=%s */\n", ansiname, guidstring);
			efree(guidstring);

			efree(ansiname);
		}

		if (id_to_name) {
			zend_hash_init(id_to_name, 0, NULL, ZVAL_PTR_DTOR, 0);
		}

		/* So we've got the dispatch interface; lets list the event methods */
		for (i = 0; i < attr->cFuncs; i++) {
			zval tmp;
			DISPID lastid = 0;	/* for props */
			int isprop;

			if (FAILED(ITypeInfo_GetFuncDesc(typeinfo, i, &func)))
				break;

			isprop = (func->invkind & DISPATCH_PROPERTYGET || func->invkind & DISPATCH_PROPERTYPUT);

			if (!isprop || lastid != func->memid) {

				lastid = func->memid;

				ITypeInfo_GetDocumentation(typeinfo, func->memid, &olename, NULL, NULL, NULL);
				ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage);
				SysFreeString(olename);

				if (printdef) {
					int j;
					char *funcdesc;
					size_t funcdesclen;
					unsigned int cnames = 0;
					BSTR *names;

					names = (BSTR*)safe_emalloc((func->cParams + 1), sizeof(BSTR), 0);

					ITypeInfo_GetNames(typeinfo, func->memid, names, func->cParams + 1, &cnames);
					/* first element is the function name */
					SysFreeString(names[0]);

					php_printf("\t/* DISPID=%d */\n", func->memid);

					if (func->elemdescFunc.tdesc.vt != VT_VOID) {
						php_printf("\t/* %s [%d] */\n",
								vt_to_string(func->elemdescFunc.tdesc.vt),
								func->elemdescFunc.tdesc.vt
								);
					}

					if (isprop) {

						ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL);
						if (olename) {
							funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage);
							SysFreeString(olename);
							php_printf("\t/* %s */\n", funcdesc);
							efree(funcdesc);
						}

						php_printf("\tvar $%s;\n\n", ansiname);

					} else {
						/* a function */

						php_printf("\tfunction %s(\n", ansiname);

						for (j = 0; j < func->cParams; j++) {
							ELEMDESC *elem = &func->lprgelemdescParam[j];

							php_printf("\t\t/* %s [%d] ", vt_to_string(elem->tdesc.vt), elem->tdesc.vt);

							if (elem->paramdesc.wParamFlags & PARAMFLAG_FIN)
								php_printf("[in]");
							if (elem->paramdesc.wParamFlags & PARAMFLAG_FOUT)
								php_printf("[out]");

							if (elem->tdesc.vt == VT_PTR) {
								/* what does it point to ? */
								php_printf(" --> %s [%d] ",
										vt_to_string(elem->tdesc.lptdesc->vt),
										elem->tdesc.lptdesc->vt
										);
							}

							/* when we handle prop put and get, this will look nicer */
							if (j+1 < (int)cnames) {
								funcdesc = php_com_olestring_to_string(names[j+1], &funcdesclen, codepage);
								SysFreeString(names[j+1]);
							} else {
								funcdesc = "???";
							}

							php_printf(" */ %s%s%c\n",
									elem->tdesc.vt == VT_PTR ? "&$" : "$",
									funcdesc,
									j == func->cParams - 1 ? ' ' : ','
									);

							if (j+1 < (int)cnames) {
								efree(funcdesc);
							}
						}

						php_printf("\t\t)\n\t{\n");

						ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL);
						if (olename) {
							funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage);
							SysFreeString(olename);
							php_printf("\t\t/* %s */\n", funcdesc);
							efree(funcdesc);
						}

						php_printf("\t}\n");
					}

					efree(names);
				}

				if (id_to_name) {
					zend_str_tolower(ansiname, ansinamelen);
					ZVAL_STRINGL(&tmp, ansiname, ansinamelen);
					zend_hash_index_update(id_to_name, func->memid, &tmp);
					// TODO: avoid reallocation???
					efree(ansiname);
				}
			}
			ITypeInfo_ReleaseFuncDesc(typeinfo, func);
		}

		if (printdef) {
			php_printf("}\n");
		}

		ret = 1;
	} else {
		zend_error(E_WARNING, "That's not a dispatchable interface!! type kind = %08x", attr->typekind);
	}

	ITypeInfo_ReleaseTypeAttr(typeinfo, attr);

	return ret;
}
Ejemplo n.º 12
0
/* {{{ php_ini_parser_cb
 */
static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, HashTable *target_hash)
{
	zval *entry;
	HashTable *active_hash;
	char *extension_name;

	if (active_ini_hash) {
		active_hash = active_ini_hash;
	} else {
		active_hash = target_hash;
	}

	switch (callback_type) {
		case ZEND_INI_PARSER_ENTRY: {
				if (!arg2) {
					/* bare string - nothing to do */
					break;
				}

				/* PHP and Zend extensions are not added into configuration hash! */
				if (!is_special_section && !strcasecmp(Z_STRVAL_P(arg1), PHP_EXTENSION_TOKEN)) { /* load PHP extension */
					extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2));
					zend_llist_add_element(&extension_lists.functions, &extension_name);
				} else if (!is_special_section && !strcasecmp(Z_STRVAL_P(arg1), ZEND_EXTENSION_TOKEN)) { /* load Zend extension */
					extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2));
					zend_llist_add_element(&extension_lists.engine, &extension_name);

				/* All other entries are added into either configuration_hash or active ini section array */
				} else {
					/* Store in active hash */
					entry = zend_hash_update(active_hash, Z_STR_P(arg1), arg2);
					Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), 1);
				}
			}
			break;

		case ZEND_INI_PARSER_POP_ENTRY: {
				zval option_arr;
				zval *find_arr;

				if (!arg2) {
					/* bare string - nothing to do */
					break;
				}

/* fprintf(stdout, "ZEND_INI_PARSER_POP_ENTRY: %s[%s] = %s\n",Z_STRVAL_P(arg1), Z_STRVAL_P(arg3), Z_STRVAL_P(arg2)); */

				/* If option not found in hash or is not an array -> create array, otherwise add to existing array */
				if ((find_arr = zend_hash_find(active_hash, Z_STR_P(arg1))) == NULL || Z_TYPE_P(find_arr) != IS_ARRAY) {
					ZVAL_NEW_PERSISTENT_ARR(&option_arr);
					zend_hash_init(Z_ARRVAL(option_arr), 8, NULL, config_zval_dtor, 1);
					find_arr = zend_hash_update(active_hash, Z_STR_P(arg1), &option_arr);
				}

				/* arg3 is possible option offset name */
				if (arg3 && Z_STRLEN_P(arg3) > 0) {
					entry = zend_symtable_update(Z_ARRVAL_P(find_arr), Z_STR_P(arg3), arg2);
				} else {
					entry = zend_hash_next_index_insert(Z_ARRVAL_P(find_arr), arg2);
				}
				Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), 1);
			}
			break;

		case ZEND_INI_PARSER_SECTION: { /* Create an array of entries of each section */

/* fprintf(stdout, "ZEND_INI_PARSER_SECTION: %s\n",Z_STRVAL_P(arg1)); */

				char *key = NULL;
				size_t key_len;

				/* PATH sections */
				if (!strncasecmp(Z_STRVAL_P(arg1), "PATH", sizeof("PATH") - 1)) {
					key = Z_STRVAL_P(arg1);
					key = key + sizeof("PATH") - 1;
					key_len = Z_STRLEN_P(arg1) - sizeof("PATH") + 1;
					is_special_section = 1;
					has_per_dir_config = 1;

					/* make the path lowercase on Windows, for case insensitivity. Does nothing for other platforms */
					TRANSLATE_SLASHES_LOWER(key);

				/* HOST sections */
				} else if (!strncasecmp(Z_STRVAL_P(arg1), "HOST", sizeof("HOST") - 1)) {
					key = Z_STRVAL_P(arg1);
					key = key + sizeof("HOST") - 1;
					key_len = Z_STRLEN_P(arg1) - sizeof("HOST") + 1;
					is_special_section = 1;
					has_per_host_config = 1;
					zend_str_tolower(key, key_len); /* host names are case-insensitive. */

				} else {
					is_special_section = 0;
				}

				if (key && key_len > 0) {
					/* Strip any trailing slashes */
					while (key_len > 0 && (key[key_len - 1] == '/' || key[key_len - 1] == '\\')) {
						key_len--;
						key[key_len] = 0;
					}

					/* Strip any leading whitespace and '=' */
					while (*key && (
						*key == '=' ||
						*key == ' ' ||
						*key == '\t'
					)) {
						key++;
						key_len--;
					}

					/* Search for existing entry and if it does not exist create one */
					if ((entry = zend_hash_str_find(target_hash, key, key_len)) == NULL) {
						zval section_arr;

						ZVAL_NEW_PERSISTENT_ARR(&section_arr);
						zend_hash_init(Z_ARRVAL(section_arr), 8, NULL, (dtor_func_t) config_zval_dtor, 1);
						entry = zend_hash_str_update(target_hash, key, key_len, &section_arr);
					}
					active_ini_hash = Z_ARRVAL_P(entry);
				}
			}
			break;
	}
}
Ejemplo n.º 13
0
static void dic_optimizer_get_handler(INTERNAL_FUNCTION_PARAMETERS)
{
	char *id, should_free = 1;
	zend_ulong id_hash;
	int id_len, i;
	long oninvalid, exception_on_invalid_reference_const;
	zval **found_service, **alias, **method_in_map = NULL, *this_services, *this_aliases, *this_methodMap, *this_loading;
	zend_function *method = NULL;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &id, &id_len, &oninvalid) == FAILURE) {
		return;
	}

	if (strcasecmp(id, "service_container") == 0) {
		RETURN_THIS;
	}

	this_services  = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_SERVICES_KEY, sizeof(SYMFONY_DIC_TOKEN_SERVICES_KEY) - 1, 0 TSRMLS_CC);
	this_aliases   = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_ALIASES_KEY, sizeof(SYMFONY_DIC_TOKEN_ALIASES_KEY) - 1, 0 TSRMLS_CC);
	this_loading   = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_LOADING_KEY, sizeof(SYMFONY_DIC_TOKEN_LOADING_KEY) - 1, 0 TSRMLS_CC);
	this_methodMap = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_METHODMAP_KEY, sizeof(SYMFONY_DIC_TOKEN_METHODMAP_KEY) - 1, 0 TSRMLS_CC);

	if (!SYMFONY_DIC_G(cache_done)) {
		zval invalidBehavior;
		zend_class_entry **exception_ce;

		zend_get_constant_ex("self::EXCEPTION_ON_INVALID_REFERENCE", sizeof("self::EXCEPTION_ON_INVALID_REFERENCE") - 1, &invalidBehavior, Z_OBJCE_P(getThis()), 0  TSRMLS_CC);
		SYMFONY_DIC_G(invalid_behavior) = Z_LVAL(invalidBehavior);

		if (FAILURE == zend_lookup_class(SYMFONY_DIC_TOKEN_SERVICE_CIRCULAR_REFERENCE_EXCEPTION_KEY_UP, sizeof(SYMFONY_DIC_TOKEN_SERVICE_CIRCULAR_REFERENCE_EXCEPTION_KEY_UP) - 1, &exception_ce TSRMLS_CC)) {
			zend_error_noreturn(E_ERROR, "Class %s not found", SYMFONY_DIC_TOKEN_SERVICE_CIRCULAR_REFERENCE_EXCEPTION_KEY_UP);
		}
		SYMFONY_DIC_G(ServiceCircularReferenceException) = *exception_ce;
		if (FAILURE == zend_lookup_class(SYMFONY_DIC_TOKEN_SERVICE_NOT_FOUND_EXCEPTION_KEY_UP, sizeof(SYMFONY_DIC_TOKEN_SERVICE_NOT_FOUND_EXCEPTION_KEY_UP) - 1, &exception_ce TSRMLS_CC)) {
			zend_error_noreturn(E_ERROR, "Class %s not found", SYMFONY_DIC_TOKEN_SERVICE_NOT_FOUND_EXCEPTION_KEY_UP);
		}
		SYMFONY_DIC_G(ServiceNotFoundException) = *exception_ce;
		if (FAILURE == zend_lookup_class(SYMFONY_DIC_TOKEN_INACTIVE_SCOPE_EXCEPTION_KEY_UP, sizeof(SYMFONY_DIC_TOKEN_INACTIVE_SCOPE_EXCEPTION_KEY_UP) - 1, &exception_ce TSRMLS_CC)) {
			zend_error_noreturn(E_ERROR, "Class %s not found", SYMFONY_DIC_TOKEN_INACTIVE_SCOPE_EXCEPTION_KEY_UP);
		}
		SYMFONY_DIC_G(InactiveScopeException) = *exception_ce;

		SYMFONY_DIC_G(cache_done) = 1;
	}

	exception_on_invalid_reference_const = SYMFONY_DIC_G(invalid_behavior);

	if (ZEND_NUM_ARGS() <= 1) {
		oninvalid = exception_on_invalid_reference_const;
	}

	if (IS_INTERNED(id)) {
		id_hash = INTERNED_HASH(id);
	} else {
		id_hash = zend_inline_hash_func(id, id_len + 1);
	}

	id = estrndup(id, id_len); /* zend_str_tolower will change it otherwise */

	for (i = 0; i <= 1; i++, zend_str_tolower(id, id_len), id_hash = zend_inline_hash_func(id, id_len + 1)) {
		if (zend_hash_quick_find(Z_ARRVAL_P(this_aliases), id, id_len + 1, id_hash, (void **)&alias) == SUCCESS) {
			should_free = 0;
			efree(id);
			id      = Z_STRVAL_PP(alias);
			id_len  = Z_STRLEN_PP(alias);
			id_hash = zend_inline_hash_func(id, id_len + 1);
		}
		if (zend_hash_quick_find(Z_ARRVAL_P(this_services), id, id_len + 1, id_hash, (void **)&found_service) == SUCCESS) {
			RETVAL_ZVAL_FAST(*found_service);
			goto free_and_return;
		}
	}

	if (zend_hash_quick_exists(Z_ARRVAL_P(this_loading), id, id_len + 1, id_hash)) {
		zval *ServiceCircularReferenceException;
		ALLOC_INIT_ZVAL(ServiceCircularReferenceException); /* ctor_args */
		object_init_ex(ServiceCircularReferenceException, SYMFONY_DIC_G(ServiceCircularReferenceException));
		zend_throw_exception_object(ServiceCircularReferenceException TSRMLS_CC);
		goto free_and_return;
	}

	zend_hash_quick_find(Z_ARRVAL_P(this_methodMap), id, id_len + 1, id_hash, (void **)&method_in_map);

	if (!method_in_map) {
		char *new_id;

		for (i=0; i < id_len; i++) {
			if (id[i] == '_') {
				memmove(&id[i], &id[i + 1], --id_len);
			}
		}
		php_strtr(id, id_len, ".\\", "__", 2);
		id_len = spprintf(&new_id, 0, "get%sservice", id);
		efree(id);
		id      = new_id;
		id_hash = zend_inline_hash_func(id, id_len + 1);

		zend_hash_quick_find(&Z_OBJCE_P(getThis())->function_table, id, id_len + 1, id_hash, (void **)&method);
		if (!method) {
			if (oninvalid == exception_on_invalid_reference_const) {
				zval *ServiceNotFoundException;
				ALLOC_INIT_ZVAL(ServiceNotFoundException);
				object_init_ex(ServiceNotFoundException, SYMFONY_DIC_G(ServiceNotFoundException));
				zend_throw_exception_object(ServiceNotFoundException TSRMLS_CC); /* ctor_args */
			}
			goto free_and_return;
		}
	} else {
		char *method_name_lc;
		method_name_lc = zend_str_tolower_dup(Z_STRVAL_PP(method_in_map), Z_STRLEN_PP(method_in_map));
		zend_hash_find(&Z_OBJCE_P(getThis())->function_table, method_name_lc, Z_STRLEN_PP(method_in_map) + 1, (void **)&method);
		efree(method_name_lc);
	}

	zend_fcall_info fci = {0};
	zend_fcall_info_cache fcic = {0};
	zval *loading, *result;

	ALLOC_INIT_ZVAL(loading); ZVAL_BOOL(loading, 1);
	zend_hash_quick_add(Z_ARRVAL_P(this_loading), id, id_len + 1, id_hash, &loading, sizeof(zval *), NULL);

	fcic.called_scope = Z_OBJCE_P(getThis());
	fcic.calling_scope = Z_OBJCE_P(getThis());
	fcic.function_handler = method;
	fcic.initialized = 1;
	fcic.object_ptr = getThis();

	fci.retval_ptr_ptr = &result;
	fci.size = sizeof(zend_fcall_info);

	zend_call_function(&fci, &fcic TSRMLS_CC);

	zend_hash_quick_del(Z_ARRVAL_P(this_loading), id, id_len + 1, id_hash);

	if (!EG(exception)) {
		RETVAL_ZVAL_FAST(result);
	} else {
		zend_hash_quick_del(Z_ARRVAL_P(this_services), id, id_len, id_hash);

		if (instanceof_function(Z_OBJCE_P(EG(exception)), SYMFONY_DIC_G(InactiveScopeException) TSRMLS_CC) && oninvalid == exception_on_invalid_reference_const) {
			EG(exception) = NULL;
		}
	}
	zval_ptr_dtor(&result);
free_and_return:
	if (should_free) { efree(id); }
	return;
}
Ejemplo n.º 14
0
int zend_optimizer_update_op2_const(zend_op_array *op_array,
                                    zend_op       *opline,
                                    zval          *val)
{
	switch (opline->opcode) {
		case ZEND_ASSIGN_REF:
			zval_dtor(val);
			return 0;
		case ZEND_FETCH_CLASS:
		case ZEND_INIT_FCALL_BY_NAME:
		/*case ZEND_INIT_NS_FCALL_BY_NAME:*/
		case ZEND_ADD_INTERFACE:
		case ZEND_ADD_TRAIT:
		case ZEND_INSTANCEOF:
		case ZEND_FETCH_STATIC_PROP_R:
		case ZEND_FETCH_STATIC_PROP_W:
		case ZEND_FETCH_STATIC_PROP_RW:
		case ZEND_FETCH_STATIC_PROP_IS:
		case ZEND_FETCH_STATIC_PROP_UNSET:
		case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
		case ZEND_UNSET_STATIC_PROP:
		case ZEND_ISSET_ISEMPTY_STATIC_PROP:
			REQUIRES_STRING(val);
			drop_leading_backslash(val);
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
			alloc_cache_slots_op2(op_array, opline, 1);
			break;
		case ZEND_INIT_FCALL:
			REQUIRES_STRING(val);
			zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			alloc_cache_slots_op2(op_array, opline, 1);
			break;
		case ZEND_INIT_DYNAMIC_CALL:
			if (Z_TYPE_P(val) == IS_STRING) {
				if (zend_memrchr(Z_STRVAL_P(val), ':', Z_STRLEN_P(val))) {
					zval_dtor(val);
					return 0;
				}

				opline->opcode = ZEND_INIT_FCALL_BY_NAME;
				drop_leading_backslash(val);
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
				zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
				alloc_cache_slots_op2(op_array, opline, 1);
			} else {
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			}
			break;
		case ZEND_INIT_METHOD_CALL:
		case ZEND_INIT_STATIC_METHOD_CALL:
			REQUIRES_STRING(val);
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
			alloc_cache_slots_op2(op_array, opline, 2);
			break;
		/*case ZEND_FETCH_CLASS_CONSTANT:*/
		case ZEND_ASSIGN_OBJ:
		case ZEND_FETCH_OBJ_R:
		case ZEND_FETCH_OBJ_W:
		case ZEND_FETCH_OBJ_RW:
		case ZEND_FETCH_OBJ_IS:
		case ZEND_FETCH_OBJ_UNSET:
		case ZEND_FETCH_OBJ_FUNC_ARG:
		case ZEND_UNSET_OBJ:
		case ZEND_PRE_INC_OBJ:
		case ZEND_PRE_DEC_OBJ:
		case ZEND_POST_INC_OBJ:
		case ZEND_POST_DEC_OBJ:
		case ZEND_ISSET_ISEMPTY_PROP_OBJ:
			TO_STRING_NOWARN(val);
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			alloc_cache_slots_op2(op_array, opline, 2);
			break;
		case ZEND_ASSIGN_ADD:
		case ZEND_ASSIGN_SUB:
		case ZEND_ASSIGN_MUL:
		case ZEND_ASSIGN_DIV:
		case ZEND_ASSIGN_POW:
		case ZEND_ASSIGN_MOD:
		case ZEND_ASSIGN_SL:
		case ZEND_ASSIGN_SR:
		case ZEND_ASSIGN_CONCAT:
		case ZEND_ASSIGN_BW_OR:
		case ZEND_ASSIGN_BW_AND:
		case ZEND_ASSIGN_BW_XOR:
			if (opline->extended_value == ZEND_ASSIGN_OBJ) {
				TO_STRING_NOWARN(val);
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
				alloc_cache_slots_op2(op_array, opline, 2);
			} else {
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			}
			break;
		case ZEND_OP_DATA:
			if ((opline-1)->opcode != ZEND_ASSIGN_DIM &&
				((opline-1)->extended_value != ZEND_ASSIGN_DIM ||
				 ((opline-1)->opcode != ZEND_ASSIGN_ADD &&
				 (opline-1)->opcode != ZEND_ASSIGN_SUB &&
				 (opline-1)->opcode != ZEND_ASSIGN_MUL &&
				 (opline-1)->opcode != ZEND_ASSIGN_DIV &&
				 (opline-1)->opcode != ZEND_ASSIGN_POW &&
				 (opline-1)->opcode != ZEND_ASSIGN_MOD &&
				 (opline-1)->opcode != ZEND_ASSIGN_SL &&
				 (opline-1)->opcode != ZEND_ASSIGN_SR &&
				 (opline-1)->opcode != ZEND_ASSIGN_CONCAT &&
				 (opline-1)->opcode != ZEND_ASSIGN_BW_OR &&
				 (opline-1)->opcode != ZEND_ASSIGN_BW_AND &&
				 (opline-1)->opcode != ZEND_ASSIGN_BW_XOR))
			) {
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
				break;
			}
			/* break missing intentionally */
		case ZEND_ISSET_ISEMPTY_DIM_OBJ:
		case ZEND_ADD_ARRAY_ELEMENT:
		case ZEND_INIT_ARRAY:
		case ZEND_ASSIGN_DIM:
		case ZEND_UNSET_DIM:
		case ZEND_FETCH_DIM_R:
		case ZEND_FETCH_DIM_W:
		case ZEND_FETCH_DIM_RW:
		case ZEND_FETCH_DIM_IS:
		case ZEND_FETCH_DIM_FUNC_ARG:
		case ZEND_FETCH_DIM_UNSET:
		case ZEND_FETCH_LIST:
			if (Z_TYPE_P(val) == IS_STRING) {
				zend_ulong index;
				if (ZEND_HANDLE_NUMERIC(Z_STR_P(val), index)) {
					zval_dtor(val);
					ZVAL_LONG(val, index);
				}
			}
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			break;
		case ZEND_ROPE_INIT:
		case ZEND_ROPE_ADD:
		case ZEND_ROPE_END:
		case ZEND_CONCAT:
		case ZEND_FAST_CONCAT:
			TO_STRING_NOWARN(val);
			/* break missing intentionally */
		default:
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			break;
	}

	ZEND_OP2_TYPE(opline) = IS_CONST;
	if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
		zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline)));
	}
	return 1;
}