Skip to content

Commit a06723e

Browse files
committed
add more tests and fix a memory leak
1 parent 05686a2 commit a06723e

File tree

9 files changed

+128
-11
lines changed

9 files changed

+128
-11
lines changed

Zend/tests/errmsg/errmsg_027.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ class test {
1313
echo "Done\n";
1414
?>
1515
--EXPECTF--
16-
Fatal error: Class declarations may not be nested in %s on line %d
16+
Fatal error: Class declarations may not be declared inside functions in %s on line %d

Zend/zend_namespaces.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ static zend_class_entry *insert_namespace(const zend_string *name) {
3939
const char *pos = start;
4040
size_t len = 0;
4141

42-
while (pos < end) {
43-
if (*pos == '\\') {
42+
while (pos <= end) {
43+
if (pos == end || *pos == '\\') {
4444
len = pos - start;
4545
zend_string *needle = zend_string_init(ZSTR_VAL(name), len, 0);
4646

@@ -51,8 +51,14 @@ static zend_class_entry *insert_namespace(const zend_string *name) {
5151
ns = create_namespace(interned_name);
5252
ns->lexical_scope = parent_ns;
5353
zend_hash_add_ptr(EG(namespaces), interned_name, ns);
54+
55+
/* sometimes, opcache refuses to intern the string */
56+
if (interned_name == needle) {
57+
zend_string_release(interned_name);
58+
}
59+
} else {
60+
zend_string_release(needle);
5461
}
55-
zend_string_release(needle);
5662

5763
parent_ns = ns;
5864
}
@@ -96,9 +102,10 @@ zend_class_entry *zend_lookup_namespace(zend_string *name) {
96102
}
97103

98104
void zend_destroy_namespaces(void) {
99-
zend_hash_destroy(EG(namespaces));
100-
FREE_HASHTABLE(EG(namespaces));
101-
EG(namespaces) = NULL;
102-
pefree(EG(global_namespace), 0);
103-
EG(global_namespace) = NULL;
105+
if (EG(namespaces) != NULL) {
106+
zend_hash_destroy(EG(namespaces));
107+
FREE_HASHTABLE(EG(namespaces));
108+
EG(namespaces) = NULL;
109+
EG(global_namespace) = NULL;
110+
}
104111
}

Zend/zend_opcode.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ ZEND_API void destroy_zend_class(zval *zv)
432432
}
433433
break;
434434
case ZEND_INTERNAL_CLASS:
435+
case ZEND_NAMESPACE_CLASS:
435436
if (ce->doc_comment) {
436437
zend_string_release_ex(ce->doc_comment, 1);
437438
}
@@ -527,7 +528,11 @@ ZEND_API void destroy_zend_class(zval *zv)
527528
if (ce->attributes) {
528529
zend_hash_release(ce->attributes);
529530
}
530-
free(ce);
531+
if (ce->type == ZEND_NAMESPACE_CLASS) {
532+
pefree(ce, 0);
533+
} else {
534+
free(ce);
535+
}
531536
break;
532537
}
533538
}

ext/reflection/tests/bug74454.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ function load_file() {
1414
}
1515
?>
1616
--EXPECT--
17-
ParseError: syntax error, unexpected token "if", expecting "function"
17+
ParseError: syntax error, unexpected token "if", expecting "class"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
nested inside function
3+
--FILE--
4+
<?php
5+
6+
class Outer {
7+
public function test() {
8+
class Inner {}
9+
}
10+
}
11+
?>
12+
--EXPECTF--
13+
Fatal error: Class declarations may not be declared inside functions in %s on line %d
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
basic nested classes
3+
--FILE--
4+
<?php
5+
6+
namespace Foo;
7+
8+
class Outer {
9+
class Middle {
10+
class Inner {
11+
public function test() {
12+
echo __CLASS__;
13+
}
14+
}
15+
}
16+
}
17+
new Outer\Middle\Inner()->test();
18+
?>
19+
--EXPECT--
20+
Foo\Outer\Middle\Inner
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
scope resolution access
3+
--FILE--
4+
<?php
5+
6+
class Outer {
7+
public class Middle {
8+
}
9+
public static function testSelf(): Middle {
10+
return new Middle();
11+
}
12+
}
13+
14+
class Outer2 extends Outer {
15+
public class Middle extends Outer\Middle {
16+
}
17+
18+
public static function testParent(): Outer\Middle {
19+
return new Outer\Middle();
20+
}
21+
22+
public static function testSelf(): Middle {
23+
return new Middle();
24+
}
25+
}
26+
27+
var_dump(Outer::testSelf());
28+
var_dump(Outer2::testParent());
29+
var_dump(Outer2::testSelf());
30+
31+
?>
32+
--EXPECT--
33+
object(Outer\Middle)#1 (0) {
34+
}
35+
object(Outer\Middle)#1 (0) {
36+
}
37+
object(Outer2\Middle)#1 (0) {
38+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
failed inheritance
3+
--FILE--
4+
<?php
5+
6+
class Outer {
7+
public class Middle {
8+
}
9+
public static function testSelf(): Middle {
10+
return new Middle();
11+
}
12+
}
13+
14+
class Outer2 extends Outer {
15+
public class Middle {
16+
}
17+
18+
public static function testParent(): Outer\Middle {
19+
return new Outer\Middle();
20+
}
21+
22+
public static function testSelf(): Middle {
23+
return new Middle();
24+
}
25+
}
26+
27+
var_dump(Outer::testSelf());
28+
var_dump(Outer2::testParent());
29+
var_dump(Outer2::testSelf());
30+
var_dump(Outer2::testSelf());
31+
32+
?>
33+
--EXPECTF--
34+
Fatal error: Declaration of Outer2::testSelf(): Outer2\middle must be compatible with Outer::testSelf(): Outer\middle in %s on line %d

0 commit comments

Comments
 (0)