|
28 | 28 | #include "zend_globals.h" |
29 | 29 | #include "zend_API.h" |
30 | 30 |
|
| 31 | +/* Protection from recursive self-referencing class constants */ |
| 32 | +#define IS_CONSTANT_VISITED_MARK 0x80 |
| 33 | + |
| 34 | +#define IS_CONSTANT_VISITED(zv) (Z_ACCESS_FLAGS_P(zv) & IS_CONSTANT_VISITED_MARK) |
| 35 | +#define MARK_CONSTANT_VISITED(zv) Z_ACCESS_FLAGS_P(zv) |= IS_CONSTANT_VISITED_MARK |
| 36 | +#define RESET_CONSTANT_VISITED(zv) Z_ACCESS_FLAGS_P(zv) &= ~IS_CONSTANT_VISITED_MARK |
| 37 | + |
31 | 38 | void free_zend_constant(zval *zv) |
32 | 39 | { |
33 | 40 | zend_constant *c = Z_PTR_P(zv); |
@@ -353,20 +360,22 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, |
353 | 360 | } |
354 | 361 |
|
355 | 362 | if (ret_constant && Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) { |
356 | | - if (Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) { |
357 | | - if (IS_CONSTANT_VISITED(ret_constant)) { |
358 | | - zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); |
359 | | - ret_constant = NULL; |
360 | | - goto failure; |
361 | | - } |
362 | | - MARK_CONSTANT_VISITED(ret_constant); |
363 | | - } |
364 | | - if (UNEXPECTED(zval_update_constant_ex(ret_constant, c->ce) != SUCCESS)) { |
365 | | - RESET_CONSTANT_VISITED(ret_constant); |
| 363 | + int ret; |
| 364 | + |
| 365 | + if (IS_CONSTANT_VISITED(ret_constant)) { |
| 366 | + zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); |
366 | 367 | ret_constant = NULL; |
367 | 368 | goto failure; |
368 | 369 | } |
| 370 | + |
| 371 | + MARK_CONSTANT_VISITED(ret_constant); |
| 372 | + ret = zval_update_constant_ex(ret_constant, c->ce); |
369 | 373 | RESET_CONSTANT_VISITED(ret_constant); |
| 374 | + |
| 375 | + if (UNEXPECTED(ret != SUCCESS)) { |
| 376 | + ret_constant = NULL; |
| 377 | + goto failure; |
| 378 | + } |
370 | 379 | } |
371 | 380 | failure: |
372 | 381 | zend_string_release(class_name); |
|
0 commit comments