diff options
author | Junio C Hamano <gitster@pobox.com> | 2017-11-21 14:07:52 +0900 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-11-21 14:07:52 +0900 |
commit | 5ed69ca6dbcef6122d90b9b8fb9a1b1f65208a6d (patch) | |
tree | 6cc93ae1b60d537bd4293845e6cadd29b8395265 /apply.c | |
parent | 1a5f2e44312e52d93edead612ea692cfc5c90c3b (diff) | |
parent | 6ce15ce576afb0510e9d6189ff3780369fdc5b2b (diff) | |
download | git-5ed69ca6dbcef6122d90b9b8fb9a1b1f65208a6d.tar.gz |
Merge branch 'rs/apply-fuzzy-match-fix'
A fix for an ancient bug in "git apply --ignore-space-change" codepath.
* rs/apply-fuzzy-match-fix:
apply: avoid out-of-bounds access in fuzzy_matchlines()
Diffstat (limited to 'apply.c')
-rw-r--r-- | apply.c | 59 |
1 files changed, 20 insertions, 39 deletions
@@ -300,52 +300,33 @@ static uint32_t hash_line(const char *cp, size_t len) static int fuzzy_matchlines(const char *s1, size_t n1, const char *s2, size_t n2) { - const char *last1 = s1 + n1 - 1; - const char *last2 = s2 + n2 - 1; - int result = 0; + const char *end1 = s1 + n1; + const char *end2 = s2 + n2; /* ignore line endings */ - while ((*last1 == '\r') || (*last1 == '\n')) - last1--; - while ((*last2 == '\r') || (*last2 == '\n')) - last2--; - - /* skip leading whitespaces, if both begin with whitespace */ - if (s1 <= last1 && s2 <= last2 && isspace(*s1) && isspace(*s2)) { - while (isspace(*s1) && (s1 <= last1)) - s1++; - while (isspace(*s2) && (s2 <= last2)) - s2++; - } - /* early return if both lines are empty */ - if ((s1 > last1) && (s2 > last2)) - return 1; - while (!result) { - result = *s1++ - *s2++; - /* - * Skip whitespace inside. We check for whitespace on - * both buffers because we don't want "a b" to match - * "ab" - */ - if (isspace(*s1) && isspace(*s2)) { - while (isspace(*s1) && s1 <= last1) + while (s1 < end1 && (end1[-1] == '\r' || end1[-1] == '\n')) + end1--; + while (s2 < end2 && (end2[-1] == '\r' || end2[-1] == '\n')) + end2--; + + while (s1 < end1 && s2 < end2) { + if (isspace(*s1)) { + /* + * Skip whitespace. We check on both buffers + * because we don't want "a b" to match "ab". + */ + if (!isspace(*s2)) + return 0; + while (s1 < end1 && isspace(*s1)) s1++; - while (isspace(*s2) && s2 <= last2) + while (s2 < end2 && isspace(*s2)) s2++; - } - /* - * If we reached the end on one side only, - * lines don't match - */ - if ( - ((s2 > last2) && (s1 <= last1)) || - ((s1 > last1) && (s2 <= last2))) + } else if (*s1++ != *s2++) return 0; - if ((s1 > last1) && (s2 > last2)) - break; } - return !result; + /* If we reached the end on one side only, lines don't match. */ + return s1 == end1 && s2 == end2; } static void add_line_info(struct image *img, const char *bol, size_t len, unsigned flag) |