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 для разблокировки файла. Поэтому я просто размещаю эту информацию там.