summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Jeff King <peff@peff.net>2012-10-28 07:40:00 -0400
committerLibravatar Jeff King <peff@peff.net>2012-10-28 07:59:44 -0400
commitb1c2f57db326c43ec286855b396fb16b4890cf2d (patch)
tree072f9b8a85cea0166e4fafd3df7cd1968d81dea7
parentGit 1.7.12.4 (diff)
downloadtgif-b1c2f57db326c43ec286855b396fb16b4890cf2d.tar.xz
diff_grep: use textconv buffers for add/deleted files
If you use "-G" to grep a diff, we will apply a configured textconv filter to the data before generating the diff. However, if the diff is an addition or deletion, we do not bother running the diff at all, and just look for the token in the added (or removed) content. This works because we know that the diff must contain every line of content. However, while we used the textconv-derived buffers in the regular diff, we accidentally passed the original unmodified buffers to regexec when checking the added or removed content. This could lead to an incorrect answer. Worse, in some cases we might have a textconv buffer but no original buffer (e.g., if we pulled the textconv data from cache, or if we reused a working tree file when generating it). In that case, we could actually feed NULL to regexec and segfault. Reported-by: Peter Oberndorfer <kumbayo84@arcor.de> Signed-off-by: Jeff King <peff@peff.net>
-rw-r--r--diffcore-pickaxe.c4
-rwxr-xr-xt/t4030-diff-textconv.sh12
2 files changed, 14 insertions, 2 deletions
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index ed23eb4bdd..a209376354 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -104,10 +104,10 @@ static int diff_grep(struct diff_filepair *p, struct diff_options *o,
if (!mf2.ptr)
return 0; /* ignore unmerged */
/* created "two" -- does it have what we are looking for? */
- hit = !regexec(regexp, p->two->data, 1, &regmatch, 0);
+ hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);
} else if (!mf2.ptr) {
/* removed "one" -- did it have what we are looking for? */
- hit = !regexec(regexp, p->one->data, 1, &regmatch, 0);
+ hit = !regexec(regexp, mf1.ptr, 1, &regmatch, 0);
} else {
/*
* We have both sides; need to run textual diff and see if
diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh
index eebb1eed8b..461d27ac20 100755
--- a/t/t4030-diff-textconv.sh
+++ b/t/t4030-diff-textconv.sh
@@ -84,6 +84,18 @@ test_expect_success 'status -v produces text' '
git reset --soft HEAD@{1}
'
+test_expect_success 'grep-diff (-G) operates on textconv data (add)' '
+ echo one >expect &&
+ git log --root --format=%s -G0 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'grep-diff (-G) operates on textconv data (modification)' '
+ echo two >expect &&
+ git log --root --format=%s -G1 >actual &&
+ test_cmp expect actual
+'
+
cat >expect.stat <<'EOF'
file | Bin 2 -> 4 bytes
1 file changed, 0 insertions(+), 0 deletions(-)