Skip to content

Commit bed2d0c

Browse files
committed
Update constants and check abstract classes
1 parent 3187a21 commit bed2d0c

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
PhpToken extensions that throw during construction
3+
--FILE--
4+
<?php
5+
6+
class MyPhpToken1 extends PhpToken {
7+
public $extra = UNKNOWN;
8+
}
9+
10+
try {
11+
var_dump(MyPhpToken1::getAll("<?php foo"));
12+
} catch (Error $e) {
13+
echo $e->getMessage(), "\n";
14+
}
15+
16+
abstract class MyPhpToken2 extends PhpToken {
17+
}
18+
19+
try {
20+
var_dump(MyPhpToken2::getAll("<?php foo"));
21+
} catch (Error $e) {
22+
echo $e->getMessage(), "\n";
23+
}
24+
25+
?>
26+
--EXPECT--
27+
Undefined constant 'UNKNOWN'
28+
Cannot instantiate abstract class MyPhpToken2

ext/tokenizer/tokenizer.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ PHP_METHOD(PhpToken, getAll)
116116
ZEND_PARSE_PARAMETERS_END();
117117

118118
token_class = zend_get_called_scope(execute_data);
119+
120+
/* Check construction preconditions in advance, so these are not repeated for each token. */
121+
if (token_class->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) {
122+
zend_throw_error(NULL, "Cannot instantiate abstract class %s", ZSTR_VAL(token_class->name));
123+
RETURN_THROWS();
124+
}
125+
if (zend_update_class_constants(token_class) == FAILURE) {
126+
RETURN_THROWS();
127+
}
128+
119129
if (!tokenize_common(return_value, source, flags, token_class)) {
120130
RETURN_THROWS();
121131
}

0 commit comments

Comments
 (0)