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 package org.eclipse.jgit.lib;
45
46 import static org.eclipse.jgit.junit.Assert.assertEquals;
47
48 import org.eclipse.jgit.junit.MockSystemReader;
49 import org.eclipse.jgit.util.SystemReader;
50 import org.junit.Test;
51
52 public class ValidRefNameTest {
53 private static void assertValid(final boolean exp, final String name) {
54 SystemReader instance = SystemReader.getInstance();
55 try {
56 setUnixSystemReader();
57 assertEquals("\"" + name + "\"", exp,
58 Repository.isValidRefName(name));
59 setWindowsSystemReader();
60 assertEquals("\"" + name + "\"", exp,
61 Repository.isValidRefName(name));
62 } finally {
63 SystemReader.setInstance(instance);
64 }
65 }
66
67 private static void setWindowsSystemReader() {
68 SystemReader.setInstance(new MockSystemReader() {
69 {
70 setWindows();
71 }
72 });
73 }
74
75 private static void setUnixSystemReader() {
76 SystemReader.setInstance(new MockSystemReader() {
77 {
78 setUnix();
79 }
80 });
81 }
82
83 private static void assertInvalidOnWindows(final String name) {
84 SystemReader instance = SystemReader.getInstance();
85 try {
86 setUnixSystemReader();
87 assertEquals("\"" + name + "\"", true,
88 Repository.isValidRefName(name));
89 setWindowsSystemReader();
90 assertEquals("\"" + name + "\"", false,
91 Repository.isValidRefName(name));
92 } finally {
93 SystemReader.setInstance(instance);
94 }
95 }
96
97 @Test
98 public void testEmptyString() {
99 assertValid(false, "");
100 assertValid(false, "/");
101 }
102
103 @Test
104 public void testMustHaveTwoComponents() {
105 assertValid(false, "master");
106 assertValid(true, "heads/master");
107 }
108
109 @Test
110 public void testValidHead() {
111 assertValid(true, "refs/heads/master");
112 assertValid(true, "refs/heads/pu");
113 assertValid(true, "refs/heads/z");
114 assertValid(true, "refs/heads/FoO");
115 }
116
117 @Test
118 public void testValidTag() {
119 assertValid(true, "refs/tags/v1.0");
120 }
121
122 @Test
123 public void testNoLockSuffix() {
124 assertValid(false, "refs/heads/master.lock");
125 }
126
127 @Test
128 public void testNoDirectorySuffix() {
129 assertValid(false, "refs/heads/master/");
130 }
131
132 @Test
133 public void testNoSpace() {
134 assertValid(false, "refs/heads/i haz space");
135 }
136
137 @Test
138 public void testNoAsciiControlCharacters() {
139 for (char c = '\0'; c < ' '; c++)
140 assertValid(false, "refs/heads/mast" + c + "er");
141 }
142
143 @Test
144 public void testNoBareDot() {
145 assertValid(false, "refs/heads/.");
146 assertValid(false, "refs/heads/..");
147 assertValid(false, "refs/heads/./master");
148 assertValid(false, "refs/heads/../master");
149 }
150
151 @Test
152 public void testNoLeadingOrTrailingDot() {
153 assertValid(false, ".");
154 assertValid(false, "refs/heads/.bar");
155 assertValid(false, "refs/heads/..bar");
156 assertValid(false, "refs/heads/bar.");
157 }
158
159 @Test
160 public void testContainsDot() {
161 assertValid(true, "refs/heads/m.a.s.t.e.r");
162 assertValid(false, "refs/heads/master..pu");
163 }
164
165 @Test
166 public void testNoMagicRefCharacters() {
167 assertValid(false, "refs/heads/master^");
168 assertValid(false, "refs/heads/^master");
169 assertValid(false, "^refs/heads/master");
170
171 assertValid(false, "refs/heads/master~");
172 assertValid(false, "refs/heads/~master");
173 assertValid(false, "~refs/heads/master");
174
175 assertValid(false, "refs/heads/master:");
176 assertValid(false, "refs/heads/:master");
177 assertValid(false, ":refs/heads/master");
178 }
179
180 @Test
181 public void testShellGlob() {
182 assertValid(false, "refs/heads/master?");
183 assertValid(false, "refs/heads/?master");
184 assertValid(false, "?refs/heads/master");
185
186 assertValid(false, "refs/heads/master[");
187 assertValid(false, "refs/heads/[master");
188 assertValid(false, "[refs/heads/master");
189
190 assertValid(false, "refs/heads/master*");
191 assertValid(false, "refs/heads/*master");
192 assertValid(false, "*refs/heads/master");
193 }
194
195 @Test
196 public void testValidSpecialCharacterUnixs() {
197 assertValid(true, "refs/heads/!");
198 assertValid(true, "refs/heads/#");
199 assertValid(true, "refs/heads/$");
200 assertValid(true, "refs/heads/%");
201 assertValid(true, "refs/heads/&");
202 assertValid(true, "refs/heads/'");
203 assertValid(true, "refs/heads/(");
204 assertValid(true, "refs/heads/)");
205 assertValid(true, "refs/heads/+");
206 assertValid(true, "refs/heads/,");
207 assertValid(true, "refs/heads/-");
208 assertValid(true, "refs/heads/;");
209 assertValid(true, "refs/heads/=");
210 assertValid(true, "refs/heads/@");
211 assertValid(true, "refs/heads/]");
212 assertValid(true, "refs/heads/_");
213 assertValid(true, "refs/heads/`");
214 assertValid(true, "refs/heads/{");
215 assertValid(true, "refs/heads/}");
216
217
218
219
220 assertValid(false, "refs/heads/\\");
221
222
223 assertInvalidOnWindows("refs/heads/\"");
224 assertInvalidOnWindows("refs/heads/<");
225 assertInvalidOnWindows("refs/heads/>");
226 assertInvalidOnWindows("refs/heads/|");
227 }
228
229 @Test
230 public void testUnicodeNames() {
231 assertValid(true, "refs/heads/\u00e5ngstr\u00f6m");
232 }
233
234 @Test
235 public void testRefLogQueryIsValidRef() {
236 assertValid(false, "refs/heads/master@{1}");
237 assertValid(false, "refs/heads/master@{1.hour.ago}");
238 }
239
240 @Test
241 public void testWindowsReservedNames() {
242
243
244 assertInvalidOnWindows("refs/heads/con");
245 assertInvalidOnWindows("refs/con/x");
246 assertInvalidOnWindows("con/heads/x");
247 assertValid(true, "refs/heads/conx");
248 assertValid(true, "refs/heads/xcon");
249 }
250 }