From 07ef5f45df75a5a803d9b8494d3bdfd05ebe1694 Mon Sep 17 00:00:00 2001 From: Oleksandr Kosariev Date: Wed, 28 Jan 2026 16:27:46 +0100 Subject: [PATCH] =?UTF-8?q?fix(lexer):=20=F0=9F=A9=B9=20handle=20escaped?= =?UTF-8?q?=20quotes=20in=20single-quoted=20strings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lexer was incorrectly stopping at the first single quote encountered, without checking for YAML's escape sequence (two consecutive single quotes ''). This caused parsing errors for strings containing escaped quotes. Updated _parse_quoted_scalar to detect and skip escaped single quotes by checking if a quote is followed by another quote of the same type. Added test case to verify proper parsing of complex single-quoted strings with multiple escaped quotes. --- tests/test_everything.yaml | 4 ++++ yamlium/lexer.py | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/test_everything.yaml b/tests/test_everything.yaml index 4a6a3c3..d823162 100644 --- a/tests/test_everything.yaml +++ b/tests/test_everything.yaml @@ -129,3 +129,7 @@ complex_anchor_chains: final: <<: *derived2 # Final merge final: value3 + +# Complex string +config: + where: '{{ "my_column != date ''2025-08-31''" if target.name == ''prod'' else ''1=1'' }}' diff --git a/yamlium/lexer.py b/yamlium/lexer.py index 5b8dd1d..4730b03 100644 --- a/yamlium/lexer.py +++ b/yamlium/lexer.py @@ -393,7 +393,18 @@ def _parse_quoted_scalar(self) -> list[Token]: quote_char = self.c self._nc() char = self.c - while char != quote_char: + while True: + if char == quote_char: + # Check if this is an escaped quote (two consecutive quotes) + if quote_char == "'" and self.c_future == "'": + # Skip both quotes - this is an escaped single quote + self._nc() # Skip first quote + self._nc() # Skip second quote + char = self.c + continue + else: + # Found the closing quote + break if char == "\n": # In YAML, quoted strings can span multiple lines # Track the newline for proper line/column tracking