]> git.ipfire.org Git - thirdparty/git.git/blobdiff - apply.c
Start the 2.46 cycle
[thirdparty/git.git] / apply.c
diff --git a/apply.c b/apply.c
index 432837a674c3cc559f762aa4b7766bd8f43177e0..901b67e6255af4174a1e5a00cf01de4d2545d659 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -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;
 }