diff --git a/Jint.Tests/Runtime/RegExpTests.cs b/Jint.Tests/Runtime/RegExpTests.cs index 14803c28f..7a4b704bb 100644 --- a/Jint.Tests/Runtime/RegExpTests.cs +++ b/Jint.Tests/Runtime/RegExpTests.cs @@ -150,6 +150,30 @@ public void ShouldSupportRegExpModifiersInLiteralsAndConstructor() """).AsString().Should().Be("false,true"); } + [Fact] + public void ShouldAllowClassSetSyntaxCharacterOutsideClassSetForFlagV() + { + var engine = new Engine(); + var result = engine.Evaluate(@"new RegExp('/-', 'v').test('/-')"); + Assert.True(result.AsBoolean()); + } + + [Fact] + public void ShouldAllowClassSetReservedDoublePunctuatorCharactersOutsideClassSetForFlagV() + { + var engine = new Engine(); + var result = engine.Evaluate(@"new RegExp('&&!!##%%,,::;;<<==>>@@``~~', 'v').test('&&!!##%%,,::;;<<==>>@@``~~')"); + Assert.True(result.AsBoolean()); + } + + [Fact] + public void ShouldAllowEscapedClassSetReservedPunctuatorsForFlagV() + { + var engine = new Engine(); + var result = engine.Evaluate(@"new RegExp('[\\!\\#\\%\\&\\,\\-\\:\\;\\<\\=\\>\\@\\`\\~]{14}', 'v').test('!#%&,-:;<=>@`~')"); + Assert.True(result.AsBoolean()); + } + [Fact] public void Issue506() { diff --git a/Jint/Runtime/RegExp/RegExpCompiler.cs b/Jint/Runtime/RegExp/RegExpCompiler.cs index c8507b163..20abccc67 100644 --- a/Jint/Runtime/RegExp/RegExpCompiler.cs +++ b/Jint/Runtime/RegExp/RegExpCompiler.cs @@ -1241,7 +1241,16 @@ private int GetClassAtom(REStringList? cr, bool inclass) else { _pos = savedPos; - if (IsUnicode) + if (IsUnicode + && (!UnicodeSets + || !inclass + || _pattern[_pos] is not + ( + '!' or '#' or '%' or '&' + or ',' or '-' or ':' or ';' + or '<' or '=' or '>' or '@' + or '`' or '~' + ))) { throw new RegExpSyntaxException("invalid escape sequence in regular expression"); } @@ -1274,7 +1283,7 @@ private int GetClassAtom(REStringList? cr, bool inclass) case '^': case '`': case '~': - if (UnicodeSets && _pos + 1 < _patternEnd && _pattern[_pos + 1] == c) + if (UnicodeSets && inclass && _pos + 1 < _patternEnd && _pattern[_pos + 1] == c) { // Forbidden double characters in unicode-sets mode throw new RegExpSyntaxException("invalid class set operation in regular expression"); @@ -1290,7 +1299,7 @@ private int GetClassAtom(REStringList? cr, bool inclass) case '/': case '-': case '|': - if (UnicodeSets) + if (UnicodeSets && inclass) { throw new RegExpSyntaxException("invalid character in class in regular expression"); }