summaryrefslogtreecommitdiff
path: root/t/t4139-apply-escape.sh
blob: e5c7439df13389a3caa9f3f76f70e31fea96c90b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/sh

test_description='paths written by git-apply cannot escape the working tree'

TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh

# tests will try to write to ../foo, and we do not
# want them to escape the trash directory when they
# fail
test_expect_success 'bump git repo one level down' '
	mkdir inside &&
	mv .git inside/ &&
	cd inside
'

# $1 = name of file
# $2 = current path to file (if different)
mkpatch_add () {
	rm -f "${2:-$1}" &&
	cat <<-EOF
	diff --git a/$1 b/$1
	new file mode 100644
	index 0000000..53c74cd
	--- /dev/null
	+++ b/$1
	@@ -0,0 +1 @@
	+evil
	EOF
}

mkpatch_del () {
	echo evil >"${2:-$1}" &&
	cat <<-EOF
	diff --git a/$1 b/$1
	deleted file mode 100644
	index 53c74cd..0000000
	--- a/$1
	+++ /dev/null
	@@ -1 +0,0 @@
	-evil
	EOF
}

# $1 = name of file
# $2 = content of symlink
mkpatch_symlink () {
	rm -f "$1" &&
	cat <<-EOF
	diff --git a/$1 b/$1
	new file mode 120000
	index 0000000..$(printf "%s" "$2" | git hash-object --stdin)
	--- /dev/null
	+++ b/$1
	@@ -0,0 +1 @@
	+$2
	\ No newline at end of file
	EOF
}

test_expect_success 'cannot create file containing ..' '
	mkpatch_add ../foo >patch &&
	test_must_fail git apply patch &&
	test_path_is_missing ../foo
'

test_expect_success 'can create file containing .. with --unsafe-paths' '
	mkpatch_add ../foo >patch &&
	git apply --unsafe-paths patch &&
	test_path_is_file ../foo
'

test_expect_success  'cannot create file containing .. (index)' '
	mkpatch_add ../foo >patch &&
	test_must_fail git apply --index patch &&
	test_path_is_missing ../foo
'

test_expect_success  'cannot create file containing .. with --unsafe-paths (index)' '
	mkpatch_add ../foo >patch &&
	test_must_fail git apply --index --unsafe-paths patch &&
	test_path_is_missing ../foo
'

test_expect_success 'cannot delete file containing ..' '
	mkpatch_del ../foo >patch &&
	test_must_fail git apply patch &&
	test_path_is_file ../foo
'

test_expect_success 'can delete file containing .. with --unsafe-paths' '
	mkpatch_del ../foo >patch &&
	git apply --unsafe-paths patch &&
	test_path_is_missing ../foo
'

test_expect_success 'cannot delete file containing .. (index)' '
	mkpatch_del ../foo >patch &&
	test_must_fail git apply --index patch &&
	test_path_is_file ../foo
'

test_expect_success SYMLINKS 'symlink escape via ..' '
	{
		mkpatch_symlink tmp .. &&
		mkpatch_add tmp/foo ../foo
	} >patch &&
	test_must_fail git apply patch &&
	test_path_is_missing tmp &&
	test_path_is_missing ../foo
'

test_expect_success SYMLINKS 'symlink escape via .. (index)' '
	{
		mkpatch_symlink tmp .. &&
		mkpatch_add tmp/foo ../foo
	} >patch &&
	test_must_fail git apply --index patch &&
	test_path_is_missing tmp &&
	test_path_is_missing ../foo
'

test_expect_success SYMLINKS 'symlink escape via absolute path' '
	{
		mkpatch_symlink tmp "$(pwd)" &&
		mkpatch_add tmp/foo ../foo
	} >patch &&
	test_must_fail git apply patch &&
	test_path_is_missing tmp &&
	test_path_is_missing ../foo
'

test_expect_success SYMLINKS 'symlink escape via absolute path (index)' '
	{
		mkpatch_symlink tmp "$(pwd)" &&
		mkpatch_add tmp/foo ../foo
	} >patch &&
	test_must_fail git apply --index patch &&
	test_path_is_missing tmp &&
	test_path_is_missing ../foo
'

test_done