Skip to content

Commit 2ec8774

Browse files
bmwillgitster
authored andcommitted
mv: remove use of deprecated 'get_pathspec()'
Convert the 'internal_copy_pathspec()' function to 'prefix_path()' instead of using the deprecated 'get_pathspec()' interface. Also, rename 'internal_copy_pathspec()' to 'internal_prefix_pathspec()' to be more descriptive of what the funciton is actually doing. In addition to this, fix a memory leak caused by only duplicating some of the pathspec elements. Instead always duplicate all of the the pathspec elements as an intermediate step (with modificationed based on the passed in flags). This way the intermediate strings can then be freed after getting the result from 'prefix_path()'. Signed-off-by: Brandon Williams <bmwill@google.com> Reviewed-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 454cb6b commit 2ec8774

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

builtin/mv.c

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (C) 2006 Johannes Schindelin
55
*/
66
#include "builtin.h"
7+
#include "pathspec.h"
78
#include "lockfile.h"
89
#include "dir.h"
910
#include "cache-tree.h"
@@ -19,31 +20,42 @@ static const char * const builtin_mv_usage[] = {
1920
#define DUP_BASENAME 1
2021
#define KEEP_TRAILING_SLASH 2
2122

22-
static const char **internal_copy_pathspec(const char *prefix,
23-
const char **pathspec,
24-
int count, unsigned flags)
23+
static const char **internal_prefix_pathspec(const char *prefix,
24+
const char **pathspec,
25+
int count, unsigned flags)
2526
{
2627
int i;
2728
const char **result;
29+
int prefixlen = prefix ? strlen(prefix) : 0;
2830
ALLOC_ARRAY(result, count + 1);
29-
COPY_ARRAY(result, pathspec, count);
30-
result[count] = NULL;
31+
32+
/* Create an intermediate copy of the pathspec based on the flags */
3133
for (i = 0; i < count; i++) {
32-
int length = strlen(result[i]);
34+
int length = strlen(pathspec[i]);
3335
int to_copy = length;
36+
char *it;
3437
while (!(flags & KEEP_TRAILING_SLASH) &&
35-
to_copy > 0 && is_dir_sep(result[i][to_copy - 1]))
38+
to_copy > 0 && is_dir_sep(pathspec[i][to_copy - 1]))
3639
to_copy--;
37-
if (to_copy != length || flags & DUP_BASENAME) {
38-
char *it = xmemdupz(result[i], to_copy);
39-
if (flags & DUP_BASENAME) {
40-
result[i] = xstrdup(basename(it));
41-
free(it);
42-
} else
43-
result[i] = it;
40+
41+
it = xmemdupz(pathspec[i], to_copy);
42+
if (flags & DUP_BASENAME) {
43+
result[i] = xstrdup(basename(it));
44+
free(it);
45+
} else {
46+
result[i] = it;
4447
}
4548
}
46-
return get_pathspec(prefix, result);
49+
result[count] = NULL;
50+
51+
/* Prefix the pathspec and free the old intermediate strings */
52+
for (i = 0; i < count; i++) {
53+
const char *match = prefix_path(prefix, prefixlen, result[i]);
54+
free((char *) result[i]);
55+
result[i] = match;
56+
}
57+
58+
return result;
4759
}
4860

4961
static const char *add_slash(const char *path)
@@ -130,7 +142,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
130142
if (read_cache() < 0)
131143
die(_("index file corrupt"));
132144

133-
source = internal_copy_pathspec(prefix, argv, argc, 0);
145+
source = internal_prefix_pathspec(prefix, argv, argc, 0);
134146
modes = xcalloc(argc, sizeof(enum update_mode));
135147
/*
136148
* Keep trailing slash, needed to let
@@ -140,16 +152,16 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
140152
flags = KEEP_TRAILING_SLASH;
141153
if (argc == 1 && is_directory(argv[0]) && !is_directory(argv[1]))
142154
flags = 0;
143-
dest_path = internal_copy_pathspec(prefix, argv + argc, 1, flags);
155+
dest_path = internal_prefix_pathspec(prefix, argv + argc, 1, flags);
144156
submodule_gitfile = xcalloc(argc, sizeof(char *));
145157

146158
if (dest_path[0][0] == '\0')
147159
/* special case: "." was normalized to "" */
148-
destination = internal_copy_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
160+
destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
149161
else if (!lstat(dest_path[0], &st) &&
150162
S_ISDIR(st.st_mode)) {
151163
dest_path[0] = add_slash(dest_path[0]);
152-
destination = internal_copy_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
164+
destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME);
153165
} else {
154166
if (argc != 1)
155167
die(_("destination '%s' is not a directory"), dest_path[0]);

0 commit comments

Comments
 (0)