#include "xdiff-interface.h"
#include "run-command.h"
#include "ll-merge.h"
+#include "quote.h"
struct ll_merge_driver;
xmparam_t xmp;
assert(opts);
- if (buffer_is_binary(orig->ptr, orig->size) ||
+ if (orig->size > MAX_XDIFF_SIZE ||
+ src1->size > MAX_XDIFF_SIZE ||
+ src2->size > MAX_XDIFF_SIZE ||
+ buffer_is_binary(orig->ptr, orig->size) ||
buffer_is_binary(src1->ptr, src1->size) ||
buffer_is_binary(src2->ptr, src2->size)) {
return ll_binary_merge(drv_unused, result,
{ "union", "built-in union merge", ll_union_merge },
};
-static void create_temp(mmfile_t *src, char *path)
+static void create_temp(mmfile_t *src, char *path, size_t len)
{
int fd;
- strcpy(path, ".merge_file_XXXXXX");
+ xsnprintf(path, len, ".merge_file_XXXXXX");
fd = xmkstemp(path);
if (write_in_full(fd, src->ptr, src->size) != src->size)
die_errno("unable to write temp-file");
{
char temp[4][50];
struct strbuf cmd = STRBUF_INIT;
- struct strbuf_expand_dict_entry dict[5];
+ struct strbuf_expand_dict_entry dict[6];
+ struct strbuf path_sq = STRBUF_INIT;
const char *args[] = { NULL, NULL };
int status, fd, i;
struct stat st;
assert(opts);
+ sq_quote_buf(&path_sq, path);
dict[0].placeholder = "O"; dict[0].value = temp[0];
dict[1].placeholder = "A"; dict[1].value = temp[1];
dict[2].placeholder = "B"; dict[2].value = temp[2];
dict[3].placeholder = "L"; dict[3].value = temp[3];
- dict[4].placeholder = NULL; dict[4].value = NULL;
+ dict[4].placeholder = "P"; dict[4].value = path_sq.buf;
+ dict[5].placeholder = NULL; dict[5].value = NULL;
if (fn->cmdline == NULL)
die("custom merge driver %s lacks command line.", fn->name);
result->ptr = NULL;
result->size = 0;
- create_temp(orig, temp[0]);
- create_temp(src1, temp[1]);
- create_temp(src2, temp[2]);
- sprintf(temp[3], "%d", marker_size);
+ create_temp(orig, temp[0], sizeof(temp[0]));
+ create_temp(src1, temp[1], sizeof(temp[1]));
+ create_temp(src2, temp[2], sizeof(temp[2]));
+ xsnprintf(temp[3], sizeof(temp[3]), "%d", marker_size);
strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict);
if (fstat(fd, &st))
goto close_bad;
result->size = st.st_size;
- result->ptr = xmalloc(result->size + 1);
+ result->ptr = xmallocz(result->size);
if (read_in_full(fd, result->ptr, result->size) != result->size) {
free(result->ptr);
result->ptr = NULL;
for (i = 0; i < 3; i++)
unlink_or_warn(temp[i]);
strbuf_release(&cmd);
+ strbuf_release(&path_sq);
return status;
}
* %A - temporary file name for our version.
* %B - temporary file name for the other branches' version.
* %L - conflict marker length
+ * %P - the original path (safely quoted for the shell)
*
* The external merge driver should write the results in the
* file named by %A, and signal that it has done with zero exit