En PHP, ¿qué significa que una función sea binaria segura?

120

PHP¿ En qué se entiende por función ser binary-safe?

¿Qué los hace especiales y dónde se utilizan normalmente?

Zacky112
fuente

Respuestas:

106

Significa que la función funcionará correctamente cuando le pase datos binarios arbitrarios (es decir, cadenas que contengan bytes no ASCII y / o bytes nulos).

Por ejemplo, una función no binaria segura podría basarse en una función C que espera cadenas terminadas en nulo, por lo que si la cadena contiene un carácter nulo, la función ignoraría cualquier cosa después de ella.

Esto es relevante porque PHP no separa claramente los datos binarios y de cadena.

Michael Borgwardt
fuente
2
¿Significa eso que las cadenas binarias seguras solo contienen "caracteres" de 1 byte de longitud?
Charlie Parker
3
@CharlieParker: No, lo entendiste al revés. La seguridad binaria es una propiedad de las funciones, lo que significa que procesan cualquier cadena correctamente. Lo contrario sería una cadena que contiene solo caracteres ASCII y no caracteres nulos; dicha cadena debe ser procesada correctamente por cualquier función.
Michael Borgwardt
tal vez me confundí porque estaba leyendo el protocolo redis para "cadenas a granel" y decía que representan una "cadena binaria segura única". Creo que ahora entiendo tu publicación correctamente. Sin embargo, ¿tiene sentido decir que una cadena es "binaria segura" (como en el ejemplo que proporcioné)?
Charlie Parker
93

Los otros usuarios ya mencionaron lo que binary safesignifica en general.

En PHP, el significado es más específico, refiriéndose solo a lo que Michael da como ejemplo.

Todas las cadenas en PHP tienen una longitud asociada, que es la cantidad de bytes que la componen. Cuando una función manipula una cadena, puede:

  1. Confíe en esa longitud de metadatos.
  2. Confíe en que la cadena esté terminada en nulo, es decir, que después de los datos que son realmente parte de la cadena, 0aparecerá un byte con valor .

También es cierto que todas las variables PHP de cadena manipuladas por el motor también tienen terminación nula. El problema con las funciones que se basan en 2. es que, si la cadena en sí contiene un byte con valor 0, la función que lo está manipulando pensará que la cadena ha terminado en ese punto e ignorará todo después de eso.

Por ejemplo, si la strlenfunción de PHP funcionara como la biblioteca estándar de C strlen, el resultado aquí sería incorrecto:

$str = "abc\x00abc";
echo strlen($str); //gives 7, not 3!
Artefacto
fuente
15
¡Por fin un ejemplo!
Raffaele
5
En mi prueba en PHP 7.0, la función strlen () es una función binaria segura.
linjie
@Artefacto: ¿Estás diciendo que la función PHP incorporada strlen()es una función binaria segura ? Lo estoy confirmando porque en la página del Manual de PHP para la función strlen()no se ha mencionado si es una función segura para binarios o una función no segura para binarios . Lo único que falta en el Manual de PHP está creando confusión en mi mente, así que quiero confirmarlo de su parte. Espero ansiosamente su respuesta. Gracias.
PHPLover
@PHPLover sí strlen () es binario seguro. dirigido php -r 'var_dump("\x00\x00\x00");'a verificar, pero strlen de PHP ha sido seguro binaria por un muy largo tiempo, ya que al menos PHP 4.x (Dicho esto, hay una abominación llamada "mb_overload", pero deja a pretender que no existe - php.net /manual/en/mbstring.overload.php )
hanshenrik
62

Más ejemplos:

<?php

    $string1 = "Hello";
    $string2 = "Hello\x00World";

    // This function is NOT ! binary safe
    echo strcoll($string1, $string2); // gives 0, strings are equal.

    // This function is binary safe
    echo strcmp($string1, $string2); // gives <0, $string1 is less than $string2.

?>

\xindica notación hexadecimal. Ver: cadenas PHP

0x00 = NULL
0x04 = EOT (End of transmission)

Tabla ASCII para ver la lista de caracteres ASCII

Subscriberius
fuente
Solo para asegurarme de que lo he entendido, entonces Hello\r\nWORLDno debería ser lo mismo que Hellosi la función fuera binaria segura, ¿verdad?
Charlie Parker
Además, ¿cómo se implementa dicha función? ¿Existe una expresión regular que compruebe que es binaria segura o utiliza un método diferente?
Charlie Parker
@Subscriberius: ¿La función incorporada es strlen() binaria segura ?
PHPNut