LINUX.ORG.RU

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

 ,


0

1

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

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

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

Об ошибках сообщают в багтрекер. Пехепешный запросто гуглится. Если ты хотел спросить ошибка это или нет, то можно тут)

goingUp ★★★★★
()
Ответ на: комментарий от 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

Чтобы ее воспроизвести, нужна винда

О, даже в золотые годы php они не особо рвались фиксить баги под винду)

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

Так мне кажется, наоборот сейчас золотые. релизы только выходят, не успеваешь обновляться. Еще недавно на пятерке сидел, а тут уже 9 или какая.

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

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

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

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

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

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

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

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

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

Кстати, поймал такую же ошибку на $ uname -a Linux 5.4.0-146-generic #163-Ubuntu SMP Fri Mar 17 18:26:02 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

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)
Ответ на: комментарий от romanlinux

Т.е. я правильно понимаю - если у меня UTF-16, где длина символа фиксированная (2 байта), то я могу всегда брать strlen strpos ?

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

Подожди. Вот у меня показывает смещение 1023. Умножаю его на 2 - опять мимо. Могу скинуть файл, ради интереса, что тебя покажет.

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

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

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

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

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

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

Таких символов там нет, разве что РНР их ошибочно интерпретирует. В винде есть либо cp1251, либо вот utf16LE

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

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

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

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

Если это реальный экзешник, то это не юникод строка, а набор всяких бинарных данных. Например машкодов)

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

Но почему оно его не читает как utf-16 ? я же задаю mb_internal_encoding . Или РНР сам интерпретирует, как ему в голову зайдет?

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

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

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

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

Да не знаю, ну может и так. В общем, спасибо за помощь, тогда буду юзать strpos да и все.

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

сообщите в компетентные органы, там разберутся

lovesan ★★
()

Предположительно нашел ошибку в РНР.
Предположительно
в РНР
куда сообщить?

Очевидно что в спортлото.

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

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

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

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

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

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

неправильное значение $pos.

Неправильное это меньше?

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

Что значит неправильное значение? Оно должно вернуть смещение в символах, а strpos возвращает смещение в байтах.

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

UTF-16, где длина символа фиксированная (2 байта)

Нет.

Ну как нет.

The encoding is variable-length, as code points are encoded with one or two 16-bit code units.

anc ★★★★★
()

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

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

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

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

annulen ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.