Merge "Fix ' escaping in adb."
This commit is contained in:
commit
d0008c971d
3 changed files with 29 additions and 8 deletions
|
@ -45,11 +45,16 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Prefix and suffix the whole string with '.
|
||||
|
|
|
@ -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("));
|
||||
|
|
|
@ -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
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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…
Reference in a new issue