Whe checking for an endless loop, look through all stack elements entered at the same position

This commit is contained in:
Alexandru Dima 2021-01-29 14:31:53 +01:00
Родитель 0906b05c84
Коммит 5146f83e79
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 6E58D7B045760DA0
1 изменённых файлов: 6 добавлений и 17 удалений

Просмотреть файл

@ -961,7 +961,7 @@ function _tokenizeString(grammar: Grammar, lineText: OnigString, isFirstLine: bo
stack = stack.setEndRule(pushedRule.getEndWithResolvedBackReferences(lineText.content, captureIndices));
}
if (stack.hasEndlessLoop(anchorPosition)) {
if (!hasAdvanced && beforePush.hasSameRuleAs(stack)) {
// Grammar pushed the same rule without advancing
if (DebugFlags.InDebugMode) {
console.error('[2] - Grammar is in an endless loop - Grammar pushed the same rule without advancing');
@ -988,7 +988,7 @@ function _tokenizeString(grammar: Grammar, lineText: OnigString, isFirstLine: bo
stack = stack.setEndRule(pushedRule.getWhileWithResolvedBackReferences(lineText.content, captureIndices));
}
if (stack.hasEndlessLoop(anchorPosition)) {
if (!hasAdvanced && beforePush.hasSameRuleAs(stack)) {
// Grammar pushed the same rule without advancing
if (DebugFlags.InDebugMode) {
console.error('[3] - Grammar is in an endless loop - Grammar pushed the same rule without advancing');
@ -1434,23 +1434,12 @@ export class StackElement implements StackElementDef {
}
public hasSameRuleAs(other: StackElement): boolean {
return this.ruleId === other.ruleId;
}
public hasEndlessLoop(anchorPosition: number): boolean {
if (anchorPosition === -1) {
// method is unavailable
return true;
}
let se = this as StackElement;
while (anchorPosition === se._anchorPos && se.parent !== null) {
se = se.parent;
if (this.hasSameRuleAs(se)) {
// endless loop detected
let el: StackElement | null = this;
while (el && el._enterPos === other._enterPos) {
if (el.ruleId === other.ruleId) {
return true;
}
el = el.parent;
}
return false;
}