@@ -1347,6 +1347,88 @@ static inline zend_bool class_name_refers_to_active_ce(zend_string *class_name,
1347
1347
}
1348
1348
/* }}} */
1349
1349
1350
+ uint32_t zend_get_class_fetch_type (zend_string * name ) /* {{{ */
1351
+ {
1352
+ if (zend_string_equals_literal_ci (name , "self" )) {
1353
+ return ZEND_FETCH_CLASS_SELF ;
1354
+ } else if (zend_string_equals_literal_ci (name , "parent" )) {
1355
+ return ZEND_FETCH_CLASS_PARENT ;
1356
+ } else if (zend_string_equals_literal_ci (name , "static" )) {
1357
+ return ZEND_FETCH_CLASS_STATIC ;
1358
+ } else {
1359
+ return ZEND_FETCH_CLASS_DEFAULT ;
1360
+ }
1361
+ }
1362
+ /* }}} */
1363
+
1364
+ static uint32_t zend_get_class_fetch_type_ast (zend_ast * name_ast ) /* {{{ */
1365
+ {
1366
+ /* Fully qualified names are always default refs */
1367
+ if (name_ast -> attr == ZEND_NAME_FQ ) {
1368
+ return ZEND_FETCH_CLASS_DEFAULT ;
1369
+ }
1370
+
1371
+ return zend_get_class_fetch_type (zend_ast_get_str (name_ast ));
1372
+ }
1373
+ /* }}} */
1374
+
1375
+ static void zend_ensure_valid_class_fetch_type (uint32_t fetch_type ) /* {{{ */
1376
+ {
1377
+ if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && !CG (active_class_entry ) && zend_is_scope_known ()) {
1378
+ zend_error_noreturn (E_COMPILE_ERROR , "Cannot use \"%s\" when no class scope is active" ,
1379
+ fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
1380
+ fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static" );
1381
+ }
1382
+ }
1383
+ /* }}} */
1384
+
1385
+ static zend_bool zend_try_compile_const_expr_resolve_class_name (zval * zv , zend_ast * class_ast , zend_ast * name_ast , zend_bool constant ) /* {{{ */
1386
+ {
1387
+ uint32_t fetch_type ;
1388
+
1389
+ if (name_ast -> kind != ZEND_AST_ZVAL ) {
1390
+ return 0 ;
1391
+ }
1392
+
1393
+ if (!zend_string_equals_literal_ci (zend_ast_get_str (name_ast ), "class" )) {
1394
+ return 0 ;
1395
+ }
1396
+
1397
+ if (class_ast -> kind != ZEND_AST_ZVAL ) {
1398
+ zend_error_noreturn (E_COMPILE_ERROR ,
1399
+ "Dynamic class names are not allowed in compile-time ::class fetch" );
1400
+ }
1401
+
1402
+ fetch_type = zend_get_class_fetch_type (zend_ast_get_str (class_ast ));
1403
+ zend_ensure_valid_class_fetch_type (fetch_type );
1404
+
1405
+ switch (fetch_type ) {
1406
+ case ZEND_FETCH_CLASS_SELF :
1407
+ if (constant || (CG (active_class_entry ) && zend_is_scope_known ())) {
1408
+ ZVAL_STR_COPY (zv , CG (active_class_entry )-> name );
1409
+ } else {
1410
+ ZVAL_NULL (zv );
1411
+ }
1412
+ return 1 ;
1413
+ case ZEND_FETCH_CLASS_STATIC :
1414
+ case ZEND_FETCH_CLASS_PARENT :
1415
+ if (constant ) {
1416
+ zend_error_noreturn (E_COMPILE_ERROR ,
1417
+ "%s::class cannot be used for compile-time class name resolution" ,
1418
+ fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
1419
+ );
1420
+ } else {
1421
+ ZVAL_NULL (zv );
1422
+ }
1423
+ return 1 ;
1424
+ case ZEND_FETCH_CLASS_DEFAULT :
1425
+ ZVAL_STR (zv , zend_resolve_class_name_ast (class_ast ));
1426
+ return 1 ;
1427
+ EMPTY_SWITCH_DEFAULT_CASE ()
1428
+ }
1429
+ }
1430
+ /* }}} */
1431
+
1350
1432
static zend_bool zend_try_ct_eval_class_const (zval * zv , zend_string * class_name , zend_string * name ) /* {{{ */
1351
1433
{
1352
1434
uint32_t fetch_type = zend_get_class_fetch_type (class_name );
@@ -1627,41 +1709,6 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify
1627
1709
}
1628
1710
/* }}} */
1629
1711
1630
- uint32_t zend_get_class_fetch_type (zend_string * name ) /* {{{ */
1631
- {
1632
- if (zend_string_equals_literal_ci (name , "self" )) {
1633
- return ZEND_FETCH_CLASS_SELF ;
1634
- } else if (zend_string_equals_literal_ci (name , "parent" )) {
1635
- return ZEND_FETCH_CLASS_PARENT ;
1636
- } else if (zend_string_equals_literal_ci (name , "static" )) {
1637
- return ZEND_FETCH_CLASS_STATIC ;
1638
- } else {
1639
- return ZEND_FETCH_CLASS_DEFAULT ;
1640
- }
1641
- }
1642
- /* }}} */
1643
-
1644
- static uint32_t zend_get_class_fetch_type_ast (zend_ast * name_ast ) /* {{{ */
1645
- {
1646
- /* Fully qualified names are always default refs */
1647
- if (name_ast -> attr == ZEND_NAME_FQ ) {
1648
- return ZEND_FETCH_CLASS_DEFAULT ;
1649
- }
1650
-
1651
- return zend_get_class_fetch_type (zend_ast_get_str (name_ast ));
1652
- }
1653
- /* }}} */
1654
-
1655
- static void zend_ensure_valid_class_fetch_type (uint32_t fetch_type ) /* {{{ */
1656
- {
1657
- if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && !CG (active_class_entry ) && zend_is_scope_known ()) {
1658
- zend_error_noreturn (E_COMPILE_ERROR , "Cannot use \"%s\" when no class scope is active" ,
1659
- fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
1660
- fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static" );
1661
- }
1662
- }
1663
- /* }}} */
1664
-
1665
1712
ZEND_API zend_string * zend_get_compiled_variable_name (const zend_op_array * op_array , uint32_t var ) /* {{{ */
1666
1713
{
1667
1714
return op_array -> vars [EX_VAR_TO_NUM (var )];
@@ -4749,6 +4796,11 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
4749
4796
zend_string * name = zend_ast_get_str (name_ast );
4750
4797
zval value_zv ;
4751
4798
4799
+ if (zend_string_equals_literal_ci (name , "class" )) {
4800
+ zend_error (E_COMPILE_ERROR ,
4801
+ "A class constant must not be called 'class'; it is reserved for class name fetching" );
4802
+ }
4803
+
4752
4804
zend_const_expr_to_zval (& value_zv , value_ast );
4753
4805
4754
4806
name = zend_new_interned_string_safe (name );
@@ -6315,6 +6367,16 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
6315
6367
zend_op * opline ;
6316
6368
zend_string * resolved_name ;
6317
6369
6370
+ if (zend_try_compile_const_expr_resolve_class_name (& result -> u .constant , class_ast , const_ast , 0 )) {
6371
+ if (Z_TYPE (result -> u .constant ) == IS_NULL ) {
6372
+ zend_op * opline = zend_emit_op_tmp (result , ZEND_FETCH_CLASS_NAME , NULL , NULL );
6373
+ opline -> extended_value = zend_get_class_fetch_type (zend_ast_get_str (class_ast ));
6374
+ } else {
6375
+ result -> op_type = IS_CONST ;
6376
+ }
6377
+ return ;
6378
+ }
6379
+
6318
6380
zend_eval_const_expr (& class_ast );
6319
6381
zend_eval_const_expr (& const_ast );
6320
6382
@@ -6326,6 +6388,10 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
6326
6388
return ;
6327
6389
}
6328
6390
}
6391
+ if (const_ast -> kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci (zend_ast_get_str (const_ast ), "class" )) {
6392
+ zend_error_noreturn (E_COMPILE_ERROR ,
6393
+ "Dynamic class names are not allowed in compile-time ::class fetch" );
6394
+ }
6329
6395
6330
6396
if (zend_is_const_default_class_ref (class_ast )) {
6331
6397
class_node .op_type = IS_CONST ;
@@ -6538,7 +6604,7 @@ zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */
6538
6604
|| kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_DIM
6539
6605
|| kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM
6540
6606
|| kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST
6541
- || kind == ZEND_AST_RESOLVE_CLASS_NAME || kind == ZEND_AST_MAGIC_CONST ;
6607
+ || kind == ZEND_AST_MAGIC_CONST ;
6542
6608
}
6543
6609
/* }}} */
6544
6610
@@ -6557,6 +6623,11 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
6557
6623
"Dynamic class names are not allowed in compile-time class constant references" );
6558
6624
}
6559
6625
6626
+ if (zend_try_compile_const_expr_resolve_class_name (& result , class_ast , const_ast , 1 )) {
6627
+ * ast_ptr = zend_ast_create_zval (& result );
6628
+ return ;
6629
+ }
6630
+
6560
6631
class_name = zend_ast_get_str (class_ast );
6561
6632
fetch_type = zend_get_class_fetch_type (class_name );
6562
6633
@@ -6612,36 +6683,6 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */
6612
6683
}
6613
6684
/* }}} */
6614
6685
6615
- void zend_compile_const_expr_resolve_class_name (zend_ast * * ast_ptr ) /* {{{ */
6616
- {
6617
- zend_ast * ast = * ast_ptr ;
6618
- zend_ast * name_ast = ast -> child [0 ];
6619
- zval result ;
6620
- uint32_t fetch_type = zend_get_class_fetch_type (zend_ast_get_str (name_ast ));
6621
- zend_ensure_valid_class_fetch_type (fetch_type );
6622
-
6623
- switch (fetch_type ) {
6624
- case ZEND_FETCH_CLASS_SELF :
6625
- ZVAL_STR_COPY (& result , CG (active_class_entry )-> name );
6626
- break ;
6627
- case ZEND_FETCH_CLASS_STATIC :
6628
- case ZEND_FETCH_CLASS_PARENT :
6629
- zend_error_noreturn (E_COMPILE_ERROR ,
6630
- "%s::class cannot be used for compile-time class name resolution" ,
6631
- fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
6632
- );
6633
- break ;
6634
- case ZEND_FETCH_CLASS_DEFAULT :
6635
- ZVAL_STR (& result , zend_resolve_class_name_ast (name_ast ));
6636
- break ;
6637
- EMPTY_SWITCH_DEFAULT_CASE ()
6638
- }
6639
-
6640
- zend_ast_destroy (ast );
6641
- * ast_ptr = zend_ast_create_zval (& result );
6642
- }
6643
- /* }}} */
6644
-
6645
6686
void zend_compile_const_expr_magic_const (zend_ast * * ast_ptr ) /* {{{ */
6646
6687
{
6647
6688
zend_ast * ast = * ast_ptr ;
@@ -6680,9 +6721,6 @@ void zend_compile_const_expr(zend_ast **ast_ptr) /* {{{ */
6680
6721
case ZEND_AST_CONST :
6681
6722
zend_compile_const_expr_const (ast_ptr );
6682
6723
break ;
6683
- case ZEND_AST_RESOLVE_CLASS_NAME :
6684
- zend_compile_const_expr_resolve_class_name (ast_ptr );
6685
- break ;
6686
6724
case ZEND_AST_MAGIC_CONST :
6687
6725
zend_compile_const_expr_magic_const (ast_ptr );
6688
6726
break ;
@@ -6957,9 +6995,6 @@ void zend_compile_expr(znode *result, zend_ast *ast) /* {{{ */
6957
6995
case ZEND_AST_CLASS_CONST :
6958
6996
zend_compile_class_const (result , ast );
6959
6997
return ;
6960
- case ZEND_AST_RESOLVE_CLASS_NAME :
6961
- zend_compile_resolve_class_name (result , ast );
6962
- return ;
6963
6998
case ZEND_AST_ENCAPS_LIST :
6964
6999
zend_compile_encaps_list (result , ast );
6965
7000
return ;
@@ -7129,9 +7164,18 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
7129
7164
zend_ast * name_ast = ast -> child [1 ];
7130
7165
zend_string * resolved_name ;
7131
7166
7167
+ if (zend_try_compile_const_expr_resolve_class_name (& result , class_ast , name_ast , 1 )) {
7168
+ break ;
7169
+ }
7170
+
7132
7171
zend_eval_const_expr (& class_ast );
7133
7172
zend_eval_const_expr (& name_ast );
7134
7173
7174
+ if (name_ast -> kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci (zend_ast_get_str (name_ast ), "class" )) {
7175
+ zend_error_noreturn (E_COMPILE_ERROR ,
7176
+ "Dynamic class names are not allowed in compile-time ::class fetch" );
7177
+ }
7178
+
7135
7179
if (class_ast -> kind != ZEND_AST_ZVAL || name_ast -> kind != ZEND_AST_ZVAL ) {
7136
7180
return ;
7137
7181
}
0 commit comments