Игнорирование \n при запуске через exec/other

Пишу кастомный шифровщик/дешифровщик кода, проблема в том, что при дешифровке кода функцией daed(), и при последующем запуске дешифрованного кода будь то через exec, subprocess, eval (в т.ч. создание временного файла tempfile+subprocess) код интерпретирует управляющие символы \n и другие что моментально приводит к ошибке, экранизация не помогает. Это мешает к примеру при дешифровке и выполнению python-кода с телеграм ботом где в ответах юзеру используются переносы строки. K примеру как await answer("Hi!\nhow i help you?"), вызывая незавершённый строковой литерал. Возможно ли как то игнорировать \n до определённого момента, или чтобы он не интерпретировался exec и не вызывал ошибки по типу unterminated string literal, а интерпретировался только при сообщению юзеру в самом телеграме и т.д.? Сама функция:

def daed(custom_encoded):
    parts = custom_encoded.split('###')

    byte_list = parts[0].split('||||')
    byte_values = [int(byte) for byte in byte_list]

    xor_key1 = [int(byte) for byte in parts[1].split('||||')]
    xor_key2 = [int(byte) for byte in parts[2].split('||||')]
    xor_key3 = combine_keys(bytes(xor_key1), bytes(xor_key2))

    byte_values = xor_with_key(byte_values[:-1], xor_key3)

    decoded_base64_str = bytes(byte_values).decode('latin1')
    decoded_ascii_str = base64.b64decode(decoded_base64_str).decode('utf-8')

    exec(decoded_ascii_str)

Проблема в реалиях:

  File "<string>", line 1, in <module>
  File "/data/user/0/lttest/files/aarch64-linux-android/lib/python3.11/site-packages/cipherbyte.py", line 76, in daed
    exec(decoded_ascii_str)
  File "<string>", line 37
    await message.edit("? Реклама уже запущена в этом чате.
                       ^
SyntaxError: unterminated string literal (detected at line 37)

[Program finished]

Пример выполнения:

from cipherbyte import *

cdl = "print('Hi\nBro!')"
lt = encryptData(cdl)
print(lt)
daed(lt)

Нужен cipherbyte==0.1.4

Я знаю про -e в консоли, есть ли обратная аналогия такой команде? (Я искал, но не нашёл). Или может можно использовать маркеры замены, к примеру с \n на ced (или любые другие маркеры), которые будут делать перенос строки уже в логике моего кода?


Ответы (1 шт):

Автор решения: Pak Uula

Шифрование тут ни при чем. Исключение выбрасывает exec.

Вы написали ваш скрипт для exec вот так:

cdl = 'print("Bro,\nHello, World!")'

Проблема в том, что при парсинге этой строки, ещё до присваивания её в cdl, интерпретатор Пайтона превратил escape-последовательность \n в перевод строки, и скрипт превратился в тыкву:

print('Hi
Bro!')

Есть как минимум три способа побороть.

  1. Сделать программу устойчивой к появлению новых строк. Для этого достаточно записать внутренний строковый литерал в многострочной форме:
cdl = "print('''Hi\nBro!''')"

Интерпретатор пайтона превратит этот скрипт во вполне легальную пайтоновскую программу

print('''Hi
Bro!''')
  1. Экранировать \ ещё одним обратным слешем:
cdl = "print('Hi\\nBro!')"

Интерпретатор пайтона заменит в литерале двойной слеш на одинарный, до вашего exec скрипт дойдёт в нужном виде.

  1. Запретить интерпретатору обработку escape-последовательности: использовать raw литерал:
cdl = r"print('Hi\nBro!')"

Буковка r перед кавычками сообщает интерпретатору, что строковый литерал нужно оставить как есть.

Я бы сказал, что второй способ наиболее подходящий для вас, так как в остальных случаях вам всё равно придётся экранировать все слеши, помимо \n

→ Ссылка