Skip to content

Commit

Permalink
apply.c:update_pre_post_images(): the preimage can be truncated
Browse files Browse the repository at this point in the history
5166714 (apply: Allow blank context lines to match beyond EOF,
2010-03-06) and then later 0c3ef98 (apply: Allow blank *trailing*
context lines to match beyond EOF, 2010-04-08) taught "git apply"
to trim new blank lines at the end in the patch text when matching
the contents being patched and the preimage recorded in the patch,
under --whitespace=fix mode.

When a preimage is modified to match the current contents in
preparation for such a "fixed" patch application, the context lines
in the postimage must be updated to match (otherwise, it would
reintroduce whitespace breakages), and update_pre_post_images()
function is responsible for doing this.  However, this function was
not updated to take into account a case where the removal of
trailing blank lines reduces the number of lines in the preimage,
and triggered an assertion error.

The logic to fix the postimage by copying the corrected context
lines from the preimage was not prepared to handle this case,
either, but it was protected by the assert() and only got exposed
when the assertion is corrected.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Junio C Hamano committed Oct 12, 2012
1 parent bafc478 commit 5de7166
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions builtin/apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -2086,7 +2086,7 @@ static void update_pre_post_images(struct image *preimage,
char *buf,
size_t len, size_t postlen)
{
int i, ctx;
int i, ctx, reduced;
char *new, *old, *fixed;
struct image fixed_preimage;

Expand All @@ -2096,8 +2096,10 @@ static void update_pre_post_images(struct image *preimage,
* free "oldlines".
*/
prepare_image(&fixed_preimage, buf, len, 1);
assert(fixed_preimage.nr == preimage->nr);
for (i = 0; i < preimage->nr; i++)
assert(postlen
? fixed_preimage.nr == preimage->nr
: fixed_preimage.nr <= preimage->nr);
for (i = 0; i < fixed_preimage.nr; i++)
fixed_preimage.line[i].flag = preimage->line[i].flag;
free(preimage->line_allocated);
*preimage = fixed_preimage;
Expand All @@ -2117,7 +2119,8 @@ static void update_pre_post_images(struct image *preimage,
else
new = old;
fixed = preimage->buf;
for (i = ctx = 0; i < postimage->nr; i++) {

for (i = reduced = ctx = 0; i < postimage->nr; i++) {
size_t len = postimage->line[i].len;
if (!(postimage->line[i].flag & LINE_COMMON)) {
/* an added line -- no counterparts in preimage */
Expand All @@ -2136,8 +2139,15 @@ static void update_pre_post_images(struct image *preimage,
fixed += preimage->line[ctx].len;
ctx++;
}
if (preimage->nr <= ctx)
die(_("oops"));

/*
* preimage is expected to run out, if the caller
* fixed addition of trailing blank lines.
*/
if (preimage->nr <= ctx) {
reduced++;
continue;
}

/* and copy it in, while fixing the line length */
len = preimage->line[ctx].len;
Expand All @@ -2150,6 +2160,7 @@ static void update_pre_post_images(struct image *preimage,

/* Fix the length of the whole thing */
postimage->len = new - postimage->buf;
postimage->nr -= reduced;
}

static int match_fragment(struct image *img,
Expand Down

0 comments on commit 5de7166

Please sign in to comment.