Skip to content

Commit 72aea5a

Browse files
committed
Allow internal compiler attribute validators to check for attributed target.
1 parent 0bb4d66 commit 72aea5a

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--TEST--
2+
Attributes: Prevent PhpAttribute on non classes
3+
--FILE--
4+
<?php
5+
6+
<<PhpAttribute>>
7+
function foo() {}
8+
--EXPECTF--
9+
Fatal error: Only classes can be marked with <<PhpAttribute>> in %s

Zend/zend_attributes.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
#include "zend_API.h"
33
#include "zend_attributes.h"
44

5-
void zend_attribute_validate_phpattribute(zval *attribute)
5+
void zend_attribute_validate_phpattribute(zval *attribute, int target)
66
{
7+
if (target != ZEND_ATTRIBUTE_TARGET_CLASS) {
8+
zend_error(E_COMPILE_ERROR, "Only classes can be marked with <<PhpAttribute>>");
9+
}
710
}
811

9-
void zend_attribute_validate_phpcompilerattribute(zval *attribute)
12+
void zend_attribute_validate_phpcompilerattribute(zval *attribute, int target)
1013
{
1114
zend_error(E_COMPILE_ERROR, "The PhpCompilerAttribute can only be used by internal classes, use PhpAttribute instead");
1215
}

Zend/zend_attributes.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
#ifndef ZEND_ATTRIBUTES_H
22
#define ZEND_ATTRIBUTES_H
33

4+
#define ZEND_ATTRIBUTE_TARGET_CLASS 1
5+
#define ZEND_ATTRIBUTE_TARGET_FUNCTION 2
6+
#define ZEND_ATTRIBUTE_TARGET_METHOD 4
7+
#define ZEND_ATTRIBUTE_TARGET_PROPERTY 8
8+
#define ZEND_ATTRIBUTE_TARGET_CLASS_CONST 16
9+
#define ZEND_ATTRIBUTE_TARGET_PARAMETER 32
10+
#define ZEND_ATTRIBUTE_TARGET_ALL 63
11+
412
zend_class_entry *zend_ce_php_attribute;
513
zend_class_entry *zend_ce_php_compiler_attribute;
614

7-
typedef void (*zend_attributes_internal_validator)(zval *attribute);
15+
typedef void (*zend_attributes_internal_validator)(zval *attribute, int target);
816
HashTable zend_attributes_internal_validators;
917

1018
void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator *validator);

Zend/zend_compile.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5743,7 +5743,7 @@ static void zend_compile_attribute(zval *v, zend_ast *ast) /* {{{ */
57435743
}
57445744
/* }}} */
57455745

5746-
static HashTable *zend_compile_attributes(zend_ast *ast) /* {{{ */
5746+
static HashTable *zend_compile_attributes(zend_ast *ast, int target) /* {{{ */
57475747
{
57485748
HashTable *attr;
57495749

@@ -5778,7 +5778,7 @@ static HashTable *zend_compile_attributes(zend_ast *ast) /* {{{ */
57785778

57795779
if (validator != NULL) {
57805780
cb = *validator;
5781-
cb(&a);
5781+
cb(&a, target);
57825782
}
57835783

57845784
if (x) {
@@ -5921,7 +5921,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall
59215921
zend_hash_init(op_array->attributes, 8, NULL, ZVAL_PTR_DTOR, 0);
59225922
}
59235923

5924-
ZVAL_ARR(&attr, zend_compile_attributes(attributes_ast));
5924+
ZVAL_ARR(&attr, zend_compile_attributes(attributes_ast, ZEND_ATTRIBUTE_TARGET_PARAMETER));
59255925
zend_hash_index_add(op_array->attributes, i, &attr);
59265926
}
59275927

@@ -6381,7 +6381,11 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
63816381
op_array->doc_comment = zend_string_copy(decl->doc_comment);
63826382
}
63836383
if (decl->attributes) {
6384-
op_array->attributes = zend_compile_attributes(decl->attributes);
6384+
int target = ZEND_ATTRIBUTE_TARGET_FUNCTION;
6385+
if (is_method) {
6386+
target = ZEND_ATTRIBUTE_TARGET_METHOD;
6387+
}
6388+
op_array->attributes = zend_compile_attributes(decl->attributes, target);
63856389
}
63866390
if (decl->kind == ZEND_AST_CLOSURE || decl->kind == ZEND_AST_ARROW_FUNC) {
63876391
op_array->fn_flags |= ZEND_ACC_CLOSURE;
@@ -6555,7 +6559,7 @@ void zend_compile_prop_group(zend_ast *list) /* {{{ */
65556559
zend_ast *type_ast = list->child[0];
65566560
zend_ast *prop_ast = list->child[1];
65576561

6558-
attributes = list->child[2] ? zend_compile_attributes(list->child[2]) : NULL;
6562+
attributes = list->child[2] ? zend_compile_attributes(list->child[2], ZEND_ATTRIBUTE_TARGET_PROPERTY) : NULL;
65596563

65606564
zend_compile_prop_decl(prop_ast, type_ast, list->attr, attributes);
65616565

@@ -6589,7 +6593,7 @@ void zend_compile_class_const_decl(zend_ast *ast, zend_ast *attr_ast) /* {{{ */
65896593
return;
65906594
}
65916595

6592-
attributes = attr_ast ? zend_compile_attributes(attr_ast) : NULL;
6596+
attributes = attr_ast ? zend_compile_attributes(attr_ast, ZEND_ATTRIBUTE_TARGET_CLASS_CONST) : NULL;
65936597

65946598
for (i = 0; i < list->children; ++i) {
65956599
zend_ast *const_ast = list->child[i];
@@ -6820,7 +6824,7 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
68206824
ce->info.user.doc_comment = zend_string_copy(decl->doc_comment);
68216825
}
68226826
if (decl->attributes) {
6823-
ce->info.user.attributes = zend_compile_attributes(decl->attributes);
6827+
ce->info.user.attributes = zend_compile_attributes(decl->attributes, ZEND_ATTRIBUTE_TARGET_CLASS);
68246828
}
68256829

68266830
if (UNEXPECTED((decl->flags & ZEND_ACC_ANON_CLASS))) {

0 commit comments

Comments
 (0)