Skip to content

Commit 5de7166

Browse files
committed
apply.c:update_pre_post_images(): the preimage can be truncated
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 <[email protected]>
1 parent bafc478 commit 5de7166

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

builtin/apply.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,7 +2086,7 @@ static void update_pre_post_images(struct image *preimage,
20862086
char *buf,
20872087
size_t len, size_t postlen)
20882088
{
2089-
int i, ctx;
2089+
int i, ctx, reduced;
20902090
char *new, *old, *fixed;
20912091
struct image fixed_preimage;
20922092

@@ -2096,8 +2096,10 @@ static void update_pre_post_images(struct image *preimage,
20962096
* free "oldlines".
20972097
*/
20982098
prepare_image(&fixed_preimage, buf, len, 1);
2099-
assert(fixed_preimage.nr == preimage->nr);
2100-
for (i = 0; i < preimage->nr; i++)
2099+
assert(postlen
2100+
? fixed_preimage.nr == preimage->nr
2101+
: fixed_preimage.nr <= preimage->nr);
2102+
for (i = 0; i < fixed_preimage.nr; i++)
21012103
fixed_preimage.line[i].flag = preimage->line[i].flag;
21022104
free(preimage->line_allocated);
21032105
*preimage = fixed_preimage;
@@ -2117,7 +2119,8 @@ static void update_pre_post_images(struct image *preimage,
21172119
else
21182120
new = old;
21192121
fixed = preimage->buf;
2120-
for (i = ctx = 0; i < postimage->nr; i++) {
2122+
2123+
for (i = reduced = ctx = 0; i < postimage->nr; i++) {
21212124
size_t len = postimage->line[i].len;
21222125
if (!(postimage->line[i].flag & LINE_COMMON)) {
21232126
/* an added line -- no counterparts in preimage */
@@ -2136,8 +2139,15 @@ static void update_pre_post_images(struct image *preimage,
21362139
fixed += preimage->line[ctx].len;
21372140
ctx++;
21382141
}
2139-
if (preimage->nr <= ctx)
2140-
die(_("oops"));
2142+
2143+
/*
2144+
* preimage is expected to run out, if the caller
2145+
* fixed addition of trailing blank lines.
2146+
*/
2147+
if (preimage->nr <= ctx) {
2148+
reduced++;
2149+
continue;
2150+
}
21412151

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

21512161
/* Fix the length of the whole thing */
21522162
postimage->len = new - postimage->buf;
2163+
postimage->nr -= reduced;
21532164
}
21542165

21552166
static int match_fragment(struct image *img,

0 commit comments

Comments
 (0)