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()
This commit is contained in:
commit
5ed69ca6db
57
apply.c
57
apply.c
@ -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,
|
static int fuzzy_matchlines(const char *s1, size_t n1,
|
||||||
const char *s2, size_t n2)
|
const char *s2, size_t n2)
|
||||||
{
|
{
|
||||||
const char *last1 = s1 + n1 - 1;
|
const char *end1 = s1 + n1;
|
||||||
const char *last2 = s2 + n2 - 1;
|
const char *end2 = s2 + n2;
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
/* ignore line endings */
|
/* ignore line endings */
|
||||||
while ((*last1 == '\r') || (*last1 == '\n'))
|
while (s1 < end1 && (end1[-1] == '\r' || end1[-1] == '\n'))
|
||||||
last1--;
|
end1--;
|
||||||
while ((*last2 == '\r') || (*last2 == '\n'))
|
while (s2 < end2 && (end2[-1] == '\r' || end2[-1] == '\n'))
|
||||||
last2--;
|
end2--;
|
||||||
|
|
||||||
/* skip leading whitespaces, if both begin with whitespace */
|
while (s1 < end1 && s2 < end2) {
|
||||||
if (s1 <= last1 && s2 <= last2 && isspace(*s1) && isspace(*s2)) {
|
if (isspace(*s1)) {
|
||||||
while (isspace(*s1) && (s1 <= last1))
|
/*
|
||||||
s1++;
|
* Skip whitespace. We check on both buffers
|
||||||
while (isspace(*s2) && (s2 <= last2))
|
* because we don't want "a b" to match "ab".
|
||||||
s2++;
|
*/
|
||||||
}
|
if (!isspace(*s2))
|
||||||
/* early return if both lines are empty */
|
return 0;
|
||||||
if ((s1 > last1) && (s2 > last2))
|
while (s1 < end1 && isspace(*s1))
|
||||||
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)
|
|
||||||
s1++;
|
s1++;
|
||||||
while (isspace(*s2) && s2 <= last2)
|
while (s2 < end2 && isspace(*s2))
|
||||||
s2++;
|
s2++;
|
||||||
}
|
} else if (*s1++ != *s2++)
|
||||||
/*
|
|
||||||
* If we reached the end on one side only,
|
|
||||||
* lines don't match
|
|
||||||
*/
|
|
||||||
if (
|
|
||||||
((s2 > last2) && (s1 <= last1)) ||
|
|
||||||
((s1 > last1) && (s2 <= last2)))
|
|
||||||
return 0;
|
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)
|
static void add_line_info(struct image *img, const char *bol, size_t len, unsigned flag)
|
||||||
|
Loading…
Reference in New Issue
Block a user