Skip to content

Commit 2bba4a0

Browse files
committed
Fix bug #69676
1 parent f3ab4c1 commit 2bba4a0

File tree

7 files changed

+101
-7
lines changed

7 files changed

+101
-7
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ PHP NEWS
88
USE_ZEND_ALLOC=0). (Nikita)
99
. Fixed bug #73960 (Leak with instance method calling static method with
1010
referenced return). (Nikita)
11+
. Fixed bug #69676 (Resolution of self::FOO in class constants not correct).
12+
(Nikita)
1113

1214
- Date:
1315
. Fixed bug #72096 (Swatch time value incorrect for dates before 1970). (mcq8)

Zend/tests/bug69676_2.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Bug #69676: Resolution of self::FOO in class constants not correct (variation)
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
const A = 'Foo::A';
8+
const B = self::A . ' and ' . self::C;
9+
const C = 'Foo::C';
10+
11+
}
12+
13+
class Bar extends Foo {
14+
const A = 'Bar::A';
15+
const C = 'Bar::C';
16+
}
17+
18+
var_dump(Bar::B);
19+
20+
?>
21+
--EXPECT--
22+
string(17) "Foo::A and Foo::C"

Zend/tests/bug69676_3.phpt

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
--TEST--
2+
Bug #69676: Resolution of self::FOO in class constants not correct (variation)
3+
--FILE--
4+
<?php
5+
6+
class P {
7+
const N = 'P';
8+
}
9+
class A extends P {
10+
const selfN = self::N;
11+
const parentN = parent::N;
12+
const N = 'A';
13+
}
14+
class B extends A {
15+
const N = 'B';
16+
}
17+
18+
var_dump(B::selfN); // A
19+
var_dump(B::parentN); // P
20+
21+
class A2 {
22+
const selfN = self::N;
23+
const N = 'A2';
24+
}
25+
class B2 extends A2 {
26+
const indSelfN = self::selfN;
27+
const N = 'B2';
28+
}
29+
class C2 extends B2 {
30+
const N = 'C2';
31+
}
32+
33+
var_dump(C2::indSelfN); // A2
34+
35+
class A3 {
36+
const selfN = self::N;
37+
const N = 'A3';
38+
}
39+
class B3 extends A3 {
40+
const exprSelfN = "expr" . self::selfN;
41+
const N = 'B3';
42+
}
43+
class C3 extends B3 {
44+
const N = 'C3';
45+
}
46+
47+
var_dump(C3::exprSelfN); // exprA3
48+
49+
class A4 {
50+
const selfN = self::N;
51+
const N = 'A4';
52+
}
53+
class B4 extends A4 {
54+
const N = 'B4';
55+
public $prop = self::selfN;
56+
}
57+
class C4 extends B4 {
58+
const N = 'C4';
59+
}
60+
61+
var_dump((new C4)->prop); // A4
62+
63+
?>
64+
--EXPECT--
65+
string(1) "A"
66+
string(1) "P"
67+
string(2) "A2"
68+
string(6) "exprA3"
69+
string(2) "A4"

Zend/zend_API.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
11321132
ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) {
11331133
val = &c->value;
11341134
if (Z_CONSTANT_P(val)) {
1135-
if (UNEXPECTED(zval_update_constant_ex(val, class_type) != SUCCESS)) {
1135+
if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) {
11361136
return FAILURE;
11371137
}
11381138
}

Zend/zend_constants.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
327327
size_t const_name_len = name_len - class_name_len - 2;
328328
zend_string *constant_name = zend_string_init(colon + 1, const_name_len, 0);
329329
zend_string *class_name = zend_string_init(name, class_name_len, 0);
330+
zend_class_constant *c = NULL;
330331
zval *ret_constant = NULL;
331332

332333
if (zend_string_equals_literal_ci(class_name, "self")) {
@@ -355,7 +356,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
355356
ce = zend_fetch_class(class_name, flags);
356357
}
357358
if (ce) {
358-
zend_class_constant *c = zend_hash_find_ptr(&ce->constants_table, constant_name);
359+
c = zend_hash_find_ptr(&ce->constants_table, constant_name);
359360
if (c == NULL) {
360361
if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
361362
zend_throw_error(NULL, "Undefined class constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
@@ -380,7 +381,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
380381
}
381382
MARK_CONSTANT_VISITED(ret_constant);
382383
}
383-
if (UNEXPECTED(zval_update_constant_ex(ret_constant, ce) != SUCCESS)) {
384+
if (UNEXPECTED(zval_update_constant_ex(ret_constant, c->ce) != SUCCESS)) {
384385
RESET_CONSTANT_VISITED(ret_constant);
385386
ret_constant = NULL;
386387
goto failure;

Zend/zend_vm_def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5191,7 +5191,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
51915191
}
51925192
value = &c->value;
51935193
if (Z_CONSTANT_P(value)) {
5194-
zval_update_constant_ex(value, ce);
5194+
zval_update_constant_ex(value, c->ce);
51955195
if (UNEXPECTED(EG(exception) != NULL)) {
51965196
HANDLE_EXCEPTION();
51975197
}

Zend/zend_vm_execute.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5797,7 +5797,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
57975797
}
57985798
value = &c->value;
57995799
if (Z_CONSTANT_P(value)) {
5800-
zval_update_constant_ex(value, ce);
5800+
zval_update_constant_ex(value, c->ce);
58015801
if (UNEXPECTED(EG(exception) != NULL)) {
58025802
HANDLE_EXCEPTION();
58035803
}
@@ -19985,7 +19985,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
1998519985
}
1998619986
value = &c->value;
1998719987
if (Z_CONSTANT_P(value)) {
19988-
zval_update_constant_ex(value, ce);
19988+
zval_update_constant_ex(value, c->ce);
1998919989
if (UNEXPECTED(EG(exception) != NULL)) {
1999019990
HANDLE_EXCEPTION();
1999119991
}
@@ -29790,7 +29790,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
2979029790
}
2979129791
value = &c->value;
2979229792
if (Z_CONSTANT_P(value)) {
29793-
zval_update_constant_ex(value, ce);
29793+
zval_update_constant_ex(value, c->ce);
2979429794
if (UNEXPECTED(EG(exception) != NULL)) {
2979529795
HANDLE_EXCEPTION();
2979629796
}

0 commit comments

Comments
 (0)