Python ValueError: небезопасный струйный рассол
PКогда я пытаюсь загрузить что-то, что я сбросил с помощью cPickle, я получаю сообщение об ошибке:
ValueError: insecure string pickle
Обе работы по загрузке и загрузке выполняются на одном компьютере, таким образом, такая же ОС: Ubuntu 8.04.
Как я могу решить эту проблему?
Ответы
Ответ 1
"гораздо более вероятны, чем никогда не наблюдавшаяся ошибка в самом Python в функциональности, которая использовалась миллиарды раз в день во всем мире": она всегда поражает меня тем, как люди-кресты попадают на эти форумы.
Один простой способ получить эту проблему - забыть закрыть поток, который вы используете для сброса структуры данных. Я просто сделал
>>> out = open('xxx.dmp', 'w')
>>> cPickle.dump(d, out)
>>> k = cPickle.load(open('xxx.dmp', 'r'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: insecure string pickle
Вот почему я пришел сюда в первую очередь, потому что я не мог понять, что я сделал неправильно.
И тогда я действительно думал об этом, а не просто приезжал сюда, и понял, что должен был сделать:
>>> out = open('xxx.dmp', 'w')
>>> cPickle.dump(d, out)
>>> out.close() # close it to make sure it all been written
>>> k = cPickle.load(open('xxx.dmp', 'r'))
Легко забыть. Не нужно, чтобы людям говорили, что они идиоты.
Ответ 2
Отметьте этот поток. Питер Оттен говорит:
Коррумпированный рассол. Ошибка если строка в дампе не начинайте и не заканчивайте "или".
и показывает простой способ воспроизвести такую "коррупцию". Стив Холден, в последующей записи, предлагает другой способ вызвать проблему, заключающуюся в несоответствии "rb" и "wb" (но в Python 2 и Linux, что конкретная ошибка должна пройти незамеченной).
Ответ 3
Что вы делаете с данными между dump()
и load()
? Это довольно распространенная ошибка для хранения маринованных данных в файле, открытом в текстовом режиме (в Windows) или в хранилище базы данных, так, что это не работает должным образом для двоичных данных (столбцы VARCHAR, TEXT в некоторых базах данных, некоторые хранилища значений ключа). Попробуйте сравнить маринованные данные, которые вы переходите на хранение и сразу же извлекаете из него.
Ответ 4
Если у кого-то есть эта ошибка с помощью youtube-dl
, эта проблема имеет исправление: https://github.com/rg3/youtube-dl/issues/7172#issuecomment-242961695
richiecannizzo прокомментировал 28 августа
brew install libav
Необходимо немедленно установить его на mac или
sudo apt-get install libav
#on linux
Ответ 5
Такая же проблема с файлом, который был сделан с python на окнах, и перезагружен с помощью python на linux.
Решение: dos2unix в файле перед чтением в linux: работает как прелесть!
Ответ 6
Я получил эту ошибку в Python 2.7 из-за открытого режима 'rb':
with open(path_to_file, 'rb') as pickle_file:
obj = pickle.load(pickle_file)
Итак, для Python 2 'mode' должен быть 'r'
Кроме того, я задался вопросом, что Python 3 не поддерживает формат pickle Python 2, и в случае, если вы попытаетесь загрузить файл pickle, созданный в Python 2, вы получите:
pickle.unpicklingerror: the string opcode argument must be quoted
Ответ 7
Эта ошибка может возникать и с python 2 (и ранними версиями python 3), если ваш рассол большой (Python Issue # 11564):
Python 2.7.11 |Anaconda custom (64-bit)| (default, Dec 6 2015, 18:08:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://anaconda.org
>>> import cPickle as pickle
>>> string = "X"*(2**31)
>>> pp = pickle.dumps(string)
>>> len(pp)
2147483656
>>> ss = pickle.loads(pp)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: insecure string pickle
Это ограничение было рассмотрено с введением протокола pickle 4 в python 3.4 (PEP 3154). К сожалению, эта функция не была перенесена на python 2 и, вероятно, никогда не будет. Если это ваша проблема, и вам нужно использовать пинтон 2, наилучшим образом вы можете уменьшить размер рассола, например, вместо того, чтобы травить list
, разделить элементы индивидуально на list
соленья.
Ответ 8
Я получил сообщение Python ValueError: insecure string pickle
по-другому.
Для меня это произошло после base64
кодирования двоичного файла и прохождения через urllib2
сокеты.
Сначала я обертывал файл, подобный этому
with open(path_to_binary_file) as data_file:
contents = data_file.read()
filename = os.path.split(path)[1]
url = 'http://0.0.0.0:8080/upload'
message = {"filename" : filename, "contents": contents}
pickled_message = cPickle.dumps(message)
base64_message = base64.b64encode(pickled_message)
the_hash = hashlib.md5(base64_message).hexdigest()
server_response = urllib2.urlopen(url, base64_message)
Но на сервере хэш продолжал выходить по-разному для некоторых двоичных файлов
decoded_message = base64.b64decode(incoming_base64_message)
the_hash = hashlib.md5(decoded_message).hexdigest()
И распечатка дала сообщение insecure string pickle
cPickle.loads(decoded_message)
НО УСПЕХ
Для меня работала urlsafe_b64encode()
base64_message = base64.urlsafe_b64encode(cPickle.dumps(message))
И декодируйте с помощью
base64_decoded_message = base64.urlsafe_b64decode(base64_message)
Ссылки
http://docs.python.org/2/library/base64.html
https://tools.ietf.org/html/rfc3548.html#section-3
Ответ 9
Вот что со мной произошло, может быть, небольшая часть населения, но я хочу все это вынести здесь, для них:
Interpreter (Python3) дал бы вам ошибку, заявив, что требуется, чтобы входной поток файлов находился в байтах, а не как строка, и вы, возможно, изменили аргумент открытого режима с 'r' на 'rb' и теперь он говорит вам, что строка повреждена, и именно поэтому вы пришли сюда.
Простейшим вариантом для таких случаев является установка Python2 (вы можете установить 2.7), а затем запустить свою программу с помощью среды Python 2.7, чтобы она без проблем распаковывала ваш файл. В основном я потратил много времени на сканирование своей строки, если она была действительно повреждена, когда все, что мне нужно было сделать, это изменить режим открытия файла с rb на r, а затем использовать Python2 для разблокировки файла. Поэтому я просто размещаю эту информацию там.