Skip to content

Commit 7b972cb

Browse files
committed
Better protect against collisions
1 parent af09543 commit 7b972cb

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
@@ -976,15 +976,38 @@ public static function polyfillTokenizerConstants(): void
976976
// numbering scheme from 135_000.
977977
$nextTokenNumber = 135000;
978978

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

981998
foreach ($tokensToPolyfill as $tokenName) {
999+
if (isset(get_defined_constants(true)['tokenizer'][$tokenName]) === true) {
1000+
// This is a PHP native token, which is already defined by PHP.
1001+
continue;
1002+
}
1003+
9821004
if (defined($tokenName) === false) {
983-
while (isset($polyfillMappingTable[$nextTokenNumber]) === true) {
1005+
while (isset($existingConstants[$nextTokenNumber]) === true) {
9841006
$nextTokenNumber++;
9851007
}
9861008

9871009
define($tokenName, $nextTokenNumber);
1010+
$existingConstants[$nextTokenNumber] = $tokenName;
9881011
}
9891012

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

0 commit comments

Comments
 (0)