From d389f5dd46a743dc39ff1c8d0ab744cf2ae511c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Mon, 11 Dec 2017 20:17:31 +0100 Subject: [PATCH] Tar: do not assume `exec` yields a POSIX shell --- plugins/_disabled/tar/tar.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/plugins/_disabled/tar/tar.php b/plugins/_disabled/tar/tar.php index 9d3a46f..cf60bc8 100644 --- a/plugins/_disabled/tar/tar.php +++ b/plugins/_disabled/tar/tar.php @@ -17,8 +17,10 @@ along with this program. If not, see . */ -# do not enable recursive tars by default -$TAR_FLAGS = "--no-recursion"; +$TAR_BINARY = "/bin/tar"; + +# Add arbitrary parameters to tar +$TAR_FLAGS = ""; # send content length for browsers to display the progress bar # note : won't work if the http server uses Chunked transfer encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding) @@ -45,21 +47,24 @@ if ( ! is_dir($realDir) ) { die("Directory Not Found"); } -# change to the parent directory -chdir(dirname($realDir)); +function escapePath($path) { + # same as escapeshellarg function but this supports utf8 regardless of locale + return "'".str_replace("'", "'\\''", $path)."'"; +} -$filesarg = basename($realDir); -# same as escapeshellarg function but this supports utf8 regardless of locale -$filesarg = "'".str_replace("'", "'\\''", $filesarg)."'"; -$filesarg = "$filesarg/*"; +$path = escapePath(realpath(dirname($realDir))); +$filesarg = escapePath(basename($realDir)); # compute and send content-length header if ($SEND_CONTENT_LENGTH) { - $out = exec("tar $TAR_FLAGS --totals -cf /dev/null $filesarg 2>&1", $output, $ret); + $out = exec("$TAR_BINARY $TAR_FLAGS --totals -cf /dev/null " + . "-C $path $filesarg 2>&1", + $output, $ret); preg_match('/^Total bytes written: ([0-9]+) /', $out, $matches); $totalsize = $matches[1]; - ($totalsize > 1000 and $ret === 0) or die("Could not tar: $filesarg. Try checking permissions."); + ($totalsize > 1000 and $ret === 0) + or die("Could not tar: $filesarg. Try checking permissions."); header("Content-Length: $totalsize"); } @@ -68,6 +73,6 @@ if ($SEND_CONTENT_LENGTH) { header('Content-Type: application/x-tar'); header('Content-Disposition: attachment; filename="'.basename($realDir).'.tar"'); -passthru("tar $TAR_FLAGS -c $filesarg"); +passthru("$TAR_BINARY $TAR_FLAGS -C $path -c $filesarg"); ?>