fix memory leak in copy_remote_dir_local
Bug https://code.google.com/p/android/issues/detail?id=82436
Change-Id: I4bfa865638742e1b7cedd17f5b33dcc10c7f711c
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c
index ad59e81..7fb3e3b 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.c
@@ -893,6 +893,21 @@
return r1 ? : r2;
}
+/* Return a copy of the path string with / appended if needed */
+static char *add_slash_to_path(const char *path)
+{
+ if (path[strlen(path) - 1] != '/') {
+ size_t len = strlen(path) + 2;
+ char *path_with_slash = malloc(len);
+ if (path_with_slash == NULL)
+ return NULL;
+ snprintf(path_with_slash, len, "%s/", path);
+ return path_with_slash;
+ } else {
+ return strdup(path);
+ }
+}
+
static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
int copy_attrs)
{
@@ -900,28 +915,32 @@
copyinfo *ci, *next;
int pulled = 0;
int skipped = 0;
+ char *rpath_clean = NULL;
+ char *lpath_clean = NULL;
+ int ret = 0;
+
+ if (rpath[0] == '\0' || lpath[0] == '\0') {
+ ret = -1;
+ goto finish;
+ }
/* Make sure that both directory paths end in a slash. */
- if (rpath[0] == 0 || lpath[0] == 0) return -1;
- if (rpath[strlen(rpath) - 1] != '/') {
- int tmplen = strlen(rpath) + 2;
- char *tmp = malloc(tmplen);
- if (tmp == 0) return -1;
- snprintf(tmp, tmplen, "%s/", rpath);
- rpath = tmp;
+ rpath_clean = add_slash_to_path(rpath);
+ if (!rpath_clean) {
+ ret = -1;
+ goto finish;
}
- if (lpath[strlen(lpath) - 1] != '/') {
- int tmplen = strlen(lpath) + 2;
- char *tmp = malloc(tmplen);
- if (tmp == 0) return -1;
- snprintf(tmp, tmplen, "%s/", lpath);
- lpath = tmp;
+ lpath_clean = add_slash_to_path(lpath);
+ if (!lpath_clean) {
+ ret = -1;
+ goto finish;
}
- fprintf(stderr, "pull: building file list...\n");
/* Recursively build the list of files to copy. */
- if (remote_build_list(fd, &filelist, rpath, lpath)) {
- return -1;
+ fprintf(stderr, "pull: building file list...\n");
+ if (remote_build_list(fd, &filelist, rpath_clean, lpath_clean)) {
+ ret = -1;
+ goto finish;
}
for (ci = filelist; ci != 0; ci = next) {
@@ -929,11 +948,13 @@
if (ci->flag == 0) {
fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst);
if (sync_recv(fd, ci->src, ci->dst, 0 /* no show progress */)) {
- return 1;
+ ret = -1;
+ goto finish;
}
if (copy_attrs && set_time_and_mode(ci->dst, ci->time, ci->mode)) {
- return 1;
+ ret = -1;
+ goto finish;
}
pulled++;
} else {
@@ -946,7 +967,10 @@
pulled, (pulled == 1) ? "" : "s",
skipped, (skipped == 1) ? "" : "s");
- return 0;
+finish:
+ free(lpath_clean);
+ free(rpath_clean);
+ return ret;
}
int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int copy_attrs)