diff options
author | Junio C Hamano <gitster@pobox.com> | 2010-01-22 14:17:06 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2010-01-22 14:31:30 -0800 |
commit | af82559b435aa2a18f38a4f47a93729c8dc543d3 (patch) | |
tree | 1b778e52a005cdd96b3f59c6439c88a9ec83e0f8 /builtin-mv.c | |
parent | 30c9e919b6ef33b0427a3ad784ed9e951ea48648 (diff) | |
download | git-af82559b435aa2a18f38a4f47a93729c8dc543d3.tar.gz git-af82559b435aa2a18f38a4f47a93729c8dc543d3.tar.xz |
git-mv: fix moving more than one source to a single destination
The code used as if return value from basename(3) were stable, but
often the function is implemented to return a pointer to a static
storage internal to it.
Because basename(3) is also allowed to modify its input parameter in
place, casting constness away from the strings we obtained from the
caller and giving them to basename is a no-no.
Reported, and initial fix and test supplied by David Rydh.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-mv.c')
-rw-r--r-- | builtin-mv.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/builtin-mv.c b/builtin-mv.c index 82471869a..c07f53b34 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -24,10 +24,13 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, result[count] = NULL; for (i = 0; i < count; i++) { int length = strlen(result[i]); - if (length > 0 && is_dir_sep(result[i][length - 1])) - result[i] = xmemdupz(result[i], length - 1); - if (base_name) - result[i] = basename((char *)result[i]); + int to_copy = length; + while (to_copy > 0 && is_dir_sep(result[i][to_copy - 1])) + to_copy--; + if (to_copy != length || base_name) { + char *it = xmemdupz(result[i], to_copy); + result[i] = base_name ? strdup(basename(it)) : it; + } } return get_pathspec(prefix, result); } |