Python的ValueError:不安全的string酱菜

当我试图加载使用cPickle转储的东西时,我收到错误消息:

ValueError: insecure string pickle 

转储和加载工作都在同一台计算机上完成,因此相同的操作系统:Ubuntu 8.04。

我怎么能解决这个问题?

“比起Python中一个从未被观察到的bug来说,它更有可能在全世界每天使用数十亿次的function”中:跨越人们如何进入这些论坛的事情总是让我感到惊讶。

解决这个问题的一个简单方法就是忘记closures你用来转储数据结构的stream。 我已经做了

 >>> 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's all been written >>> k = cPickle.load(open('xxx.dmp', 'r')) 

容易忘记。 不需要人们被告知他们是白痴。

检查这个线程 。 彼得·奥滕说:

一个腐败的腌菜。 如果转储中的string不是以“或”开头和结尾,则会引发错误。

并显示了一个简单的方法来再现这种“腐败”。 Steve Holden在后续文章中提出了另一种导致这个问题的方法,那就是“rb”和“wb”不匹配(但是在Python 2和Linux中,这个特殊的错误应该不被忽视)。

dump()load()之间的数据是怎么做的? 将pickle数据存储在以文本模式打开的文件(Windows)或数据库存储中的方式对于二进制数据(VARCHAR,某些数据库中的TEXT列,某些键值存储区)无法正常工作是非常常见的错误。 尝试比较您传递到存储的腌制数据,并立即从中检索。

如果任何人有这个错误使用youtube-dl ,这个问题有修复: https : //github.com/rg3/youtube-dl/issues/7172#issuecomment-242961695

richiecannizzo在8月28日评论

brew install libav
应该马上修复它在Mac或

sudo apt-get install libav
#on linux

在Windows上使用python创build的文件也是如此,在linux上使用python重新加载。 解决方法:在linux上读取文件之前,先看dos2unix:作为一个魅力!

由于开放模式'rb',我得到了Python 2.7中的这个错误:

  with open(path_to_file, 'rb') as pickle_file: obj = pickle.load(pickle_file) 

所以,对于Python 2'模式'应该是'r'

另外,我想知道Python 3不支持Python 2的pickle格式,如果你尝试加载在Python 2中创build的pickle文件,你会得到:

 pickle.unpicklingerror: the string opcode argument must be quoted 

如果你的pickle很大( Python Issue#11564 ),python 2(和python 3的早期版本)也会出现这个错误:

 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 

Python 3.4中引入了pickle协议4( PEP 3154 )解决了这个限制。 不幸的是,这个function还没有被移植到Python 2,而且可能永远不会。 如果这是你的问题,你需要使用python 2 pickle,那么你可以做的最好的事情就是减lesspickle的大小,例如,不要酸洗一个list ,而是把这些元素分别放到pickle list中。

我以不同的方式得到了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

这是发生在我身上的事情,可能是一小部分人口,但是我想把这个放在这里,对他们来说:

解释器(Python3)会给你一个错误,说它需要input文件stream是以字节为单位的,而不是string,你可能已经把开放模式的参数从'r'改为'rb',现在是告诉你这个string是腐败的,那就是你来这里的原因。

这种情况下最简单的select是安装Python2(您可以安装2.7),然后运行您的程序与Python 2.7环境,所以它unpickles你的文件没有问题。 基本上我浪费了很多时间来扫描我的string,看看它是否确实损坏,当我所要做的只是将打开文件的模式从rb更改为r,然后使用Python2来取消打开文件。 所以我只是把这些信息放在那里。