Skip to content

Commit

Permalink
implement semi-reserved words support for object declaration, object …
Browse files Browse the repository at this point in the history
…member access and namespaces
  • Loading branch information
marcioAlmada committed Feb 20, 2015
1 parent 9d6295e commit c01014f
Show file tree
Hide file tree
Showing 5 changed files with 19,785 additions and 3,723 deletions.
55 changes: 40 additions & 15 deletions Zend/zend_compile.c
Expand Up @@ -695,7 +695,7 @@ zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* {{{ */
zend_string_addref(name);
}
/* Ensure that \self, \parent and \static are not used */
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
if (ZEND_FETCH_CLASS_DEFAULT != zend_check_reserved_name(name)) {
zend_error_noreturn(E_COMPILE_ERROR, "'\\%s' is an invalid class name", name->val);
}
return name;
Expand Down Expand Up @@ -1479,6 +1479,27 @@ uint32_t zend_get_class_fetch_type(zend_string *name) /* {{{ */
}
/* }}} */

uint32_t zend_check_reserved_name(zend_string *name) /* {{{ */
{
if (zend_string_equals_literal_ci(name, "self")) {
return ZEND_FETCH_CLASS_SELF;
} else if (zend_string_equals_literal_ci(name, "parent")) {
return ZEND_FETCH_CLASS_PARENT;
} else if (zend_string_equals_literal_ci(name, "static")) {
return ZEND_FETCH_CLASS_STATIC;
} else if (zend_string_equals_literal_ci(name, "namespace")) {
return ZEND_FETCH_NAMESPACE;
} else if (zend_string_equals_literal_ci(name, "array")) {
return ZEND_FETCH_ARRAY;
} else if (zend_string_equals_literal_ci(name, "callable")) {
return ZEND_FETCH_CALLABLE;
} else {
return ZEND_FETCH_CLASS_DEFAULT;
}
}
/* }}} */


ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, uint32_t var) /* {{{ */
{
return op_array->vars[EX_VAR_TO_NUM(var)];
Expand Down Expand Up @@ -4404,6 +4425,12 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
zend_const_expr_to_zval(&value_zv, value_ast);

name = zend_new_interned_string_safe(name);

if (zend_string_equals_literal_ci(name, "class")) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine %s::%s as ::%s is reserved",
ce->name->val, name->val, name->val);
}

if (zend_hash_add(&ce->constants_table, name, &value_zv) == NULL) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s",
ce->name->val, name->val);
Expand Down Expand Up @@ -4513,13 +4540,8 @@ void zend_compile_use_trait(zend_ast *ast) /* {{{ */
"%s is used in %s", name->val, ce->name->val);
}

switch (zend_get_class_fetch_type(name)) {
case ZEND_FETCH_CLASS_SELF:
case ZEND_FETCH_CLASS_PARENT:
case ZEND_FETCH_CLASS_STATIC:
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as trait name "
"as it is reserved", name->val);
break;
if(ZEND_FETCH_CLASS_DEFAULT != zend_check_reserved_name(name)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as trait name as it is reserved", name->val);
}

opline = get_next_op(CG(active_op_array));
Expand Down Expand Up @@ -4593,7 +4615,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
return;
}

if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
if (ZEND_FETCH_CLASS_DEFAULT != zend_check_reserved_name(name)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved",
name->val);
}
Expand Down Expand Up @@ -4845,13 +4867,16 @@ void zend_compile_use(zend_ast *ast) /* {{{ */
lookup_name = zend_string_tolower(new_name);
}

if (type == T_CLASS && (zend_string_equals_literal(lookup_name, "self")
|| zend_string_equals_literal(lookup_name, "parent"))
) {
if (type == T_CLASS && ZEND_FETCH_CLASS_DEFAULT != zend_check_reserved_name(lookup_name)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' "
"is a special class name", old_name->val, new_name->val, new_name->val);
}

if (type == T_CLASS && ZEND_FETCH_CLASS_DEFAULT != zend_check_reserved_name(old_name)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s because '%s' "
"is a special class name", old_name->val, old_name->val);
}

if (current_ns) {
zend_string *ns_name = zend_string_alloc(current_ns->len + 1 + new_name->len, 0);
zend_str_tolower_copy(ns_name->val, current_ns->val, current_ns->len);
Expand Down Expand Up @@ -5001,7 +5026,7 @@ void zend_compile_namespace(zend_ast *ast) /* {{{ */
if (name_ast) {
name = zend_ast_get_str(name_ast);

if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
if (ZEND_FETCH_CLASS_DEFAULT != zend_check_reserved_name(name)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", name->val);
}

Expand Down Expand Up @@ -5842,7 +5867,7 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
zend_ast *const_ast = ast->child[1];

znode class_node, const_node;
zend_op *opline, *class_op = NULL;
zend_op *opline;
zend_string *resolved_name;

zend_eval_const_expr(&class_ast);
Expand All @@ -5864,7 +5889,7 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
if (class_ast->kind == ZEND_AST_ZVAL) {
zend_string_release(resolved_name);
}
class_op = zend_compile_class_ref(&class_node, class_ast);
zend_compile_class_ref(&class_node, class_ast);
}

zend_compile_expr(&const_node, const_ast);
Expand Down
4 changes: 4 additions & 0 deletions Zend/zend_compile.h
Expand Up @@ -719,6 +719,7 @@ ZEND_API zend_bool zend_is_compiling(void);
ZEND_API char *zend_make_compiled_string_description(const char *name);
ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers);
uint32_t zend_get_class_fetch_type(zend_string *name);
uint32_t zend_check_reserved_name(zend_string *name);

typedef zend_bool (*zend_auto_global_callback)(zend_string *name);
typedef struct _zend_auto_global {
Expand Down Expand Up @@ -753,6 +754,9 @@ int zend_add_literal(zend_op_array *op_array, zval *zv);
#define ZEND_FETCH_CLASS_AUTO 4
#define ZEND_FETCH_CLASS_INTERFACE 5
#define ZEND_FETCH_CLASS_TRAIT 6
#define ZEND_FETCH_NAMESPACE 7
#define ZEND_FETCH_ARRAY 8
#define ZEND_FETCH_CALLABLE 9
#define ZEND_FETCH_CLASS_MASK 0x0f
#define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80
#define ZEND_FETCH_CLASS_SILENT 0x0100
Expand Down

0 comments on commit c01014f

Please sign in to comment.