2009-04-02 20 views
7

Estoy trabajando con SimpleCookie de Python y me encontré con este problema y no estoy seguro si es algo con mi sintaxis o qué. Además, este es un trabajo de clase para mi clase de Python, por lo que está destinado a enseñar sobre Python, así que esto está muy lejos de la forma en que lo haría en el mundo real.Se están agregando barras invertidas en mi cookie en Python

De todos modos, así que básicamente estoy manteniendo la entrada de información en un formulario en una cookie. Estoy intentando anexar a la cookie anterior con la nueva información ingresada. Pero por alguna razón en la tercera entrada de datos, la cookie de repente se pone "\" en ella. Sin embargo, no estoy seguro de dónde vienen.

Este es el tipo de salida que estoy recibiendo:

"\" \\ "\\\\" prueba: más \\\\ ": rttre \\": más \ "; y más"

#!/usr/local/bin/python 

import cgi,os,time,Cookie 
#error checking 
import cgitb 
cgitb.enable() 

if 'HTTP_COOKIE' in os.environ: 
    cookies = os.environ['HTTP_COOKIE'] 
    cookies = cookies.split('; ') 
    for myCookie in cookies: 
     myCookie = myCookie.split('=') 
     name = myCookie[0] 
     value = myCookie[1] 
     if name == 'critter' : 
      hideMe = value 

#import critterClass 

#get info from form 
form = cgi.FieldStorage() 
critterName = form.getvalue('input') 
input2 = form.getvalue('input2') 
hiddenCookie = form.getvalue('hiddenCookie') 
hiddenVar = form.getvalue('hiddenVar') 

#make cookie 
cookie = Cookie.SimpleCookie() 

#set critter Cookie 
if critterName is not None: 
    cookie['critter'] = critterName 
#If already named 
else: 
    #if action asked, append cookie 
    if input2 is not None: 
     cookie['critter'] = hideMe+":"+input2 
    else: 
     cookie['critter'] = "default" 

print cookie 


print "Content-type: text/html\n\n" 



if ((critterName is None) and (input2 is None)): 
    print """ 
    <form name="critter" id="critter" method="post" action="critter.py"> 
    <label for="name">Name your pet: <input type="text" name="input" id="input" /></label> 
    <input type="submit" name="submit" id="submit" value="Submit" /> 
    </form> 
    """ 
else: 
    formTwo =""" 
    <form name="critter2" id="critter2" method="post" action="critter.py"> 
    <label for="name">%s wants to: <input type="text" name="input2" id="input2" /></label> 
    <input type="hidden" name="hiddenVar" id="hiddenVar" value="%s" /> 
    <input type="submit" name="submit" id="submit" value="Submit" /> 
    </form> 
    [name,play,feed,mood,levels,end] 
    """ 
    print formTwo % (critterName,critterName) 

if 'HTTP_COOKIE' in os.environ: 
    cookies = os.environ['HTTP_COOKIE'] 
    cookies = cookies.split('; ') 
    for myCookie in cookies: 
     myCookie = myCookie.split('=') 
     name = myCookie[0] 
     value = myCookie[1] 
     if name == 'critter' : 
      print "name"+name 
      print "value"+value 
+0

Gravemente interesante formateo. Eché un vistazo para arreglarlo, pero era sopa de etiqueta. :) Inténtalo de nuevo, límpialo para que parezca el código Python normal, luego selecciona el bloque de código y haz clic en el botón "Ejemplo de código" encima del editor (el "101010"). – unwind

+0

Me disculpo, espero que esto sea mejor. – Levi

+0

Mucho mejor, gracias! :) – unwind

Respuesta

3

Según lo explicado por otros, las barras diagonales escapan de los caracteres de comillas dobles que inserta en el valor de la cookie. El mecanismo (oculto) en acción aquí es la clase SimpleCookie. El método BaseCookie.output() devuelve una representación de cadena adecuada para enviarse como encabezados HTTP.Insertará caracteres de escape (barras invertidas) antes de los caracteres de comillas dobles y antes de los caracteres de barra invertida.

La declaración

print cookie 

activa BaseCookie.output().

En cada viaje su cadena hace a través del método de la cookie output(), las barras invertidas se multiplican (comenzando con el primer par de comillas).

>>> c1=Cookie.SimpleCookie() 
>>> c1['name']='A:0' 
>>> print c1 
Set-Cookie: name="A:0" 
>>> c1['name']=r'"A:0"' 
>>> print c1 
Set-Cookie: name="\"A:0\"" 
>>> c1['name']=r'"\"A:0\""' 
>>> print c1 
Set-Cookie: name="\"\\\"A:0\\\"\"" 
>>> 
2

no estoy seguro, pero parece que la cadena Python normal escapar. Si tiene una cadena que contiene una barra invertida o una comilla doble, por ejemplo, Python a menudo la imprimirá en forma de escape, para hacer que la cadena impresa sea una cadena literal válida.

El siguiente fragmento ilustra:

>>> a='hell\'s bells, \"my\" \\' 
>>> a 
'hell\'s bells, "my" \\' 
>>> print a 
hell's bells, "my" \ 

No estoy seguro si esto es relevante, tal vez alguien con más conocimiento del dominio pueda intervenir

+0

¿Crees que si escribiera una expresión regular para sacar el escape, funcionaría? Miré a mi alrededor y descubrí que no había una función unescape() como php has. – Levi

+0

Raw Strings se imprimirá como está y no se escapará, aunque no está seguro de si SimpleCookie lo admite. –

2

Las barras son el resultado de escapar de las comillas dobles.. Aparentemente, la primera vez, su código está viendo la comilla doble y escapándola agregando una barra invertida. Luego lee la barra invertida escapada y escapa de la barra inclinada al anteponerla con una barra diagonal inversa. Luego lee ...

El problema está sucediendo cuando llamas a append.

1

Las barras diagonales inversas se utilizan para "escapar" caracteres en cadenas que de otro modo tendrían un significado especial, lo que les privaría de su significado especial. El caso clásico es la forma en que puede incluir comillas en cadenas entre comillas, por ejemplo:

Bob said "Hey!" 

que puede escribirse como una cadena de esta manera:

"Bob said \"Hey!\"" 

Por supuesto, es posible que desee tener una barra diagonal inversa, por lo que "\" solo significa una sola barra inclinada invertida.

EDIT: En respuesta a su comentario sobre otra respuesta (sobre el uso de una expresión regular para eliminar las barras) creo que está recogiendo el extremo equivocado del palo. Las barras no son el problema, son un síntoma. El problema es que estás haciendo viajes redondos tratando cadenas que representan cadenas entrecomilladas como si fueran cadenas simples. Imaginemos dos amigos, Bob y Sam, teniendo una conversación:

Bob: Hey! 
Sam: Did you say "Hey!"? 
Bob: Did you say "Did you say \"Hey!\"?"? 

Es por eso que el no aparecen hasta el tercer tiempo.

2

como ya se ha dicho, está experimentando problemas de cuerda escapar tan pronto como se añada "y más" en el extremo de la cookie.

Hasta ese momento, el encabezado de la cookie se devuelve desde SimpleCookie sin incluir comillas. (Si no hay espacios en el valor de la cookie, no son necesarias las citas a continuación, que encierran.)

# HTTP cookie header with no spaces in value 
Set-Cookie: cookie=value 

# HTTP cookie header with spaces in value 
Set-Cookie: cookie="value with spaces" 

se recomienda usar la misma clase SimpleCookie analizar la cabecera de cookies inicialmente, ahorrándole de hacerlo a mano, y también manejando desengranar las cuerdas apropiadamente.

cookies = Cookie.SimpleCookie(os.environ.get('HTTP_COOKIE', '')) 
print cookies['critter'].value 

edición: Todo este trato con los espacios no se aplica a esta pregunta (aunque puede en ciertas circunstancias venir a morder cuando no lo esté esperando.) Pero mi sugerencia de utilizar la SimpleCookie para analizar aún está en pie.

1

Otros ya han señalado que esto es resultado de una barra invertida: escapes de comillas y barras diagonales inversas. Solo quería señalar que si observa detenidamente la estructura de la salida que cita, puede ver cómo se está construyendo la estructura aquí.

El valor de la cookie que está recibiendo de SimpleCookie está envuelto entre comillas - el (sin procesar) cookie tiene, por ejemplo,

`'[...], critter="value1", [...]'` 

después de dividir en ', ' y '=', que tiene una cadena que contiene "value1". A continuación, agrega un nuevo valor a esa cadena, de modo que la cadena contenga "value1":value2.

La próxima vez, recupera esa cadena, pero con otro conjunto de citas que la envuelve, conceptualmente, ""value1":value2". Pero para que un navegador web no vea dos comillas al principio y piense que es todo lo que hay, se está escapando el conjunto interno de comillas, por lo que en realidad se devuelve como "\"value1\":value2".

A continuación, agrega otro trozo, realiza otro paso adelante y atrás entre el servidor y el cliente, y la próxima vez (porque esas barras invertidas también deben escaparse) obtienes "\"\\"value1\\":value2\":value3". Y así.

La solución correcta, como ya se ha señalado, es dejar que SimpleCookie realice el análisis en lugar de cortar las cadenas usted mismo.

+0

Gracias por tomarse el tiempo para caminar a través de la cadena de procesamiento. –

Cuestiones relacionadas