From 307a6ac3b809c858ef638eb8fa4db3f32d5d83d0 Mon Sep 17 00:00:00 2001 From: Denny J Mangalathu <219673442+Denny-j-mangalathu@users.noreply.github.com> Date: Mon, 9 Nov 2026 15:01:04 +0530 Subject: [PATCH] Normalize line endings in JavaScript template messages --- babel/messages/jslexer.py | 3 +++ tests/messages/test_js_extract.py | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/babel/messages/jslexer.py b/babel/messages/jslexer.py index 6e123449b..e76aa82bc 100644 --- a/babel/messages/jslexer.py +++ b/babel/messages/jslexer.py @@ -104,6 +104,9 @@ def unquote_string(string: str) -> str: assert string and string[0] == string[-1] and string[0] in '"\'`', ( 'string provided is not properly delimited' ) + if string[0] == '`': + # ECMAScript normalizes physical CRLF and CR in template literals. + string = string.replace('\r\n', '\n').replace('\r', '\n') string = line_join_re.sub('\\1', string[1:-1]) result: list[str] = [] add = result.append diff --git a/tests/messages/test_js_extract.py b/tests/messages/test_js_extract.py index 68395787d..8e43abae6 100644 --- a/tests/messages/test_js_extract.py +++ b/tests/messages/test_js_extract.py @@ -211,3 +211,12 @@ def test_template_string_with_literal_braces() -> None: ) messages = list(extract.extract("javascript", buf, {"gettext": None}, [], {"parse_template_string": True})) assert messages == [] + + +@pytest.mark.parametrize('line_ending', ['\n', '\r\n', '\r']) +def test_extract_normalizes_template_line_endings(line_ending): + source = f"_('escaped\\r\\n');{line_ending}_(`first{line_ending}second`);" + assert list(extract.extract('javascript', BytesIO(source.encode('utf-8')))) == [ + (1, 'escaped\r\n', [], None), + (2, 'first\nsecond', [], None), + ]