Browse Source

Fixed issues found by Nikita

pull/1662/head
Dmitry Stogov 10 years ago
parent
commit
51deab84b2
  1. 10
      Zend/zend_compile.c
  2. 4
      Zend/zend_constants.c
  3. 6
      Zend/zend_inheritance.c
  4. 2
      Zend/zend_language_parser.y
  5. 1
      ext/opcache/Optimizer/pass1_5.c
  6. 12
      ext/opcache/zend_persist.c
  7. 33
      ext/reflection/php_reflection.c
  8. 34
      tests/classes/constants_comments_001.phpt
  9. 10
      tests/classes/constants_visibility_005.phpt
  10. 11
      tests/classes/constants_visibility_006.phpt
  11. 10
      tests/classes/constants_visibility_007.phpt

10
Zend/zend_compile.c

@ -5200,6 +5200,16 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
zend_string *doc_comment = doc_comment_ast ? zend_string_copy(zend_ast_get_str(doc_comment_ast)) : NULL;
zval value_zv;
if (UNEXPECTED(ast->attr & (ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_FINAL))) {
if (ast->attr & ZEND_ACC_STATIC) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as constant modifier");
} else if (ast->attr & ZEND_ACC_ABSTRACT) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'abstract' as constant modifier");
} else if (ast->attr & ZEND_ACC_FINAL) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'final' as constant modifier");
}
}
zend_const_expr_to_zval(&value_zv, value_ast);
name = zend_new_interned_string_safe(name);

4
Zend/zend_constants.c

@ -261,7 +261,6 @@ ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry *
ZEND_ASSERT(c->flags & ZEND_ACC_PROTECTED);
return zend_check_protected(c->ce, scope);
}
return 0;
}
/* }}} */
@ -390,9 +389,6 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
return NULL;
}
ret_constant = &c->value;
if (Z_ISREF_P(ret_constant)) {
ret_constant = Z_REFVAL_P(ret_constant);
}
}
}
zend_string_release(class_name);

6
Zend/zend_inheritance.c

@ -714,11 +714,11 @@ static void do_inherit_class_constant(zend_string *name, zend_class_constant *pa
if (Z_REFCOUNTED(parent_const->value)) {
Z_ADDREF(parent_const->value);
}
if (ce->type & ZEND_INTERNAL_CLASS) {
if (ce->type & ZEND_INTERNAL_CLASS) {
c = pemalloc(sizeof(zend_class_constant), 1);
} else {
} else {
c = zend_arena_alloc(&CG(arena), sizeof(zend_class_constant));
}
}
memcpy(c, parent_const, sizeof(zend_class_constant));
_zend_hash_append_ptr(&ce->constants_table, name, c);
}

2
Zend/zend_language_parser.y

@ -702,7 +702,7 @@ class_statement:
variable_modifiers property_list ';'
{ $$ = $2; $$->attr = $1; }
| method_modifiers T_CONST class_const_list ';'
{ $$ = $3; $$->attr = $1; RESET_DOC_COMMENT(); }
{ $$ = $3; $$->attr = $1; }
| T_USE name_list trait_adaptations
{ $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); }
| method_modifiers function returns_ref identifier '(' parameter_list ')'

1
ext/opcache/Optimizer/pass1_5.c

@ -331,7 +331,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
Z_STR(ZEND_OP2_LITERAL(opline)))) != NULL &&
(cc->flags & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC) {
c = &cc->value;
ZVAL_DEREF(c);
if (Z_TYPE_P(c) == IS_CONSTANT_AST) {
break;
}

12
ext/opcache/zend_persist.c

@ -732,12 +732,18 @@ static void zend_persist_class_constant(zval *zv)
c->ce = zend_shared_alloc_get_xlat_entry(c->ce);
if (c->doc_comment) {
if (ZCG(accel_directives).save_comments) {
zend_accel_store_string(c->doc_comment);
zend_string *doc_comment = zend_shared_alloc_get_xlat_entry(c->doc_comment);
if (doc_comment) {
c->doc_comment = doc_comment;
} else {
zend_accel_store_string(c->doc_comment);
}
} else {
if (!zend_shared_alloc_get_xlat_entry(c->doc_comment)) {
zend_string *doc_comment = zend_shared_alloc_get_xlat_entry(c->doc_comment);
if (!doc_comment) {
zend_shared_alloc_register_xlat_entry(c->doc_comment, c->doc_comment);
zend_string_release(c->doc_comment);
}
zend_string_release(c->doc_comment);
c->doc_comment = NULL;
}
}

33
ext/reflection/php_reflection.c

@ -634,21 +634,9 @@ static void _const_string(string *str, char *name, zval *value, char *indent)
static void _class_const_string(string *str, char *name, zend_class_constant *c, char *indent)
{
char *type = zend_zval_type_name(&c->value);
char *visibility = NULL;
char *visibility = zend_visibility_string(c->flags);
zend_string *value_str = zval_get_string(&c->value);
switch (c->flags & ZEND_ACC_PPP_MASK) {
case ZEND_ACC_PUBLIC:
visibility = "public";
break;
case ZEND_ACC_PRIVATE:
visibility = "private";
break;
case ZEND_ACC_PROTECTED:
visibility = "protected";
break;
}
string_printf(str, "%s Constant [ %s %s %s ] { %s }\n",
indent, visibility, type, name, ZSTR_VAL(value_str));
@ -3796,7 +3784,7 @@ ZEND_METHOD(reflection_class_constant, __toString)
/* }}} */
/* {{{ proto public string ReflectionClassConstant::getName()
Returns the class' name */
Returns the constant' name */
ZEND_METHOD(reflection_class_constant, getName)
{
if (zend_parse_parameters_none() == FAILURE) {
@ -3820,7 +3808,7 @@ static void _class_constant_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /
/* }}} */
/* {{{ proto public bool ReflectionClassConstant::isPublic()
Returns whether this property is public */
Returns whether this constant is public */
ZEND_METHOD(reflection_class_constant, isPublic)
{
_class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC);
@ -3828,7 +3816,7 @@ ZEND_METHOD(reflection_class_constant, isPublic)
/* }}} */
/* {{{ proto public bool ReflectionClassConstant::isPrivate()
Returns whether this property is private */
Returns whether this constant is private */
ZEND_METHOD(reflection_class_constant, isPrivate)
{
_class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
@ -3836,7 +3824,7 @@ ZEND_METHOD(reflection_class_constant, isPrivate)
/* }}} */
/* {{{ proto public bool ReflectionClassConstant::isProtected()
Returns whether this property is protected */
Returns whether this constant is protected */
ZEND_METHOD(reflection_class_constant, isProtected)
{
_class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
@ -3844,7 +3832,7 @@ ZEND_METHOD(reflection_class_constant, isProtected)
/* }}} */
/* {{{ proto public int ReflectionClassConstant::getModifiers()
Returns a bitfield of the access modifiers for this property */
Returns a bitfield of the access modifiers for this constant */
ZEND_METHOD(reflection_class_constant, getModifiers)
{
reflection_object *intern;
@ -3860,7 +3848,7 @@ ZEND_METHOD(reflection_class_constant, getModifiers)
/* }}} */
/* {{{ proto public mixed ReflectionClassConstant::getValue()
Returns this property's value */
Returns this constant's value */
ZEND_METHOD(reflection_class_constant, getValue)
{
reflection_object *intern;
@ -3892,7 +3880,7 @@ ZEND_METHOD(reflection_class_constant, getDeclaringClass)
/* }}} */
/* {{{ proto public string ReflectionClassConstant::getDocComment()
Returns the doc comment for this function */
Returns the doc comment for this constant */
ZEND_METHOD(reflection_class_constant, getDocComment)
{
reflection_object *intern;
@ -4670,7 +4658,7 @@ ZEND_METHOD(reflection_class, getConstants)
return;
}
val = zend_hash_add_new(Z_ARRVAL_P(return_value), key, &c->value);
zval_add_ref_unref(val);
Z_TRY_ADDREF_P(val);
} ZEND_HASH_FOREACH_END();
}
/* }}} */
@ -4692,9 +4680,8 @@ ZEND_METHOD(reflection_class, getReflectionConstants)
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, name, constant) {
zval class_const;
reflection_class_constant_factory(ce, name, constant, &class_const);
zend_hash_next_index_insert(HASH_OF(return_value), &class_const);
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &class_const);
} ZEND_HASH_FOREACH_END();
zend_hash_copy(Z_ARRVAL_P(return_value), &ce->constants_table, zval_add_ref_unref);
}
/* }}} */

34
tests/classes/constants_comments_001.phpt

@ -0,0 +1,34 @@
--TEST--
Class constants and doc comments
--INI--
opcache.save_comments=1
--FILE--
<?php
class X {
/** comment X1 */
const X1 = 1;
const X2 = 2;
/** comment X3 */
const X3 = 3;
}
class Y extends X {
/** comment Y1 */
const Y1 = 1;
const Y2 = 2;
/** comment Y3 */
const Y3 = 3;
}
$r = new ReflectionClass('Y');
foreach ($r->getReflectionConstants() as $rc) {
echo $rc->getName() . " : " . $rc->getDocComment() . "\n";
}
?>
--EXPECT--
Y1 : /** comment Y1 */
Y2 :
Y3 : /** comment Y3 */
X1 : /** comment X1 */
X2 :
X3 : /** comment X3 */

10
tests/classes/constants_visibility_005.phpt

@ -0,0 +1,10 @@
--TEST--
Static constants are not allowed
--FILE--
<?php
class A {
static const X = 1;
}
?>
--EXPECTF--
Fatal error: Cannot use 'static' as constant modifier in %s on line 3

11
tests/classes/constants_visibility_006.phpt

@ -0,0 +1,11 @@
--TEST--
Abstract constants are not allowed
--FILE--
<?php
class A {
abstract const X = 1;
}
?>
--EXPECTF--
Fatal error: Cannot use 'abstract' as constant modifier in %s on line 3

10
tests/classes/constants_visibility_007.phpt

@ -0,0 +1,10 @@
--TEST--
Final constants are not allowed
--FILE--
<?php
class A {
final const X = 1;
}
?>
--EXPECTF--
Fatal error: Cannot use 'final' as constant modifier in %s on line 3
Loading…
Cancel
Save