mirror of
https://github.com/git/git.git
synced 2026-02-07 00:05:02 +00:00
fixup! git tag --contains : avoid stack overflow
This commit is contained in:
@@ -73,11 +73,17 @@ static int in_commit_list(const struct commit_list *want, struct commit *c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum contains_result {
|
||||
CONTAINS_UNKNOWN = -1,
|
||||
CONTAINS_NO = 0,
|
||||
CONTAINS_YES = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Test whether the candidate or one of its parents is contained in the list.
|
||||
* Do not recurse to find out, though, but return -1 if inconclusive.
|
||||
*/
|
||||
static int contains_test(struct commit *candidate,
|
||||
static enum contains_result contains_test(struct commit *candidate,
|
||||
const struct commit_list *want)
|
||||
{
|
||||
/* was it previously marked as containing a want commit? */
|
||||
@@ -121,12 +127,13 @@ static void push_to_stack(struct commit *candidate, struct stack *stack)
|
||||
stack->stack[index].parents = candidate->parents;
|
||||
}
|
||||
|
||||
static int contains(struct commit *candidate, const struct commit_list *want)
|
||||
static enum contains_result contains(struct commit *candidate,
|
||||
const struct commit_list *want)
|
||||
{
|
||||
struct stack stack = { 0, 0, NULL };
|
||||
int result = contains_test(candidate, want);
|
||||
|
||||
if (result >= 0)
|
||||
if (result != CONTAINS_UNKNOWN)
|
||||
return result;
|
||||
|
||||
push_to_stack(candidate, &stack);
|
||||
@@ -136,7 +143,7 @@ static int contains(struct commit *candidate, const struct commit_list *want)
|
||||
struct commit_list *parents = entry->parents;
|
||||
|
||||
if (!parents) {
|
||||
commit->object.flags = UNINTERESTING;
|
||||
commit->object.flags |= UNINTERESTING;
|
||||
stack.nr--;
|
||||
}
|
||||
/*
|
||||
@@ -144,14 +151,14 @@ static int contains(struct commit *candidate, const struct commit_list *want)
|
||||
* therefore contains_test will return a meaningful 0 or 1.
|
||||
*/
|
||||
else switch (contains_test(parents->item, want)) {
|
||||
case 1:
|
||||
case CONTAINS_YES:
|
||||
commit->object.flags |= TMP_MARK;
|
||||
stack.nr--;
|
||||
break;
|
||||
case 0:
|
||||
case CONTAINS_NO:
|
||||
entry->parents = parents->next;
|
||||
break;
|
||||
default:
|
||||
case CONTAINS_UNKNOWN:
|
||||
push_to_stack(parents->item, &stack);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1380,10 +1380,11 @@ test_expect_success 'multiple --points-at are OR-ed together' '
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_lazy_prereq BASH 'bash --version'
|
||||
|
||||
>expect
|
||||
# ulimit is a bash builtin; we can rely on that in MinGW, but nowhere else
|
||||
test_expect_success MINGW '--contains works in a deep repo' '
|
||||
ulimit -s 64
|
||||
# we require bash for its 'ulimit' builtin
|
||||
test_expect_success BASH '--contains works in a deep repo' '
|
||||
i=1 &&
|
||||
while test $i -lt 1000
|
||||
do
|
||||
@@ -1397,7 +1398,7 @@ EOF"
|
||||
done | git fast-import &&
|
||||
git checkout master &&
|
||||
git tag far-far-away HEAD^ &&
|
||||
git tag --contains HEAD >actual &&
|
||||
bash -c "ulimit -s 64 && git tag --contains HEAD >actual" &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user