2009-11-17 20 views
40

Wenn ich etwas zu laden, versuche ich cPickle dumped verwenden, erhalte ich die Fehlermeldung:Valueerror: unsichere String Gurke

ValueError: insecure string pickle 

Sowohl das Dumping und Ladearbeiten auf demselben Computer durchgeführt, so dass gleiche OS: Ubuntu 8.04.

Wie könnte ich dieses Problem lösen?

+0

Wenn ich das Objekt cPickle.dump kann, warum kann ich das Objekt nicht cPickle.load? Ist es nicht seltsam? Python macht manchmal dumme Sachen. –

+0

Ich habe das, wenn ich eingelegte Daten in der Datenbank in Django-Anwendung gespeichert. Dann änderte ich die Zeichenkette manuell über Admin-Schnittstelle und brach es. (Ich denke, dass django '\ n' Zeichen fallen ließ) – SummerBreeze

+0

@SummerBreeze: Wie hast du es behoben. Ich stehe beim Bearbeiten mit django-admin vor dem gleichen Problem. Danke im Voraus . –

Antwort

7

Überprüfen Sie this thread. Peter Otten sagt:

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

und zeigt eine einfache Möglichkeit, solche "Korruption" zu reproduzieren. Steve Holden schlägt im folgenden Post einen anderen Weg vor, um das Problem zu verursachen, dass "rb" und "wb" nicht übereinstimmen (aber in Python 2 und unter Linux sollte dieser bestimmte Fehler unbemerkt bleiben).

+0

Ich habe diesen Artikel gelesen. Ich kann ihm nicht zustimmen. Wie mein Programm läuft auf Linux und Python 2. Und es sollte jede miss-match 'oder "sein. Da der Dump auch von Python generiert wird, denke ich, die Dump-Methode von Python kann das Miss-Match-Problem behandelt, richtig? –

+0

@Peter, ich kenne keine solchen Fälle (aber, überprüfen Sie den Python-Tracker). Beizen kann (und tut dies auch oft für benutzercodierte Klassen), benutzercodierte Methoden wie '__reduce__' & c aufrufen, also Fehler in solchen benutzercodierten Methoden sind viel wahrscheinlicher als ein nie beobachteter Fehler in Python selbst in einer Funktionalität, die auf der ganzen Welt millionenfach am Tag verwendet wird. (Benutzer-kodierte können von allen Modulen von Drittanbietern sein, die Sie verwenden, natürlich, es ist einfach "Im Gegensatz zu Pythons internen Maschinerie"! -). –

7

Was machst du mit Daten zwischen dump() und ? Es ist ein häufiger Fehler, eingelegte Daten in einer Datei zu speichern, die im Textmodus (unter Windows) oder im Datenbankspeicher auf eine Weise geöffnet wird, die für Binärdaten (VARCHAR-, TEXT-Spalten in einigen Datenbanken, einige Schlüssel/Wert-Speicher) nicht richtig funktioniert. Versuchen Sie, gebeizte Daten zu vergleichen, die Sie an den Speicher übergeben und sofort daraus abrufen.

80

"sind viel wahrscheinlicher als ein nie beobachteter Fehler in Python selbst in einer Funktionalität, die millionenfach am Tag auf der ganzen Welt verwendet wird": Es erstaunt mich immer wieder, wie viele Leute in diese Foren kommen.

Ein einfacher Weg, um dieses Problem zu bekommen, ist vergessen, den Strom zu schließen, den Sie zum Dumping der Datenstruktur verwenden. Ich habe gerade

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

, weshalb ich hier in erster Linie kam, weil ich nicht sehen konnte, was ich falsch gemacht habe.
Und dann dachte ich darüber eigentlich, und nicht nur hier kommen, und erkannte, dass ich es hätte tun sollen:

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

Leicht zu vergessen. Ich brauchte nicht, dass Leuten gesagt wurde, dass sie Idioten sind.

+0

Danke, das war genau mein Problem. Das ist, was ich bekomme, um etwas schnell zusammen zu werfen! – grinch

+0

Ich hatte den Fehler, obwohl ich close(). Es ist eine sehr alberne Fehlermeldung sagen nichts nützliches, am Ende dos2unix über die f Ile war die Lösung, die geholfen hat. – falkb

+0

Danke für die Antwort. Dein letzter Satz ist besonders passend. –

3

Ich habe die Python ValueError: insecure string pickle Nachricht auf eine andere Art und Weise.

Für mich geschah es nach einer base64 Codierung einer Binärdatei und durch urllib2 Sockets.

Anfangs wickelte ich wie dieses

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) 

Aber auf dem Server der Hash gehalten herauskommt anders für einige binäre Dateien

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

Und Unpickling gab insecure string pickle eine Datei, Nachricht

cPickle.loads(decoded_message) 

aber der Erfolg

Was für mich gearbeitet wurde mit

base64_decoded_message = base64.urlsafe_b64decode(base64_message) 

Referenzen urlsafe_b64encode()

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

und dekodieren verwenden

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

https://tools.ietf.org/html/rfc3548.html#section-3

4

gleiches Problem mit einer Datei, die mit Python auf Windows und neu geladen mit Python auf Linux gemacht wurde. Lösung: dos2unix auf der Datei vor dem Lesen in Linux: funktioniert als Charme!

+0

Das klingt nach der Situation in der ich bin. Was meinst du mit ": dos2unix in der Datei"? – rschwieb

+0

Ich hatte das gleiche Problem, löste es mit dos2unix. Wenn Sie dieses Modul nicht haben, können Sie es einfach selber schreiben, siehe hier: [link] (http://stackoverflow.com/questions/16695950/how-to-read-windows-file-in-linux- Umgebung) – mike622867

+0

Ich hatte das selbe Problem und reparierte es durch Änderung des Quellcodes: Ersetze "r" durch "rb" und "w" durch "wb", damit sind Pickle-Dateien unter Linux und Windows identisch und können von geladen werden beide Betriebssysteme. – hochl

3

ich habe diesen Fehler in Python 2.7 wegen der offenen Modus 'rb':

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

Also, für Python 2 'mode' sollte 'r'

Auch ich habe fragte sich, dass Sie in Python nicht Beize Format von Python 2 und im Fall unterstützen, wenn Sie versuchen, Gurke Datei 2 erstellt laden Python 3 erhalten:

pickle.unpicklingerror: the string opcode argument must be quoted 
+0

Danke, das hat bei mir funktioniert. Realisiert hatte ich mit 'w' und nicht 'wb' gebeizt. –

1

Das ist, was mir passiert ist, könnte ein kleiner Teil der Bevölkerung sein, aber ich w ant, um dies hier dennoch für sie auszustellen:

Interpreter (Python3) hätte Ihnen einen Fehler gegeben, der besagt, dass der Eingabedateistrom in Bytes und nicht als Zeichenfolge eingegeben werden muss und Sie möglicherweise das Öffnen geändert haben Modus-Argument von 'r' bis 'rb', und jetzt sagt es dir, dass die Zeichenfolge korrupt ist, und deshalb bist du hierher gekommen.

Die einfachste Option für solche Fälle ist die Installation von Python2 (Sie können 2.7 installieren) und führen Sie dann Ihr Programm mit Python 2.7 Umgebung, so dass es Ihre Datei ohne Problem entpackt. Im Grunde habe ich viel Zeit damit verbracht, meine Zeichenkette zu scannen, um zu sehen, ob sie wirklich beschädigt war, wenn ich nur den Modus zum Öffnen der Datei von rb auf r ändern und dann Python2 verwenden musste, um die Datei zu entpacken. Ich stelle diese Informationen einfach nur da raus.

3

Dieser Fehler auch mit Python 2 (und frühen Versionen von Python 3), wenn Ihre Gurke groß ist (Python Issue #11564) auftreten kann: mit der Einführung der Gurke Protokoll 4 in Python 3.4 angesprochen wurde

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 

Diese Einschränkung (PEP 3154). Leider wurde diese Funktion nicht auf Python 2 portiert und wird es wahrscheinlich auch nie sein. Wenn dies Ihr Problem ist und Sie Python 2 Pickle verwenden müssen, ist es am besten, die Größe Ihrer Pickle zu reduzieren, z. B. anstatt die list zu beizen, die Elemente einzeln in ein list Gurken einlegen.