Loading adb/adb_utils.cpp +10 −5 Original line number Diff line number Diff line Loading @@ -45,10 +45,15 @@ bool directory_exists(const std::string& path) { std::string escape_arg(const std::string& s) { std::string result = s; // Insert a \ before any ' in the string. for (auto it = result.begin(); it != result.end(); ++it) { if (*it == '\'') { it = result.insert(it, '\\') + 1; // 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; } } Loading adb/adb_utils_test.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -30,21 +30,21 @@ TEST(adb_utils, 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')", 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)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(")); Loading adb/tests/test_adb.py +16 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ tests that attempt to touch all accessible attached devices. """ import hashlib import os import pipes import random import re import shlex Loading Loading @@ -162,6 +163,9 @@ class AdbWrapper(object): def shell_nocheck(self, cmd): return call_combined(self.adb_cmd + "shell " + cmd) def install(self, filename): return call_checked(self.adb_cmd + "install {}".format(pipes.quote(filename))) def push(self, local, remote): return call_checked(self.adb_cmd + "push {} {}".format(local, remote)) Loading Loading @@ -290,6 +294,18 @@ class AdbBasic(unittest.TestCase): self.assertEqual('t', adb.shell("FOO=a BAR=b echo t").strip()) self.assertEqual('123Linux', adb.shell("echo -n 123\;uname").strip()) def test_install_argument_escaping(self): """Make sure that install argument escaping works.""" adb = AdbWrapper() # http://b/20323053 tf = tempfile.NamedTemporaryFile("w", suffix="-text;ls;1.apk") self.assertIn("-text;ls;1.apk", adb.install(tf.name)) # http://b/3090932 tf = tempfile.NamedTemporaryFile("w", suffix="-Live Hold'em.apk") self.assertIn("-Live Hold'em.apk", adb.install(tf.name)) class AdbFile(unittest.TestCase): SCRATCH_DIR = "/data/local/tmp" Loading Loading
adb/adb_utils.cpp +10 −5 Original line number Diff line number Diff line Loading @@ -45,10 +45,15 @@ bool directory_exists(const std::string& path) { std::string escape_arg(const std::string& s) { std::string result = s; // Insert a \ before any ' in the string. for (auto it = result.begin(); it != result.end(); ++it) { if (*it == '\'') { it = result.insert(it, '\\') + 1; // 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; } } Loading
adb/adb_utils_test.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -30,21 +30,21 @@ TEST(adb_utils, 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')", 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)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(")); Loading
adb/tests/test_adb.py +16 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ tests that attempt to touch all accessible attached devices. """ import hashlib import os import pipes import random import re import shlex Loading Loading @@ -162,6 +163,9 @@ class AdbWrapper(object): def shell_nocheck(self, cmd): return call_combined(self.adb_cmd + "shell " + cmd) def install(self, filename): return call_checked(self.adb_cmd + "install {}".format(pipes.quote(filename))) def push(self, local, remote): return call_checked(self.adb_cmd + "push {} {}".format(local, remote)) Loading Loading @@ -290,6 +294,18 @@ class AdbBasic(unittest.TestCase): self.assertEqual('t', adb.shell("FOO=a BAR=b echo t").strip()) self.assertEqual('123Linux', adb.shell("echo -n 123\;uname").strip()) def test_install_argument_escaping(self): """Make sure that install argument escaping works.""" adb = AdbWrapper() # http://b/20323053 tf = tempfile.NamedTemporaryFile("w", suffix="-text;ls;1.apk") self.assertIn("-text;ls;1.apk", adb.install(tf.name)) # http://b/3090932 tf = tempfile.NamedTemporaryFile("w", suffix="-Live Hold'em.apk") self.assertIn("-Live Hold'em.apk", adb.install(tf.name)) class AdbFile(unittest.TestCase): SCRATCH_DIR = "/data/local/tmp" Loading