@@ -324,11 +324,87 @@ ZEND_API zval *zend_get_constant(zend_string *name)
324
324
return NULL ;
325
325
}
326
326
327
+ ZEND_API zval * zend_get_class_constant_ex (zend_string * class_name , zend_string * constant_name , zend_class_entry * scope , uint32_t flags )
328
+ {
329
+ zend_class_entry * ce = NULL ;
330
+ zend_class_constant * c = NULL ;
331
+ zval * ret_constant = NULL ;
332
+
333
+ if (ZSTR_HAS_CE_CACHE (class_name )) {
334
+ ce = ZSTR_GET_CE_CACHE (class_name );
335
+ if (!ce ) {
336
+ ce = zend_fetch_class (class_name , flags );
337
+ }
338
+ } else if (zend_string_equals_literal_ci (class_name , "self" )) {
339
+ if (UNEXPECTED (!scope )) {
340
+ zend_throw_error (NULL , "Cannot access \"self\" when no class scope is active" );
341
+ goto failure ;
342
+ }
343
+ ce = scope ;
344
+ } else if (zend_string_equals_literal_ci (class_name , "parent" )) {
345
+ if (UNEXPECTED (!scope )) {
346
+ zend_throw_error (NULL , "Cannot access \"parent\" when no class scope is active" );
347
+ goto failure ;
348
+ } else if (UNEXPECTED (!scope -> parent )) {
349
+ zend_throw_error (NULL , "Cannot access \"parent\" when current class scope has no parent" );
350
+ goto failure ;
351
+ } else {
352
+ ce = scope -> parent ;
353
+ }
354
+ } else if (zend_string_equals_literal_ci (class_name , "static" )) {
355
+ ce = zend_get_called_scope (EG (current_execute_data ));
356
+ if (UNEXPECTED (!ce )) {
357
+ zend_throw_error (NULL , "Cannot access \"static\" when no class scope is active" );
358
+ goto failure ;
359
+ }
360
+ } else {
361
+ ce = zend_fetch_class (class_name , flags );
362
+ }
363
+ if (ce ) {
364
+ c = zend_hash_find_ptr (CE_CONSTANTS_TABLE (ce ), constant_name );
365
+ if (c == NULL ) {
366
+ if ((flags & ZEND_FETCH_CLASS_SILENT ) == 0 ) {
367
+ zend_throw_error (NULL , "Undefined constant %s::%s" , ZSTR_VAL (class_name ), ZSTR_VAL (constant_name ));
368
+ goto failure ;
369
+ }
370
+ ret_constant = NULL ;
371
+ } else {
372
+ if (!zend_verify_const_access (c , scope )) {
373
+ if ((flags & ZEND_FETCH_CLASS_SILENT ) == 0 ) {
374
+ zend_throw_error (NULL , "Cannot access %s constant %s::%s" , zend_visibility_string (Z_ACCESS_FLAGS (c -> value )), ZSTR_VAL (class_name ), ZSTR_VAL (constant_name ));
375
+ }
376
+ goto failure ;
377
+ }
378
+ ret_constant = & c -> value ;
379
+ }
380
+ }
381
+
382
+ if (ret_constant && Z_TYPE_P (ret_constant ) == IS_CONSTANT_AST ) {
383
+ zend_result ret ;
384
+
385
+ if (IS_CONSTANT_VISITED (ret_constant )) {
386
+ zend_throw_error (NULL , "Cannot declare self-referencing constant %s::%s" , ZSTR_VAL (class_name ), ZSTR_VAL (constant_name ));
387
+ ret_constant = NULL ;
388
+ goto failure ;
389
+ }
390
+
391
+ MARK_CONSTANT_VISITED (ret_constant );
392
+ ret = zval_update_constant_ex (ret_constant , c -> ce );
393
+ RESET_CONSTANT_VISITED (ret_constant );
394
+
395
+ if (UNEXPECTED (ret != SUCCESS )) {
396
+ ret_constant = NULL ;
397
+ goto failure ;
398
+ }
399
+ }
400
+ failure :
401
+ return ret_constant ;
402
+ }
403
+
327
404
ZEND_API zval * zend_get_constant_ex (zend_string * cname , zend_class_entry * scope , uint32_t flags )
328
405
{
329
406
zend_constant * c ;
330
407
const char * colon ;
331
- zend_class_entry * ce = NULL ;
332
408
const char * name = ZSTR_VAL (cname );
333
409
size_t name_len = ZSTR_LEN (cname );
334
410
@@ -344,7 +420,14 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
344
420
int class_name_len = colon - name - 1 ;
345
421
size_t const_name_len = name_len - class_name_len - 2 ;
346
422
zend_string * constant_name = zend_string_init (colon + 1 , const_name_len , 0 );
347
- zend_string * class_name = zend_string_init (name , class_name_len , 0 );
423
+ zend_string * class_name = zend_string_init_interned (name , class_name_len , 0 );
424
+ zval * ret_constant = zend_get_class_constant_ex (class_name , constant_name , scope , flags );
425
+
426
+ zend_string_release_ex (class_name , 0 );
427
+ zend_string_efree (constant_name );
428
+ return ret_constant ;
429
+ /*
430
+ zend_class_entry *ce = NULL;
348
431
zend_class_constant *c = NULL;
349
432
zval *ret_constant = NULL;
350
433
@@ -414,6 +497,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
414
497
zend_string_release_ex(class_name, 0);
415
498
zend_string_efree(constant_name);
416
499
return ret_constant;
500
+ */
417
501
}
418
502
419
503
/* non-class constant */
0 commit comments