diff --git a/src/lxc/criu.c b/src/lxc/criu.c index 67d6fdc55..f22873643 100644 --- a/src/lxc/criu.c +++ b/src/lxc/criu.c @@ -282,7 +282,7 @@ static void exec_criu(struct criu_opts *opts) } } - if (!lxc_deslashify(path)) { + if (!lxc_deslashify(&path)) { ERROR("failed to deslashify %s", path); free(path); goto err; diff --git a/src/lxc/utils.c b/src/lxc/utils.c index c72c26a50..ebf3ad981 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -716,21 +716,40 @@ char **lxc_normalize_path(const char *path) return components; } -bool lxc_deslashify(char *path) +bool lxc_deslashify(char **path) { - char **parts = NULL, *path2; + char *p; + char **parts = NULL; + size_t n, len; - parts = lxc_normalize_path(path); + parts = lxc_normalize_path(*path); if (!parts) return false; - path2 = lxc_string_join("/", (const char **) parts, *path == '/'); - lxc_free_array((void **) parts, free); - if (!path2) + /* We'll end up here if path == "///" or path == "". */ + if (!*parts) { + len = strlen(*path); + if (!len) + return true; + n = strcspn(*path, "/"); + if (n == len) { + p = strdup("/"); + if (!p) + return false; + free(*path); + *path = p; + return true; + } + } + + p = lxc_string_join("/", (const char **)parts, **path == '/'); + lxc_free_array((void **)parts, free); + if (!p) return false; - strncpy(path, path2, strlen(path)); - free(path2); + free(*path); + *path = p; + return true; } diff --git a/src/lxc/utils.h b/src/lxc/utils.h index c2eef507b..88719a0f3 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -249,7 +249,7 @@ extern char *lxc_string_join(const char *sep, const char **parts, bool use_as_pr */ extern char **lxc_normalize_path(const char *path); /* remove multiple slashes from the path, e.g. ///foo//bar -> /foo/bar */ -extern bool lxc_deslashify(char *path); +extern bool lxc_deslashify(char **path); extern char *lxc_append_paths(const char *first, const char *second); /* Note: the following two functions use strtok(), so they will never * consider an empty element, even if two delimiters are next to