Skip to content

Commit f7d23a3

Browse files
committed
Fixes microsoft#8712: Bail out of tokenization if too many states are pushed and not popped
1 parent c6d4e03 commit f7d23a3

2 files changed

Lines changed: 14 additions & 2 deletions

File tree

src/vs/editor/node/textMate/TMSyntax.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {ILineTokens, IMode, ITokenizationSupport} from 'vs/editor/common/modes';
1212
import {TMState} from 'vs/editor/common/modes/TMState';
1313
import {LineTokens, Token} from 'vs/editor/common/modes/supports';
1414
import {IModeService} from 'vs/editor/common/services/modeService';
15-
import {IGrammar, Registry} from 'vscode-textmate';
15+
import {IGrammar, Registry, StackElement} from 'vscode-textmate';
1616
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
1717
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
1818

@@ -239,6 +239,15 @@ export class TMTokenDecodeData {
239239
}
240240
}
241241

242+
function depth(stackElement: StackElement): number {
243+
let result = 0;
244+
while (stackElement) {
245+
result++;
246+
stackElement = stackElement._parent;
247+
}
248+
return result;
249+
}
250+
242251
class Tokenizer {
243252
private _grammar: IGrammar;
244253
private _modeId: string;
@@ -251,7 +260,9 @@ class Tokenizer {
251260
}
252261

253262
public tokenize(line: string, state: TMState, offsetDelta: number = 0, stopAtOffset?: number): ILineTokens {
254-
if (line.length >= 20000) {
263+
// Do not attempt to tokenize if a line has over 20k
264+
// or if the rule stack contains more than 30 rules (indicator of broken grammar that forgets to pop rules)
265+
if (line.length >= 20000 || depth(state.getRuleStack()) > 30) {
255266
return new LineTokens(
256267
[new Token(offsetDelta, '')],
257268
[new ModeTransition(offsetDelta, state.getMode())],

src/vs/editor/node/textMate/vscode-textmate.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export interface IToken {
7272
*/
7373
export interface StackElement {
7474
_stackElementBrand: void;
75+
_parent: StackElement;
7576

7677
equals(other:StackElement): boolean;
7778
}

0 commit comments

Comments
 (0)