2010-09-17 16 views
19

Estoy ayudando a un cliente a convertir su sitio de boletines de archivos planos de Perl de ISO-8859-1 a Unicode.Lista de comprobación para ir por Unicode con Perl

Dado que esta es mi primera vez, me gustaría saber si la siguiente "lista de verificación" está completa. Todo funciona bien en las pruebas, pero me puede estar perdiendo algo que solo ocurriría en raras ocasiones.

Esto es lo que he hecho hasta ahora (perdóname por sólo incluyendo "Resumen" ejemplos de código):

  1. de files hechas son siempre leídos y escritos en UTF-8:

    use open ':utf8'; 
    
  2. Hecho de entrada CGI seguro es recibido como UTF-8 (el sitio no está utilizando CGI.pm):

    s{%([a-fA-F0-9]{2})}{ pack ("C", hex ($1)) }eg; # Kept from existing code 
    s{%u([0-9A-F]{4})}{ pack ('U*', hex ($1)) }eg;  # Added 
    utf8::decode $_; 
    
  3. Hecho texto seguro se imprime como UTF-8: navegadores seguro

    binmode STDOUT, ':utf8'; 
    
  4. Hecho interpretan el contenido de mi como UTF-8:

    Content-Type: text/html; charset=UTF-8 
    <meta http-equiv="content-type" content="text/html;charset=UTF-8"> 
    
  5. formas seguras Hecho envían UTF-8 (probablemente no es necesario ya siempre y cuando la página de codificación se establece):

    accept-charset="UTF-8" 
    
  6. no creo que sea necesario lo siguiente, ya que el texto en línea (menús, títulos, etc.) es sólo en ASCII:

    use utf8; 
    

hace esto parece razonable, o me estoy perdiendo algo?

EDITAR: Probablemente también debería mencionar que ejecutaremos un lote por única vez para leer todos los archivos de datos de texto existentes y guardarlos en codificación UTF-8.

+1

No menciona qué utilizará para el "lote de un solo uso" para convertir los datos existentes. El problema que preveo es que algunos de los archivos existentes no contendrán ISO-8859-1, pero en realidad tendrán datos de CP1252 y algunos incluso pueden tener UTF-8. Este es exactamente el problema que [Encoding :: FixLatin] (http://search.cpan.org/dist/Encoding-FixLatin/) se escribió para resolverlo, por lo que puede resultarle útil. –

Respuesta

26
  • La capa :utf8PerlIO es not strict enough. Permite la entrada que cumple con los requisitos estructurales de secuencias de bytes UTF-8, pero para una buena seguridad, desea rechazar cosas que no son realmente válidas Unicode. Reemplácelo en todas partes con la capa PerlIO::encoding, por lo tanto: :encoding(UTF-8).

  • Por la misma razón, siempre Encode::decode('UTF-8', …), no Encode::decode_utf8(…).

  • decodificación hacer fracasar duro con una excepción, comparar:

    perl -E'use Encode qw(decode); say decode(q(UTF-8), qq(\x{c0})); say q(survived)' 
    perl -E'use Encode qw(decode); say decode(q(UTF-8), qq(\x{c0}), Encode::FB_CROAK); say q(survived)' 
    
  • Usted no está tomando el cuidado de los pares suplentes en la notación %u. Este es el único error importante que puedo ver en tu lista. 2. se escribe correctamente como:

    use Encode qw(decode); 
    use URI::Escape::XS qw(decodeURIComponent); 
    $_ = decode('UTF-8', decodeURIComponent($_), Encode::FB_CROAK); 
    
  • no hacer perder el tiempo con las funciones del módulo de utf8. Su documentación lo dice.Se pretende como pragma decirle a Perl que el código fuente está en UTF-8. Si desea hacer codificación/decodificación, use el módulo Encode.

  • Agregue el pragma utf8 de todos modos en cada módulo. No puede doler, pero tendrá un mantenimiento de código a prueba de futuro en caso de que alguien agregue esos literales de cadena. Vea también CodeLayout::RequireUseUTF8.

  • Emplea encoding::warnings para eliminar las actualizaciones implícitas restantes. Verifique para cada caso si esto es intencionado/necesario. En caso afirmativo, conviértalo en una actualización explícita con Unicode::Semantics. De lo contrario, esta es una pista que debería haber tenido anteriormente un paso de decodificación. Los documentos de http://p3rl.org/UNI dan consejos para decodificar inmediatamente después de recibir los datos de la fuente. Repase los lugares donde el código está leyendo/escribiendo datos y verifique que tiene un paso de decodificación/codificación, explícitamente (decode('UTF-8', …)) o implícitamente a través de una capa (use open pragma, binmode, forma de argumento 3 de open).

  • Para la depuración: Si no está seguro de qué cadena es en una variable en la que la representación en un momento determinado, puede no sólo print, utilizar las herramientas Devel::StringInfo y Devel::Peek lugar.

+0

Gracias por su aporte. Puede que sea un poco lento aquí, pero sería genial saber en qué número de la lista de verificación (si corresponde) * cada * punto de la respuesta se refiere. – W3Coder

+0

Además, ¿podría (o cualquier otra persona) ampliar un poco el tema de seguridad? ¿Perl Unicode representa un posible peligro para la seguridad (para sitios web) y cómo? – W3Coder

+0

Todos los lenguajes que funcionan de forma nativa con bytes en lugar de cadenas Unicode (Perl, PHP, Ruby) tienen este problema: a menos que ingrese controles específicos para detenerlo, permitirán a través de secuencias de bytes UTF-8 'over-long': es decir, decodificarían a un personaje de lo que debería expresarse usando una secuencia más corta. Si luego hace codificación HTML en los bytes, perderá un carácter '<' que ha sido codificado como 0xC0 0xB3 en lugar de 0x3C. – bobince

8

Siempre le falta algo. Sin embargo, el problema suele ser las incógnitas desconocidas. :)

Effective Perl Programming tiene un capítulo de Unicode que cubre muchos de los conceptos básicos de Perl. El único ítem que no cubrimos fue todo lo que tenía que hacer para asegurarse de que su servidor de base de datos y su servidor web hicieran lo correcto.

Algunas otras cosas que usted tiene que hacer:

  • actualizar a la más reciente de Perl que pueda. Las cosas de Unicode se hicieron mucho más fáciles en 5.8, y aún más fáciles en 5.10.

  • Asegúrese de que el contenido del sitio se convierta en UTF-8. Puede escribir un rastreador para acceder a las páginas y buscar el carácter de sustitución Unicode (esa cosa que se parece a un diamante con un signo de interrogación). Veamos si puedo hacerlo en StackOverflow: & # xfffd;

  • Asegúrese de que su servidor de base de datos sea compatible con UTF-8, configure las tablas con columnas con reconocimiento UTF-8 y diga a DBI que use el soporte UTF-8 en su controlador (parte de esto es en el libro).

  • Asegúrese de que todo lo que mira a @ARGV traduce los elementos de la configuración regional de la línea de comandos a UTF-8 (está en el libro).

Si encuentra algo más, por favor háganoslo saber respondiendo su propia pregunta con lo que dejamos afuera. ;)

+0

¿Puedo comprarlo en línea? ;) – W3Coder

+2

No sé si * usted * puede comprarlo en línea. Está en los principales vendedores de libros en muchos países de habla inglesa, pero no sé qué hay disponible para ti. Tengo una gran pila de ellos que puedo enviar casi (casi) a cualquier parte del mundo. –

+0

Lo siento por no ser claro, me gustaría comprar en línea y leer desde mi computadora (no quiero una copia física). – W3Coder

Cuestiones relacionadas