summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2010-05-02 11:34:24 +0200
committerAndreas Gruenbacher <agruen@suse.de>2010-05-02 12:40:35 +0200
commitcabd1add5753f9c5479011383e844a9ee93b387b (patch)
tree0159d76a7eb3cadedd72345631ddec0fcc509a3f
parent9e39d9c9950076e319d1dbbeeb7b8bd268b465f3 (diff)
downloadpatch-cabd1add5753f9c5479011383e844a9ee93b387b.tar.gz
Refuse to patch read-only files
* src/patch.c (main): Refuse to patch read-only files, or at least warn when patching such files with --force or --batch. * patch.man: Document the changed behavior. * tests/read-only-files: Split read-only file test case off from tests/remember-backup-files. * tests/Makefile.am: Add new test case.
-rw-r--r--ChangeLog9
-rw-r--r--patch.man4
-rw-r--r--src/patch.c15
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/read-only-files48
-rw-r--r--tests/remember-backup-files26
6 files changed, 73 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 5b709bc..ee6cc15 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-05-02 Andreas Gruenbacher <agruen@suse.de>
+
+ * src/patch.c (main): Refuse to patch read-only files, or at least warn
+ when patching such files with --force or --batch.
+ * patch.man: Document the changed behavior.
+ * tests/read-only-files: Split read-only file test case off from
+ tests/remember-backup-files.
+ * tests/Makefile.am: Add new test case.
+
2009-04-29 Andreas Gruenbacher <agruen@suse.de>
* src/patch.c (main): Support git diffs which copy or rename files.
diff --git a/patch.man b/patch.man
index 87fe124..02e6b90 100644
--- a/patch.man
+++ b/patch.man
@@ -356,8 +356,8 @@ removes a file, it also attempts to remove any empty ancestor directories.
\fB\-f\fP or \fB\*=force\fP
Assume that the user knows exactly what he or she is doing, and do not
ask any questions. Skip patches whose headers
-do not say which file is to be patched; patch files even though they have the
-wrong version for the
+do not say which file is to be patched; patch files even though they are
+read-only or have the wrong version for the
.B Prereq:\&
line in the patch; and assume that
patches are not reversed even if they look like they are.
diff --git a/src/patch.c b/src/patch.c
index be76f68..1d42d90 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -229,7 +229,19 @@ main (int argc, char **argv)
skip_rest_of_patch = true;
somefailed = true;
}
-
+ if (! inerrno && ! S_ISLNK (instat.st_mode)
+ && access (inname, W_OK) != 0)
+ {
+ say ("File %s is read-only; ", quotearg (inname));
+ if (force || batch)
+ say ("trying to patch anyway\n");
+ else
+ {
+ say ("refusing to patch\n");
+ skip_rest_of_patch = true;
+ somefailed = true;
+ }
+ }
/* initialize the patched file */
if (! skip_rest_of_patch && ! outfile)
{
@@ -382,7 +394,6 @@ main (int argc, char **argv)
if (! skip_rest_of_patch && ! outfile) {
bool backup = make_backups
|| (backup_if_mismatch && (mismatch | failed));
-
if (outstate.zero_output
&& (remove_empty_files
|| (pch_says_nonexistent (! reverse) == 2
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3498cc1..39af751 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -37,6 +37,7 @@ TESTS = \
preserve-c-function-names \
preserve-mode-and-timestamp \
quoted-filenames \
+ read-only-files \
reject-format \
remember-backup-files \
remember-reject-files \
diff --git a/tests/read-only-files b/tests/read-only-files
new file mode 100644
index 0000000..816baab
--- /dev/null
+++ b/tests/read-only-files
@@ -0,0 +1,48 @@
+# Copyright (C) 2009 Free Software Foundation, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# in any medium, are permitted without royalty provided the copyright
+# notice and this notice are preserved.
+
+# Patching read-only files
+
+. $srcdir/test-lib.sh
+
+require_cat
+use_local_patch
+use_tmpdir
+
+# ==============================================================
+
+cat > f.diff <<EOF
+--- f.orig
++++ f
+@@ -1 +1 @@
+-one
++two
+--- f.orig
++++ f
+@@ -1 +1 @@
+-two
++three
+EOF
+
+echo one > f
+chmod a=r f
+
+check 'patch -p0 < f.diff || echo "Status: $?"' <<EOF
+File f is read-only; refusing to patch
+1 out of 1 hunk ignored -- saving rejects to file f.rej
+File f is read-only; refusing to patch
+1 out of 1 hunk ignored -- saving rejects to file f.rej
+Status: 1
+EOF
+
+rm -f f.rej
+
+check 'patch -f -p0 < f.diff || echo "Status: $?"' <<EOF
+File f is read-only; trying to patch anyway
+patching file f
+File f is read-only; trying to patch anyway
+patching file f
+EOF
diff --git a/tests/remember-backup-files b/tests/remember-backup-files
index 86aafa3..b475d2f 100644
--- a/tests/remember-backup-files
+++ b/tests/remember-backup-files
@@ -82,29 +82,3 @@ EOF
check 'cat g.orig' <<EOF
one
EOF
-
-# ==============================================================
-
-# This test case failed with a permission denied error with a
-# previous version of the remember-backup-files patch.
-
-cat > f.diff <<EOF
---- f.orig
-+++ f
-@@ -1 +1 @@
--one
-+two
---- f.orig
-+++ f
-@@ -1 +1 @@
--two
-+three
-EOF
-
-echo one > f
-chmod a=r f
-
-check 'patch -p0 < f.diff' <<EOF
-patching file f
-patching file f
-EOF