From: "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Paul Ganssle <paul@ganssle.io>, Jeff King <peff@peff.net>,
Johannes Schindelin <johannes.schindelin@gmx.de>,
Johannes Schindelin <johannes.schindelin@gmx.de>
Subject: [PATCH] rebase --autosquash: fix a potential segfault
Date: Mon, 04 May 2020 20:40:04 +0000 [thread overview]
Message-ID: <pull.625.git.1588624804554.gitgitgadget@gmail.com> (raw)
From: Johannes Schindelin <johannes.schindelin@gmx.de>
When rearranging the todo list so that the fixups/squashes are reordered
just after the commits they intend to fix up, we use two arrays to
maintain that list: `next` and `tail`.
The idea is that `next[i]`, if set to a non-negative value, contains the
index of the item that should be rearranged just after the `i`th item.
To avoid having to walk the entire `next` chain when appending another
fixup/squash, we also store the end of the `next` chain in `last[i]`.
The logic we currently use to update these array items is based on the
assumption that given a fixup/squash item at index `i`, we just found
the index `i2` indicating the first item in that fixup chain.
However, as reported by Paul Ganssle, that need not be true: the special
form `fixup! <commit-hash>` is allowed to point to _another_ fixup
commit in the middle of the fixup chain.
Example:
* 0192a To fixup
* 02f12 fixup! To fixup
* 03763 fixup! To fixup
* 04ecb fixup! 02f12
Note how the fourth commit targets the second commit, which is already a
fixup that targets the first commit.
The good news is that it is easy to fix this: we can detect the
situation by looking at `last[i2]` (which will be `-1` if `i2` is
actually in the middle of a fixup chain), and in that case we simply
need to squeeze the current item into the middle of the `next` chain,
without touching `last` (i.e. leaving the end index of the fixup chain
alone).
Reported-by: Paul Ganssle <paul@ganssle.io>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
rebase --autosquash: fix a potential segfault
This patch is in response to
https://lore.kernel.org/git/017dbc40-8d21-00fb-7b0e-6708d2dcb366@ganssle.io/
.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-625%2Fdscho%2Fautosquash-segfault-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-625/dscho/autosquash-segfault-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/625
sequencer.c | 11 ++++++++++-
t/t3415-rebase-autosquash.sh | 14 ++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/sequencer.c b/sequencer.c
index e528225e787..0d4d53d2a49 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -5266,8 +5266,17 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)
TODO_FIXUP : TODO_SQUASH;
if (next[i2] < 0)
next[i2] = i;
- else
+ else if (tail[i2] >= 0)
next[tail[i2]] = i;
+ else {
+ /*
+ * i2 refers to a fixup commit in the middle of
+ * a fixup chain
+ */
+ next[i] = next[i2];
+ next[i2] = i;
+ continue;
+ }
tail[i2] = i;
} else if (!hashmap_get_from_hash(&subject2item,
strhash(subject), subject)) {
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 093de9005b7..ca135349346 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -424,4 +424,18 @@ test_expect_success 'abort last squash' '
! grep first actual
'
+test_expect_success 'fixup a fixup' '
+ echo 0to-fixup >file0 &&
+ test_tick &&
+ git commit -m "to-fixup" file0 &&
+ test_tick &&
+ git commit --squash HEAD -m X --allow-empty &&
+ test_tick &&
+ git commit --squash HEAD^ -m Y --allow-empty &&
+ test_tick &&
+ git commit -m "squash! $(git rev-parse HEAD^)" -m Z --allow-empty &&
+ git rebase -ki --autosquash HEAD~4 &&
+ test XZY = $(git show | tr -cd X-Z)
+'
+
test_done
base-commit: af6b65d45ef179ed52087e80cb089f6b2349f4ec
--
gitgitgadget
next reply other threads:[~2020-05-04 20:40 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-04 20:40 Johannes Schindelin via GitGitGadget [this message]
2020-05-04 21:19 ` [PATCH] rebase --autosquash: fix a potential segfault Junio C Hamano
2020-05-04 21:33 ` Jeff King
2020-05-04 22:09 ` Taylor Blau
2020-05-05 20:30 ` Junio C Hamano
2020-05-06 21:35 ` Johannes Schindelin
2020-05-07 19:17 ` Jeff King
2020-05-08 23:45 ` Johannes Schindelin
2020-05-05 22:33 ` [PATCH v2] " Johannes Schindelin via GitGitGadget
2020-05-09 19:23 ` [PATCH v3] " Johannes Schindelin via GitGitGadget
2020-05-06 15:12 ` [PATCH] " Andrei Rybak
2020-05-07 14:27 ` Johannes Schindelin
2020-05-08 16:43 ` Philip Oakley
2020-05-08 16:57 ` Andrei Rybak
2020-05-08 17:21 ` Philip Oakley
2020-05-18 16:47 ` Philip Oakley
2020-05-18 3:27 ` Johannes Schindelin
2020-05-25 17:29 ` Philip Oakley
2020-05-25 21:36 ` [PATCH 0/2] Clarify some of the fixup! documenation Philip Oakley
2020-05-25 21:36 ` [PATCH 1/2] doc: fixup/squash: clarify use of <oid-hash> in subject line Philip Oakley
2020-05-27 17:35 ` Junio C Hamano
2020-05-29 11:41 ` Philip Oakley
2020-05-25 21:36 ` [PATCH 2/2] doc: fixup/squash: remove ellipsis marks, use <line> for clarify Philip Oakley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.625.git.1588624804554.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=johannes.schindelin@gmx.de \
--cc=paul@ganssle.io \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.