e467a90c7a
Currently the 'compute_assignment()' function may read memory out of bounds, even if used correctly. Namely this happens when we only have one column. In that case we try to calculate the initial minimum cost using '!j1' as column in the reduction transfer code. That in turn causes us to try and get the cost from column 1 in the cost matrix, which does not exist, and thus results in an out of bounds memory read. In the original paper [1], the example code initializes that minimum cost to "infinite". We could emulate something similar by setting the minimum cost to INT_MAX, which would result in the same minimum cost as the current algorithm, as we'd always go into the if condition at least once, except when we only have one column, and column_count thus equals 1. If column_count does equal 1, the condition in the loop would always be false, and we'd end up with a minimum of INT_MAX, which may lead to integer overflows later in the algorithm. For a column count of 1, we however do not even really need to go through the whole algorithm. A column count of 1 means that there's no possible assignments, and we can just zero out the column2row and row2column arrays, and return early from the function, while keeping the reduction transfer part of the function the same as it is currently. Another solution would be to just not call the 'compute_assignment()' function from the range diff code in this case, however it's better to make the compute_assignment function more robust, so future callers don't run into this potential problem. Note that the test only fails under valgrind on Linux, but the same command has been reported to segfault on Mac OS. [1]: Jonker, R., & Volgenant, A. (1987). A shortest augmenting path algorithm for dense and sparse linear assignment problems. Computing, 38(4), 325–340. Reported-by: ryenus <ryenus@gmail.com> Helped-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
151 lines
3.5 KiB
Bash
Executable File
151 lines
3.5 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='range-diff tests'
|
|
|
|
. ./test-lib.sh
|
|
|
|
# Note that because of the range-diff's heuristics, test_commit does more
|
|
# harm than good. We need some real history.
|
|
|
|
test_expect_success 'setup' '
|
|
git fast-import < "$TEST_DIRECTORY"/t3206/history.export
|
|
'
|
|
|
|
test_expect_success 'simple A..B A..C (unmodified)' '
|
|
git range-diff --no-color master..topic master..unmodified \
|
|
>actual &&
|
|
cat >expected <<-EOF &&
|
|
1: 4de457d = 1: 35b9b25 s/5/A/
|
|
2: fccce22 = 2: de345ab s/4/A/
|
|
3: 147e64e = 3: 9af6654 s/11/B/
|
|
4: a63e992 = 4: 2901f77 s/12/B/
|
|
EOF
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'simple B...C (unmodified)' '
|
|
git range-diff --no-color topic...unmodified >actual &&
|
|
# same "expected" as above
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'simple A B C (unmodified)' '
|
|
git range-diff --no-color master topic unmodified >actual &&
|
|
# same "expected" as above
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'trivial reordering' '
|
|
git range-diff --no-color master topic reordered >actual &&
|
|
cat >expected <<-EOF &&
|
|
1: 4de457d = 1: aca177a s/5/A/
|
|
3: 147e64e = 2: 14ad629 s/11/B/
|
|
4: a63e992 = 3: ee58208 s/12/B/
|
|
2: fccce22 = 4: 307b27a s/4/A/
|
|
EOF
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'removed a commit' '
|
|
git range-diff --no-color master topic removed >actual &&
|
|
cat >expected <<-EOF &&
|
|
1: 4de457d = 1: 7657159 s/5/A/
|
|
2: fccce22 < -: ------- s/4/A/
|
|
3: 147e64e = 2: 43d84d3 s/11/B/
|
|
4: a63e992 = 3: a740396 s/12/B/
|
|
EOF
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'added a commit' '
|
|
git range-diff --no-color master topic added >actual &&
|
|
cat >expected <<-EOF &&
|
|
1: 4de457d = 1: 2716022 s/5/A/
|
|
2: fccce22 = 2: b62accd s/4/A/
|
|
-: ------- > 3: df46cfa s/6/A/
|
|
3: 147e64e = 4: 3e64548 s/11/B/
|
|
4: a63e992 = 5: 12b4063 s/12/B/
|
|
EOF
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'new base, A B C' '
|
|
git range-diff --no-color master topic rebased >actual &&
|
|
cat >expected <<-EOF &&
|
|
1: 4de457d = 1: cc9c443 s/5/A/
|
|
2: fccce22 = 2: c5d9641 s/4/A/
|
|
3: 147e64e = 3: 28cc2b6 s/11/B/
|
|
4: a63e992 = 4: 5628ab7 s/12/B/
|
|
EOF
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'new base, B...C' '
|
|
# this syntax includes the commits from master!
|
|
git range-diff --no-color topic...rebased >actual &&
|
|
cat >expected <<-EOF &&
|
|
-: ------- > 1: a31b12e unrelated
|
|
1: 4de457d = 2: cc9c443 s/5/A/
|
|
2: fccce22 = 3: c5d9641 s/4/A/
|
|
3: 147e64e = 4: 28cc2b6 s/11/B/
|
|
4: a63e992 = 5: 5628ab7 s/12/B/
|
|
EOF
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'changed commit' '
|
|
git range-diff --no-color topic...changed >actual &&
|
|
cat >expected <<-EOF &&
|
|
1: 4de457d = 1: a4b3333 s/5/A/
|
|
2: fccce22 = 2: f51d370 s/4/A/
|
|
3: 147e64e ! 3: 0559556 s/11/B/
|
|
@@ -10,7 +10,7 @@
|
|
9
|
|
10
|
|
-11
|
|
-+B
|
|
++BB
|
|
12
|
|
13
|
|
14
|
|
4: a63e992 ! 4: d966c5c s/12/B/
|
|
@@ -8,7 +8,7 @@
|
|
@@
|
|
9
|
|
10
|
|
- B
|
|
+ BB
|
|
-12
|
|
+B
|
|
13
|
|
EOF
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'changed message' '
|
|
git range-diff --no-color topic...changed-message >actual &&
|
|
sed s/Z/\ /g >expected <<-EOF &&
|
|
1: 4de457d = 1: f686024 s/5/A/
|
|
2: fccce22 ! 2: 4ab067d s/4/A/
|
|
@@ -2,6 +2,8 @@
|
|
Z
|
|
Z s/4/A/
|
|
Z
|
|
+ Also a silly comment here!
|
|
+
|
|
Zdiff --git a/file b/file
|
|
Z--- a/file
|
|
Z+++ b/file
|
|
3: 147e64e = 3: b9cb956 s/11/B/
|
|
4: a63e992 = 4: 8add5f1 s/12/B/
|
|
EOF
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'no commits on one side' '
|
|
git commit --amend -m "new message" &&
|
|
git range-diff master HEAD@{1} HEAD
|
|
'
|
|
|
|
test_done
|