diff --git a/CHANGES b/CHANGES index fbfeeb1c88..c8b5dfbbd1 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,7 @@ Version 2.7.4 (not released yet) - Fixed infinite loop in SML lexer (#1625) +- Fixed backtracking string regexes in JavaScript/TypeScript lexers (#1637) Version 2.7.3 diff --git a/pygments/lexers/javascript.py b/pygments/lexers/javascript.py index 49bf6d24c2..d2467ce171 100644 --- a/pygments/lexers/javascript.py +++ b/pygments/lexers/javascript.py @@ -95,10 +95,20 @@ class JavascriptLexer(RegexLexer): r'Error|eval|isFinite|isNaN|isSafeInteger|parseFloat|parseInt|' r'document|this|window)\b', Name.Builtin), (JS_IDENT, Name.Other), - (r'"(\\\\|\\"|[^"])*"', String.Double), - (r"'(\\\\|\\'|[^'])*'", String.Single), + (r'"', String.Double, 'string-double'), + (r"'", String.Single, 'string-single'), (r'`', String.Backtick, 'interp'), ], + 'string-double': [ + (r'\\.', String.Double), + (r'[^\\"]+', String.Double), + (r'"', String.Double, '#pop'), + ], + 'string-single': [ + (r'\\.', String.Single), + (r"[^\\']+", String.Single), + (r"'", String.Single, '#pop'), + ], 'interp': [ (r'`', String.Backtick, '#pop'), (r'\\\\', String.Backtick), @@ -112,7 +122,6 @@ class JavascriptLexer(RegexLexer): (r'\}', String.Interpol, '#pop'), include('root'), ], - # (\\\\|\\`|[^`])*`', String.Backtick), } @@ -522,12 +531,22 @@ class TypeScriptLexer(RegexLexer): (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float), (r'0x[0-9a-fA-F]+', Number.Hex), (r'[0-9]+', Number.Integer), - (r'"(\\\\|\\"|[^"])*"', String.Double), - (r"'(\\\\|\\'|[^'])*'", String.Single), + (r'"', String.Double, 'string-double'), + (r"'", String.Single, 'string-single'), (r'`', String.Backtick, 'interp'), # Match stuff like: Decorators (r'@\w+', Keyword.Declaration), ], + 'string-double': [ + (r'\\.', String.Double), + (r'[^\\"]+', String.Double), + (r'"', String.Double, '#pop'), + ], + 'string-single': [ + (r'\\.', String.Single), + (r"[^\\']+", String.Single), + (r"'", String.Single, '#pop'), + ], # The 'interp*' rules match those in JavascriptLexer. Changes made # there should be reflected here as well. diff --git a/tests/test_html_lexer.py b/tests/test_html_lexer.py index 62f1c8d488..9ac72e33e1 100644 --- a/tests/test_html_lexer.py +++ b/tests/test_html_lexer.py @@ -65,7 +65,9 @@ def test_long_unclosed_javascript_fragment(lexer_html): tokens_body = [ (Token.Name.Other, 'alert'), (Token.Punctuation, '('), - (Token.Literal.String.Double, '"hi"'), + (Token.Literal.String.Double, '"'), + (Token.Literal.String.Double, 'hi'), + (Token.Literal.String.Double, '"'), (Token.Punctuation, ')'), (Token.Punctuation, ';'), ]