Escape arguments to filter commands

This will allow both the path to git-crypt and the path to the key file
to contain arbitrary characters, notably spaces.
This commit is contained in:
Andrew Ayer
2013-04-04 18:52:06 -07:00
parent b10fbcd299
commit 2b936c74f1
3 changed files with 22 additions and 17 deletions

View File

@@ -230,11 +230,8 @@ void init (const char* argv0, const char* keyfile)
std::string keyfile_path(resolve_path(keyfile)); std::string keyfile_path(resolve_path(keyfile));
// git config filter.git-crypt.smudge "git-crypt smudge /path/to/key" // git config filter.git-crypt.smudge "git-crypt smudge /path/to/key"
std::string command("git config filter.git-crypt.smudge \""); std::string command("git config filter.git-crypt.smudge ");
command += git_crypt_path; command += escape_shell_arg(escape_shell_arg(git_crypt_path) + " smudge " + escape_shell_arg(keyfile_path));
command += " smudge ";
command += keyfile_path;
command += "\"";
if (system(command.c_str()) != 0) { if (system(command.c_str()) != 0) {
std::clog << "git config failed\n"; std::clog << "git config failed\n";
@@ -242,11 +239,8 @@ void init (const char* argv0, const char* keyfile)
} }
// git config filter.git-crypt.clean "git-crypt clean /path/to/key" // git config filter.git-crypt.clean "git-crypt clean /path/to/key"
command = "git config filter.git-crypt.clean \""; command = "git config filter.git-crypt.clean ";
command += git_crypt_path; command += escape_shell_arg(escape_shell_arg(git_crypt_path) + " clean " + escape_shell_arg(keyfile_path));
command += " clean ";
command += keyfile_path;
command += "\"";
if (system(command.c_str()) != 0) { if (system(command.c_str()) != 0) {
std::clog << "git config failed\n"; std::clog << "git config failed\n";
@@ -254,11 +248,8 @@ void init (const char* argv0, const char* keyfile)
} }
// git config diff.git-crypt.textconv "git-crypt diff /path/to/key" // git config diff.git-crypt.textconv "git-crypt diff /path/to/key"
command = "git config diff.git-crypt.textconv \""; command = "git config diff.git-crypt.textconv ";
command += git_crypt_path; command += escape_shell_arg(escape_shell_arg(git_crypt_path) + " diff " + escape_shell_arg(keyfile_path));
command += " diff ";
command += keyfile_path;
command += "\"";
if (system(command.c_str()) != 0) { if (system(command.c_str()) != 0) {
std::clog << "git config failed\n"; std::clog << "git config failed\n";
@@ -278,8 +269,7 @@ void init (const char* argv0, const char* keyfile)
if (path_to_top.empty()) { if (path_to_top.empty()) {
command += "."; command += ".";
} else { } else {
command += path_to_top; // git rev-parse --show-cdup only outputs sequences of ../ so we command += escape_shell_arg(path_to_top);
// don't need to worry about shell escaping :-)
} }
if (system(command.c_str()) != 0) { if (system(command.c_str()) != 0) {

View File

@@ -112,3 +112,17 @@ void open_tempfile (std::fstream& file, std::ios_base::openmode mode)
delete[] path; delete[] path;
} }
std::string escape_shell_arg (const std::string& str)
{
std::string new_str;
new_str.push_back('"');
for (std::string::const_iterator it(str.begin()); it != str.end(); ++it) {
if (*it == '"' || *it == '\\' || *it == '$' || *it == '`') {
new_str.push_back('\\');
}
new_str.push_back(*it);
}
new_str.push_back('"');
return new_str;
}

View File

@@ -38,6 +38,7 @@
int exec_command (const char* command, std::ostream& output); int exec_command (const char* command, std::ostream& output);
std::string resolve_path (const char* path); std::string resolve_path (const char* path);
void open_tempfile (std::fstream&, std::ios_base::openmode); void open_tempfile (std::fstream&, std::ios_base::openmode);
std::string escape_shell_arg (const std::string&);
#endif #endif