BearPro
Дек. 8, 2016 20:59:31
Помню, где-то видел способ интерпретировать строку как код.
И вот как раз у меня есть строка, которую неплохо бы интепретировать, потому что представляет она собой словарь со списками со словарями, из которых мне нужно извлечь кучу нужных данных.
Напомните?
BearPro
Дек. 8, 2016 21:09:02
Закрывайте тред, нашёл ответ на этом же форуме в разделе “Для экспертов”
Ответ - функция eval(string)
py.user.next
Дек. 9, 2016 02:18:42
BearPro
И вот как раз у меня есть строка, которую неплохо бы интепретировать, потому что представляет она собой словарь со списками со словарями, из которых мне нужно извлечь кучу нужных данных.
Это json и модуль для этого - json. А использование eval() - практически всегда признак непрофессионализма, так как 1) он создаёт серьёзные проблемы 2) без него всегда можно обойтись, заменив.
ZerG
Дек. 9, 2016 08:05:16
py.user.next
А какие проблемы от него можно ожидать? Я им не пользуюсь но что бы не наступать на грабле?
plusplus
Дек. 9, 2016 08:12:41
ZerG
py.user.nextА какие проблемы от него можно ожидать? Я им не пользуюсь но что бы не наступать на грабле?
Ну, к примеру, твое веб-приложение принимает json, который парсится функцией eval. В таком случае стороннее лицо может передать любой питоновский код вместо json который, например, сделает копию базы и отправит ему на почту.
ZerG
Дек. 9, 2016 08:20:47
А если к примеру я своем веб приложении проверяю данные которые ко мне пришли и если это не список/словаь И так далее - посылаю нафик?
py.user.next
Дек. 9, 2016 08:33:01
ZerG
А какие проблемы от него можно ожидать?
Вот здесь описание примеров
http://getpython3.com/diveintopython3/advanced-iterators.html#eval
>>> eval('[1, 2, [__import__("os").system("ls -l /etc/passwd")]]')
-rw-r--r--. 1 root root 2381 окт 3 00:13 /etc/passwd
[1, 2, [0]]
>>>
То есть, если у тебя обнаруживают eval(), то стараются выполнить свой код, а так как строка в eval() подаётся откуда-то, то стараются оттуда же и подать нужную строку.
FishHook
Дек. 9, 2016 09:11:18
А этот json не распарсится
import json
d = '[1, 2, [__import__("os").system("ls -l /etc/passwd")]]'
print(json.loads(d))
Traceback (most recent call last):
File “/Users/asmirnov/PycharmProjects/test/test.py”, line 3, in <module>
print(json.loads(d))
File “/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/__init__.py”, line 319, in loads
return _default_decoder.decode(s)
File “/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/decoder.py”, line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File “/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/decoder.py”, line 357, in raw_decode
raise JSONDecodeError(“Expecting value”, s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 9 (char 8)
FishHook
Дек. 9, 2016 09:12:46
В json могут быть только строки и числа (ну и всякие null), и можно сколько угодно пытаться выполнить строку
ZerG
Дек. 9, 2016 09:48:31
FishHook
Я как раз это и говорил! У меня как раз крутится решение подобное! Ивалов нет. Но было интересно.