diff --git a/commit.c b/commit.c index e867b86e6a..edd4dedcdd 100644 --- a/commit.c +++ b/commit.c @@ -560,6 +560,9 @@ void sort_in_topological_order(struct commit_list ** list) next = next->next; count++; } + + if (!count) + return; /* allocate an array to help sort the list */ nodes = xcalloc(count, sizeof(*nodes)); /* link the list to the array */ diff --git a/diff.c b/diff.c index c8159183da..66057e5d61 100644 --- a/diff.c +++ b/diff.c @@ -504,9 +504,9 @@ static void prepare_temp_file(const char *name, } if (S_ISLNK(st.st_mode)) { int ret; - char *buf, buf_[1024]; - buf = ((sizeof(buf_) < st.st_size) ? - xmalloc(st.st_size) : buf_); + char buf[PATH_MAX + 1]; /* ought to be SYMLINK_MAX */ + if (sizeof(buf) <= st.st_size) + die("symlink too long: %s", name); ret = readlink(name, buf, st.st_size); if (ret < 0) die("readlink(%s)", name); @@ -650,7 +650,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one) if (DIFF_FILE_VALID(one)) { if (!one->sha1_valid) { struct stat st; - if (stat(one->path, &st) < 0) + if (lstat(one->path, &st) < 0) die("stat %s", one->path); if (index_path(one->sha1, one->path, &st, 0)) die("cannot hash %s\n", one->path); diff --git a/diffcore-order.c b/diffcore-order.c index b38122361f..0bc2b22f84 100644 --- a/diffcore-order.c +++ b/diffcore-order.c @@ -105,9 +105,13 @@ static int compare_pair_order(const void *a_, const void *b_) void diffcore_order(const char *orderfile) { struct diff_queue_struct *q = &diff_queued_diff; - struct pair_order *o = xmalloc(sizeof(*o) * q->nr); + struct pair_order *o; int i; + if (!q->nr) + return; + + o = xmalloc(sizeof(*o) * q->nr); prepare_order(orderfile); for (i = 0; i < q->nr; i++) { o[i].pair = q->queue[i]; diff --git a/diffcore-pathspec.c b/diffcore-pathspec.c index 68fe009132..139fe882f9 100644 --- a/diffcore-pathspec.c +++ b/diffcore-pathspec.c @@ -48,6 +48,9 @@ void diffcore_pathspec(const char **pathspec) for (i = 0; pathspec[i]; i++) ; speccnt = i; + if (!speccnt) + return; + spec = xmalloc(sizeof(*spec) * speccnt); for (i = 0; pathspec[i]; i++) { spec[i].spec = pathspec[i]; diff --git a/diffcore-rename.c b/diffcore-rename.c index dba965c0b4..39d9126cb9 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -282,7 +282,7 @@ void diffcore_rename(struct diff_options *options) else if (detect_rename == DIFF_DETECT_COPY) register_rename_src(p->one, 1); } - if (rename_dst_nr == 0 || + if (rename_dst_nr == 0 || rename_src_nr == 0 || (0 < rename_limit && rename_limit < rename_dst_nr)) goto cleanup; /* nothing to do */ diff --git a/index-pack.c b/index-pack.c index d4ce3af587..541d7bc1c1 100644 --- a/index-pack.c +++ b/index-pack.c @@ -352,18 +352,24 @@ static int sha1_compare(const void *_a, const void *_b) static void write_index_file(const char *index_name, unsigned char *sha1) { struct sha1file *f; - struct object_entry **sorted_by_sha = - xcalloc(nr_objects, sizeof(struct object_entry *)); - struct object_entry **list = sorted_by_sha; - struct object_entry **last = sorted_by_sha + nr_objects; + struct object_entry **sorted_by_sha, **list, **last; unsigned int array[256]; int i; SHA_CTX ctx; - for (i = 0; i < nr_objects; ++i) - sorted_by_sha[i] = &objects[i]; - qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]), - sha1_compare); + if (nr_objects) { + sorted_by_sha = + xcalloc(nr_objects, sizeof(struct object_entry *)); + list = sorted_by_sha; + last = sorted_by_sha + nr_objects; + for (i = 0; i < nr_objects; ++i) + sorted_by_sha[i] = &objects[i]; + qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]), + sha1_compare); + + } + else + sorted_by_sha = list = last = NULL; unlink(index_name); f = sha1create("%s", index_name); diff --git a/read-tree.c b/read-tree.c index e3b9c0d9fa..a46c6fe2f5 100644 --- a/read-tree.c +++ b/read-tree.c @@ -294,17 +294,20 @@ static int unpack_trees(merge_fn_t fn) { int indpos = 0; unsigned len = object_list_length(trees); - struct tree_entry_list **posns = - xmalloc(len * sizeof(struct tree_entry_list *)); + struct tree_entry_list **posns; int i; struct object_list *posn = trees; merge_size = len; - for (i = 0; i < len; i++) { - posns[i] = ((struct tree *) posn->item)->entries; - posn = posn->next; + + if (len) { + posns = xmalloc(len * sizeof(struct tree_entry_list *)); + for (i = 0; i < len; i++) { + posns[i] = ((struct tree *) posn->item)->entries; + posn = posn->next; + } + if (unpack_trees_rec(posns, len, "", fn, &indpos)) + return -1; } - if (unpack_trees_rec(posns, len, "", fn, &indpos)) - return -1; if (trivial_merges_only && nontrivial_merge) die("Merge requires file-level merging"); diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh new file mode 100755 index 0000000000..e3ebf382e3 --- /dev/null +++ b/t/t4011-diff-symlink.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# +# Copyright (c) 2005 Johannes Schindelin +# + +test_description='Test diff of symlinks. + +' +. ./test-lib.sh +. ../diff-lib.sh + +cat > expected << EOF +diff --git a/frotz b/frotz +new file mode 120000 +index 0000000..7c465af +--- /dev/null ++++ b/frotz +@@ -0,0 +1 @@ ++xyzzy +\ No newline at end of file +EOF + +test_expect_success \ + 'diff new symlink' \ + 'ln -s xyzzy frotz && + git-update-index && + tree=$(git-write-tree) && + git-update-index --add frotz && + GIT_DIFF_OPTS=--unified=0 git-diff-index -M -p $tree > current && + compare_diff_patch current expected' + +test_expect_success \ + 'diff unchanged symlink' \ + 'tree=$(git-write-tree) && + git-update-index frotz && + test -z "$(git-diff-index --name-only $tree)"' + +cat > expected << EOF +diff --git a/frotz b/frotz +deleted file mode 120000 +index 7c465af..0000000 +--- a/frotz ++++ /dev/null +@@ -1 +0,0 @@ +-xyzzy +\ No newline at end of file +EOF + +test_expect_success \ + 'diff removed symlink' \ + 'rm frotz && + git-diff-index -M -p $tree > current && + compare_diff_patch current expected' + +cat > expected << EOF +diff --git a/frotz b/frotz +EOF + +test_expect_success \ + 'diff identical, but newly created symlink' \ + 'sleep 1 && + ln -s xyzzy frotz && + git-diff-index -M -p $tree > current && + compare_diff_patch current expected' + +cat > expected << EOF +diff --git a/frotz b/frotz +index 7c465af..df1db54 120000 +--- a/frotz ++++ b/frotz +@@ -1 +1 @@ +-xyzzy +\ No newline at end of file ++yxyyz +\ No newline at end of file +EOF + +test_expect_success \ + 'diff different symlink' \ + 'rm frotz && + ln -s yxyyz frotz && + git-diff-index -M -p $tree > current && + compare_diff_patch current expected' + +test_done diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 7dfb1ab77b..1510ea9fcc 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -142,6 +142,7 @@ test_expect_success \ else :; fi && + : PACK_SIGNATURE && cp test-1-${packname_1}.pack test-3.pack && dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=2 && if git-verify-pack test-3.idx @@ -149,6 +150,7 @@ test_expect_success \ else :; fi && + : PACK_VERSION && cp test-1-${packname_1}.pack test-3.pack && dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=7 && if git-verify-pack test-3.idx @@ -156,6 +158,7 @@ test_expect_success \ else :; fi && + : TYPE/SIZE byte of the first packed object data && cp test-1-${packname_1}.pack test-3.pack && dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=12 && if git-verify-pack test-3.idx @@ -163,8 +166,11 @@ test_expect_success \ else :; fi && + : sum of the index file itself && + l=`wc -c