Что делать с тем фактом, что функция escapeshellarg() PHP не работает в Windows?

#php #windows #terminal

#php #Windows #терминал

Вопрос:

У меня есть файлы с допустимыми именами файлов. Если бы они не были допустимыми, их было бы невозможно сохранить в моей файловой системе. Windows. NTFS.

Например:

 E:videosHappy Fun Time!.mp4
  

Если я сделаю:

 if (file_exists('E:videosHappy Fun Time!.mp4'))
  

Затем PHP «видит» файл; он существует. Хорошо.

Однако, если я попытаюсь фактически использовать путь к файлу, например, отправив его в команде:

 shell_exec('test.exe --input=' . escapeshellarg('E:videosHappy Fun Time!.mp4'));
  

… затем test.exe получает / отправляется:

 test.exe --input="E:videosHappy Fun Time .mp4"
  

Она превратила «!» в пробел, что делает его более недействительным.

Я знаю, что они делают это по соображениям безопасности, и что правильное экранирование в Windows — это что-то вроде кошмара. Тем не менее, это все еще остается проблемой, поскольку я не могу ссылаться на какой-либо файл, содержащий «!» и, возможно, также другие допустимые символы.

При запуске такого рода вещей я обычно получаю «meh… на самом деле нам не хочется поддерживать реакцию разработчиков на вашу «странную ОС». Они действуют так, как будто Windows — это какой-то непонятный дистрибутив Linux, а не настольная ОС № 1 в мире. Даже если вы думаете, что это отстой, с чем я полностью согласен, кстати, разве задача кодирования не «забавна» в некотором роде для умных программистов? Довольно неприятно, когда люди ведут себя так, как будто PHP и другое программное обеспечение кроссплатформенны, когда на самом деле это «Linux-first, и, возможно, какая-нибудь полуфабрикатная поддержка Windows, если у нас есть время и хочется». (Но я остановлюсь на этом, опасаясь пометки «rant».)

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

Как может быть, что file_exists может безопасно проверять ее существование, даже с помощью «!»? file_exist Есть ли какой-то внутренний код, который безопасно и корректно проверяет все допустимые имена файлов, тогда как escapeshellarg() по какой-то причине этого не хватает? Или file_exist «запрашивает ОС» или «запрашивает файловую систему» каким-либо встроенным способом, который полностью обходит необходимость обрабатывать экранирование строки пути к файлу?

Я не знаю, что теперь делать. Какой-то парень ссылался на исходный код ReactOS, но это не PHP, и если это такое отличное решение, почему это не было включено в сам PHP? Я не понимаю, почему так много функций PHP никогда не обновляются / не улучшаются или не добавляются новые улучшенные, вместо того, чтобы каждый отдельный «PHPhant» (так я называю себя и других пользователей PHP) пытался собрать воедино свое собственное решение для таких важных и распространенных задач?

Комментарии:

1. Я не знаком с тем, что ! делает в командной строке Windows, но если вы знаете, что это безопасно, вы могли бы заменить ее заполнителем перед вызовом escape, то замените заполнитель обратно. Мне пока не удалось найти file_exists определение в исходном коде PHP. Также, возможно, одно из решений на php.net/manual/en/function.escapeshellarg.php#123718 решает это?

2. Вам, вероятно, потребуется ^! экранирование курсора, если вы продолжаете использовать cmd.exe вместо Powershell с его более последовательным «синтаксическим анализом» командной строки.

3. @mario Я не использую cmd.exe. PHP работает. И Windows. Кроме того, в PowerShell есть множество странных проблем, с которыми я столкнулся на собственном опыте, пытаясь заставить PHP и себя использовать его. И теперь, когда Windows Terminal становится чем-то особенным, PowerShell, как я полагаю, в любом случае уходит в прошлое. Но опять же, я не использую cmd.exe. Это то, что… используется.

4. @user3783243 Я начал использовать это сейчас, но мне кажется чрезвычайно странным использовать сторонний код вместо собственной функции PHP: github.com/johnstevenson/winbox-args