Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79f60472 authored by Ryan Prichard's avatar Ryan Prichard Committed by android-build-merger
Browse files

Merge "adb: fix escape_arg for multiple quotes" am: bcfc8a2a

am: 6065c03a

Change-Id: Ia1111aafd1caf7b51ea80291fda004fcaef73283
parents a7ab5d05 6065c03a
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -79,22 +79,24 @@ bool directory_exists(const std::string& path) {
}

std::string escape_arg(const std::string& s) {
  std::string result = s;

  // Escape any ' in the string (before we single-quote the whole thing).
  // The correct way to do this for the shell is to replace ' with '\'' --- that is,
  // close the existing single-quoted string, escape a single single-quote, and start
  // a new single-quoted string. Like the C preprocessor, the shell will concatenate
  // these pieces into one string.
  for (size_t i = 0; i < s.size(); ++i) {
    if (s[i] == '\'') {
      result.insert(i, "'\\'");
      i += 2;
    }

  std::string result;
  result.push_back('\'');

  size_t base = 0;
  while (true) {
    size_t found = s.find('\'', base);
    result.append(s, base, found - base);
    if (found == s.npos) break;
    result.append("'\\''");
    base = found + 1;
  }

  // Prefix and suffix the whole string with '.
  result.insert(result.begin(), '\'');
  result.push_back('\'');
  return result;
}
+32 −24
Original line number Diff line number Diff line
@@ -82,30 +82,38 @@ TEST(adb_utils, directory_exists_win32_symlink_junction) {
#endif

TEST(adb_utils, escape_arg) {
  ASSERT_EQ(R"('')", escape_arg(""));

  ASSERT_EQ(R"('abc')", escape_arg("abc"));

  ASSERT_EQ(R"(' abc')", escape_arg(" abc"));
  ASSERT_EQ(R"(''\''abc')", escape_arg("'abc"));
  ASSERT_EQ(R"('"abc')", escape_arg("\"abc"));
  ASSERT_EQ(R"('\abc')", escape_arg("\\abc"));
  ASSERT_EQ(R"('(abc')", escape_arg("(abc"));
  ASSERT_EQ(R"(')abc')", escape_arg(")abc"));

  ASSERT_EQ(R"('abc abc')", escape_arg("abc abc"));
  ASSERT_EQ(R"('abc'\''abc')", escape_arg("abc'abc"));
  ASSERT_EQ(R"('abc"abc')", escape_arg("abc\"abc"));
  ASSERT_EQ(R"('abc\abc')", escape_arg("abc\\abc"));
  ASSERT_EQ(R"('abc(abc')", escape_arg("abc(abc"));
  ASSERT_EQ(R"('abc)abc')", escape_arg("abc)abc"));

  ASSERT_EQ(R"('abc ')", escape_arg("abc "));
  ASSERT_EQ(R"('abc'\''')", escape_arg("abc'"));
  ASSERT_EQ(R"('abc"')", escape_arg("abc\""));
  ASSERT_EQ(R"('abc\')", escape_arg("abc\\"));
  ASSERT_EQ(R"('abc(')", escape_arg("abc("));
  ASSERT_EQ(R"('abc)')", escape_arg("abc)"));
  EXPECT_EQ(R"('')", escape_arg(""));

  EXPECT_EQ(R"('abc')", escape_arg("abc"));

  auto wrap = [](const std::string& x) { return '\'' + x + '\''; };
  const std::string q = R"('\'')";
  EXPECT_EQ(wrap(q), escape_arg("'"));
  EXPECT_EQ(wrap(q + q), escape_arg("''"));
  EXPECT_EQ(wrap(q + "abc" + q), escape_arg("'abc'"));
  EXPECT_EQ(wrap(q + "abc"), escape_arg("'abc"));
  EXPECT_EQ(wrap("abc" + q), escape_arg("abc'"));
  EXPECT_EQ(wrap("abc" + q + "def"), escape_arg("abc'def"));
  EXPECT_EQ(wrap("a" + q + "b" + q + "c"), escape_arg("a'b'c"));
  EXPECT_EQ(wrap("a" + q + "bcde" + q + "f"), escape_arg("a'bcde'f"));

  EXPECT_EQ(R"(' abc')", escape_arg(" abc"));
  EXPECT_EQ(R"('"abc')", escape_arg("\"abc"));
  EXPECT_EQ(R"('\abc')", escape_arg("\\abc"));
  EXPECT_EQ(R"('(abc')", escape_arg("(abc"));
  EXPECT_EQ(R"(')abc')", escape_arg(")abc"));

  EXPECT_EQ(R"('abc abc')", escape_arg("abc abc"));
  EXPECT_EQ(R"('abc"abc')", escape_arg("abc\"abc"));
  EXPECT_EQ(R"('abc\abc')", escape_arg("abc\\abc"));
  EXPECT_EQ(R"('abc(abc')", escape_arg("abc(abc"));
  EXPECT_EQ(R"('abc)abc')", escape_arg("abc)abc"));

  EXPECT_EQ(R"('abc ')", escape_arg("abc "));
  EXPECT_EQ(R"('abc"')", escape_arg("abc\""));
  EXPECT_EQ(R"('abc\')", escape_arg("abc\\"));
  EXPECT_EQ(R"('abc(')", escape_arg("abc("));
  EXPECT_EQ(R"('abc)')", escape_arg("abc)"));
}

void test_mkdirs(const std::string& basepath) {