From 94dc19ff57a2c5a09d74362d0c1a1231cc027d7f Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 14 Sep 2016 16:13:50 -0700 Subject: [PATCH] adb: let `adb push` follow symlinks. Bug: http://b/31491920 Test: touch foo; ln -s foo bar; adb push bar /data/local/tmp Test: python test_device.py Change-Id: I0a00b3d49fdf7206e27d66ac110b56e22449a1ad --- adb/file_sync_client.cpp | 2 +- adb/test_device.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/adb/file_sync_client.cpp b/adb/file_sync_client.cpp index 56ff68c58..f1e4179c3 100644 --- a/adb/file_sync_client.cpp +++ b/adb/file_sync_client.cpp @@ -606,7 +606,7 @@ static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath, } if (st.st_size < SYNC_DATA_MAX) { std::string data; - if (!android::base::ReadFileToString(lpath, &data)) { + if (!android::base::ReadFileToString(lpath, &data, true)) { sc.Error("failed to read all of '%s': %s", lpath, strerror(errno)); return false; } diff --git a/adb/test_device.py b/adb/test_device.py index 2efac9dd4..b12bf88b5 100644 --- a/adb/test_device.py +++ b/adb/test_device.py @@ -787,6 +787,36 @@ class FileOperationsTest(DeviceTest): if host_dir is not None: shutil.rmtree(host_dir) + @unittest.skipIf(sys.platform == "win32", "symlinks require elevated privileges on windows") + def test_push_symlink(self): + """Push a symlink. + + Bug: http://b/31491920 + """ + try: + host_dir = tempfile.mkdtemp() + + # Make sure the temp directory isn't setuid, or else adb will + # complain. + os.chmod(host_dir, 0o700) + + with open(os.path.join(host_dir, 'foo'), 'w') as f: + f.write('foo') + + symlink_path = os.path.join(host_dir, 'symlink') + os.symlink('foo', symlink_path) + + self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR]) + self.device.shell(['mkdir', self.DEVICE_TEMP_DIR]) + self.device.push(symlink_path, self.DEVICE_TEMP_DIR) + rc, out, _ = self.device.shell_nocheck( + ['cat', posixpath.join(self.DEVICE_TEMP_DIR, 'symlink')]) + self.assertEqual(0, rc) + self.assertEqual(out.strip(), 'foo') + finally: + if host_dir is not None: + shutil.rmtree(host_dir) + def test_multiple_push(self): """Push multiple files to the device in one adb push command.