Каковы функции PHP, которые, как говорят, не являются "бинарно-безопасными"? В какие библиотеки эти «недвоичные безопасные» функции передают строки? И почему? - PullRequest
0 голосов
/ 23 июня 2018

Я использую Windows 10 Home Single Language Edition , которая является 64-битной операционной системой на моей машине.

Я установил самую последнюю версию XAMPP , которая установила PHP 7.2.7 на мою машину.

Я задаю этот вопрос на основе выдержки из Руководства PHP :

Строка в PHP реализована как массив байтов и целое число с указанием длины буфера. У него нет информации о том, как эти байты переводятся в символы, оставляя эту задачу программист. Нет ограничений на значения строки состоит из; в частности, байты со значением 0 («байты NUL») разрешено в любом месте строки (однако, несколько функций, упомянутых в этом руководство не должно быть «бинарно-безопасным», может передавать строки в библиотеки которые игнорируют данные после байта NUL.)

Я очень хорошо понимаю разницу между бинарно-безопасными и небинарно-безопасными функциями в PHP. У меня в голове следуют сомнения. Пожалуйста, ответьте на них один за другим с соответствующими пояснениями и соответствующими примерами.

  • Является ли явление «небинарно-безопасных» и «бинарно-безопасных» функций присутствующим в PHP только потому, что весь синтаксический анализатор PHP написан на C языке ?
  • Каковы различия между C и PHP в случае обработки строк, содержащих любое значение (включая байт NUL)?
  • Мне нужны полные списки функций в PHP, которые «небинарно безопасны» и «бинарно безопасны».
  • Применима ли характеристика «недвоичный безопасный» и «двоичный безопасный» только к функциям, которые манипулируют над строками и не применима к функциям PHP, которые имеют дело с другими типами в PHP?
  • Почему недвоичные безопасные функции передают строки библиотекам?
  • Двоичные безопасные функции передают строки библиотекам, только если строка, которую они обрабатывают, содержит байт NUL?
  • Что это за библиотеки, которым эти «недвоичные безопасные» функции передают строки?
  • Как эти библиотеки обрабатывают строки, полученные от «небинарных безопасных» функций?
  • Работают ли "небинарные безопасные" функции как "бинарные безопасные" функции после передачи строк, содержащих байт NUL, в какую-либо библиотеку?

Ответы [ 3 ]

0 голосов
/ 29 июля 2018

Традиционно есть два способа представления строк: сигнализируя конец строки, используя специальный символ, или сохраняя ее длину вместе со строковыми данными. С использует первое; строка - это массив символов с нулевым символом в конце. Однако это имеет ограничение, заключающееся в том, что строки в C не могут использовать нулевой символ где-либо еще, кроме как в конце.

Чтобы преодолеть это ограничение, движок PHP использует эту структуру для представления строки:

struct _zend_string {
    zend_refcounted_h gc; /* refcount struct */
    zend_ulong        h;  /* hash value */
    size_t            len; /* length of string */
    char              val[1]; /* array of chars (using struct "hack") */
};

Как видите, разработчики PHP решили хранить длину строки вместе с ее данными.

Что будет, если смешать функции «бинарный безопасный» и «небинарный безопасный»?

Рассмотрим следующий фрагмент кода C, который может использоваться при написании расширения PHP:

zend_string *a = zend_string_init("a\0b", /* string length */ 3, 0);
zend_string *b = zend_string_init("a\0c", /* string length */ 3, 0);

if (strcmp(a->val, b->val) == 0) {
    php_printf("Strings are equal!");
}

Как вы думаете, что произойдет? Этот код выводит "Строки равны!" пока они явно не равны. Поскольку strcmp не учитывает длину строк, это небинарная безопасная функция.

Большинство стандартных строковых функций библиотеки C можно классифицировать как «недвоичные безопасные», поскольку они основаны на нулевом символе завершения.

При работе с zend_string в коде расширения вы должны использовать строковые функции Zend (zend_string_*) вместо строковой библиотеки C.

Чтобы исправить предыдущий код:

if (zend_string_equals(a, b)) {
    php_printf("Equal!");
} else {
    php_printf("Not equal");
}

Теперь это правильно печатает "Не равно".

0 голосов
/ 31 июля 2018

Как объяснил Аркаша, проблема «бинарно-безопасного» и «не-бинарно-безопасного» не имеет ничего общего с языком.

Использование нулевого байта (0x00) для обозначения концаСтрока проще (вероятно, именно поэтому C и пошел с ней), но недостатком является то, что вы не можете иметь нулевой байт нигде в строке, что является большим ограничением, если вам нужно обрабатывать все виды данных.Сохранение длины в виде части метаданных строки является более сложным, как показывает Пит, но оно позволяет обрабатывать данные любого типа.

Относительно того, какие функции являются «бинарно-безопасными» или «не-безопасными».бинарно-безопасный ", просто прочитайте руководство PHP перед , используя функции.Это то, чем я занимаюсь.Нет необходимости составлять список, потому что руководство по PHP уже объясняет, что вам нужно знать о функциях, в том числе, если они бинарно-безопасны или нет.

Большая часть вашего поста, я полагаю, связана снеправильное понимание объяснения PHP Manual, которое вы процитировали, особенно эту часть:

однако некоторые функции, которые в этом руководстве не являются «бинарно-безопасными», могут передавать строки библиотекам, которые игнорируютданные после байта NUL.

Позвольте мне попытаться прояснить ситуацию, добавив несколько моих собственных слов:

однако некоторые функции, упомянутые в этом руководстве, небыть «бинарно-безопасными», - это функции, которые может передавать строки библиотекам, которые игнорируют данные после байта NUL.

Так что на самом деле это не говорит «небинарные безопасные функции передают строки библиотекам ", это неверное толкование.Это означает, что «функции, которые могут передавать строки библиотекам, которые игнорируют данные после байта NUL, в этом руководстве называются небезопасными».

«Передача в библиотеки» - это еще один способсказать "вызов функций из других библиотек".«Игнорирование данных после байта NUL» - это поведение, которое называется небинарно-безопасным.

Еще один способ выразить это:

Некоторые функции в этом руководстве, как говорится, небыть "бинарно-безопасным" , потому что они могут вызывать другие функции, которые также не являются "бинарно-безопасными" (функции, которые игнорируют данные после байта NUL).

Я надеюсь, что это очищаетэто для вас.

0 голосов
/ 23 июня 2018

Вопрос о том, обрабатывает ли функция данные времени выполнения «бинарно-безопасным» способом или нет, не имеет никакого отношения к языку, на котором была реализована система. Это вопрос о том, как обрабатываются данные.PHP является языком высокого уровня, что означает, что он имеет реализацию высокого уровня строкового типа.Это не зависит от завершающего нулевого символа, на который полагается C, вместо этого тип строки поддерживает метаданные о сохраненной строке, что обеспечивает гораздо более гибкую и надежную реализацию.Это, однако, имеет мало общего с тем, чтобы быть "бинарно-безопасным" или нет.

На остальные ваши вопросы невозможно дать четкий ответ.Какие библиотеки использует php, зависит от ваших настроек, это динамическая среда.То, как потенциальные библиотеки обрабатывают данные, переданные им, опять же не имеет никакого отношения к тому, можно ли считать функцию php «бинарной безопасностью» - библиотека не знает о php, она только передает данные и обрабатывает их в соответствии с тем, как библиотекареализованы.

...