summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2016-11-02 09:23:53 +0100
committerGitHub <noreply@github.com>2016-11-02 09:23:53 +0100
commit19001ca7ba175500978386729b49435dfcde3d67 (patch)
tree39c4ee616c3ca12251e6a5722a05c1437196bcac
parent41ad9ebfad2e8a6c1191580250ce8d63cf5d328a (diff)
parent95fa38802f12b930b3acf3fe842408bb33eb1d18 (diff)
downloadlibgit2-19001ca7ba175500978386729b49435dfcde3d67.tar.gz
Merge pull request #3976 from pks-t/pks/pqueue-null-deref
pqueue: resolve possible NULL pointer dereference
-rw-r--r--src/pqueue.c5
-rw-r--r--tests/core/pqueue.c22
2 files changed, 25 insertions, 2 deletions
diff --git a/src/pqueue.c b/src/pqueue.c
index 8cfc4390f..9341d1af3 100644
--- a/src/pqueue.c
+++ b/src/pqueue.c
@@ -86,8 +86,9 @@ int git_pqueue_insert(git_pqueue *pq, void *item)
if ((pq->flags & GIT_PQUEUE_FIXED_SIZE) != 0 &&
pq->length >= pq->_alloc_size)
{
- /* skip this item if below min item in heap */
- if (pq->_cmp(item, git_vector_get(pq, 0)) <= 0)
+ /* skip this item if below min item in heap or if
+ * we do not have a comparison function */
+ if (!pq->_cmp || pq->_cmp(item, git_vector_get(pq, 0)) <= 0)
return 0;
/* otherwise remove the min item before inserting new */
(void)git_pqueue_pop(pq);
diff --git a/tests/core/pqueue.c b/tests/core/pqueue.c
index bcd4eea9f..2b90f4172 100644
--- a/tests/core/pqueue.c
+++ b/tests/core/pqueue.c
@@ -93,7 +93,29 @@ void test_core_pqueue__max_heap_size(void)
cl_assert_equal_i(0, git_pqueue_size(&pq));
git_pqueue_free(&pq);
+}
+
+void test_core_pqueue__max_heap_size_without_comparison(void)
+{
+ git_pqueue pq;
+ int i, vals[100] = { 0 };
+
+ cl_git_pass(git_pqueue_init(&pq, GIT_PQUEUE_FIXED_SIZE, 50, NULL));
+
+ for (i = 0; i < 100; ++i)
+ cl_git_pass(git_pqueue_insert(&pq, &vals[i]));
+ cl_assert_equal_i(50, git_pqueue_size(&pq));
+
+ /* As we have no comparison function, we cannot make any
+ * actual assumptions about which entries are part of the
+ * pqueue */
+ for (i = 0; i < 50; ++i)
+ cl_assert(git_pqueue_pop(&pq));
+
+ cl_assert_equal_i(0, git_pqueue_size(&pq));
+
+ git_pqueue_free(&pq);
}
static int cmp_ints_like_commit_time(const void *a, const void *b)