ValueError:不安全的字符串pickle

发布于 2024-08-11 14:25:12 字数 170 浏览 4 评论 0原文

当我尝试加载使用 cPickle 转储的内容时,收到错误消息:

ValueError: insecure string pickle

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

我该如何解决这个问题?

When I am trying to load something I dumped using cPickle, I get the error message:

ValueError: insecure string pickle

Both the dumping and loading work are done on the same computer, thus same OS: Ubuntu 8.04.

How could I solve this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

夜访吸血鬼 2024-08-18 14:25:12

“在全世界范围内每天使用数十亿次的功能中,比 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's all been written
>>> k = cPickle.load(open('xxx.dmp', 'r'))

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

"are much more likely than a never-observed bug in Python itself in a functionality that's used billions of times a day all over the world": it always amazes me how cross people get in these forums.

One easy way to get this problem is by forgetting to close the stream that you're using for dumping the data structure. I just did

>>> 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

Which is why I came here in the first place, because I couldn't see what I'd done wrong.
And then I actually thought about it, rather than just coming here, and realized that I should have done:

>>> 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'))

Easy to forget. Didn't need people being told that they are idiots.

天冷不及心凉 2024-08-18 14:25:12

由于开放模式“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 中创建的 pickle 文件,您将得到:

pickle.unpicklingerror: the string opcode argument must be quoted

I've get this error in Python 2.7 because of open mode 'rb':

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

So, for Python 2 'mode' should be 'r'

Also, I've wondered that Python 3 doesn't support pickle format of Python 2, and in case when you'll try to load pickle file created in Python 2 you'll get:

pickle.unpicklingerror: the string opcode argument must be quoted
太阳公公是暖光 2024-08-18 14:25:12

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

腐败的泡菜。错误是
如果转储中的字符串确实存在,则引发
不能同时以 " 或 ' 开头和结尾。

并显示了重现此类“损坏”的简单方法。Steve Holden 在后续帖子中建议导致问题的另一种方法是不匹配“rb”和“wb” (但在 Python 2 和 Linux 上,这个特定的错误应该不会被注意到)。

Check this thread. Peter Otten says:

A corrupted pickle. The error is
raised if a string in the dump does
not both start and end with " or '.

and shows a simple way to reproduce such "corruption". Steve Holden, in the follow-up post, suggests another way to cause the problem would be to mismatch 'rb' and 'wb' (but in Python 2 and on Linux that particular mistake should pass unnoticed).

弱骨蛰伏 2024-08-18 14:25:12

您如何处理 dump()load() 之间的数据?将腌制数据存储在以文本模式(在 Windows 上)打开的文件中或以不适用于二进制数据(某些数据库中的 VARCHAR、TEXT 列、某些键值存储)的方式存储在数据库存储中是很常见的错误。尝试比较传递到存储并立即从存储中检索的腌制数据。

What are you doing with data between dump() and load()? It's quite common error to store pickled data in file opened in text mode (on Windows) or in database storage in the way that doesn't work properly for binary data (VARCHAR, TEXT columns in some databases, some key-value storages). Try to compare pickled data that you pass to storage and immediately retrieved from it.

2024-08-18 14:25:12

如果有人在使用 youtube-dl 时遇到此错误,此问题已得到修复:https://github.com/rg3/youtube-dl/issues/7172#issuecomment-242961695

richiecannizzo 于 8 月 28 日发表评论

brew 安装 libav
应该立即在 mac 上修复它或

sudo apt-get install libav
#在Linux上

If anyone has this error using youtube-dl, this issue has the fix: https://github.com/rg3/youtube-dl/issues/7172#issuecomment-242961695

richiecannizzo commented on Aug 28

brew install libav
Should fix it instantly on mac or

sudo apt-get install libav
#on linux

許願樹丅啲祈禱 2024-08-18 14:25:12

如果您的 pickle 很大,则 python 2(以及 python 3 的早期版本)也可能会出现此错误(Python Issue #11564< /a>):

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)。不幸的是,这个功能还没有向后移植到 python 2,而且可能永远不会。如果这是您的问题并且您需要使用 python 2 pickle,那么您能做的最好的事情就是减小 pickle 的大小,例如,不要对 list 进行 pickle,而是将元素单独 pickle 到 泡菜列表

This error may also occur with python 2 (and early versions of python 3) if your pickle is large (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

This limitation was addressed with the introduction of pickle protocol 4 in python 3.4 (PEP 3154). Unfortunately, this feature has not been back-ported to python 2, and probably won't ever be. If this is your problem and you need to use python 2 pickle, the best you can do is reduce the size of your pickle, e.g., instead of pickling a list, pickle the elements individually into a list of pickles.

巾帼英雄 2024-08-18 14:25:12

在 Windows 上使用 python 制作并在 Linux 上使用 python 重新加载的文件也存在同样的问题。
解决方案:在 linux 中读取之前在 dos2unix 上的文件:很有魅力!

Same problem with a file that was made with python on windows, and reloaded with python on linux.
Solution : dos2unix on the file before reading in linux : works as a charm !

稍尽春風 2024-08-18 14:25:12

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

并且 unpickling 给出了不安全的字符串 pickle< /code> message

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< /a>

https://www.rfc-editor.org/rfc /rfc3548.html#section-3

I got the Python ValueError: insecure string pickle message in a different way.

For me it happened after a base64 encoding a binary file and passing through urllib2 sockets.

Initially I was wrapping up a file like this

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)

But on the server the hash kept coming out differently for some binary files

decoded_message = base64.b64decode(incoming_base64_message)
the_hash = hashlib.md5(decoded_message).hexdigest()

And unpickling gave insecure string pickle message

cPickle.loads(decoded_message)

BUT SUCCESS

What worked for me was to use urlsafe_b64encode()

base64_message = base64.urlsafe_b64encode(cPickle.dumps(message))

And decode with

base64_decoded_message = base64.urlsafe_b64decode(base64_message)

References

http://docs.python.org/2/library/base64.html

https://www.rfc-editor.org/rfc/rfc3548.html#section-3

兮子 2024-08-18 14:25:12

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

解释器(Python3)会给你一个错误,说它要求输入文件流以字节为单位,而不是字符串,您可能已将开放模式参数从“r”更改为“rb”,现在它告诉您字符串已损坏,这就是您来到这里的原因。

对于这种情况,最简单的选择是安装 Python2(您可以安装 2.7),然后在 Python 2.7 环境中运行您的程序,这样它就可以毫无问题地解封您的文件。基本上,我浪费了很多时间扫描我的字符串,看看它是否确实损坏,而我所要做的就是将打开文件的模式从 rb 更改为 r,然后使用 Python2 来解封文件。所以我只是把这些信息放在那里。

This is what happened to me, might be a small section of population, but I want to put this out here nevertheless, for them:

Interpreter (Python3) would have given you an error saying it required the input file stream to be in bytes, and not as a string, and you may have changed the open mode argument from 'r' to 'rb', and now it is telling you the string is corrupt, and thats why you have come here.

The simplest option for such cases is to install Python2 (You can install 2.7) and then run your program with Python 2.7 environment, so it unpickles your file without issue. Basically I wasted a lot of time scanning my string seeing if it was indeed corrupt when all I had to do was change the mode of opening the file from rb to r, and then use Python2 to unpickle the file. So I'm just putting this information out there.

我最亲爱的 2024-08-18 14:25:12

我之前遇到过这个问题,找到了这个线程,并假设我对这些答案中提到的文件关闭问题免疫,因为我使用的是 with 语句:

with tempfile.NamedTemporaryFile(mode='wb') as temp_file:
    pickle.dump(foo, temp_file)

    # Push file to another machine
    _send_file(temp_file.name)

但是,由于我正在推动从内部 with 读取临时文件,该文件仍然没有关闭,因此我推送的文件被截断了。这导致在读取远程计算机上的文件的脚本中出现相同的不安全字符串pickle错误。

对此有两个可能的修复方法: 保持文件打开并强制刷新:

with tempfile.NamedTemporaryFile(mode='wb') as temp_file:
    pickle.dump(foo, temp_file)
    temp_file.flush()

    # Push file to another machine
    _send_file(temp_file.name)

或者确保文件在执行任何操作之前已关闭:

file_name = ''
with tempfile.NamedTemporaryFile(mode='wb', delete=False) as temp_file:
    file_name = temp_file.name
    pickle.dump(foo, temp_file)

# Push file to another machine
_send_file(file_name)

I ran into this earlier, found this thread, and assumed that I was immune to the file closing issue mentioned in a couple of these answers since I was using a with statement:

with tempfile.NamedTemporaryFile(mode='wb') as temp_file:
    pickle.dump(foo, temp_file)

    # Push file to another machine
    _send_file(temp_file.name)

However, since I was pushing the temp file from inside the with, the file still wasn't closed, so the file I was pushing was truncated. This resulted in the same insecure string pickle error in the script that read the file on the remote machine.

Two potential fixes to this: Keep the file open and force a flush:

with tempfile.NamedTemporaryFile(mode='wb') as temp_file:
    pickle.dump(foo, temp_file)
    temp_file.flush()

    # Push file to another machine
    _send_file(temp_file.name)

Or make sure the file is closed before doing anything with it:

file_name = ''
with tempfile.NamedTemporaryFile(mode='wb', delete=False) as temp_file:
    file_name = temp_file.name
    pickle.dump(foo, temp_file)

# Push file to another machine
_send_file(file_name)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文