mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-10 10:17:11 +03:00
Pop grammar rules that result in infinite loops
This commit is contained in:
parent
266c305ebb
commit
84fe0a384d
@ -258,3 +258,13 @@ describe "TextMateGrammar", ->
|
||||
{tokens, ruleStack} = grammar.tokenizeLine("if(1){if(1){m()}}")
|
||||
expect(tokens[5]).toEqual value: "if", scopes: ["source.c", "meta.block.c", "keyword.control.c"]
|
||||
expect(tokens[10]).toEqual value: "m", scopes: ["source.c", "meta.block.c", "meta.block.c", "meta.function-call.c", "support.function.any-method.c"]
|
||||
|
||||
describe "when the grammar can infinitely loop over a line", ->
|
||||
it "aborts tokenization", ->
|
||||
spyOn(console, 'error')
|
||||
window.loadPackage("package-with-infinite-loop-grammar")
|
||||
grammar = syntax.grammarForFilePath("something.package-with-infinite-loop-grammar")
|
||||
{tokens} = grammar.tokenizeLine("abc")
|
||||
expect(tokens[0].value).toBe "a"
|
||||
expect(tokens[1].value).toBe "bc"
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
|
18
spec/fixtures/packages/package-with-infinite-loop-grammar/grammars/grammar.cson
vendored
Normal file
18
spec/fixtures/packages/package-with-infinite-loop-grammar/grammars/grammar.cson
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
'fileTypes': ['package-with-infinite-loop-grammar']
|
||||
'name': 'package-with-infinite-loop-grammar'
|
||||
'scopeName': 'source.package-with-infinite-loop-grammar'
|
||||
|
||||
# This grammar should loop forever if the line contains an `a`
|
||||
'patterns': [
|
||||
{
|
||||
'name': 'start'
|
||||
'begin': '^'
|
||||
'end': '$'
|
||||
'patterns': [
|
||||
{
|
||||
name: 'negative-look-ahead'
|
||||
match: "(?!a)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -31,9 +31,10 @@ class TextMateGrammar
|
||||
ruleStack = new Array(ruleStack...) # clone ruleStack
|
||||
tokens = []
|
||||
position = 0
|
||||
|
||||
loop
|
||||
scopes = scopesFromStack(ruleStack)
|
||||
previousRuleStackLength = ruleStack.length
|
||||
previousPosition = position
|
||||
|
||||
if line.length == 0
|
||||
tokens = [new Token(value: "", scopes: scopes)]
|
||||
@ -61,6 +62,10 @@ class TextMateGrammar
|
||||
))
|
||||
break
|
||||
|
||||
if position == previousPosition and ruleStack.length == previousRuleStackLength
|
||||
console.error("Popping rule because it loops at column #{position} of line '#{line}'", _.clone(ruleStack))
|
||||
ruleStack.pop()
|
||||
|
||||
ruleStack.forEach (rule) -> rule.clearAnchorPosition()
|
||||
{ tokens, ruleStack }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user