summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2017-04-16 23:29:34 -0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2017-04-16 23:29:34 -0700
commit7b612c966ec3ee68fb60410db06222b7d728f965 (patch)
treeb8499e5afa7927424abde334f2150524e3210389 /builtin
parentMerge branch 'sb/unpack-trees-would-lose-submodule-message-update' (diff)
parentdifftool: fix use-after-free (diff)
downloadtgif-7b612c966ec3ee68fb60410db06222b7d728f965.tar.xz
Merge branch 'js/difftool-builtin'
Code cleanup. * js/difftool-builtin: difftool: fix use-after-free difftool: avoid strcpy
Diffstat (limited to 'builtin')
-rw-r--r--builtin/difftool.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 25e54ad3ed..1354d0e462 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -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);