1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-09-20 00:49:11 +02:00

Fix escaping of "git log ---format" command on Windows

Summary:
On Windows, the PHP function escapeshellarg() replaces '%' with ' ' (space). This is apparently because there is no safe way to escape % inside of strings.

cmd.exe does use "^" as an escape character, so I think replacing "xyz" with "^x^y^z" might work for arbitrary strings (maybe?), or at least some subset of strings, but I don't know cmd.exe well enough to make that call without being concerned I'm introducing a security issue.

Although this patch is dumb, it's certinaly safe, and can only do something wrong if the user has environmental variables like H, P, T, or x01, in which case they're sort of asking for it.

cmd.exe also truncates output on \0, so use \1 as a delimiter instead.

Seriously it's like this thing was written in 1982 and never ever changed.

Test Plan: Created D1783 successfully after applying this patch.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran, epriestley

Maniphest Tasks: T124

Differential Revision: https://secure.phabricator.com/D1785
This commit is contained in:
epriestley 2012-03-05 13:22:41 -08:00
parent d7b10e4f44
commit 0e35dc64a9

View file

@ -75,10 +75,19 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
$against = $this->getRelativeCommit().'..HEAD';
}
// NOTE: Windows escaping of "%" symbols apparently is inherently broken;
// when passed throuhgh escapeshellarg() they are replaced with spaces.
// TODO: Learn how cmd.exe works and find some clever workaround?
// NOTE: If we use "%x00", output is truncated in Windows.
list($info) = $this->execxLocal(
'log %s --format=%s --',
phutil_is_windows()
? 'log %s --format=%C --'
: 'log %s --format=%s --',
$against,
'%H%x00%T%x00%P%x00%at%x00%an%x00%s');
'%H%x01%T%x01%P%x01%at%x01%an%x01%s');
$commits = array();
@ -86,7 +95,7 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
$info = explode("\n", $info);
foreach ($info as $line) {
list($commit, $tree, $parents, $time, $author, $title)
= explode("\0", $line, 6);
= explode("\1", $line, 6);
$commits[] = array(
'commit' => $commit,