if (i != 0) {
result += ' ';
}
- std::string arg(argv[i]);
+ std::string arg = replace_all(argv[i], "\\", "\\\\");
+ arg = replace_all(arg, "\"", "\\\"");
if (arg.empty() || arg.find(' ') != std::string::npos) {
arg = FMT("\"{}\"", arg);
}
bool ends_with(std::string_view string, std::string_view suffix);
// Format `argv` as a simple string for logging purposes. That is, the result is
-// not intended to be machine parsable. `argv` must be terminated by a nullptr.
+// not intended to be easily machine parsable. `argv` must be terminated by a
+// nullptr.
std::string format_argv_for_logging(const char* const* argv);
// Format a hexadecimal string representing `data`. The returned string will be
TEST_CASE("util::format_argv_for_logging")
{
- const char* argv_0[] = {nullptr};
- CHECK(util::format_argv_for_logging(argv_0) == "");
+ SUBCASE("nullptr")
+ {
+ const char* argv[] = {nullptr};
+ CHECK(util::format_argv_for_logging(argv) == "");
+ }
- const char* argv_2[] = {"foo", "bar", nullptr};
- CHECK(util::format_argv_for_logging(argv_2) == "foo bar");
+ SUBCASE("plain arguments")
+ {
+ const char* argv[] = {"foo", "bar", nullptr};
+ CHECK(util::format_argv_for_logging(argv) == "foo bar");
+ }
+
+ SUBCASE("argument with space")
+ {
+ const char* argv[] = {"foo bar", "fum", nullptr};
+ CHECK(util::format_argv_for_logging(argv) == "\"foo bar\" fum");
+ }
+
+ SUBCASE("argument with double quote")
+ {
+ const char* argv[] = {"foo\"bar", "fum", nullptr};
+ CHECK(util::format_argv_for_logging(argv) == "foo\\\"bar fum");
+ }
+
+ SUBCASE("argument with backslash")
+ {
+ const char* argv[] = {"foo\\bar", "fum", nullptr};
+ CHECK(util::format_argv_for_logging(argv) == "foo\\\\bar fum");
+ }
}
TEST_CASE("util::format_base16")