mirror of
https://github.com/git/git
synced 2024-08-28 12:09:19 +00:00
Merge branch 'js/difftool-builtin'
Code cleanup. * js/difftool-builtin: difftool: fix use-after-free difftool: avoid strcpy
This commit is contained in:
commit
7b612c966e
|
@ -297,6 +297,19 @@ static char *get_symlink(const struct object_id *oid, const char *path)
|
|||
return data;
|
||||
}
|
||||
|
||||
static int checkout_path(unsigned mode, struct object_id *oid,
|
||||
const char *path, const struct checkout *state)
|
||||
{
|
||||
struct cache_entry *ce;
|
||||
int ret;
|
||||
|
||||
ce = make_cache_entry(mode, oid->hash, path, 0, 0);
|
||||
ret = checkout_entry(ce, state, NULL);
|
||||
|
||||
free(ce);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
|
@ -305,8 +318,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
struct strbuf rpath = STRBUF_INIT, buf = STRBUF_INIT;
|
||||
struct strbuf ldir = STRBUF_INIT, rdir = STRBUF_INIT;
|
||||
struct strbuf wtdir = STRBUF_INIT;
|
||||
char *lbase_dir, *rbase_dir;
|
||||
size_t ldir_len, rdir_len, wtdir_len;
|
||||
struct cache_entry *ce = xcalloc(1, sizeof(ce) + PATH_MAX + 1);
|
||||
const char *workdir, *tmp;
|
||||
int ret = 0, i;
|
||||
FILE *fp;
|
||||
|
@ -339,11 +352,11 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
memset(&wtindex, 0, sizeof(wtindex));
|
||||
|
||||
memset(&lstate, 0, sizeof(lstate));
|
||||
lstate.base_dir = ldir.buf;
|
||||
lstate.base_dir = lbase_dir = xstrdup(ldir.buf);
|
||||
lstate.base_dir_len = ldir.len;
|
||||
lstate.force = 1;
|
||||
memset(&rstate, 0, sizeof(rstate));
|
||||
rstate.base_dir = rdir.buf;
|
||||
rstate.base_dir = rbase_dir = xstrdup(rdir.buf);
|
||||
rstate.base_dir_len = rdir.len;
|
||||
rstate.force = 1;
|
||||
|
||||
|
@ -377,7 +390,6 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
struct object_id loid, roid;
|
||||
char status;
|
||||
const char *src_path, *dst_path;
|
||||
size_t src_path_len, dst_path_len;
|
||||
|
||||
if (starts_with(info.buf, "::"))
|
||||
die(N_("combined diff formats('-c' and '--cc') are "
|
||||
|
@ -390,17 +402,14 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
if (strbuf_getline_nul(&lpath, fp))
|
||||
break;
|
||||
src_path = lpath.buf;
|
||||
src_path_len = lpath.len;
|
||||
|
||||
i++;
|
||||
if (status != 'C' && status != 'R') {
|
||||
dst_path = src_path;
|
||||
dst_path_len = src_path_len;
|
||||
} else {
|
||||
if (strbuf_getline_nul(&rpath, fp))
|
||||
break;
|
||||
dst_path = rpath.buf;
|
||||
dst_path_len = rpath.len;
|
||||
}
|
||||
|
||||
if (S_ISGITLINK(lmode) || S_ISGITLINK(rmode)) {
|
||||
|
@ -430,11 +439,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
}
|
||||
|
||||
if (lmode && status != 'C') {
|
||||
ce->ce_mode = lmode;
|
||||
oidcpy(&ce->oid, &loid);
|
||||
strcpy(ce->name, src_path);
|
||||
ce->ce_namelen = src_path_len;
|
||||
if (checkout_entry(ce, &lstate, NULL))
|
||||
if (checkout_path(lmode, &loid, src_path, &lstate))
|
||||
return error("could not write '%s'", src_path);
|
||||
}
|
||||
|
||||
|
@ -451,11 +456,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
hashmap_add(&working_tree_dups, entry);
|
||||
|
||||
if (!use_wt_file(workdir, dst_path, &roid)) {
|
||||
ce->ce_mode = rmode;
|
||||
oidcpy(&ce->oid, &roid);
|
||||
strcpy(ce->name, dst_path);
|
||||
ce->ce_namelen = dst_path_len;
|
||||
if (checkout_entry(ce, &rstate, NULL))
|
||||
if (checkout_path(rmode, &roid, dst_path, &rstate))
|
||||
return error("could not write '%s'",
|
||||
dst_path);
|
||||
} else if (!is_null_oid(&roid)) {
|
||||
|
@ -625,7 +626,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
exit_cleanup(tmpdir, rc);
|
||||
|
||||
finish:
|
||||
free(ce);
|
||||
free(lbase_dir);
|
||||
free(rbase_dir);
|
||||
strbuf_release(&ldir);
|
||||
strbuf_release(&rdir);
|
||||
strbuf_release(&wtdir);
|
||||
|
|
|
@ -393,6 +393,25 @@ test_expect_success 'setup change in subdirectory' '
|
|||
git commit -m "modified both"
|
||||
'
|
||||
|
||||
test_expect_success 'difftool -d with growing paths' '
|
||||
a=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
|
||||
git init growing &&
|
||||
(
|
||||
cd growing &&
|
||||
echo "test -f \"\$2/b\"" | write_script .git/test-for-b.sh &&
|
||||
one=$(printf 1 | git hash-object -w --stdin) &&
|
||||
two=$(printf 2 | git hash-object -w --stdin) &&
|
||||
git update-index --add \
|
||||
--cacheinfo 100644,$one,$a --cacheinfo 100644,$two,b &&
|
||||
tree1=$(git write-tree) &&
|
||||
git update-index --add \
|
||||
--cacheinfo 100644,$two,$a --cacheinfo 100644,$one,b &&
|
||||
tree2=$(git write-tree) &&
|
||||
git checkout -- $a &&
|
||||
git difftool -d --extcmd .git/test-for-b.sh $tree1 $tree2
|
||||
)
|
||||
'
|
||||
|
||||
run_dir_diff_test () {
|
||||
test_expect_success "$1 --no-symlinks" "
|
||||
symlinks=--no-symlinks &&
|
||||
|
|
Loading…
Reference in a new issue