static uint32_t StringToGenericRegister(llvm::StringRef s);
- static const char *GetShellSafeArgument(const FileSpec &shell,
- const char *unsafe_arg,
- std::string &safe_arg);
+ static std::string GetShellSafeArgument(const FileSpec &shell,
+ llvm::StringRef unsafe_arg);
// EncodeEscapeSequences will change the textual representation of common
// escape sequences like "\n" (two characters) into a single '\n'. It does
if (argv == nullptr || argv[0] == nullptr)
return false;
Args shell_arguments;
- std::string safe_arg;
shell_arguments.AppendArgument(shell_executable);
const llvm::Triple &triple = GetArchitecture().GetTriple();
if (triple.getOS() == llvm::Triple::Win32 &&
return false;
} else {
for (size_t i = 0; argv[i] != nullptr; ++i) {
- const char *arg =
- Args::GetShellSafeArgument(m_shell, argv[i], safe_arg);
- shell_command.Printf(" %s", arg);
+ std::string safe_arg = Args::GetShellSafeArgument(m_shell, argv[i]);
+ // Add a space to separate this arg from the previous one.
+ shell_command.PutCString(" ");
+ shell_command.PutCString(safe_arg);
}
}
shell_arguments.AppendArgument(shell_command.GetString());
m_argv.push_back(nullptr);
}
-const char *Args::GetShellSafeArgument(const FileSpec &shell,
- const char *unsafe_arg,
- std::string &safe_arg) {
+std::string Args::GetShellSafeArgument(const FileSpec &shell,
+ llvm::StringRef unsafe_arg) {
struct ShellDescriptor {
ConstString m_basename;
const char *m_escapables;
}
}
- safe_arg.assign(unsafe_arg);
+ std::string safe_arg(unsafe_arg);
size_t prev_pos = 0;
while (prev_pos < safe_arg.size()) {
// Escape spaces and quotes
} else
break;
}
- return safe_arg.c_str();
+ return safe_arg;
}
lldb::Encoding Args::StringToEncoding(llvm::StringRef s,
#include "gtest/gtest.h"
#include "lldb/Utility/Args.h"
+#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StringList.h"
#include <limits>
EXPECT_EQ(entries[2].GetQuoteChar(), '"');
EXPECT_EQ(entries[3].GetQuoteChar(), '\0');
}
+
+TEST(ArgsTest, GetShellSafeArgument) {
+ // Try escaping with bash at start/middle/end of the argument.
+ FileSpec bash("/bin/bash", FileSpec::Style::posix);
+ EXPECT_EQ(Args::GetShellSafeArgument(bash, "\"b"), "\\\"b");
+ EXPECT_EQ(Args::GetShellSafeArgument(bash, "a\""), "a\\\"");
+ EXPECT_EQ(Args::GetShellSafeArgument(bash, "a\"b"), "a\\\"b");
+
+ // String that doesn't need to be escaped
+ EXPECT_EQ(Args::GetShellSafeArgument(bash, "a"), "a");
+
+ // Try escaping with tcsh and the tcsh-specific "$" escape.
+ FileSpec tcsh("/bin/tcsh", FileSpec::Style::posix);
+ EXPECT_EQ(Args::GetShellSafeArgument(tcsh, "a$b"), "a\\$b");
+ // Bash however doesn't need escaping for "$".
+ EXPECT_EQ(Args::GetShellSafeArgument(bash, "a$b"), "a$b");
+
+ // Try escaping with an unknown shell.
+ FileSpec unknown_shell("/bin/unknown_shell", FileSpec::Style::posix);
+ EXPECT_EQ(Args::GetShellSafeArgument(unknown_shell, "a'b"), "a\\'b");
+ EXPECT_EQ(Args::GetShellSafeArgument(unknown_shell, "a\"b"), "a\\\"b");
+}