diff --git a/hcl2/reconstructor.py b/hcl2/reconstructor.py index bf653c05..42e88fdb 100644 --- a/hcl2/reconstructor.py +++ b/hcl2/reconstructor.py @@ -352,11 +352,21 @@ def _name_to_identifier(name: str) -> Tree: @staticmethod def _escape_interpolated_str(interp_s: str) -> str: - # begin by doing basic JSON string escaping, to add backslashes - interp_s = json.dumps(interp_s) - + if interp_s.strip().startswith('<<-') or interp_s.strip().startswith('<<'): + # For heredoc strings, preserve their format exactly + return reverse_quotes_within_interpolation(interp_s) + # Escape backslashes first (very important to do this first) + escaped = interp_s.replace('\\', '\\\\') + # Escape quotes + escaped = escaped.replace('"', '\\"') + # Escape control characters + escaped = escaped.replace('\n', '\\n') + escaped = escaped.replace('\r', '\\r') + escaped = escaped.replace('\t', '\\t') + escaped = escaped.replace('\b', '\\b') + escaped = escaped.replace('\f', '\\f') # find each interpolation within the string and remove the backslashes - interp_s = reverse_quotes_within_interpolation(interp_s) + interp_s = reverse_quotes_within_interpolation(f'"{escaped}"') return interp_s @staticmethod diff --git a/test/helpers/terraform-config-json/unicode_strings.json b/test/helpers/terraform-config-json/unicode_strings.json new file mode 100644 index 00000000..8eedf932 --- /dev/null +++ b/test/helpers/terraform-config-json/unicode_strings.json @@ -0,0 +1,20 @@ +{ + "locals": [ + { + "basic_unicode": "Hello, 世界! こんにちは Привет नमस्ते", + "unicode_escapes": "© ♥ ♪ ☠ ☺", + "emoji_string": "🚀 🌍 🔥 🎉", + "rtl_text": "English and العربية text mixed", + "complex_unicode": "Python (파이썬) es 很棒的! ♥ αβγδ", + "ascii": "ASCII: abc123", + "emoji": "Emoji: 🚀🌍🔥🎉", + "math": "Math: ∑∫√∞≠≤≥", + "currency": "Currency: £€¥₹₽₩", + "arrows": "Arrows: ←↑→↓↔↕", + "cjk": "CJK: 你好世界안녕하세요こんにちは", + "cyrillic": "Cyrillic: Привет мир", + "special": "Special: ©®™§¶†‡", + "mixed_content": "Line with interpolation: ${var.name}\nLine with emoji: 👨‍👩‍👧‍👦\nLine with quotes: \"quoted text\"\nLine with backslash: \\escaped" + } + ] +} diff --git a/test/helpers/terraform-config/unicode_strings.tf b/test/helpers/terraform-config/unicode_strings.tf new file mode 100644 index 00000000..83c76a4c --- /dev/null +++ b/test/helpers/terraform-config/unicode_strings.tf @@ -0,0 +1,21 @@ +locals { + basic_unicode = "Hello, 世界! こんにちは Привет नमस्ते" + unicode_escapes = "© ♥ ♪ ☠ ☺" + emoji_string = "🚀 🌍 🔥 🎉" + rtl_text = "English and العربية text mixed" + complex_unicode = "Python (파이썬) es 很棒的! ♥ αβγδ" + ascii = "ASCII: abc123" + emoji = "Emoji: 🚀🌍🔥🎉" + math = "Math: ∑∫√∞≠≤≥" + currency = "Currency: £€¥₹₽₩" + arrows = "Arrows: ←↑→↓↔↕" + cjk = "CJK: 你好世界안녕하세요こんにちは" + cyrillic = "Cyrillic: Привет мир" + special = "Special: ©®™§¶†‡" + mixed_content = <<-EOT + Line with interpolation: ${var.name} + Line with emoji: 👨‍👩‍👧‍👦 + Line with quotes: "quoted text" + Line with backslash: \escaped + EOT +}