Hello community,

here is the log from the commit of package libgit2 for openSUSE:Factory checked 
in at 2015-10-14 16:43:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libgit2 (Old)
 and      /work/SRC/openSUSE:Factory/.libgit2.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libgit2"

Changes:
--------
--- /work/SRC/openSUSE:Factory/libgit2/libgit2.changes  2015-09-17 
09:17:36.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.libgit2.new/libgit2.changes     2015-10-14 
16:43:37.000000000 +0200
@@ -1,0 +2,10 @@
+Wed Oct  7 09:29:34 UTC 2015 - astie...@suse.com
+
+- libgit2 0.23.3, containing critical fixes:  
+  * blame: guard xdiff calls for large files
+  * diff: don't feed large files to xdiff
+  * merge_file: treat large files as binary
+  * xdiff: convert size variables to size_t
+  * GITERR_CHECK_ALLOC_ADDn: multi-arg adders
+
+-------------------------------------------------------------------

Old:
----
  libgit2-0.23.2.tar.gz

New:
----
  libgit2-0.23.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libgit2.spec ++++++
--- /var/tmp/diff_new_pack.6jk1DF/_old  2015-10-14 16:43:38.000000000 +0200
+++ /var/tmp/diff_new_pack.6jk1DF/_new  2015-10-14 16:43:38.000000000 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           libgit2
-Version:        0.23.2
+Version:        0.23.3
 Release:        0
 Summary:        C git library
 License:        GPL-2.0-with-GCC-exception

++++++ libgit2-0.23.2.tar.gz -> libgit2-0.23.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/include/git2/version.h 
new/libgit2-0.23.3/include/git2/version.h
--- old/libgit2-0.23.2/include/git2/version.h   2015-09-05 16:48:42.000000000 
+0200
+++ new/libgit2-0.23.3/include/git2/version.h   2015-10-05 23:37:22.000000000 
+0200
@@ -7,10 +7,10 @@
 #ifndef INCLUDE_git_version_h__
 #define INCLUDE_git_version_h__
 
-#define LIBGIT2_VERSION "0.23.2"
+#define LIBGIT2_VERSION "0.23.3"
 #define LIBGIT2_VER_MAJOR 0
 #define LIBGIT2_VER_MINOR 23
-#define LIBGIT2_VER_REVISION 2
+#define LIBGIT2_VER_REVISION 3
 #define LIBGIT2_VER_PATCH 0
 
 #define LIBGIT2_SOVERSION 23
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/blame.c 
new/libgit2-0.23.3/src/blame.c
--- old/libgit2-0.23.2/src/blame.c      2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/blame.c      2015-10-05 23:37:22.000000000 +0200
@@ -331,7 +331,7 @@
 
        blame->ent = ent;
 
-       git_blame__like_git(blame, blame->options.flags);
+       error = git_blame__like_git(blame, blame->options.flags);
 
 cleanup:
        for (ent = blame->ent; ent; ) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/blame_git.c 
new/libgit2-0.23.3/src/blame_git.c
--- old/libgit2-0.23.2/src/blame_git.c  2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/blame_git.c  2015-10-05 23:37:22.000000000 +0200
@@ -9,6 +9,7 @@
 #include "commit.h"
 #include "blob.h"
 #include "xdiff/xinclude.h"
+#include "diff_xdiff.h"
 
 /*
  * Origin is refcounted and usually we keep the blob contents to be
@@ -351,6 +352,13 @@
        ecb.priv = cb_data;
 
        trim_common_tail(&file_a, &file_b, 0);
+
+       if (file_a.size > GIT_XDIFF_MAX_SIZE ||
+               file_b.size > GIT_XDIFF_MAX_SIZE) {
+               giterr_set(GITERR_INVALID, "file too large to blame");
+               return -1;
+       }
+
        return xdl_diff(&file_a, &file_b, &xpp, &xecfg, &ecb);
 }
 
@@ -379,7 +387,9 @@
        fill_origin_blob(parent, &file_p);
        fill_origin_blob(target, &file_o);
 
-       diff_hunks(file_p, file_o, &d);
+       if (diff_hunks(file_p, file_o, &d) < 0)
+               return -1;
+
        /* The reset (i.e. anything after tlno) are the same as the parent */
        blame_chunk(blame, d.tlno, d.plno, last_in_target, target, parent);
 
@@ -477,12 +487,13 @@
        }
 }
 
-static void pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t 
opt)
+static int pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t 
opt)
 {
        git_commit *commit = origin->commit;
        int i, num_parents;
        git_blame__origin *sg_buf[16];
        git_blame__origin *porigin, **sg_origin = sg_buf;
+       int ret, error = 0;
 
        num_parents = git_commit_parentcount(commit);
        if (!git_oid_cmp(git_commit_id(commit), &blame->options.oldest_commit))
@@ -540,8 +551,13 @@
                        origin_incref(porigin);
                        origin->previous = porigin;
                }
-               if (pass_blame_to_parent(blame, origin, porigin))
+
+               if ((ret = pass_blame_to_parent(blame, origin, porigin)) != 0) {
+                       if (ret < 0)
+                               error = -1;
+
                        goto finish;
+               }
        }
 
        /* TODO: optionally find moves in parents' files */
@@ -554,7 +570,7 @@
                        origin_decref(sg_origin[i]);
        if (sg_origin != sg_buf)
                git__free(sg_origin);
-       return;
+       return error;
 }
 
 /*
@@ -583,7 +599,7 @@
        }
 }
 
-void git_blame__like_git(git_blame *blame, uint32_t opt)
+int git_blame__like_git(git_blame *blame, uint32_t opt)
 {
        while (true) {
                git_blame__entry *ent;
@@ -594,11 +610,13 @@
                        if (!ent->guilty)
                                suspect = ent->suspect;
                if (!suspect)
-                       return; /* all done */
+                       return 0; /* all done */
 
                /* We'll use this suspect later in the loop, so hold on to it 
for now. */
                origin_incref(suspect);
-               pass_blame(blame, suspect, opt);
+
+               if (pass_blame(blame, suspect, opt) < 0)
+                       return -1;
 
                /* Take responsibility for the remaining entries */
                for (ent = blame->ent; ent; ent = ent->next) {
@@ -613,6 +631,8 @@
        }
 
        coalesce(blame);
+
+       return 0;
 }
 
 void git_blame__free_entry(git_blame__entry *ent)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/blame_git.h 
new/libgit2-0.23.3/src/blame_git.h
--- old/libgit2-0.23.2/src/blame_git.h  2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/blame_git.h  2015-10-05 23:37:22.000000000 +0200
@@ -15,6 +15,6 @@
                git_commit *commit,
                const char *path);
 void git_blame__free_entry(git_blame__entry *ent);
-void git_blame__like_git(git_blame *sb, uint32_t flags);
+int git_blame__like_git(git_blame *sb, uint32_t flags);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/checkout.c 
new/libgit2-0.23.3/src/checkout.c
--- old/libgit2-0.23.2/src/checkout.c   2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/checkout.c   2015-10-05 23:37:22.000000000 +0200
@@ -18,6 +18,7 @@
 #include "git2/submodule.h"
 #include "git2/sys/index.h"
 #include "git2/sys/filter.h"
+#include "git2/merge.h"
 
 #include "refs.h"
 #include "repository.h"
@@ -27,7 +28,7 @@
 #include "diff.h"
 #include "pathspec.h"
 #include "buf_text.h"
-#include "merge_file.h"
+#include "diff_xdiff.h"
 #include "path.h"
 #include "attr.h"
 #include "pool.h"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/common.h 
new/libgit2-0.23.3/src/common.h
--- old/libgit2-0.23.2/src/common.h     2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/common.h     2015-10-05 23:37:22.000000000 +0200
@@ -199,6 +199,15 @@
 #define GITERR_CHECK_ALLOC_ADD(out, one, two) \
        if (GIT_ADD_SIZET_OVERFLOW(out, one, two)) { return -1; }
 
+#define GITERR_CHECK_ALLOC_ADD3(out, one, two, three) \
+       if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \
+               GIT_ADD_SIZET_OVERFLOW(out, *(out), three)) { return -1; }
+
+#define GITERR_CHECK_ALLOC_ADD4(out, one, two, three, four) \
+       if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \
+               GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \
+               GIT_ADD_SIZET_OVERFLOW(out, *(out), four)) { return -1; }
+
 /** Check for multiplicative overflow, failing if it would occur. */
 #define GITERR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \
        if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/diff_patch.c 
new/libgit2-0.23.3/src/diff_patch.c
--- old/libgit2-0.23.2/src/diff_patch.c 2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/diff_patch.c 2015-10-05 23:37:22.000000000 +0200
@@ -30,6 +30,10 @@
                (patch->nfile.file->flags & GIT_DIFF_FLAG_BINARY) != 0)
                patch->delta->flags |= GIT_DIFF_FLAG_BINARY;
 
+       else if (patch->ofile.file->size > GIT_XDIFF_MAX_SIZE ||
+                        patch->nfile.file->size > GIT_XDIFF_MAX_SIZE)
+               patch->delta->flags |= GIT_DIFF_FLAG_BINARY;
+
        else if ((patch->ofile.file->flags & DIFF_FLAGS_NOT_BINARY) != 0 &&
                         (patch->nfile.file->flags & DIFF_FLAGS_NOT_BINARY) != 
0)
                patch->delta->flags |= GIT_DIFF_FLAG_NOT_BINARY;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/diff_xdiff.c 
new/libgit2-0.23.3/src/diff_xdiff.c
--- old/libgit2-0.23.2/src/diff_xdiff.c 2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/diff_xdiff.c 2015-10-05 23:37:22.000000000 +0200
@@ -4,6 +4,7 @@
  * This file is part of libgit2, distributed under the GNU GPL v2 with
  * a Linking Exception. For full terms see the included COPYING file.
  */
+#include "git2/errors.h"
 #include "common.h"
 #include "diff.h"
 #include "diff_driver.h"
@@ -208,6 +209,12 @@
        git_patch__old_data(&info.xd_old_data.ptr, &info.xd_old_data.size, 
patch);
        git_patch__new_data(&info.xd_new_data.ptr, &info.xd_new_data.size, 
patch);
 
+       if (info.xd_old_data.size > GIT_XDIFF_MAX_SIZE ||
+               info.xd_new_data.size > GIT_XDIFF_MAX_SIZE) {
+               giterr_set(GITERR_INVALID, "files too large for diff");
+               return -1;
+       }
+
        xdl_diff(&info.xd_old_data, &info.xd_new_data,
                &xo->params, &xo->config, &xo->callback);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/diff_xdiff.h 
new/libgit2-0.23.3/src/diff_xdiff.h
--- old/libgit2-0.23.2/src/diff_xdiff.h 2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/diff_xdiff.h 2015-10-05 23:37:22.000000000 +0200
@@ -11,6 +11,11 @@
 #include "diff_patch.h"
 #include "xdiff/xdiff.h"
 
+/* xdiff cannot cope with large files.  these files should not be passed to
+ * xdiff.  callers should treat these large files as binary.
+ */
+#define GIT_XDIFF_MAX_SIZE (1024LL * 1024 * 1023)
+
 /* A git_xdiff_output is a git_diff_output with extra fields necessary
  * to use libxdiff.  Calling git_xdiff_init() will set the diff_cb field
  * of the output to use xdiff to generate the diffs.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/merge.c 
new/libgit2-0.23.3/src/merge.c
--- old/libgit2-0.23.2/src/merge.c      2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/merge.c      2015-10-05 23:37:22.000000000 +0200
@@ -20,7 +20,6 @@
 #include "diff.h"
 #include "checkout.h"
 #include "tree.h"
-#include "merge_file.h"
 #include "blob.h"
 #include "oid.h"
 #include "index.h"
@@ -61,12 +60,6 @@
        git_merge_diff *prev_conflict;
 };
 
-GIT_INLINE(int) merge_diff_detect_binary(
-       bool *binary_out,
-       git_repository *repo,
-       const git_merge_diff *conflict);
-
-
 /* Merge base computation */
 
 int merge_bases_many(git_commit_list **out, git_revwalk **walk_out, 
git_repository *repo, size_t length, const git_oid input_array[])
@@ -668,7 +661,6 @@
        git_odb *odb = NULL;
        git_oid automerge_oid;
        int error = 0;
-       bool binary = false;
 
        assert(resolved && diff_list && conflict);
 
@@ -703,12 +695,6 @@
                strcmp(conflict->ancestor_entry.path, 
conflict->their_entry.path) != 0)
                return 0;
 
-       /* Reject binary conflicts */
-       if ((error = merge_diff_detect_binary(&binary, diff_list->repo, 
conflict)) < 0)
-               return error;
-       if (binary)
-               return 0;
-
        ancestor = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
                &conflict->ancestor_entry : NULL;
        ours = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
@@ -1314,48 +1300,6 @@
        return 0;
 }
 
-GIT_INLINE(int) merge_diff_detect_binary(
-       bool *binary_out,
-       git_repository *repo,
-       const git_merge_diff *conflict)
-{
-       git_blob *ancestor_blob = NULL, *our_blob = NULL, *their_blob = NULL;
-       int error = 0;
-       bool binary = false;
-
-       if (GIT_MERGE_INDEX_ENTRY_ISFILE(conflict->ancestor_entry)) {
-               if ((error = git_blob_lookup(&ancestor_blob, repo, 
&conflict->ancestor_entry.id)) < 0)
-                       goto done;
-
-               binary = git_blob_is_binary(ancestor_blob);
-       }
-
-       if (!binary &&
-               GIT_MERGE_INDEX_ENTRY_ISFILE(conflict->our_entry)) {
-               if ((error = git_blob_lookup(&our_blob, repo, 
&conflict->our_entry.id)) < 0)
-                       goto done;
-
-               binary = git_blob_is_binary(our_blob);
-       }
-
-       if (!binary &&
-               GIT_MERGE_INDEX_ENTRY_ISFILE(conflict->their_entry)) {
-               if ((error = git_blob_lookup(&their_blob, repo, 
&conflict->their_entry.id)) < 0)
-                       goto done;
-
-               binary = git_blob_is_binary(their_blob);
-       }
-
-       *binary_out = binary;
-
-done:
-       git_blob_free(ancestor_blob);
-       git_blob_free(our_blob);
-       git_blob_free(their_blob);
-
-       return error;
-}
-
 GIT_INLINE(int) index_entry_dup_pool(
        git_index_entry *out,
        git_pool *pool,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/merge_file.c 
new/libgit2-0.23.3/src/merge_file.c
--- old/libgit2-0.23.2/src/merge_file.c 2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/merge_file.c 2015-10-05 23:37:22.000000000 +0200
@@ -7,17 +7,23 @@
 
 #include "common.h"
 #include "repository.h"
-#include "merge_file.h"
 #include "posix.h"
 #include "fileops.h"
 #include "index.h"
+#include "diff_xdiff.h"
 
 #include "git2/repository.h"
 #include "git2/object.h"
 #include "git2/index.h"
+#include "git2/merge.h"
 
 #include "xdiff/xdiff.h"
 
+/* only examine the first 8000 bytes for binaryness.
+ * 
https://github.com/git/git/blob/77bd3ea9f54f1584147b594abc04c26ca516d987/xdiff-interface.c#L197
+ */
+#define GIT_MERGE_FILE_BINARY_SIZE 8000
+
 #define GIT_MERGE_FILE_SIDE_EXISTS(X)  ((X)->mode != 0)
 
 GIT_INLINE(const char *) merge_file_best_path(
@@ -100,7 +106,7 @@
        }
 }
 
-static int git_merge_file__from_inputs(
+static int merge_file__xdiff(
        git_merge_file_result *out,
        const git_merge_file_input *ancestor,
        const git_merge_file_input *ours,
@@ -189,6 +195,63 @@
        return error;
 }
 
+static bool merge_file__is_binary(const git_merge_file_input *file)
+{
+       size_t len = file ? file->size : 0;
+
+       if (len > GIT_XDIFF_MAX_SIZE)
+               return true;
+       if (len > GIT_MERGE_FILE_BINARY_SIZE)
+               len = GIT_MERGE_FILE_BINARY_SIZE;
+
+       return len ? (memchr(file->ptr, 0, len) != NULL) : false;
+}
+
+static int merge_file__binary(
+       git_merge_file_result *out,
+       const git_merge_file_input *ours,
+       const git_merge_file_input *theirs,
+       const git_merge_file_options *given_opts)
+{
+       const git_merge_file_input *favored = NULL;
+
+       memset(out, 0x0, sizeof(git_merge_file_result));
+
+       if (given_opts && given_opts->favor == GIT_MERGE_FILE_FAVOR_OURS)
+               favored = ours;
+       else if (given_opts && given_opts->favor == GIT_MERGE_FILE_FAVOR_THEIRS)
+               favored = theirs;
+       else
+               goto done;
+
+       if ((out->path = git__strdup(favored->path)) == NULL ||
+               (out->ptr = git__malloc(favored->size)) == NULL)
+               goto done;
+
+       memcpy((char *)out->ptr, favored->ptr, favored->size);
+       out->len = favored->size;
+       out->mode = favored->mode;
+       out->automergeable = 1;
+
+done:
+       return 0;
+}
+
+static int merge_file__from_inputs(
+       git_merge_file_result *out,
+       const git_merge_file_input *ancestor,
+       const git_merge_file_input *ours,
+       const git_merge_file_input *theirs,
+       const git_merge_file_options *given_opts)
+{
+       if (merge_file__is_binary(ancestor) ||
+               merge_file__is_binary(ours) ||
+               merge_file__is_binary(theirs))
+               return merge_file__binary(out, ours, theirs, given_opts);
+
+       return merge_file__xdiff(out, ancestor, ours, theirs, given_opts);
+}
+
 static git_merge_file_input *git_merge_file__normalize_inputs(
        git_merge_file_input *out,
        const git_merge_file_input *given)
@@ -223,7 +286,7 @@
        ours = git_merge_file__normalize_inputs(&inputs[1], ours);
        theirs = git_merge_file__normalize_inputs(&inputs[2], theirs);
 
-       return git_merge_file__from_inputs(out, ancestor, ours, theirs, 
options);
+       return merge_file__from_inputs(out, ancestor, ours, theirs, options);
 }
 
 int git_merge_file_from_index(
@@ -234,8 +297,8 @@
        const git_index_entry *theirs,
        const git_merge_file_options *options)
 {
-       git_merge_file_input inputs[3] = { {0} },
-               *ancestor_input = NULL, *our_input = NULL, *their_input = NULL;
+       git_merge_file_input *ancestor_ptr = NULL,
+               ancestor_input = {0}, our_input = {0}, their_input = {0};
        git_odb *odb = NULL;
        git_odb_object *odb_object[3] = { 0 };
        int error = 0;
@@ -249,27 +312,20 @@
 
        if (ancestor) {
                if ((error = git_merge_file__input_from_index(
-                       &inputs[0], &odb_object[0], odb, ancestor)) < 0)
+                       &ancestor_input, &odb_object[0], odb, ancestor)) < 0)
                        goto done;
 
-               ancestor_input = &inputs[0];
+               ancestor_ptr = &ancestor_input;
        }
 
        if ((error = git_merge_file__input_from_index(
-               &inputs[1], &odb_object[1], odb, ours)) < 0)
+                       &our_input, &odb_object[1], odb, ours)) < 0 ||
+               (error = git_merge_file__input_from_index(
+                       &their_input, &odb_object[2], odb, theirs)) < 0)
                goto done;
 
-       our_input = &inputs[1];
-
-       if ((error = git_merge_file__input_from_index(
-               &inputs[2], &odb_object[2], odb, theirs)) < 0)
-               goto done;
-
-       their_input = &inputs[2];
-
-       if ((error = git_merge_file__from_inputs(out,
-               ancestor_input, our_input, their_input, options)) < 0)
-               goto done;
+       error = merge_file__from_inputs(out,
+               ancestor_ptr, &our_input, &their_input, options);
 
 done:
        git_odb_object_free(odb_object[0]);
@@ -286,7 +342,5 @@
                return;
 
        git__free((char *)result->path);
-
-       /* xdiff uses malloc() not git_malloc, so we use free(), not git_free() 
*/
-       free((char *)result->ptr);
+       git__free((char *)result->ptr);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/merge_file.h 
new/libgit2-0.23.3/src/merge_file.h
--- old/libgit2-0.23.2/src/merge_file.h 2015-09-05 16:48:42.000000000 +0200
+++ new/libgit2-0.23.3/src/merge_file.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,14 +0,0 @@
-/*
- * Copyright (C) the libgit2 contributors. All rights reserved.
- *
- * This file is part of libgit2, distributed under the GNU GPL v2 with
- * a Linking Exception. For full terms see the included COPYING file.
- */
-#ifndef INCLUDE_filediff_h__
-#define INCLUDE_filediff_h__
-
-#include "xdiff/xdiff.h"
-
-#include "git2/merge.h"
-
-#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/xdiff/xdiff.h 
new/libgit2-0.23.3/src/xdiff/xdiff.h
--- old/libgit2-0.23.2/src/xdiff/xdiff.h        2015-09-05 16:48:42.000000000 
+0200
+++ new/libgit2-0.23.3/src/xdiff/xdiff.h        2015-10-05 23:37:22.000000000 
+0200
@@ -20,6 +20,8 @@
  *
  */
 
+#include "util.h"
+
 #if !defined(XDIFF_H)
 #define XDIFF_H
 
@@ -106,9 +108,9 @@
 } bdiffparam_t;
 
 
-#define xdl_malloc(x) malloc(x)
-#define xdl_free(ptr) free(ptr)
-#define xdl_realloc(ptr,x) realloc(ptr,x)
+#define xdl_malloc(x) git__malloc(x)
+#define xdl_free(ptr) git__free(ptr)
+#define xdl_realloc(ptr,x) git__realloc(ptr,x)
 
 void *xdl_mmfile_first(mmfile_t *mmf, long *size);
 long xdl_mmfile_size(mmfile_t *mmf);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/xdiff/xdiffi.c 
new/libgit2-0.23.3/src/xdiff/xdiffi.c
--- old/libgit2-0.23.2/src/xdiff/xdiffi.c       2015-09-05 16:48:42.000000000 
+0200
+++ new/libgit2-0.23.3/src/xdiff/xdiffi.c       2015-10-05 23:37:22.000000000 
+0200
@@ -21,7 +21,8 @@
  */
 
 #include "xinclude.h"
-
+#include "common.h"
+#include "integer.h"
 
 
 #define XDL_MAX_COST_MIN 256
@@ -323,7 +324,7 @@
 
 int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
                xdfenv_t *xe) {
-       long ndiags;
+       size_t ndiags, allocsize;
        long *kvd, *kvdf, *kvdb;
        xdalgoenv_t xenv;
        diffdata_t dd1, dd2;
@@ -343,9 +344,12 @@
         * Allocate and setup K vectors to be used by the differential 
algorithm.
         * One is to store the forward path and one to store the backward path.
         */
-       ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
-       if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
+       GITERR_CHECK_ALLOC_ADD3(&ndiags, xe->xdf1.nreff, xe->xdf2.nreff, 3);
+       GITERR_CHECK_ALLOC_MULTIPLY(&allocsize, ndiags, 2);
+       GITERR_CHECK_ALLOC_ADD(&allocsize, allocsize, 2);
+       GITERR_CHECK_ALLOC_MULTIPLY(&allocsize, allocsize, sizeof(long));
 
+       if (!(kvd = (long *) xdl_malloc(allocsize))) {
                xdl_free_env(xe);
                return -1;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/xdiff/xhistogram.c 
new/libgit2-0.23.3/src/xdiff/xhistogram.c
--- old/libgit2-0.23.2/src/xdiff/xhistogram.c   2015-09-05 16:48:42.000000000 
+0200
+++ new/libgit2-0.23.3/src/xdiff/xhistogram.c   2015-10-05 23:37:22.000000000 
+0200
@@ -44,6 +44,7 @@
 #include "xinclude.h"
 #include "xtypes.h"
 #include "xdiff.h"
+#include "common.h"
 
 #define MAX_PTR        UINT_MAX
 #define MAX_CNT        UINT_MAX
@@ -271,7 +272,7 @@
 {
        struct histindex index;
        struct region lcs;
-       unsigned int sz;
+       size_t sz;
        int result = -1;
 
        if (count1 <= 0 && count2 <= 0)
@@ -302,7 +303,8 @@
 
        index.table_bits = xdl_hashbits(count1);
        sz = index.records_size = 1 << index.table_bits;
-       sz *= sizeof(struct record *);
+       GITERR_CHECK_ALLOC_MULTIPLY(&sz, sz, sizeof(struct record *));
+
        if (!(index.records = (struct record **) xdl_malloc(sz)))
                goto cleanup;
        memset(index.records, 0, sz);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/src/xdiff/xmerge.c 
new/libgit2-0.23.3/src/xdiff/xmerge.c
--- old/libgit2-0.23.2/src/xdiff/xmerge.c       2015-09-05 16:48:42.000000000 
+0200
+++ new/libgit2-0.23.3/src/xdiff/xmerge.c       2015-10-05 23:37:22.000000000 
+0200
@@ -21,6 +21,7 @@
  */
 
 #include "xinclude.h"
+#include "common.h"
 
 typedef struct s_xdmerge {
        struct s_xdmerge *next;
@@ -109,59 +110,74 @@
        return 0;
 }
 
-static int xdl_recs_copy_0(int use_orig, xdfenv_t *xe, int i, int count, int 
add_nl, char *dest)
+static int xdl_recs_copy_0(size_t *out, int use_orig, xdfenv_t *xe, int i, int 
count, int add_nl, char *dest)
 {
        xrecord_t **recs;
-       int size = 0;
+       size_t size = 0;
+
+       *out = 0;
 
        recs = (use_orig ? xe->xdf1.recs : xe->xdf2.recs) + i;
 
        if (count < 1)
                return 0;
 
-       for (i = 0; i < count; size += recs[i++]->size)
+       for (i = 0; i < count; ) {
                if (dest)
                        memcpy(dest + size, recs[i]->ptr, recs[i]->size);
+
+               GITERR_CHECK_ALLOC_ADD(&size, size, recs[i++]->size);
+       }
+
        if (add_nl) {
                i = recs[count - 1]->size;
                if (i == 0 || recs[count - 1]->ptr[i - 1] != '\n') {
                        if (dest)
                                dest[size] = '\n';
-                       size++;
+
+                       GITERR_CHECK_ALLOC_ADD(&size, size, 1);
                }
        }
-       return size;
+
+       *out = size;
+       return 0;
 }
 
-static int xdl_recs_copy(xdfenv_t *xe, int i, int count, int add_nl, char 
*dest)
+static int xdl_recs_copy(size_t *out, xdfenv_t *xe, int i, int count, int 
add_nl, char *dest)
 {
-       return xdl_recs_copy_0(0, xe, i, count, add_nl, dest);
+       return xdl_recs_copy_0(out, 0, xe, i, count, add_nl, dest);
 }
 
-static int xdl_orig_copy(xdfenv_t *xe, int i, int count, int add_nl, char 
*dest)
+static int xdl_orig_copy(size_t *out, xdfenv_t *xe, int i, int count, int 
add_nl, char *dest)
 {
-       return xdl_recs_copy_0(1, xe, i, count, add_nl, dest);
+       return xdl_recs_copy_0(out, 1, xe, i, count, add_nl, dest);
 }
 
-static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
+static int fill_conflict_hunk(size_t *out, xdfenv_t *xe1, const char *name1,
                              xdfenv_t *xe2, const char *name2,
                              const char *name3,
-                             int size, int i, int style,
+                             size_t size, int i, int style,
                              xdmerge_t *m, char *dest, int marker_size)
 {
        int marker1_size = (name1 ? (int)strlen(name1) + 1 : 0);
        int marker2_size = (name2 ? (int)strlen(name2) + 1 : 0);
        int marker3_size = (name3 ? (int)strlen(name3) + 1 : 0);
+       size_t copied;
+
+       *out = 0;
 
        if (marker_size <= 0)
                marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
 
        /* Before conflicting part */
-       size += xdl_recs_copy(xe1, i, m->i1 - i, 0,
-                             dest ? dest + size : NULL);
+       if (xdl_recs_copy(&copied, xe1, i, m->i1 - i, 0,
+                             dest ? dest + size : NULL) < 0)
+               return -1;
+
+       GITERR_CHECK_ALLOC_ADD(&size, size, copied);
 
        if (!dest) {
-               size += marker_size + 1 + marker1_size;
+               GITERR_CHECK_ALLOC_ADD4(&size, size, marker_size, 1, 
marker1_size);
        } else {
                memset(dest + size, '<', marker_size);
                size += marker_size;
@@ -174,13 +190,16 @@
        }
 
        /* Postimage from side #1 */
-       size += xdl_recs_copy(xe1, m->i1, m->chg1, 1,
-                             dest ? dest + size : NULL);
+       if (xdl_recs_copy(&copied, xe1, m->i1, m->chg1, 1,
+                             dest ? dest + size : NULL) < 0)
+               return -1;
+
+       GITERR_CHECK_ALLOC_ADD(&size, size, copied);
 
        if (style == XDL_MERGE_DIFF3) {
                /* Shared preimage */
                if (!dest) {
-                       size += marker_size + 1 + marker3_size;
+                       GITERR_CHECK_ALLOC_ADD4(&size, size, marker_size, 1, 
marker3_size);
                } else {
                        memset(dest + size, '|', marker_size);
                        size += marker_size;
@@ -191,12 +210,15 @@
                        }
                        dest[size++] = '\n';
                }
-               size += xdl_orig_copy(xe1, m->i0, m->chg0, 1,
-                                     dest ? dest + size : NULL);
+
+               if (xdl_orig_copy(&copied, xe1, m->i0, m->chg0, 1,
+                                     dest ? dest + size : NULL) < 0)
+                       return -1;
+               GITERR_CHECK_ALLOC_ADD(&size, size, copied);
        }
 
        if (!dest) {
-               size += marker_size + 1;
+               GITERR_CHECK_ALLOC_ADD3(&size, size, marker_size, 1);
        } else {
                memset(dest + size, '=', marker_size);
                size += marker_size;
@@ -204,10 +226,14 @@
        }
 
        /* Postimage from side #2 */
-       size += xdl_recs_copy(xe2, m->i2, m->chg2, 1,
-                             dest ? dest + size : NULL);
+
+       if (xdl_recs_copy(&copied, xe2, m->i2, m->chg2, 1,
+                             dest ? dest + size : NULL) < 0)
+               return -1;
+       GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+
        if (!dest) {
-               size += marker_size + 1 + marker2_size;
+               GITERR_CHECK_ALLOC_ADD4(&size, size, marker_size, 1, 
marker2_size);
        } else {
                memset(dest + size, '>', marker_size);
                size += marker_size;
@@ -218,46 +244,69 @@
                }
                dest[size++] = '\n';
        }
-       return size;
+
+       *out = size;
+       return 0;
 }
 
-static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,
+static int xdl_fill_merge_buffer(size_t *out,
+                                xdfenv_t *xe1, const char *name1,
                                 xdfenv_t *xe2, const char *name2,
                                 const char *ancestor_name,
                                 int favor,
                                 xdmerge_t *m, char *dest, int style,
                                 int marker_size)
 {
-       int size, i;
+       size_t size, copied;
+       int i;
+
+       *out = 0;
 
        for (size = i = 0; m; m = m->next) {
                if (favor && !m->mode)
                        m->mode = favor;
 
-               if (m->mode == 0)
-                       size = fill_conflict_hunk(xe1, name1, xe2, name2,
+               if (m->mode == 0) {
+                       if (fill_conflict_hunk(&size, xe1, name1, xe2, name2,
                                                  ancestor_name,
                                                  size, i, style, m, dest,
-                                                 marker_size);
+                                                 marker_size) < 0)
+                               return -1;
+               }
                else if (m->mode & 3) {
                        /* Before conflicting part */
-                       size += xdl_recs_copy(xe1, i, m->i1 - i, 0,
-                                             dest ? dest + size : NULL);
+                       if (xdl_recs_copy(&copied, xe1, i, m->i1 - i, 0,
+                                             dest ? dest + size : NULL) < 0)
+                               return -1;
+                       GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+
                        /* Postimage from side #1 */
-                       if (m->mode & 1)
-                               size += xdl_recs_copy(xe1, m->i1, m->chg1, 
(m->mode & 2),
-                                                     dest ? dest + size : 
NULL);
+                       if (m->mode & 1) {
+                               if (xdl_recs_copy(&copied, xe1, m->i1, m->chg1, 
(m->mode & 2),
+                                                     dest ? dest + size : 
NULL) < 0)
+                                       return -1;
+                               GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+                       }
+
                        /* Postimage from side #2 */
-                       if (m->mode & 2)
-                               size += xdl_recs_copy(xe2, m->i2, m->chg2, 0,
-                                                     dest ? dest + size : 
NULL);
+                       if (m->mode & 2) {
+                               if (xdl_recs_copy(&copied, xe2, m->i2, m->chg2, 
0,
+                                                     dest ? dest + size : 
NULL) < 0)
+                                       return -1;
+                               GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+                       }
                } else
                        continue;
                i = m->i1 + m->chg1;
        }
-       size += xdl_recs_copy(xe1, i, xe1->xdf2.nrec - i, 0,
-                             dest ? dest + size : NULL);
-       return size;
+
+       if (xdl_recs_copy(&copied, xe1, i, xe1->xdf2.nrec - i, 0,
+                             dest ? dest + size : NULL) < 0)
+               return -1;
+       GITERR_CHECK_ALLOC_ADD(&size, size, copied);
+
+       *out = size;
+       return 0;
 }
 
 /*
@@ -551,19 +600,24 @@
        /* output */
        if (result) {
                int marker_size = xmp->marker_size;
-               int size = xdl_fill_merge_buffer(xe1, name1, xe2, name2,
+               size_t size;
+
+               if (xdl_fill_merge_buffer(&size, xe1, name1, xe2, name2,
                                                 ancestor_name,
                                                 favor, changes, NULL, style,
-                                                marker_size);
+                                                marker_size) < 0)
+                       return -1;
+
                result->ptr = xdl_malloc(size);
                if (!result->ptr) {
                        xdl_cleanup_merge(changes);
                        return -1;
                }
                result->size = size;
-               xdl_fill_merge_buffer(xe1, name1, xe2, name2,
+               if (xdl_fill_merge_buffer(&size, xe1, name1, xe2, name2,
                                      ancestor_name, favor, changes,
-                                     result->ptr, style, marker_size);
+                                     result->ptr, style, marker_size) < 0)
+                       return -1;
        }
        return xdl_cleanup_merge(changes);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libgit2-0.23.2/tests/merge/files.c 
new/libgit2-0.23.3/tests/merge/files.c
--- old/libgit2-0.23.2/tests/merge/files.c      2015-09-05 16:48:42.000000000 
+0200
+++ new/libgit2-0.23.3/tests/merge/files.c      2015-10-05 23:37:22.000000000 
+0200
@@ -6,6 +6,7 @@
 #include "merge_helpers.h"
 #include "refs.h"
 #include "fileops.h"
+#include "diff_xdiff.h"
 
 #define TEST_REPO_PATH "merge-resolve"
 #define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
@@ -288,3 +289,90 @@
        git_merge_file_result_free(&result);
 }
 
+void test_merge_files__skips_large_files(void)
+{
+       git_merge_file_input ours = GIT_MERGE_FILE_INPUT_INIT,
+               theirs = GIT_MERGE_FILE_INPUT_INIT;
+       git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+       git_merge_file_result result = {0};
+
+       ours.size = GIT_XDIFF_MAX_SIZE + 1;
+       ours.path = "testfile.txt";
+       ours.mode = 0100755;
+
+       theirs.size = GIT_XDIFF_MAX_SIZE + 1;
+       theirs.path = "testfile.txt";
+       theirs.mode = 0100755;
+
+       cl_git_pass(git_merge_file(&result, NULL, &ours, &theirs, &opts));
+
+       cl_assert_equal_i(0, result.automergeable);
+
+       git_merge_file_result_free(&result);
+}
+
+void test_merge_files__skips_binaries(void)
+{
+       git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+               ours = GIT_MERGE_FILE_INPUT_INIT,
+               theirs = GIT_MERGE_FILE_INPUT_INIT;
+       git_merge_file_result result = {0};
+
+       ancestor.ptr = "ance\0stor\0";
+       ancestor.size = 10;
+       ancestor.path = "ancestor.txt";
+       ancestor.mode = 0100755;
+
+       ours.ptr = "foo\0bar\0";
+       ours.size = 8;
+       ours.path = "ours.txt";
+       ours.mode = 0100755;
+
+       theirs.ptr = "bar\0foo\0";
+       theirs.size = 8;
+       theirs.path = "theirs.txt";
+       theirs.mode = 0100644;
+
+       cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, NULL));
+
+       cl_assert_equal_i(0, result.automergeable);
+
+       git_merge_file_result_free(&result);
+}
+
+void test_merge_files__handles_binaries_when_favored(void)
+{
+       git_merge_file_input ancestor = GIT_MERGE_FILE_INPUT_INIT,
+               ours = GIT_MERGE_FILE_INPUT_INIT,
+               theirs = GIT_MERGE_FILE_INPUT_INIT;
+       git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
+       git_merge_file_result result = {0};
+
+       ancestor.ptr = "ance\0stor\0";
+       ancestor.size = 10;
+       ancestor.path = "ancestor.txt";
+       ancestor.mode = 0100755;
+
+       ours.ptr = "foo\0bar\0";
+       ours.size = 8;
+       ours.path = "ours.txt";
+       ours.mode = 0100755;
+
+       theirs.ptr = "bar\0foo\0";
+       theirs.size = 8;
+       theirs.path = "theirs.txt";
+       theirs.mode = 0100644;
+
+       opts.favor = GIT_MERGE_FILE_FAVOR_OURS;
+       cl_git_pass(git_merge_file(&result, &ancestor, &ours, &theirs, &opts));
+
+       cl_assert_equal_i(1, result.automergeable);
+
+       cl_assert_equal_s("ours.txt", result.path);
+       cl_assert_equal_i(0100755, result.mode);
+
+       cl_assert_equal_i(ours.size, result.len);
+       cl_assert(memcmp(result.ptr, ours.ptr, ours.size) == 0);
+
+       git_merge_file_result_free(&result);
+}


Reply via email to