Skip to content

Commit 94bdbad

Browse files
committed
initial implementation
1 parent bfd34d6 commit 94bdbad

3 files changed

Lines changed: 78 additions & 1 deletion

File tree

README.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,32 @@
11
# phpquoteshellarg
2-
php quote shell arguments
2+
php quote shell arguments function
3+
... doing a better job than php's builtin escapeshellarg(): https://3v4l.org/Hkv7h
4+
5+
# installation
6+
the script is just a standalone .php file, you can just copypaste it.
7+
8+
another alternative is to use composer:
9+
```
10+
composer require 'divinity76/phpquoteshellarg'
11+
```
12+
# usage
13+
14+
```
15+
<?php
16+
require_once(__DIR__ . '/vendor/autoload.php');
17+
use function Divinity76\quoteshellarg\quoteshellarg;
18+
19+
$str="æøå\x01";
20+
var_dump(["str"=>$str,"escapeshellarg"=>escapeshellarg($str), "quoteshellarg"=>quoteshellarg($str)]);
21+
```
22+
may outputs something like
23+
```
24+
array(3) {
25+
["str"]=>
26+
string(7) "æøå"
27+
["escapeshellarg"]=>
28+
string(3) "''"
29+
["quoteshellarg"]=>
30+
string(9) "'æøå'"
31+
}
32+
```

composer.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "divinity76/phpquoteshellarg",
3+
"description": "php quote shell arguments",
4+
"keywords": ["quoteshellarg", "escapeshellarg"],
5+
"homepage": "https://github.com/divinity76/phprouter",
6+
"type": "library",
7+
"license": "Unlicense",
8+
"require": {
9+
"php": ">=7.2"
10+
},
11+
"autoload": {
12+
"psr-4": {"Divinity76\\": "src/Divinity76/"}
13+
}
14+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
declare (strict_types = 1);
3+
namespace Divinity76\quoteshellarg;
4+
5+
/**
6+
* quotes shell arguments
7+
* (doing a better job than escapeshellarg)
8+
*
9+
* @param string $arg
10+
* @throws UnexpectedValueException if $arg contains null bytes
11+
* @return string
12+
*/
13+
14+
function quoteshellarg(string $arg): string
15+
{
16+
static $isUnix = null;
17+
if ($isUnix === null) {
18+
$isUnix = in_array(PHP_OS_FAMILY, array('Linux', 'BSD', 'Darwin', 'Solaris'), true);
19+
}
20+
if ($isUnix) {
21+
// PHP's built-in escapeshellarg() for unix is kindof garbage: https://3v4l.org/Hkv7h
22+
// corrupting-or-stripping UTF-8 unicode characters like "æøå" and non-printable characters like "\x01",
23+
// both of which are fully legal in unix shell arguments.
24+
// In single-quoted-unix-shell-arguments there are only 2 bytes that needs special attention: \x00 and \x27
25+
if (false !== strpos($arg, "\x00")) {
26+
throw new UnexpectedValueException('unix shell arguments cannot contain null bytes!');
27+
}
28+
return "'" . strtr($arg, array("'" => "'\\''")) . "'";
29+
}
30+
// todo: quoteshellarg for windows? it's a nightmare though: https://docs.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way
31+
// fallback to php's builtin escapeshellarg
32+
return escapeshellarg($arg);
33+
}

0 commit comments

Comments
 (0)