Skip to content

Commit 4e2f826

Browse files
committed
Better protect against collisions
1 parent 7c87f95 commit 4e2f826

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

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

977994
foreach ($tokensToPolyfill as $tokenName) {
995+
if (isset(get_defined_constants(true)['tokenizer'][$tokenName]) === true) {
996+
// This is a PHP native token, which is already defined by PHP.
997+
continue;
998+
}
999+
9781000
if (defined($tokenName) === false) {
979-
while (isset($polyfillMappingTable[$nextTokenNumber]) === true) {
1001+
while (isset($existingConstants[$nextTokenNumber]) === true) {
9801002
$nextTokenNumber++;
9811003
}
9821004

9831005
define($tokenName, $nextTokenNumber);
1006+
$existingConstants[$nextTokenNumber] = $tokenName;
9841007
}
9851008

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

0 commit comments

Comments
 (0)