diff options
Diffstat (limited to 'builtin/apply.c')
-rw-r--r-- | builtin/apply.c | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/builtin/apply.c b/builtin/apply.c index 23c18c573b..b719f41482 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -449,7 +449,7 @@ static char *find_name_gnu(const char *line, char *def, int p_value) return squash_slash(strbuf_detach(&name, NULL)); } -static size_t tz_len(const char *line, size_t len) +static size_t sane_tz_len(const char *line, size_t len) { const char *tz, *p; @@ -467,6 +467,24 @@ static size_t tz_len(const char *line, size_t len) return line + len - tz; } +static size_t tz_with_colon_len(const char *line, size_t len) +{ + const char *tz, *p; + + if (len < strlen(" +08:00") || line[len - strlen(":00")] != ':') + return 0; + tz = line + len - strlen(" +08:00"); + + if (tz[0] != ' ' || (tz[1] != '+' && tz[1] != '-')) + return 0; + p = tz + 2; + if (!isdigit(*p++) || !isdigit(*p++) || *p++ != ':' || + !isdigit(*p++) || !isdigit(*p++)) + return 0; + + return line + len - tz; +} + static size_t date_len(const char *line, size_t len) { const char *date, *p; @@ -561,7 +579,9 @@ static size_t diff_timestamp_len(const char *line, size_t len) if (!isdigit(end[-1])) return 0; - n = tz_len(line, end - line); + n = sane_tz_len(line, end - line); + if (!n) + n = tz_with_colon_len(line, end - line); end -= n; n = short_time_len(line, end - line); @@ -733,8 +753,8 @@ static int has_epoch_timestamp(const char *nameline) " " "[0-2][0-9]:[0-5][0-9]:00(\\.0+)?" " " - "([-+][0-2][0-9][0-5][0-9])\n"; - const char *timestamp = NULL, *cp; + "([-+][0-2][0-9]:?[0-5][0-9])\n"; + const char *timestamp = NULL, *cp, *colon; static regex_t *stamp; regmatch_t m[10]; int zoneoffset; @@ -764,8 +784,11 @@ static int has_epoch_timestamp(const char *nameline) return 0; } - zoneoffset = strtol(timestamp + m[3].rm_so + 1, NULL, 10); - zoneoffset = (zoneoffset / 100) * 60 + (zoneoffset % 100); + zoneoffset = strtol(timestamp + m[3].rm_so + 1, (char **) &colon, 10); + if (*colon == ':') + zoneoffset = zoneoffset * 60 + strtol(colon + 1, NULL, 10); + else + zoneoffset = (zoneoffset / 100) * 60 + (zoneoffset % 100); if (timestamp[m[3].rm_so] == '-') zoneoffset = -zoneoffset; @@ -919,28 +942,28 @@ static int gitdiff_newfile(const char *line, struct patch *patch) static int gitdiff_copysrc(const char *line, struct patch *patch) { patch->is_copy = 1; - patch->old_name = find_name(line, NULL, 0, 0); + patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0); return 0; } static int gitdiff_copydst(const char *line, struct patch *patch) { patch->is_copy = 1; - patch->new_name = find_name(line, NULL, 0, 0); + patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0); return 0; } static int gitdiff_renamesrc(const char *line, struct patch *patch) { patch->is_rename = 1; - patch->old_name = find_name(line, NULL, 0, 0); + patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0); return 0; } static int gitdiff_renamedst(const char *line, struct patch *patch) { patch->is_rename = 1; - patch->new_name = find_name(line, NULL, 0, 0); + patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0); return 0; } @@ -1025,7 +1048,7 @@ static char *git_header_name(char *line, int llen) { const char *name; const char *second = NULL; - size_t len; + size_t len, line_len; line += strlen("diff --git "); llen -= strlen("diff --git "); @@ -1125,6 +1148,10 @@ static char *git_header_name(char *line, int llen) * Accept a name only if it shows up twice, exactly the same * form. */ + second = strchr(name, '\n'); + if (!second) + return NULL; + line_len = second - name; for (len = 0 ; ; len++) { switch (name[len]) { default: @@ -1132,15 +1159,11 @@ static char *git_header_name(char *line, int llen) case '\n': return NULL; case '\t': case ' ': - second = name+len; - for (;;) { - char c = *second++; - if (c == '\n') - return NULL; - if (c == '/') - break; - } - if (second[len] == '\n' && !memcmp(name, second, len)) { + second = stop_at_slash(name + len, line_len - len); + if (!second) + return NULL; + second++; + if (second[len] == '\n' && !strncmp(name, second, len)) { return xmemdupz(name, len); } } @@ -2645,6 +2668,12 @@ static int apply_binary_fragment(struct image *img, struct patch *patch) unsigned long len; void *dst; + if (!fragment) + return error("missing binary patch data for '%s'", + patch->new_name ? + patch->new_name : + patch->old_name); + /* Binary patch is irreversible without the optional second hunk */ if (apply_in_reverse) { if (!fragment->next) |