Co to znaczy w PHP, że funkcja jest binarna?

120

W PHPco to znaczy przez funkcję bycia binary-safe?

Co sprawia, że ​​są wyjątkowe i gdzie są zwykle używane?

Zacky112
źródło

Odpowiedzi:

106

Oznacza to, że funkcja będzie działać poprawnie, gdy przekażesz jej dowolne dane binarne (tj. Łańcuchy zawierające bajty inne niż ASCII i / lub bajty zerowe).

Na przykład funkcja niebinarnie bezpieczna może opierać się na funkcji C, która oczekuje ciągów zakończonych znakiem null, więc jeśli ciąg zawiera znak null, funkcja zignoruje wszystko po nim.

Jest to istotne, ponieważ PHP nie oddziela czysto ciągów i danych binarnych.

Michael Borgwardt
źródło
2
Czy to oznacza, że ​​binarne bezpieczne łańcuchy zawierają tylko „znaki” o długości 1 bajta?
Charlie Parker
3
@CharlieParker: Nie, masz to wstecz. Bezpieczeństwo binarne jest właściwością funkcji, co oznacza, że ​​przetwarzają one poprawnie dowolny ciąg. Odwrotnością byłby ciąg zawierający tylko znaki ASCII i żadnych znaków null - taki ciąg powinien być poprawnie przetwarzany przez dowolną funkcję.
Michael Borgwardt,
być może byłem zdezorientowany, ponieważ czytałem protokół redis dla „łańcuchów zbiorczych” i powiedział, że reprezentują one „pojedynczy bezpieczny binarny łańcuch binarny”. Myślę, że teraz poprawnie rozumiem twój post. Czy jednak ma sens stwierdzenie, że łańcuch jest „bezpieczny binarnie” (tak jak w podanym przeze mnie przykładzie)?
Charlie Parker
93

Inni użytkownicy już wspomnieli, co binary safeto ogólnie znaczy.

W PHP znaczenie jest bardziej szczegółowe, odwołując się tylko do tego, co Michael podaje jako przykład.

Wszystkie łańcuchy w PHP mają skojarzoną długość, która jest liczbą bajtów, które go tworzą. Gdy funkcja manipuluje łańcuchem, może:

  1. Polegaj na metadanych o tej długości.
  2. Polegaj na tym, że łańcuch jest zakończony wartością null, tj. Że po danych, które są w rzeczywistości częścią łańcucha, pojawi się bajt z wartością 0.

Prawdą jest również, że wszystkie ciągowe zmienne PHP, którymi manipuluje silnik, są również zakończone znakiem null. Problem z funkcjami, które opierają się na 2. polega na tym, że jeśli sam łańcuch zawiera bajt z wartością 0, funkcja, która nim manipuluje, pomyśli, że łańcuch zakończył się w tym momencie i zignoruje wszystko później.

Na przykład, jeśli strlenfunkcja PHP działałaby jak standardowa biblioteka C strlen, wynik byłby tutaj nieprawidłowy:

$str = "abc\x00abc";
echo strlen($str); //gives 7, not 3!
Artefacto
źródło
15
Wreszcie przykład!
Raffaele
5
W moim teście w PHP 7.0 funkcja strlen () jest bezpieczną funkcją binarną.
linjie
@Artefacto: Czy mówisz, że wbudowana funkcja PHP strlen()jest funkcją bezpieczną dla plików binarnych ? Potwierdzam od Ciebie, ponieważ na stronie podręcznika PHP dla funkcji strlen()nie wspomniano, czy jest to funkcja bezpieczna binarnie, czy niebinarna funkcja bezpieczna . Ta jedyna brakująca rzecz w podręczniku PHP powoduje zamieszanie w moim umyśle, więc chcę to potwierdzić od Ciebie. Z niecierpliwością czekam na Twoją odpowiedź. Dziękuję Ci.
PHPL Ponad
@PHPLover yes strlen () jest bezpieczna dla plików binarnych. uruchom, php -r 'var_dump("\x00\x00\x00");'aby sprawdzić, ale strlen php był binarny bezpieczny od bardzo dawna, od co najmniej php 4.x (to powiedziawszy, istnieje obrzydliwość o nazwie "mb_overload", ale udawajmy, że nie istnieje - php.net /manual/en/mbstring.overload.php )
hanshenrik
62

Więcej przykładów:

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

?>

\xoznacza notację szesnastkową. Zobacz: ciągi PHP

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

Tabela ASCII, aby wyświetlić listę znaków ASCII

Subscriberius
źródło
Aby upewnić się, że zrozumiałem, to Hello\r\nWORLDnie powinno być takie samo, jak Hellogdyby funkcja była bezpieczna binarnie, prawda?
Charlie Parker
W jaki sposób jest implementowana taka funkcja? Czy istnieje wyrażenie regularne, które sprawdza, czy plik binarny jest bezpieczny, czy też używa innej metody?
Charlie Parker
@Subscriberius: Czy wbudowana funkcja jest strlen() binarnie bezpieczna ?
PHPNut