From 250b3c6c992b3cb04e756eb33bed99442fc55193 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 22 Mar 2013 11:10:03 -0700 Subject: [PATCH 1/2] apply --whitespace=fix: avoid running over the postimage buffer Originally update-pre-post-images could assume that any whitespace fixing will make the result only shorter by unexpanding runs of leading SPs into HTs and removing trailing whitespaces at the end of lines. Updating the post-image we read from the patch to match the actual result can be performed in-place under this assumption. These days, however, we have tab-in-indent (aka Python) rule whose result can be longer than the original, and we do need to allocate a larger buffer than the input and replace the result. Fortunately the support for lengthening rewrite was already added when we began supporting "match while ignoring whitespace differences" mode in 86c91f91794c (git apply: option to ignore whitespace differences, 2009-08-04). We only need to correctly count the number of bytes necessary to hold the updated result and tell the function to allocate a new buffer. Signed-off-by: Junio C Hamano --- builtin/apply.c | 16 ++++++++++------ t/t4124-apply-ws-rule.sh | 26 ++++++++++++++++++++++++++ t/t4150-am.sh | 2 +- t/test-lib-functions.sh | 4 ++-- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/builtin/apply.c b/builtin/apply.c index 156b3ce3b7..df773c75b9 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -2113,10 +2113,10 @@ static void update_pre_post_images(struct image *preimage, /* * Adjust the common context lines in postimage. This can be - * done in-place when we are just doing whitespace fixing, - * which does not make the string grow, but needs a new buffer - * when ignoring whitespace causes the update, since in this case - * we could have e.g. tabs converted to multiple spaces. + * done in-place when we are shrinking it with whitespace + * fixing, but needs a new buffer when ignoring whitespace or + * expanding leading tabs to spaces. + * * We trust the caller to tell us if the update can be done * in place (postlen==0) or not. */ @@ -2172,7 +2172,7 @@ static int match_fragment(struct image *img, int i; char *fixed_buf, *buf, *orig, *target; struct strbuf fixed; - size_t fixed_len; + size_t fixed_len, postlen; int preimage_limit; if (preimage->nr + try_lno <= img->nr) { @@ -2322,6 +2322,7 @@ static int match_fragment(struct image *img, strbuf_init(&fixed, preimage->len + 1); orig = preimage->buf; target = img->buf + try; + postlen = 0; for (i = 0; i < preimage_limit; i++) { size_t oldlen = preimage->line[i].len; size_t tgtlen = img->line[try_lno + i].len; @@ -2349,6 +2350,7 @@ static int match_fragment(struct image *img, match = (tgtfix.len == fixed.len - fixstart && !memcmp(tgtfix.buf, fixed.buf + fixstart, fixed.len - fixstart)); + postlen += tgtfix.len; strbuf_release(&tgtfix); if (!match) @@ -2386,8 +2388,10 @@ static int match_fragment(struct image *img, * hunk match. Update the context lines in the postimage. */ fixed_buf = strbuf_detach(&fixed, &fixed_len); + if (postlen < postimage->len) + postlen = 0; update_pre_post_images(preimage, postimage, - fixed_buf, fixed_len, 0); + fixed_buf, fixed_len, postlen); return 1; unmatch_exit: diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh index 6f6ee88b28..0bbcf0603d 100755 --- a/t/t4124-apply-ws-rule.sh +++ b/t/t4124-apply-ws-rule.sh @@ -486,4 +486,30 @@ test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' ' test_cmp one expect ' +test_expect_success 'whitespace=fix to expand' ' + qz_to_tab_space >preimage <<-\EOF && + QQa + QQb + QQc + ZZZZZZZZZZZZZZZZd + QQe + QQf + QQg + EOF + qz_to_tab_space >patch <<-\EOF && + diff --git a/preimage b/preimage + --- a/preimage + +++ b/preimage + @@ -1,7 +1,6 @@ + QQa + QQb + QQc + -QQd + QQe + QQf + QQg + EOF + git -c core.whitespace=tab-in-indent apply --whitespace=fix patch +' + test_done diff --git a/t/t4150-am.sh b/t/t4150-am.sh index cdafd7e7c1..12f6b027ac 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -17,7 +17,7 @@ test_expect_success 'setup: messages' ' vero eos et accusam et justo duo dolores et ea rebum. EOF - q_to_tab <<-\EOF >>msg && + qz_to_tab_space <<-\EOF >>msg && QDuis autem vel eum iriure dolor in hendrerit in vulputate velit Qesse molestie consequat, vel illum dolore eu feugiat nulla facilisis Qat vero eros et accumsan et iusto odio dignissim qui blandit diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 8889ba5104..dc070f8d58 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -87,8 +87,8 @@ q_to_cr () { tr Q '\015' } -q_to_tab () { - tr Q '\011' +qz_to_tab_space () { + tr QZ '\011\040' } append_cr () { From 329b26e0b4b2574960ee703eccdb0a7126a60505 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 29 Mar 2013 13:38:28 -0700 Subject: [PATCH 2/2] test: resurrect q_to_tab New test may want to use this helper; keep it for them that do not need to protect literal SP. Signed-off-by: Junio C Hamano --- t/test-lib-functions.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index dc070f8d58..4a8bac282b 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -87,6 +87,10 @@ q_to_cr () { tr Q '\015' } +q_to_tab () { + tr Q '\011' +} + qz_to_tab_space () { tr QZ '\011\040' }