Skip to content

Commit 32169bc

Browse files
committed
Fix hang when tokenizing PHP
Fix microsoft#75468
1 parent 7e03eb1 commit 32169bc

2 files changed

Lines changed: 28 additions & 4 deletions

File tree

extensions/php/build/update-grammar.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,40 @@ function adaptInjectionScope(grammar) {
2323
// Workaround for https://github.com/Microsoft/vscode/issues/40279
2424
// and https://github.com/Microsoft/vscode-textmate/issues/59
2525
function fixBadRegex(grammar) {
26+
function fail(msg) {
27+
throw new Error(`fixBadRegex callback couldn't patch ${msg}. It may be obsolete`);
28+
}
29+
2630
const scopeResolution = grammar.repository['scope-resolution'];
2731
if (scopeResolution) {
2832
const match = scopeResolution.patterns[0].match;
2933
if (match === '(?i)([a-z_\\x{7f}-\\x{7fffffff}\\\\][a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]*)(?=\\s*::)') {
3034
scopeResolution.patterns[0].match = '([A-Za-z_\\x{7f}-\\x{7fffffff}\\\\][A-Za-z0-9_\\x{7f}-\\x{7fffffff}\\\\]*)(?=\\s*::)';
31-
return;
35+
} else {
36+
fail('scope-resolution.match');
3237
}
38+
} else {
39+
fail('scope-resolution');
3340
}
3441

35-
throw new Error(`fixBadRegex callback couldn't patch the regex. It may be obsolete`);
42+
const functionCall = grammar.repository['function-call'];
43+
if (functionCall) {
44+
const begin0 = functionCall.patterns[0].begin;
45+
if (begin0 === '(?xi)\n(\n \\\\?(?<![a-z0-9_\\x{7f}-\\x{7fffffff}]) # Optional root namespace\n [a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]* # First namespace\n (?:\\\\[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)+ # Additional namespaces\n)\\s*(\\()') {
46+
functionCall.patterns[0].begin = '(?x)\n(\n \\\\?(?<![a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]) # Optional root namespace\n [a-zA-Z_\\x{7f}-\\x{7fffffff}][a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]* # First namespace\n (?:\\\\[a-zA-Z_\\x{7f}-\\x{7fffffff}][a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]*)+ # Additional namespaces\n)\\s*(\\()';
47+
} else {
48+
fail('function-call.begin0');
49+
}
50+
51+
const begin1 = functionCall.patterns[1].begin;
52+
if (begin1 === '(?i)(\\\\)?(?<![a-z0-9_\\x{7f}-\\x{7fffffff}])([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)\\s*(\\()') {
53+
functionCall.patterns[1].begin = '(\\\\)?(?<![a-zA-Z0-9_\\x{7f}-\\x{7fffffff}])([a-zA-Z_\\x{7f}-\\x{7fffffff}][a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]*)\\s*(\\()';
54+
} else {
55+
fail('function-call.begin1');
56+
}
57+
} else {
58+
fail('function-call');
59+
}
3660
}
3761

3862
updateGrammar.update('atom/language-php', 'grammars/php.cson', './syntaxes/php.tmLanguage.json', fixBadRegex);

extensions/php/syntaxes/php.tmLanguage.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@
12071207
"function-call": {
12081208
"patterns": [
12091209
{
1210-
"begin": "(?xi)\n(\n \\\\?(?<![a-z0-9_\\x{7f}-\\x{7fffffff}]) # Optional root namespace\n [a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]* # First namespace\n (?:\\\\[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)+ # Additional namespaces\n)\\s*(\\()",
1210+
"begin": "(?x)\n(\n \\\\?(?<![a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]) # Optional root namespace\n [a-zA-Z_\\x{7f}-\\x{7fffffff}][a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]* # First namespace\n (?:\\\\[a-zA-Z_\\x{7f}-\\x{7fffffff}][a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]*)+ # Additional namespaces\n)\\s*(\\()",
12111211
"beginCaptures": {
12121212
"1": {
12131213
"patterns": [
@@ -1238,7 +1238,7 @@
12381238
]
12391239
},
12401240
{
1241-
"begin": "(?i)(\\\\)?(?<![a-z0-9_\\x{7f}-\\x{7fffffff}])([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)\\s*(\\()",
1241+
"begin": "(\\\\)?(?<![a-zA-Z0-9_\\x{7f}-\\x{7fffffff}])([a-zA-Z_\\x{7f}-\\x{7fffffff}][a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]*)\\s*(\\()",
12421242
"beginCaptures": {
12431243
"1": {
12441244
"patterns": [

0 commit comments

Comments
 (0)