2009-11-17 13 views
40

Quando sto cercando di caricare qualcosa che mi ha scaricato utilizzando cPickle, ottengo il messaggio di errore:ValueError: insicuro stringa salamoia

ValueError: insecure string pickle 

Sia il lavoro di dumping e di carico sono fatto sullo stesso computer, in tal modo stesso sistema operativo: Ubuntu 8.04.

Come posso risolvere questo problema?

+0

Se posso cPickle.dump quell'oggetto, perché non posso cPickle.load quell'oggetto? Non è strano? Python fa cose stupide alcune volte. –

+0

Ho ottenuto questo quando ho memorizzato i dati in pickled nel database nell'applicazione django. Poi ho modificato manualmente la stringa tramite l'interfaccia di amministrazione e l'ho rotta. (Penso che django abbia lasciato caratteri '\ n') – SummerBreeze

+0

@ SummerBreeze: come hai risolto il problema. Sto affrontando lo stesso problema durante la modifica con django-admin. Grazie in anticipo . –

risposta

7

Controllare this thread. Peter Otten dice:

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

e mostra un modo semplice per riprodurre tale "corruzione". Steve Holden, nel post successivo, suggerisce un altro modo per far si che il problema sia la mancata corrispondenza tra 'rb' e 'wb' (ma in Python 2 e su Linux quell'errore particolare dovrebbe passare inosservato).

+0

Ho letto quell'articolo. Non posso essere d'accordo con lui. Dato che il mio programma è in esecuzione su linux e python 2. E ci dovrebbe essere qualsiasi miss-match 'o ". Siccome il dump è generato anche da python, penso che il metodo dump di python possa gestire il problema miss-match, giusto? –

+0

@Peter, non conosco casi di questo tipo (ma, controlla il tracker Python). Pickling può (e spesso fa per le classi codificate dall'utente) chiamare metodi codificati dall'utente come '__reduce__' & c, quindi errori in tali metodi codificati dall'utente sono molto più probabili di un bug mai osservato in Python stesso in una funzionalità che viene utilizzata miliardi di volte al giorno in tutto il mondo. (Il codice utente potrebbe provenire da qualsiasi modulo di terze parti che si sta utilizzando, ovviamente è solo "in contrasto con meccanismi interni di Python!" -. –

7

Cosa stai facendo con i dati tra dump() e load()? È un errore piuttosto comune memorizzare i dati in pickled nel file aperto in modalità testo (su Windows) o nella memoria del database nel modo in cui non funziona correttamente per i dati binari (colonne VARCHAR, TEXT in alcuni database, alcuni archivi di valori-chiave). Prova a confrontare i dati in pickled che hai trasferito alla memoria e ne hai immediatamente recuperato.

80

"sono molto più probabili di un bug mai osservato in Python stesso in una funzionalità che viene utilizzata miliardi di volte al giorno in tutto il mondo": mi stupisce sempre il modo in cui le persone si intromettono in questi forum.

Un modo semplice per ottenere questo problema è dimenticare di chiudere il flusso che si sta utilizzando per scaricare la struttura dei dati. Ho appena fatto

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

Ed è per questo che sono venuto qui, in primo luogo, perché non riuscivo a vedere quello che avevo fatto di sbagliato.
E poi ho effettivamente pensato, piuttosto che venire qui, e ho capito che avrei dovuto fare:

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

facile da dimenticare. Non c'era bisogno che alla gente venisse detto che sono degli idioti.

+0

Grazie), questo era esattamente il mio problema questo è ciò che ho per gettare qualcosa insieme veloce – grinch

+0

ho avuto l'errore, anche se io chiamo close() E 'un messaggio di errore molto stupido dicendo.!. niente di utile, alla fine dos2unix sul f ile è stata la soluzione che ha aiutato. – falkb

+0

Grazie per la risposta. La tua ultima frase è particolarmente a proposito. –

3

Ho ricevuto il messaggio Python ValueError: insecure string pickle in un modo diverso.

Per me è successo dopo un base64 codifica un file binario e passaggio attraverso prese urllib2.

Inizialmente ero confezionamento di un file come questo

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) 

Ma sul server l'hash continuava a uscire in modo diverso per alcuni file binari

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

E deserializzazione ha dato insecure string pickle messaggio

cPickle.loads(decoded_message) 

ma il successo

Quello che ha funzionato per me è stato quello di utilizzare urlsafe_b64encode()

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

e decodificare con

base64_decoded_message = base64.urlsafe_b64decode(base64_message) 

Riferimenti

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

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

4

stesso problema con un file che è stato fatto con il pitone su Windows, e ricaricato con python su linux. Soluzione: dos2unix sul file prima di leggere in linux: funziona come un fascino!

+0

Sembra la situazione in cui mi trovo. Cosa intendi con "dos2unix sul file"? – rschwieb

+0

Ho avuto lo stesso problema, l'ho risolto usando dos2unix. Se non si dispone di questo modulo, si può facilmente scrivere uno voi stessi, vedi qui: [link] (http://stackoverflow.com/questions/16695950/how-to-read-windows-file-in-linux- ambiente) – mike622867

+0

Ho avuto lo stesso problema e l'ho risolto modificando il codice sorgente: sostituire "r" con "rb" e "w" con "wb", quindi i file pickle saranno identici su Linux e Windows e possono essere caricati da entrambi i sistemi operativi. – hochl

3

Ho ottenere questo errore in Python 2.7 a causa delle modalità di apertura 'rb':

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

Quindi, per 'mode' Python 2 dovrebbe essere 'r'

Inoltre, ho si chiese che Python 3 non supporta il formato salamoia di Python 2, e nel caso in cui si tenta di caricare il file salamoia creato in Python 2 si otterrà:

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

Grazie, questo ha funzionato per me. Realizzato che avevo messo in salamoia con 'w' e non 'wb'. –

1

Questo è quello che è successo a me, potrebbe essere una piccola parte della popolazione, ma io w ma per loro:

L'interprete (Python3) ti avrebbe dato un errore dicendo che richiedeva che il flusso del file di input fosse in byte, e non come stringa, e potresti aver cambiato l'open argomento della modalità da 'r' a 'rb', e ora ti sta dicendo che la stringa è corrotta, e questo è il motivo per cui sei venuto qui.

L'opzione più semplice per questi casi è installare Python2 (è possibile installare 2.7) e quindi eseguire il programma con l'ambiente Python 2.7, in modo da annullare il file senza problemi. Fondamentalmente ho sprecato un sacco di tempo a scansionare la mia stringa vedendo se era effettivamente corrotto quando tutto quello che dovevo fare era cambiare la modalità di apertura del file da rb a r, e quindi usare Python2 per annullare il file. Quindi sto solo mettendo queste informazioni là fuori.

3

Questo errore può verificarsi anche con Python 2 (e le prime versioni di Python 3) se la salamoia è di grandi dimensioni (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 

Questa limitazione è stata affrontata con l'introduzione del protocollo pickle 4 in Python 3.4 (PEP 3154). Sfortunatamente, questa funzione non è stata sottoposta a porting su python 2 e probabilmente non lo sarà mai. Se questo è il tuo problema e devi usare il pickle python 2, il meglio che puoi fare è ridurre la dimensione del pickle, ad esempio, anziché decodificare uno list, decapitare gli elementi singolarmente in un sottaceto list.

Problemi correlati