Skip to content

Commit

Permalink
Prevent infinite loop in TestRegExp (#213)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma authored Dec 1, 2021
1 parent 1488954 commit e01444a
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 54 deletions.
112 changes: 58 additions & 54 deletions src/Esprima/Scanner.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Numerics;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -888,10 +888,10 @@ static string SafeSubstring(string s, int startIndex, int length)
// https://tc39.github.io/ecma262/#sec-literals-numeric-literals

public Token ScanHexLiteral(int start)
{
{
var sb = GetStringBuilder();
this.ScanLiteralPart(sb, Character.IsHexDigit);
var number = sb.ToString();
var number = sb.ToString();

if (number.Length == 0)
{
Expand Down Expand Up @@ -948,11 +948,11 @@ public Token ScanHexLiteral(int start)
}

public Token ScanBinaryLiteral(int start)
{
{
char ch;
var sb = GetStringBuilder();
this.ScanLiteralPart(sb, c => c == '0' || c == '1');
var number = sb.ToString();
var number = sb.ToString();

if (number.Length == 0)
{
Expand Down Expand Up @@ -995,8 +995,8 @@ public Token ScanOctalLiteral(char prefix, int start)
else
{
++Index;
}

}

this.ScanLiteralPart(sb, Character.IsOctalDigit);
var number = sb.ToString();

Expand Down Expand Up @@ -1056,37 +1056,37 @@ public bool IsImplicitOctalLiteral()
}

private void ScanLiteralPart(StringBuilder sb, Func<char, bool> check)
{
var charCode = Source.CharCodeAt(Index);
if (charCode == '_')
{
ThrowUnexpectedToken(Messages.NumericSeperatorNotAllowedHere);
}

while ((check(charCode) || charCode == '_'))
{
if (charCode != '_')
{
sb.Append(charCode);
}
Index++;
var newCharCode = Source.CharCodeAt(Index);
if (charCode == '_' && newCharCode == '_')
{
ThrowUnexpectedToken(Messages.NumericSeperatorOneUnderscore);
}

if (Eof())
{
break;
}
charCode = newCharCode;
}

if (charCode == '_')
{
ThrowUnexpectedToken(Messages.NumericSeperatorNotAllowedHere);
}
{
var charCode = Source.CharCodeAt(Index);
if (charCode == '_')
{
ThrowUnexpectedToken(Messages.NumericSeperatorNotAllowedHere);
}

while ((check(charCode) || charCode == '_'))
{
if (charCode != '_')
{
sb.Append(charCode);
}
Index++;
var newCharCode = Source.CharCodeAt(Index);
if (charCode == '_' && newCharCode == '_')
{
ThrowUnexpectedToken(Messages.NumericSeperatorOneUnderscore);
}

if (Eof())
{
break;
}
charCode = newCharCode;
}

if (charCode == '_')
{
ThrowUnexpectedToken(Messages.NumericSeperatorNotAllowedHere);
}
}

public Token ScanNumericLiteral()
Expand Down Expand Up @@ -1141,7 +1141,7 @@ public Token ScanNumericLiteral()

if (ch == '.')
{
sb.Append(Source[Index++]);
sb.Append(Source[Index++]);
this.ScanLiteralPart(sb, Character.IsDecimalDigit);

ch = Source.CharCodeAt(Index);
Expand All @@ -1165,21 +1165,21 @@ public Token ScanNumericLiteral()
{
ThrowUnexpectedToken();
}
}
else if (ch == 'n')
{
Index++;
var bigInt = BigInteger.Parse(sb.ToString());
return new Token
{
Type = TokenType.BigIntLiteral,
Value = bigInt,
BigIntValue = bigInt,
LineNumber = LineNumber,
LineStart = LineStart,
Start = start,
End = Index
};
}
else if (ch == 'n')
{
Index++;
var bigInt = BigInteger.Parse(sb.ToString());
return new Token
{
Type = TokenType.BigIntLiteral,
Value = bigInt,
BigIntValue = bigInt,
LineNumber = LineNumber,
LineStart = LineStart,
Start = start,
End = Index
};
}

if (Character.IsIdentifierStart(Source.CharCodeAt(Index)))
Expand Down Expand Up @@ -1640,6 +1640,10 @@ public Token ScanTemplate()
newPattern = newPattern.Substring(0, index) + @"\r?" + newPattern.Substring(index);
index += 4;
}
else
{
index++;
}
}

pattern = newPattern;
Expand Down
8 changes: 8 additions & 0 deletions test/Esprima.Tests/ScannerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,13 @@ public void CanScanMultiLineComment()

Assert.Equal(new[] { "11-28" }, results);
}

[Fact]
public void ShouldPreventInfiniteLoopWhenAdaptingMultiLine()
{
var scanner = new Scanner("", new ParserOptions { AdaptRegexp = true });
var regex = scanner.TestRegExp("\\$", "gm");
Assert.NotNull(regex);
}
}
}

0 comments on commit e01444a

Please sign in to comment.