LINUX.ORG.RU

Если я нашел ошибку в PHP , куда сообщить?

 ,


0

1

Предположительно нашел ошибку в РНР. В функции mb_strpos на винде. Проявляется на всех 7-8 версиях, хоть веб сервер, хоть cli.

Такой вопрос, возможно немного не по теме форума, но хз где спросить. На виндофорумах не шарят в пхп, а на пхп форумах все грустно.

Перемещено Zhbert из talks

Ответ на: комментарий от goingUp

Чтобы ее воспроизвести, нужна винда, а тут как понимаю, мало кто ее юзает.

Если вкратце, код типа

<?php
$data = file_get_contents("1.exe");

mb_internal_encoding('UTF-16LE');

$s = mb_convert_encoding('PLACEHOLDER_12','UTF-16LE','CP1251');
$r = mb_convert_encoding("new_text\0",'UTF-16LE','CP1251');
$pos = mb_strpos($data,$s,0,'UTF-16LE');

Вернет неправильное значение $pos. Т.е. не там, где строка.

А если заменить на strpos то все работает. Но неясно почему так здесь.

zer0cat
() автор топика
Ответ на: комментарий от zer0cat

Вроде это не совсем «баг». Просто:

Кодировка CP1251 — это однобайтовая кодировка, а UTF-16LE — это двухбайтовая

Попытка преобразовать текст из одной кодировки в другую может изменить длину строки и привести к тому, что искомая строка ($s) и содержимое файла ($data) не будут правильно соотноситься. Кроме того, использование символа \0 в строке "new_text\0" может вызвать проблемы, так как на уровне кода это нулевой байт, который может интерпретироваться как конец строки

Решение: Использовать побайтовые функции, поскольку работа идет с бинарными данными. Поэтому strpos как рази и работает «правильно», потому что: strpos() работает побайтово и не зависит от многобайтовых кодировок

romanlinux ★★★
()
Ответ на: комментарий от romanlinux

Во второй строке нуллбайт должен быть, т.к. если она будет короче первой (замена) , то прога не будет работать.

Но по поиску не пойму. Зачем тогда нужны mb_strpos? Для поиска чего?

zer0cat
() автор топика
Ответ на: комментарий от zer0cat

Функции с префиксом mb_ в PHP (например, mb_strpos, mb_strlen, и т.д.) относятся к расширению mbstring (multi-byte string), которое поддерживает работу с многобайтовыми кодировками символов, такими как UTF-8, UTF-16 и другие.

Стандартные строковые функции PHP (такие как strpos, strlen и др.) работают с байтами, а не с символами, поэтому они могут неправильно обрабатывать строки, содержащие символы, которые кодируются более чем в один байт (например, символы из наборов UTF-8, которые могут занимать 2-4 байта).

Например:

$str = "Привет"; // Кириллические символы в UTF-8
echo strlen($str);  // Выведет 12 вместо ожидаемых 6

$str = "Привет";
echo mb_strlen($str, 'UTF-8');  // Выведет 6


romanlinux ★★★
()
Ответ на: комментарий от zer0cat

mb_strpos? Для поиска чего?

mb_strpos выдает позицию не в байтах, а в символах (юникодных например). Если ты допустим из юникодной строки захочешь вырезать какое-то слово.

goingUp ★★★★★
()
Последнее исправление: goingUp (всего исправлений: 1)
Ответ на: комментарий от zer0cat

длина символа фиксированная (2 байта)

Или два, или четыре. Еще бывает всякое типа Surrogate Pairs.

Умножаю его на 2 - опять мимо.

Я так понял у тебя бинарный файл, а не чистая юникодная строка, и там могут быть символы по четыре байта. В любом случае mb_substr для работы с юникодом, для бинарных данных лучше просто substr.

goingUp ★★★★★
()
Ответ на: комментарий от zer0cat

Какую роль в твоём примере играет переменная $r ?

И про «не там где строка» - конкретнее скажи. Покажи hexdump файла в нужном месте и то чему равно $pos.

firkax ★★★★★
()
Ответ на: комментарий от zer0cat

почему оно его не читает как utf-16

Чего ты так думаешь? Ты ему передаешь считай рандомные бинарные данные, в которые вкраплены utf-16 строки. Оно может как раз и пытается читать все как utf-16, и где-то «видит» символы по 4 байта.

goingUp ★★★★★
()
Ответ на: комментарий от zer0cat

если у меня UTF-16

У тебя не UTF-16, у тебя бинарные данные. Понятие кодировки к ним не применимо. Если ты хочешь искать строки UTF-16 внутри бинарных данных, то тебе нужно после конвертирования строки в UTF-16 искать её всё-таки бинарно (т.е. с помощью strpos).

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Я полагал, что функция работает так - принимает на вход данные, и интерпретирует их как UTF-16, независимо от того, бинарные они, текстовые или какие еще.

zer0cat
() автор топика

Такой вопрос, возможно немного не по теме форума, но хз где спросить.

Где можно спросить перечислено здесь: https://www.php.net/support

В частности, нас интересует раздел Mailing Lists: https://www.php.net/mailing-lists.php

Подписываемся на рассылку, соответствующую теме вопроса, и вдумчиво пишем письмо на грамотном английском, соблюдая правила, которые перечислены выше.

annulen ★★★★★
()