Doc #80731 [Ver->Dup]: escapeshellarg() silently corrupts "\xFF" on linux
[email protected] Fri, 11 Mar 2022 09:34:39 +0000
| Newsgroups | php.doc.bugs |
|---|---|
| Message-ID | <[email protected]> |
Edit report at https://bugs.php.net/bug.php?id=80731&edit=1 ID: 80731 Updated by: [email protected] Reported by: divinity76 at gmail dot com Summary: escapeshellarg() silently corrupts "\xFF" on linux -Status: Verified +Status: Duplicate Type: Documentation Problem Package: Program Execution Operating System: Linux PHP Version: 8.0.2 -Assigned To: +Assigned To: cmb Block user comment: N Private report: N New Comment: > why does it only complain when given null bytes, and not > complain when given locale-invalid-characters? There is an explicit check for NUL bytes, since these mark the end of C strings, and as such may cause particularly dangerous behavior. Anyhow, closing as duplicate of <https://github.com/php/doc-en/issues/1452>. Previous Comments: ------------------------------------------------------------------------ [2021-02-11 16:27:59] divinity76 at gmail dot com @cmd interesting, but that begs the question, why does it only complain when given null bytes, and not complain when given locale-invalid-characters? ------------------------------------------------------------------------ [2021-02-11 15:40:57] [email protected] If mblen() is available on the system, escapeshellarg() works on multibyte characters according to the system locale[1], and skips invalid characters[2]. This is, however, not documented. [1] <https://3v4l.org/rdjpk> [2] <https://github.com/php/php-src/blob/c6723538054d96291abb6bad4628b9f55bc7fc17/ext/standard/exec.c#L313> ------------------------------------------------------------------------ [2021-02-11 15:34:02] divinity76 at gmail dot com FWIW this returns bool(true): <?php function linux_escapeshellarg(string $arg):string{ if(false!==strpos($arg, "\x00")){ throw new \InvalidArgumentException("argument contains null bytes, it's impossible to escape null bytes!"); } return "'".strtr($arg,["'"=>"'\\''"])."'"; } $everything_except_null = ""; for($i=1;$i<=0xFF;++$i){ $everything_except_null.=chr($i); } $cmd = "printf '%s' ".linux_escapeshellarg($everything_except_null); $res = shell_exec($cmd); var_dump($res === $everything_except_null); ------------------------------------------------------------------------ [2021-02-11 15:03:19] divinity76 at gmail dot com Description: ------------ escapeshellarg() silently corrupts "\xFF" on linux Test script: --------------- <?php /** * quote arguments using linux escape rules, regardless of host OS * (eg, it will use linux escape rules even when running on Windows) * * @param string $arg * @throws \InvalidArgumentException if argument contains null bytes * @return string */ function linux_escapeshellarg(string $arg): string { if (false !== strpos($arg, "\x00")) { throw new \InvalidArgumentException("argument contains null bytes, it's impossible to escape null bytes!"); } return "'" . strtr($arg, [ "'" => "'\\''" ]) . "'"; } $cmd = "printf '%s' ".linux_escapeshellarg("\xFF"); var_dump(bin2hex(shell_exec($cmd))); // ^ works fine. $cmd = "printf '%s' ".escapeshellarg("\xFF"); var_dump(bin2hex(shell_exec($cmd))); // ^ is corrupted.. Expected result: ---------------- string(2) "ff" string(2) "ff" Actual result: -------------- string(2) "ff" string(0) "" ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=80731&edit=1