Commit b8f26269 (fix directory separator treatment on Windows, 30-06-2009) introduced a bug on Mac OS X. The problem is that basename() may return a pointer to internal static storage space that will be overwritten by subsequent calls: > git mv dir/a.txt dir/b.txt other/ Checking rename of 'dir/a.txt' to 'other/b.txt' Checking rename of 'dir/b.txt' to 'other/b.txt' fatal: multiple sources for the same target, source=dir/b.txt, destination=other/b.txt This commit also fixed two potentially dangerous uses of prefix_filename() -- which returns static storage space -- in builtin-config.c and hash-object.c. get_pathspec(): If called with an empty pathspec, allocate a new pathspec with a copy of prefix. This is consistent with the behavior when called with a non-empty pathspec and prevents potential errors. Signed-off-by: David Rydh <dary@xxxxxxxxxxxxxxxxx> --- This is my first patch submission to git. Perhaps this patch should be split into two? The one-line change to builtin-mv.c suffices to fix the bug. builtin-config.c | 4 ++-- builtin-mv.c | 2 +- hash-object.c | 2 +- setup.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/builtin-config.c b/builtin-config.c index 2e3ef91..bf60f93 100644 --- a/builtin-config.c +++ b/builtin-config.c @@ -356,9 +356,9 @@ int cmd_config(int argc, const char **argv, const char *unused_prefix) config_exclusive_filename = git_etc_gitconfig(); else if (given_config_file) { if (!is_absolute_path(given_config_file) && prefix) - config_exclusive_filename = prefix_filename(prefix, + config_exclusive_filename = xstrdup(prefix_filename(prefix, strlen(prefix), - argv[2]); + argv[2])); else config_exclusive_filename = given_config_file; } diff --git a/builtin-mv.c b/builtin-mv.c index 8247186..1c1f8be 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -27,7 +27,7 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec, 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]); + result[i] = xstrdup(basename((char *)result[i])); } return get_pathspec(prefix, result); } diff --git a/hash-object.c b/hash-object.c index 9455dd0..3c509aa 100644 --- a/hash-object.c +++ b/hash-object.c @@ -91,7 +91,7 @@ int main(int argc, const char **argv) prefix = setup_git_directory(); prefix_length = prefix ? strlen(prefix) : 0; if (vpath && prefix) - vpath = prefix_filename(prefix, prefix_length, vpath); + vpath = xstrdup(prefix_filename(prefix, prefix_length, vpath)); } git_config(git_default_config, NULL); diff --git a/setup.c b/setup.c index 710e2f3..80cf535 100644 --- a/setup.c +++ b/setup.c @@ -132,8 +132,8 @@ const char **get_pathspec(const char *prefix, const char **pathspec) return NULL; if (!entry) { - static const char *spec[2]; - spec[0] = prefix; + const char **spec = xmalloc(sizeof(char *) * 2); + spec[0] = xstrdup(prefix); spec[1] = NULL; return spec; } -- 1.6.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html