Игнорирование \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 шт):
Шифрование тут ни при чем. Исключение выбрасывает exec
.
Вы написали ваш скрипт для exec
вот так:
cdl = 'print("Bro,\nHello, World!")'
Проблема в том, что при парсинге этой строки, ещё до присваивания её в cdl
, интерпретатор Пайтона превратил escape-последовательность \n
в перевод строки, и скрипт превратился в тыкву:
print('Hi
Bro!')
Есть как минимум три способа побороть.
- Сделать программу устойчивой к появлению новых строк. Для этого достаточно записать внутренний строковый литерал в многострочной форме:
cdl = "print('''Hi\nBro!''')"
Интерпретатор пайтона превратит этот скрипт во вполне легальную пайтоновскую программу
print('''Hi
Bro!''')
- Экранировать
\
ещё одним обратным слешем:
cdl = "print('Hi\\nBro!')"
Интерпретатор пайтона заменит в литерале двойной слеш на одинарный, до вашего exec скрипт дойдёт в нужном виде.
- Запретить интерпретатору обработку escape-последовательности: использовать raw литерал:
cdl = r"print('Hi\nBro!')"
Буковка r
перед кавычками сообщает интерпретатору, что строковый литерал нужно оставить как есть.
Я бы сказал, что второй способ наиболее подходящий для вас, так как в остальных случаях вам всё равно придётся экранировать все слеши, помимо \n