Move path traversal error reporting into main()

* src/safe.c (traverse_another_path): Don't report errors here.
* src/patch.c (main): Instead, recognize and report them here. Detect when an
output file name is invalid; it doesn't make sense to try creating a
reject file based on the same outbut file name in that case.
This commit is contained in:
Andreas Gruenbacher 2015-02-28 13:28:49 +01:00
parent a025a51ca5
commit 6fbdcefe7d
2 changed files with 18 additions and 13 deletions

View File

@ -115,6 +115,7 @@ main (int argc, char **argv)
struct stat tmpoutst;
char numbuf[LINENUM_LENGTH_BOUND + 1];
bool written_to_rejname = false;
bool skip_reject_file = false;
bool apply_empty_patch = false;
mode_t file_type;
int outfd = -1;
@ -190,6 +191,7 @@ main (int argc, char **argv)
there_is_another_patch (! (inname || posixly_correct), &file_type)
|| apply_empty_patch;
reinitialize_almost_everything(),
skip_reject_file = false,
apply_empty_patch = false
) { /* for each patch in patch file */
int hunk = 0;
@ -310,8 +312,19 @@ main (int argc, char **argv)
O_WRONLY | binary_transput,
instat.st_mode & S_IRWXUGO);
if (outfd == -1)
pfatal ("Can't create temporary file %s", TMPOUTNAME);
TMPOUTNAME_needs_removal = true;
{
if (errno == ELOOP || errno == EXDEV)
{
say ("Invalid file name %s -- skipping patch\n", quotearg (outname));
skip_rest_of_patch = true;
skip_reject_file = true;
somefailed = true;
}
else
pfatal ("Can't create temporary file %s", TMPOUTNAME);
}
else
TMPOUTNAME_needs_removal = true;
if (diff_type == ED_DIFF) {
outstate.zero_output = false;
somefailed |= skip_rest_of_patch;
@ -454,7 +467,8 @@ main (int argc, char **argv)
|| ! where
|| ! apply_hunk (&outstate, where))))
{
abort_hunk (outname, ! failed, reverse);
if (! skip_reject_file)
abort_hunk (outname, ! failed, reverse);
failed++;
if (verbosity == VERBOSE ||
(! skip_rest_of_patch && verbosity != SILENT))
@ -595,7 +609,7 @@ main (int argc, char **argv)
if (diff_type != ED_DIFF) {
struct stat rejst;
if (failed) {
if (failed && ! skip_reject_file) {
if (fstat (fileno (rejfp), &rejst) != 0 || fclose (rejfp) != 0)
write_fatal ();
rejfp = NULL;

View File

@ -419,15 +419,6 @@ static int traverse_another_path (const char **pathname, int keepfd)
printf (" (failed)\n");
fflush (stdout);
}
if (errno == ELOOP
|| errno == EMLINK /* FreeBSD 10.1: Too many links */
|| errno == EFTYPE /* NetBSD 6.1: Inappropriate file type or format */
|| errno == ENOTDIR)
{
say ("file %.*s is not a directory\n",
(int) (path - *pathname), *pathname);
skip_rest_of_patch = true;
}
goto fail;
}
dir = entry;