diff options
Diffstat (limited to 'apply.c')
| -rw-r--r-- | apply.c | 66 |
1 files changed, 41 insertions, 25 deletions
@@ -1292,8 +1292,15 @@ static char *git_header_name(int p_value, return NULL; /* no postimage name */ second = skip_tree_prefix(p_value, name + len + 1, line_len - (len + 1)); + /* + * If we are at the SP at the end of a directory, + * skip_tree_prefix() may return NULL as that makes + * it appears as if we have an absolute path. + * Keep going to find another SP. + */ if (!second) - return NULL; + continue; + /* * Does len bytes starting at "name" and "second" * (that are separated by one HT or SP we just @@ -3705,8 +3712,10 @@ static int apply_data(struct apply_state *state, struct patch *patch, fprintf(stderr, _("Falling back to direct application...\n")); /* Note: with --reject, apply_fragments() returns 0 */ - if (patch->direct_to_threeway || apply_fragments(state, &image, patch) < 0) + if (patch->direct_to_threeway || apply_fragments(state, &image, patch) < 0) { + clear_image(&image); return -1; + } } patch->result = image.buf; patch->resultsize = image.len; @@ -4441,6 +4450,7 @@ static int create_one_file(struct apply_state *state, const char *buf, unsigned long size) { + char *newpath = NULL; int res; if (state->cached) @@ -4502,24 +4512,26 @@ static int create_one_file(struct apply_state *state, unsigned int nr = getpid(); for (;;) { - char newpath[PATH_MAX]; - mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr); + newpath = mkpathdup("%s~%u", path, nr); res = try_create_file(state, newpath, mode, buf, size); if (res < 0) - return -1; + goto out; if (!res) { if (!rename(newpath, path)) - return 0; + goto out; unlink_or_warn(newpath); break; } if (errno != EEXIST) break; ++nr; + FREE_AND_NULL(newpath); } } - return error_errno(_("unable to write file '%s' mode %o"), - path, mode); + res = error_errno(_("unable to write file '%s' mode %o"), path, mode); +out: + free(newpath); + return res; } static int add_conflicted_stages_file(struct apply_state *state, @@ -4602,7 +4614,7 @@ static int write_out_one_result(struct apply_state *state, static int write_out_one_reject(struct apply_state *state, struct patch *patch) { FILE *rej; - char namebuf[PATH_MAX]; + char *namebuf; struct fragment *frag; int fd, cnt = 0; struct strbuf sb = STRBUF_INIT; @@ -4635,28 +4647,30 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch) say_patch_name(stderr, sb.buf, patch); strbuf_release(&sb); - cnt = strlen(patch->new_name); - if (ARRAY_SIZE(namebuf) <= cnt + 5) { - cnt = ARRAY_SIZE(namebuf) - 5; - warning(_("truncating .rej filename to %.*s.rej"), - cnt - 1, patch->new_name); - } - memcpy(namebuf, patch->new_name, cnt); - memcpy(namebuf + cnt, ".rej", 5); + namebuf = xstrfmt("%s.rej", patch->new_name); fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666); if (fd < 0) { - if (errno != EEXIST) - return error_errno(_("cannot open %s"), namebuf); - if (unlink(namebuf)) - return error_errno(_("cannot unlink '%s'"), namebuf); + if (errno != EEXIST) { + error_errno(_("cannot open %s"), namebuf); + goto error; + } + if (unlink(namebuf)) { + error_errno(_("cannot unlink '%s'"), namebuf); + goto error; + } fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666); - if (fd < 0) - return error_errno(_("cannot open %s"), namebuf); + if (fd < 0) { + error_errno(_("cannot open %s"), namebuf); + goto error; + } } rej = fdopen(fd, "w"); - if (!rej) - return error_errno(_("cannot open %s"), namebuf); + if (!rej) { + error_errno(_("cannot open %s"), namebuf); + close(fd); + goto error; + } /* Normal git tools never deal with .rej, so do not pretend * this is a git patch by saying --git or giving extended @@ -4680,6 +4694,8 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch) fputc('\n', rej); } fclose(rej); +error: + free(namebuf); return -1; } |
