Pop stack when rule is pushed without position advancement

Previously only the scope name was checked which allowed cases
were rules without scope names to grow the stack infinitely without
advancing the position.

Closes atom/language-ruby-on-rails#1
This commit is contained in:
Kevin Sawicki 2013-12-04 15:16:53 -08:00
parent 31a909828d
commit 8af0a59c52
2 changed files with 20 additions and 3 deletions

View File

@ -635,11 +635,9 @@ describe "TextMateGrammar", ->
expect(lastToken.value).toEqual ';'
describe "HTML (Ruby - ERB)", ->
beforeEach ->
it "correctly parses strings inside tags", ->
grammar = atom.syntax.selectGrammar('page.erb')
lines = grammar.tokenizeLines '<% page_title "My Page" %>'
it "correctly parses strings inside tags", ->
tokens = lines[0]
expect(tokens[2].value).toEqual '"'
@ -649,6 +647,16 @@ describe "TextMateGrammar", ->
expect(tokens[4].value).toEqual '"'
expect(tokens[4].scopes).toEqual ["text.html.erb", "meta.embedded.line.erb", "string.quoted.double.ruby", "punctuation.definition.string.end.ruby"]
it "does not loop infinitely on <%>", ->
atom.packages.activatePackage('language-html', sync: true)
atom.packages.activatePackage('language-ruby-on-rails', sync: true)
grammar = atom.syntax.selectGrammar('foo.html.erb')
[tokens] = grammar.tokenizeLines '<%>'
expect(tokens.length).toBe 1
expect(tokens[0].value).toEqual '<%>'
expect(tokens[0].scopes).toEqual ["text.html.erb"]
describe "Unicode support", ->
describe "Surrogate pair characters", ->
beforeEach ->

View File

@ -157,7 +157,16 @@ class TextMateGrammar
ruleStack.pop()
else if ruleStack.length > previousRuleStackLength # Stack size increased with zero length match
[penultimateRule, lastRule] = ruleStack[-2..]
# Same exact rule was pushed but position wasn't advanced
if lastRule? and lastRule == penultimateRule
popStack = true
# Rule with same scope name as previous rule was pushed but position wasn't advanced
if lastRule?.scopeName? and penultimateRule.scopeName == lastRule.scopeName
popStack = true
if popStack
ruleStack.pop()
tokens.push(new Token(
value: line[position...line.length]