Skip to content

Commit 74e2bd4

Browse files
committed
Better protect against collisions
1 parent 14b5822 commit 74e2bd4

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

src/Util/Tokens.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,15 +977,38 @@ public static function polyfillTokenizerConstants(): void
977977
// numbering scheme from 135_000.
978978
$nextTokenNumber = 135000;
979979

980+
// This variable is necessary to avoid collisions with any other
981+
// libraries which also polyfill T_* constants.
982+
// array_flip()/isset() because in_array() is slow.
983+
$existingConstants = array_flip(get_defined_constants(true)['tokenizer']);
984+
foreach ((get_defined_constants(true)['user'] ?? []) as $k => $v) {
985+
if (isset($k[2]) === false || $k[0] !== 'T' || $k[1] !== '_') {
986+
// We only care about T_* constants.
987+
continue;
988+
}
989+
990+
if (isset($existingConstants[$v]) === true) {
991+
throw new \Exception("Externally polyfilled tokenizer constant value collision detected! $k has the same value as {$existingConstants[$v]}");
992+
}
993+
994+
$existingConstants[$v] = $k;
995+
}
996+
980997
$polyfillMappingTable = [];
981998

982999
foreach ($tokensToPolyfill as $tokenName) {
1000+
if (isset(get_defined_constants(true)['tokenizer'][$tokenName]) === true) {
1001+
// This is a PHP native token, which is already defined by PHP.
1002+
continue;
1003+
}
1004+
9831005
if (defined($tokenName) === false) {
984-
while (isset($polyfillMappingTable[$nextTokenNumber]) === true) {
1006+
while (isset($existingConstants[$nextTokenNumber]) === true) {
9851007
$nextTokenNumber++;
9861008
}
9871009

9881010
define($tokenName, $nextTokenNumber);
1011+
$existingConstants[$nextTokenNumber] = $tokenName;
9891012
}
9901013

9911014
$polyfillMappingTable[constant($tokenName)] = $tokenName;

0 commit comments

Comments
 (0)