mirror of
https://https.git.savannah.gnu.org/git/patch.git
synced 2026-01-26 16:09:26 +00:00
438 lines
7.8 KiB
Plaintext
438 lines
7.8 KiB
Plaintext
# Copyright 2010-2025 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.
|
|
|
|
# Symlink related tests
|
|
|
|
. $srcdir/test-lib.sh
|
|
|
|
require cat
|
|
require symlinks
|
|
use_local_patch
|
|
use_tmpdir
|
|
|
|
# ==============================================================
|
|
|
|
cat > create.diff <<EOF
|
|
--- /dev/null
|
|
+++ l
|
|
@@ -0,0 +1 @@
|
|
+one
|
|
EOF
|
|
|
|
rm -f f l
|
|
echo one > f
|
|
ncheck 'ln -s f l'
|
|
|
|
check 'patch < create.diff || echo "Status: $?"' <<EOF
|
|
File l is not a regular file -- refusing to patch
|
|
1 out of 1 hunk ignored -- saving rejects to file l.rej
|
|
Status: 1
|
|
EOF
|
|
|
|
check 'cat f' <<EOF
|
|
one
|
|
EOF
|
|
|
|
# --------------------------------------------------------------
|
|
|
|
rm -f f l
|
|
echo one > f
|
|
ncheck 'ln -s f l'
|
|
|
|
cat > modify.diff <<EOF
|
|
--- l
|
|
+++ l
|
|
@@ -1 +1 @@
|
|
-one
|
|
+two
|
|
EOF
|
|
|
|
check 'patch < modify.diff || echo "Status: $?"' <<EOF
|
|
File l is not a regular file -- refusing to patch
|
|
1 out of 1 hunk ignored -- saving rejects to file l.rej
|
|
Status: 1
|
|
EOF
|
|
|
|
check 'patch --follow-symlinks < modify.diff || echo "Status: $?"' <<EOF
|
|
patching file l
|
|
EOF
|
|
|
|
check 'cat f' <<EOF
|
|
one
|
|
EOF
|
|
|
|
check 'cat l' <<EOF
|
|
two
|
|
EOF
|
|
|
|
# --------------------------------------------------------------
|
|
|
|
rm -f f l
|
|
echo one > f
|
|
ncheck 'ln -s f l'
|
|
|
|
cat > delete.diff <<EOF
|
|
--- l
|
|
+++ /dev/null
|
|
@@ -1 +0,0 @@
|
|
-one
|
|
EOF
|
|
|
|
check 'patch < delete.diff || echo "Status: $?"' <<EOF
|
|
File l is not a regular file -- refusing to patch
|
|
1 out of 1 hunk ignored -- saving rejects to file l.rej
|
|
Status: 1
|
|
EOF
|
|
|
|
# --------------------------------------------------------------
|
|
|
|
cat > create-symlink.diff <<EOF
|
|
diff --git a/symlink b/symlink
|
|
new file mode 120000
|
|
index 0000000..12a8d8a
|
|
--- /dev/null
|
|
+++ b/symlink
|
|
@@ -0,0 +1 @@
|
|
+target1
|
|
\ No newline at end of file
|
|
EOF
|
|
|
|
check 'patch -p1 < create-symlink.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link symlink
|
|
EOF
|
|
|
|
check 'echo a > target1 && cat symlink' <<EOF
|
|
a
|
|
EOF
|
|
check 'echo b > target1 && cat symlink' <<EOF
|
|
b
|
|
EOF
|
|
rm -f target1
|
|
|
|
cat > modify-symlink.diff <<EOF
|
|
diff --git a/symlink b/symlink
|
|
index 12a8d8a..3b7781e 120000
|
|
--- a/symlink
|
|
+++ b/symlink
|
|
@@ -1 +1 @@
|
|
-target1
|
|
\ No newline at end of file
|
|
+target2
|
|
\ No newline at end of file
|
|
EOF
|
|
|
|
check 'patch -p1 < modify-symlink.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link symlink
|
|
EOF
|
|
|
|
check 'echo a > target2 && cat symlink' <<EOF
|
|
a
|
|
EOF
|
|
check 'echo b > target2 && cat symlink' <<EOF
|
|
b
|
|
EOF
|
|
rm -f target2
|
|
|
|
cat > delete-symlink.diff <<EOF
|
|
diff --git a/symlink b/symlink
|
|
deleted file mode 120000
|
|
index 3b7781e..0000000
|
|
--- a/symlink
|
|
+++ /dev/null
|
|
@@ -1 +0,0 @@
|
|
-target2
|
|
\ No newline at end of file
|
|
EOF
|
|
|
|
check 'patch -p1 < delete-symlink.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link symlink
|
|
EOF
|
|
|
|
ncheck 'test ! -L symlink'
|
|
|
|
# --------------------------------------------------------------
|
|
|
|
# Recursive symlinks
|
|
|
|
ln -s l1 l2
|
|
ln -s l2 l1
|
|
|
|
cat > f.diff <<EOF
|
|
--- l1/f
|
|
+++ l1/f
|
|
@@ -0,0 +1 @@
|
|
+new
|
|
EOF
|
|
|
|
check 'patch -p0 < f.diff || echo "Status: $?"' <<EOF
|
|
Invalid file name l1/f -- skipping patch
|
|
Status: 1
|
|
EOF
|
|
|
|
rm -f l1 l2
|
|
|
|
# --------------------------------------------------------------
|
|
|
|
cat > retraverse.diff <<EOF
|
|
--- abc/def/ghi/jkl
|
|
+++ abc/def/ghi/jkl
|
|
@@ -0,0 +1 @@
|
|
+Parent directory traversal
|
|
EOF
|
|
|
|
ncheck 'mkdir abc'
|
|
ncheck 'mkdir abc/def'
|
|
ln -sf ../../abc/def abc/def/ghi
|
|
check 'patch -p0 < retraverse.diff || echo "Status: $?"' << EOF
|
|
patching file abc/def/ghi/jkl
|
|
EOF
|
|
|
|
# --------------------------------------------------------------
|
|
|
|
# Patch should not create symlinks which point outside the working directory.
|
|
|
|
mkdir d
|
|
echo one > d/f
|
|
ln -s d ld
|
|
|
|
cat > ld.diff <<EOF
|
|
--- ld/f
|
|
+++ ld/f
|
|
@@ -1 +1 @@
|
|
-one
|
|
+two
|
|
EOF
|
|
|
|
check 'patch -p0 < ld.diff' <<EOF
|
|
patching file ld/f
|
|
EOF
|
|
|
|
mkdir e
|
|
ln -s ../d e/ld
|
|
|
|
cat > eld.diff <<EOF
|
|
--- e/ld/f
|
|
+++ e/ld/f
|
|
@@ -1 +1 @@
|
|
-two
|
|
+three
|
|
EOF
|
|
|
|
check 'patch -p0 < eld.diff' <<EOF
|
|
patching file e/ld/f
|
|
EOF
|
|
|
|
rm -f e/ld
|
|
ln -sf ../ld e/ld
|
|
|
|
check 'patch -p0 -R < eld.diff' <<EOF
|
|
patching file e/ld/f
|
|
EOF
|
|
|
|
mkdir g
|
|
ln -sf ../../z g/bad-rel
|
|
ln -sf .. bad-rel-step2
|
|
ln -sf ../bad-rel-step2/z g/bad-rel-step1
|
|
ln -sf /z g/bad-abs
|
|
|
|
cat > follow-bad-symlink.diff <<EOF
|
|
--- g/bad-rel/x
|
|
+++ g/bad-rel/x
|
|
@@ -0,0 +1 @@
|
|
+relative
|
|
--- g/bad-rel-step1/x
|
|
+++ g/bad-rel-step1/x
|
|
@@ -0,0 +1 @@
|
|
+relative, 2 steps
|
|
--- g/bad-abs/x
|
|
+++ g/bad-abs/x
|
|
@@ -0,0 +1 @@
|
|
+absolute
|
|
EOF
|
|
|
|
check 'patch -p0 < follow-bad-symlink.diff || echo "Status: $?"' <<EOF
|
|
Invalid file name g/bad-rel/x -- skipping patch
|
|
Invalid file name g/bad-rel-step1/x -- skipping patch
|
|
Invalid file name g/bad-abs/x -- skipping patch
|
|
Status: 1
|
|
EOF
|
|
|
|
rm -rf ld d e g
|
|
|
|
cat > symlink-target.diff <<EOF
|
|
diff --git a/dir/foo b/dir/foo
|
|
new file mode 120000
|
|
index 0000000..cad2309
|
|
--- /dev/null
|
|
+++ b/dir/foo
|
|
@@ -0,0 +1 @@
|
|
+../foo
|
|
\ No newline at end of file
|
|
EOF
|
|
|
|
check 'patch -p1 < symlink-target.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link dir/foo
|
|
EOF
|
|
|
|
rm -f dir/foo
|
|
cat > follow-symlink.diff <<EOF
|
|
diff --git a/dir/foo b/dir/foo
|
|
new file mode 120000
|
|
index 0000000..cad2309
|
|
--- /dev/null
|
|
+++ b/dir/foo
|
|
@@ -0,0 +1 @@
|
|
+..
|
|
\ No newline at end of file
|
|
diff --git a/dir/foo/bar b/dir/foo/bar
|
|
new file mode 100644
|
|
index 0000000..2ab772d
|
|
--- /dev/null
|
|
+++ b/dir/foo/bar
|
|
@@ -0,0 +1 @@
|
|
+created in ..
|
|
diff --git a/dir/bad b/dir/bad
|
|
new file mode 120000
|
|
index 0000000..cad2309
|
|
--- /dev/null
|
|
+++ b/dir/bad
|
|
@@ -0,0 +1 @@
|
|
+../..
|
|
\ No newline at end of file
|
|
diff --git a/dir/bad/baz b/dir/bad/baz
|
|
new file mode 100644
|
|
index 0000000..2ab772d
|
|
--- /dev/null
|
|
+++ b/dir/bad/baz
|
|
@@ -0,0 +1 @@
|
|
+created in ../..
|
|
EOF
|
|
|
|
check 'patch -f -p1 < follow-symlink.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link dir/foo
|
|
patching file dir/foo/bar
|
|
patching symbolic link dir/bad
|
|
Invalid file name dir/bad/baz -- skipping patch
|
|
Status: 1
|
|
EOF
|
|
|
|
check 'cat bar' <<EOF
|
|
created in ..
|
|
EOF
|
|
|
|
rm -f bar
|
|
|
|
cat > bad-symlink-target1.diff <<EOF
|
|
diff --git a/bar b/bar
|
|
new file mode 120000
|
|
index 0000000..cad2309
|
|
--- /dev/null
|
|
+++ b/bar
|
|
@@ -0,0 +1 @@
|
|
+/bar
|
|
\ No newline at end of file
|
|
EOF
|
|
|
|
check 'patch -p1 < bad-symlink-target1.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link bar
|
|
EOF
|
|
|
|
cat > bad-symlink-target2.diff <<EOF
|
|
diff --git a/baz b/baz
|
|
new file mode 120000
|
|
index 0000000..cad2309
|
|
--- /dev/null
|
|
+++ b/baz
|
|
@@ -0,0 +1 @@
|
|
+../baz
|
|
\ No newline at end of file
|
|
EOF
|
|
|
|
check 'patch -p1 < bad-symlink-target2.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link baz
|
|
EOF
|
|
|
|
# --------------------------------------------------------------
|
|
|
|
# Absolute symlinks that point back into the working directory
|
|
|
|
mkdir d
|
|
ln -s $PWD here
|
|
ln -s $PWD/here/d here_d
|
|
|
|
cat > good-absolute.diff <<EOF
|
|
--- /dev/null
|
|
+++ here/d/foo
|
|
@@ -0,0 +1 @@
|
|
+foo
|
|
--- /dev/null
|
|
+++ here_d/bar
|
|
@@ -0,0 +1 @@
|
|
+bar
|
|
EOF
|
|
|
|
check 'patch -p0 < good-absolute.diff' <<EOF
|
|
patching file here/d/foo
|
|
patching file here_d/bar
|
|
EOF
|
|
|
|
rm -rf d
|
|
|
|
# --------------------------------------------------------------
|
|
|
|
# The backup file of a new symlink is an empty regular file.
|
|
|
|
check 'patch -p1 --backup < create-symlink.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link symlink
|
|
EOF
|
|
|
|
ncheck 'test -f symlink.orig && test ! -s symlink.orig'
|
|
|
|
# The backup file of a modified symlink is the old symlink.
|
|
|
|
check 'patch -p1 --backup < modify-symlink.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link symlink
|
|
EOF
|
|
|
|
check 'echo a > symlink.orig && cat target1' <<EOF
|
|
a
|
|
EOF
|
|
check 'echo b > symlink.orig && cat target1' <<EOF
|
|
b
|
|
EOF
|
|
rm -f target1
|
|
|
|
# The backup file of a deleted symlink is the old symlink.
|
|
|
|
check 'patch -p1 --backup < delete-symlink.diff || echo "Status: $?"' <<EOF
|
|
patching symbolic link symlink
|
|
EOF
|
|
|
|
check 'echo a > symlink.orig && cat target2' <<EOF
|
|
a
|
|
EOF
|
|
check 'echo b > symlink.orig && cat target2' <<EOF
|
|
b
|
|
EOF
|
|
rm -f target2
|
|
|
|
# --------------------------------------------------------------
|
|
# Make sure we do follow symlinks to patch files.
|
|
|
|
ncheck 'mkdir d'
|
|
cat > d/ab.diff <<EOF
|
|
--- /dev/null
|
|
+++ b/foo
|
|
@@ -0,0 +1 @@
|
|
+foo
|
|
EOF
|
|
|
|
ncheck 'ln -sf d l'
|
|
|
|
check 'patch -p1 -i l/ab.diff' <<EOF
|
|
patching file foo
|
|
EOF
|