Skip to content

Commit 13e53ad

Browse files
committed
Add very simple compiler attribute validation for now (no constant ast evaluation).
1 parent 205bd8e commit 13e53ad

File tree

4 files changed

+44
-8
lines changed

4 files changed

+44
-8
lines changed

Zend/tests/attributes/compiler_attributes.phpt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ class Foo
1111
$ref = new ReflectionClass(Foo::class);
1212
var_dump($ref->getAttributes()[0]->getAsObject());
1313
--EXPECTF--
14-
object(PhpCompilerAttribute)#3 (0) {
15-
}
14+
Fatal error: The PhpCompilerAttribute can only be used by internal classes, use PhpAttribute instead in %s

Zend/zend_attributes.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef ZEND_ATTRIBUTES_H
2+
#define ZEND_ATTRIBUTES_H
3+
4+
zend_class_entry *zend_ce_php_attribute;
5+
zend_class_entry *zend_ce_php_compiler_attribute;
6+
7+
typedef void (*zend_attributes_internal_validator)(zval *attribute);
8+
HashTable zend_attributes_internal_validators;
9+
10+
static void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator *validator)
11+
{
12+
zend_string *attribute_name = zend_string_tolower_ex(ce->name, 1);
13+
14+
zend_hash_update_mem(&zend_attributes_internal_validators, attribute_name, validator, sizeof(zend_attributes_internal_validator));
15+
}
16+
#endif

Zend/zend_compile.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <zend_language_parser.h>
2222
#include "zend.h"
23+
#include "zend_attributes.h"
2324
#include "zend_compile.h"
2425
#include "zend_constants.h"
2526
#include "zend_llist.h"
@@ -5750,6 +5751,8 @@ static HashTable *zend_compile_attributes(zend_ast *ast) /* {{{ */
57505751
uint32_t i;
57515752

57525753
zval tmp;
5754+
zend_attributes_internal_validator *validator = NULL;
5755+
zend_attributes_internal_validator cb;
57535756

57545757
ZVAL_NULL(&tmp);
57555758

@@ -5770,6 +5773,14 @@ static HashTable *zend_compile_attributes(zend_ast *ast) /* {{{ */
57705773
name = zend_string_tolower(Z_STR_P(zend_hash_index_find(Z_ARRVAL(a), 0)));
57715774
x = zend_hash_find(attr, name);
57725775

5776+
// validate internal attribute
5777+
validator = (zend_attributes_internal_validator*)zend_hash_find_ptr(&zend_attributes_internal_validators, name);
5778+
5779+
if (validator != NULL) {
5780+
cb = *validator;
5781+
cb(&a);
5782+
}
5783+
57735784
if (x) {
57745785
ZEND_ASSERT(Z_TYPE_P(x) == IS_ARRAY);
57755786

Zend/zend_default_classes.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,43 @@
1919

2020
#include "zend.h"
2121
#include "zend_API.h"
22+
#include "zend_attributes.h"
2223
#include "zend_builtin_functions.h"
2324
#include "zend_interfaces.h"
2425
#include "zend_exceptions.h"
2526
#include "zend_closures.h"
2627
#include "zend_generators.h"
2728
#include "zend_weakrefs.h"
2829

29-
zend_class_entry *zend_ce_php_attribute;
30-
zend_class_entry *zend_ce_php_compiler_attribute;
30+
void zend_attribute_validate_phpattribute(zval *attribute)
31+
{
32+
}
33+
34+
void zend_attribute_validate_phpcompilerattribute(zval *attribute)
35+
{
36+
zend_error(E_COMPILE_ERROR, "The PhpCompilerAttribute can only be used by internal classes, use PhpAttribute instead");
37+
}
3138

3239
static void zend_register_attribute_ce(void)
3340
{
41+
zend_hash_init(&zend_attributes_internal_validators, 8, NULL, NULL, 1);
42+
3443
zend_class_entry ce;
44+
zend_attributes_internal_validator cb;
3545

3646
INIT_CLASS_ENTRY(ce, "PhpAttribute", NULL);
3747
zend_ce_php_attribute = zend_register_internal_class(&ce);
3848
zend_ce_php_attribute->ce_flags |= ZEND_ACC_FINAL;
3949

40-
//zend_hash_init_ex(zend_ce_php_attribute->attributes, 8, NULL, NULL, 1, 0);
41-
//zend_hash_str_add_empty_element(zend_ce_php_attribute->attributes, "phpattribute", sizeof("phpattribute")-1);
50+
cb = zend_attribute_validate_phpattribute;
51+
zend_compiler_attribute_register(zend_ce_php_attribute, &cb);
4252

4353
INIT_CLASS_ENTRY(ce, "PhpCompilerAttribute", NULL);
4454
zend_ce_php_compiler_attribute = zend_register_internal_class(&ce);
4555
zend_ce_php_compiler_attribute->ce_flags |= ZEND_ACC_FINAL;
4656

47-
//zend_hash_init_ex(zend_ce_php_attribute->attributes, 8, NULL, NULL, 1, 0);
48-
//zend_hash_str_add_empty_element(zend_ce_php_attribute->attributes, "phpattribute", sizeof("phpattribute")-1);
57+
cb = zend_attribute_validate_phpcompilerattribute;
58+
zend_compiler_attribute_register(zend_ce_php_compiler_attribute, &cb);
4959
}
5060

5161
ZEND_API void zend_register_default_classes(void)

0 commit comments

Comments
 (0)