static int allow_overlap;
static int no_add;
static int threeway;
+static int unsafe_paths;
static const char *fake_ancestor;
static int line_termination = '\n';
static unsigned int p_context = UINT_MAX;
const char *name,
unsigned expected_mode)
{
- if (cached) {
+ if (cached || check_index) {
if (read_file_or_gitlink(ce, buf))
return error(_("read of %s failed"), name);
} else if (name) {
return read_file_or_gitlink(ce, buf);
else
return SUBMODULE_PATCH_WITHOUT_INDEX;
+ } else if (has_symlink_leading_path(name, strlen(name))) {
+ return error(_("reading from '%s' beyond a symbolic link"), name);
} else {
if (read_old_data(st, name, buf))
return error(_("read of %s failed"), name);
return 0;
}
+static void die_on_unsafe_path(struct patch *patch)
+{
+ const char *old_name = NULL;
+ const char *new_name = NULL;
+ if (patch->is_delete)
+ old_name = patch->old_name;
+ else if (!patch->is_new && !patch->is_copy)
+ old_name = patch->old_name;
+ if (!patch->is_delete)
+ new_name = patch->new_name;
+
+ if (old_name && !verify_path(old_name))
+ die(_("invalid path '%s'"), old_name);
+ if (new_name && !verify_path(new_name))
+ die(_("invalid path '%s'"), new_name);
+}
+
/*
* Check and apply the patch in-core; leave the result in patch->result
* for the caller to write it out to the final destination.
}
}
+ if (!unsafe_paths)
+ die_on_unsafe_path(patch);
+
if (apply_data(patch, &st, ce) < 0)
return error(_("%s: patch does not apply"), name);
patch->rejected = 0;
N_("make sure the patch is applicable to the current index")),
OPT_BOOL(0, "cached", &cached,
N_("apply a patch without touching the working tree")),
+ OPT_BOOL(0, "unsafe-paths", &unsafe_paths,
+ N_("accept a patch that touches outside the working area")),
OPT_BOOL(0, "apply", &force_apply,
N_("also apply the patch (use with --stat/--summary/--check)")),
OPT_BOOL('3', "3way", &threeway,
die(_("--cached outside a repository"));
check_index = 1;
}
+ if (check_index)
+ unsafe_paths = 0;
+
for (i = 0; i < argc; i++) {
const char *arg = argv[i];
int fd;