View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNull;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import java.io.BufferedOutputStream;
26  import java.io.File;
27  import java.io.IOException;
28  import java.nio.file.Files;
29  import java.nio.file.Path;
30  import java.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.Collection;
33  
34  import org.apache.commons.io.test.TestUtils;
35  import org.apache.commons.lang3.SystemUtils;
36  import org.junit.jupiter.api.BeforeEach;
37  import org.junit.jupiter.api.Test;
38  import org.junit.jupiter.api.io.TempDir;
39  
40  /**
41   * Tests {@link FilenameUtils}.
42   */
43  class FilenameUtilsTest {
44  
45      private static final String DRIVE_C = "C:";
46  
47      private static final String SEP = "" + File.separatorChar;
48  
49      private static final boolean WINDOWS = File.separatorChar == '\\';
50  
51      @TempDir
52      public Path temporaryFolder;
53  
54      private Path testFile1;
55      private Path testFile2;
56  
57      private int testFile1Size;
58      private int testFile2Size;
59  
60      @BeforeEach
61      public void setUp() throws Exception {
62          testFile1 = Files.createTempFile(temporaryFolder, "test", "1");
63          testFile2 = Files.createTempFile(temporaryFolder, "test", "2");
64  
65          testFile1Size = (int) Files.size(testFile1);
66          testFile2Size = (int) Files.size(testFile2);
67          if (!Files.exists(testFile1.getParent())) {
68              throw new IOException("Cannot create file " + testFile1
69                      + " as the parent directory does not exist");
70          }
71          try (BufferedOutputStream output3 =
72                  new BufferedOutputStream(Files.newOutputStream(testFile1))) {
73              TestUtils.generateTestData(output3, testFile1Size);
74          }
75          if (!Files.exists(testFile2.getParent())) {
76              throw new IOException("Cannot create file " + testFile2
77                      + " as the parent directory does not exist");
78          }
79          try (BufferedOutputStream output2 =
80                  new BufferedOutputStream(Files.newOutputStream(testFile2))) {
81              TestUtils.generateTestData(output2, testFile2Size);
82          }
83          if (!Files.exists(testFile1.getParent())) {
84              throw new IOException("Cannot create file " + testFile1
85                      + " as the parent directory does not exist");
86          }
87          try (BufferedOutputStream output1 =
88                  new BufferedOutputStream(Files.newOutputStream(testFile1))) {
89              TestUtils.generateTestData(output1, testFile1Size);
90          }
91          if (!Files.exists(testFile2.getParent())) {
92              throw new IOException("Cannot create file " + testFile2
93                      + " as the parent directory does not exist");
94          }
95          try (BufferedOutputStream output =
96                  new BufferedOutputStream(Files.newOutputStream(testFile2))) {
97              TestUtils.generateTestData(output, testFile2Size);
98          }
99      }
100 
101     @Test
102     void testConcat() {
103         assertNull(FilenameUtils.concat("", null));
104         assertNull(FilenameUtils.concat(null, null));
105         assertNull(FilenameUtils.concat(null, ""));
106         assertNull(FilenameUtils.concat(null, "a"));
107         assertEquals(SEP + "a", FilenameUtils.concat(null, "/a"));
108 
109         assertNull(FilenameUtils.concat("", ":")); // invalid prefix
110         assertNull(FilenameUtils.concat(":", "")); // invalid prefix
111 
112         assertEquals("f" + SEP, FilenameUtils.concat("", "f/"));
113         assertEquals("f", FilenameUtils.concat("", "f"));
114         assertEquals("a" + SEP + "f" + SEP, FilenameUtils.concat("a/", "f/"));
115         assertEquals("a" + SEP + "f", FilenameUtils.concat("a", "f"));
116         assertEquals("a" + SEP + "b" + SEP + "f" + SEP, FilenameUtils.concat("a/b/", "f/"));
117         assertEquals("a" + SEP + "b" + SEP + "f", FilenameUtils.concat("a/b", "f"));
118 
119         assertEquals("a" + SEP + "f" + SEP, FilenameUtils.concat("a/b/", "../f/"));
120         assertEquals("a" + SEP + "f", FilenameUtils.concat("a/b", "../f"));
121         assertEquals("a" + SEP + "c" + SEP + "g" + SEP, FilenameUtils.concat("a/b/../c/", "f/../g/"));
122         assertEquals("a" + SEP + "c" + SEP + "g", FilenameUtils.concat("a/b/../c", "f/../g"));
123 
124         assertEquals("a" + SEP + "c.txt" + SEP + "f", FilenameUtils.concat("a/c.txt", "f"));
125 
126         assertEquals(SEP + "f" + SEP, FilenameUtils.concat("", "/f/"));
127         assertEquals(SEP + "f", FilenameUtils.concat("", "/f"));
128         assertEquals(SEP + "f" + SEP, FilenameUtils.concat("a/", "/f/"));
129         assertEquals(SEP + "f", FilenameUtils.concat("a", "/f"));
130 
131         assertEquals(SEP + "c" + SEP + "d", FilenameUtils.concat("a/b/", "/c/d"));
132         assertEquals("C:c" + SEP + "d", FilenameUtils.concat("a/b/", "C:c/d"));
133         assertEquals(DRIVE_C + SEP + "c" + SEP + "d", FilenameUtils.concat("a/b/", "C:/c/d"));
134         assertEquals("~" + SEP + "c" + SEP + "d", FilenameUtils.concat("a/b/", "~/c/d"));
135         assertEquals("~user" + SEP + "c" + SEP + "d", FilenameUtils.concat("a/b/", "~user/c/d"));
136         assertEquals("~" + SEP, FilenameUtils.concat("a/b/", "~"));
137         assertEquals("~user" + SEP, FilenameUtils.concat("a/b/", "~user"));
138     }
139 
140     @Test
141     void testDirectoryContains() {
142         assertTrue(FilenameUtils.directoryContains("/foo", "/foo/bar"));
143         assertTrue(FilenameUtils.directoryContains("/foo/", "/foo/bar"));
144         assertTrue(FilenameUtils.directoryContains("C:\\foo", "C:\\foo\\bar"));
145         assertTrue(FilenameUtils.directoryContains("C:\\foo\\", "C:\\foo\\bar"));
146 
147         assertFalse(FilenameUtils.directoryContains("/foo", "/foo"));
148         assertFalse(FilenameUtils.directoryContains("/foo", "/foobar"));
149         assertFalse(FilenameUtils.directoryContains("C:\\foo", "C:\\foobar"));
150         assertFalse(FilenameUtils.directoryContains("/foo", null));
151         assertFalse(FilenameUtils.directoryContains("", ""));
152         assertFalse(FilenameUtils.directoryContains("", "/foo"));
153         assertFalse(FilenameUtils.directoryContains("/foo", ""));
154     }
155 
156     @Test
157     void testEquals() {
158         assertTrue(FilenameUtils.equals(null, null));
159         assertFalse(FilenameUtils.equals(null, ""));
160         assertFalse(FilenameUtils.equals("", null));
161         assertTrue(FilenameUtils.equals("", ""));
162         assertTrue(FilenameUtils.equals("file.txt", "file.txt"));
163         assertFalse(FilenameUtils.equals("file.txt", "FILE.TXT"));
164         assertFalse(FilenameUtils.equals("a\\b\\file.txt", "a/b/file.txt"));
165     }
166 
167     @Test
168     void testEquals_fullControl() {
169         assertFalse(FilenameUtils.equals("file.txt", "FILE.TXT", true, IOCase.SENSITIVE));
170         assertTrue(FilenameUtils.equals("file.txt", "FILE.TXT", true, IOCase.INSENSITIVE));
171         assertEquals(WINDOWS, FilenameUtils.equals("file.txt", "FILE.TXT", true, IOCase.SYSTEM));
172         assertFalse(FilenameUtils.equals("file.txt", "FILE.TXT", true, null));
173     }
174 
175     @Test
176     void testEqualsNormalized() {
177         assertTrue(FilenameUtils.equalsNormalized(null, null));
178         assertFalse(FilenameUtils.equalsNormalized(null, ""));
179         assertFalse(FilenameUtils.equalsNormalized("", null));
180         assertTrue(FilenameUtils.equalsNormalized("", ""));
181         assertTrue(FilenameUtils.equalsNormalized("file.txt", "file.txt"));
182         assertFalse(FilenameUtils.equalsNormalized("file.txt", "FILE.TXT"));
183         assertTrue(FilenameUtils.equalsNormalized("a\\b\\file.txt", "a/b/file.txt"));
184         assertFalse(FilenameUtils.equalsNormalized("a/b/", "a/b"));
185     }
186 
187     /**
188      * Test for https://issues.apache.org/jira/browse/IO-128
189      */
190     @Test
191     void testEqualsNormalizedError_IO_128() {
192         assertFalse(FilenameUtils.equalsNormalizedOnSystem("//file.txt", "file.txt"));
193         assertFalse(FilenameUtils.equalsNormalizedOnSystem("file.txt", "//file.txt"));
194         assertFalse(FilenameUtils.equalsNormalizedOnSystem("//file.txt", "//file.txt"));
195     }
196 
197     @Test
198     void testEqualsNormalizedOnSystem() {
199         assertTrue(FilenameUtils.equalsNormalizedOnSystem(null, null));
200         assertFalse(FilenameUtils.equalsNormalizedOnSystem(null, ""));
201         assertFalse(FilenameUtils.equalsNormalizedOnSystem("", null));
202         assertTrue(FilenameUtils.equalsNormalizedOnSystem("", ""));
203         assertTrue(FilenameUtils.equalsNormalizedOnSystem("file.txt", "file.txt"));
204         assertEquals(WINDOWS, FilenameUtils.equalsNormalizedOnSystem("file.txt", "FILE.TXT"));
205         assertTrue(FilenameUtils.equalsNormalizedOnSystem("a\\b\\file.txt", "a/b/file.txt"));
206         assertFalse(FilenameUtils.equalsNormalizedOnSystem("a/b/", "a/b"));
207         assertFalse(FilenameUtils.equalsNormalizedOnSystem("//a.html", "//ab.html"));
208     }
209 
210     @Test
211     void testEqualsOnSystem() {
212         assertTrue(FilenameUtils.equalsOnSystem(null, null));
213         assertFalse(FilenameUtils.equalsOnSystem(null, ""));
214         assertFalse(FilenameUtils.equalsOnSystem("", null));
215         assertTrue(FilenameUtils.equalsOnSystem("", ""));
216         assertTrue(FilenameUtils.equalsOnSystem("file.txt", "file.txt"));
217         assertEquals(WINDOWS, FilenameUtils.equalsOnSystem("file.txt", "FILE.TXT"));
218         assertFalse(FilenameUtils.equalsOnSystem("a\\b\\file.txt", "a/b/file.txt"));
219     }
220 
221     @Test
222     void testGetBaseName() {
223         assertNull(FilenameUtils.getBaseName(null));
224         assertEquals("noseparator", FilenameUtils.getBaseName("noseparator.inthispath"));
225         assertEquals("c", FilenameUtils.getBaseName("a/b/c.txt"));
226         assertEquals("c", FilenameUtils.getBaseName("a/b/c"));
227         assertEquals("", FilenameUtils.getBaseName("a/b/c/"));
228         assertEquals("c", FilenameUtils.getBaseName("a\\b\\c"));
229         assertEquals("file.txt", FilenameUtils.getBaseName("file.txt.bak"));
230     }
231 
232     @Test
233     void testGetBaseName_with_null_character() {
234         assertThrows(IllegalArgumentException.class, () -> FilenameUtils.getBaseName("fil\u0000e.txt.bak"));
235     }
236 
237     @Test
238     void testGetExtension() {
239         assertNull(FilenameUtils.getExtension(null));
240         assertEquals("ext", FilenameUtils.getExtension("file.ext"));
241         assertEquals("", FilenameUtils.getExtension("README"));
242         assertEquals("com", FilenameUtils.getExtension("domain.dot.com"));
243         assertEquals("jpeg", FilenameUtils.getExtension("image.jpeg"));
244         assertEquals("", FilenameUtils.getExtension("a.b/c"));
245         assertEquals("txt", FilenameUtils.getExtension("a.b/c.txt"));
246         assertEquals("", FilenameUtils.getExtension("a/b/c"));
247         assertEquals("", FilenameUtils.getExtension("a.b\\c"));
248         assertEquals("txt", FilenameUtils.getExtension("a.b\\c.txt"));
249         assertEquals("", FilenameUtils.getExtension("a\\b\\c"));
250         assertEquals("", FilenameUtils.getExtension("C:\\temp\\foo.bar\\README"));
251         assertEquals("ext", FilenameUtils.getExtension("../filename.ext"));
252 
253         if (FilenameUtils.isSystemWindows()) {
254             // Special case handling for NTFS ADS names
255             final IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> FilenameUtils.getExtension("foo.exe:bar.txt"));
256             assertEquals("NTFS ADS separator (':') in file name is forbidden.", e.getMessage());
257         } else {
258             // Upwards compatibility:
259             assertEquals("txt", FilenameUtils.getExtension("foo.exe:bar.txt"));
260         }
261     }
262 
263     @Test
264     void testGetFullPath() {
265         assertNull(FilenameUtils.getFullPath(null));
266         assertEquals("", FilenameUtils.getFullPath("noseparator.inthispath"));
267         assertEquals("a/b/", FilenameUtils.getFullPath("a/b/c.txt"));
268         assertEquals("a/b/", FilenameUtils.getFullPath("a/b/c"));
269         assertEquals("a/b/c/", FilenameUtils.getFullPath("a/b/c/"));
270         assertEquals("a\\b\\", FilenameUtils.getFullPath("a\\b\\c"));
271 
272         assertNull(FilenameUtils.getFullPath(":"));
273         assertNull(FilenameUtils.getFullPath("1:/a/b/c.txt"));
274         assertNull(FilenameUtils.getFullPath("1:"));
275         assertNull(FilenameUtils.getFullPath("1:a"));
276         assertNull(FilenameUtils.getFullPath("///a/b/c.txt"));
277         assertNull(FilenameUtils.getFullPath("//a"));
278 
279         assertEquals("", FilenameUtils.getFullPath(""));
280 
281         if (SystemUtils.IS_OS_WINDOWS) {
282             assertEquals(DRIVE_C, FilenameUtils.getFullPath(DRIVE_C));
283         }
284         if (SystemUtils.IS_OS_LINUX) {
285             assertEquals("", FilenameUtils.getFullPath(DRIVE_C));
286         }
287 
288         assertEquals("C:/", FilenameUtils.getFullPath("C:/"));
289         assertEquals("//server/", FilenameUtils.getFullPath("//server/"));
290         assertEquals("~/", FilenameUtils.getFullPath("~"));
291         assertEquals("~/", FilenameUtils.getFullPath("~/"));
292         assertEquals("~user/", FilenameUtils.getFullPath("~user"));
293         assertEquals("~user/", FilenameUtils.getFullPath("~user/"));
294 
295         assertEquals("a/b/", FilenameUtils.getFullPath("a/b/c.txt"));
296         assertEquals("/a/b/", FilenameUtils.getFullPath("/a/b/c.txt"));
297         assertEquals(DRIVE_C, FilenameUtils.getFullPath("C:a"));
298         assertEquals("C:a/b/", FilenameUtils.getFullPath("C:a/b/c.txt"));
299         assertEquals("C:/a/b/", FilenameUtils.getFullPath("C:/a/b/c.txt"));
300         assertEquals("//server/a/b/", FilenameUtils.getFullPath("//server/a/b/c.txt"));
301         assertEquals("~/a/b/", FilenameUtils.getFullPath("~/a/b/c.txt"));
302         assertEquals("~user/a/b/", FilenameUtils.getFullPath("~user/a/b/c.txt"));
303     }
304 
305     @Test
306     void testGetFullPathNoEndSeparator() {
307         assertNull(FilenameUtils.getFullPathNoEndSeparator(null));
308         assertEquals("", FilenameUtils.getFullPathNoEndSeparator("noseparator.inthispath"));
309         assertEquals("a/b", FilenameUtils.getFullPathNoEndSeparator("a/b/c.txt"));
310         assertEquals("a/b", FilenameUtils.getFullPathNoEndSeparator("a/b/c"));
311         assertEquals("a/b/c", FilenameUtils.getFullPathNoEndSeparator("a/b/c/"));
312         assertEquals("a\\b", FilenameUtils.getFullPathNoEndSeparator("a\\b\\c"));
313 
314         assertNull(FilenameUtils.getFullPathNoEndSeparator(":"));
315         assertNull(FilenameUtils.getFullPathNoEndSeparator("1:/a/b/c.txt"));
316         assertNull(FilenameUtils.getFullPathNoEndSeparator("1:"));
317         assertNull(FilenameUtils.getFullPathNoEndSeparator("1:a"));
318         assertNull(FilenameUtils.getFullPathNoEndSeparator("///a/b/c.txt"));
319         assertNull(FilenameUtils.getFullPathNoEndSeparator("//a"));
320 
321         assertEquals("", FilenameUtils.getFullPathNoEndSeparator(""));
322 
323         if (SystemUtils.IS_OS_WINDOWS) {
324             assertEquals(DRIVE_C, FilenameUtils.getFullPathNoEndSeparator(DRIVE_C));
325         }
326         if (SystemUtils.IS_OS_LINUX) {
327             assertEquals("", FilenameUtils.getFullPathNoEndSeparator(DRIVE_C));
328         }
329 
330         assertEquals("C:/", FilenameUtils.getFullPathNoEndSeparator("C:/"));
331         assertEquals("//server/", FilenameUtils.getFullPathNoEndSeparator("//server/"));
332         assertEquals("~", FilenameUtils.getFullPathNoEndSeparator("~"));
333         assertEquals("~/", FilenameUtils.getFullPathNoEndSeparator("~/"));
334         assertEquals("~user", FilenameUtils.getFullPathNoEndSeparator("~user"));
335         assertEquals("~user/", FilenameUtils.getFullPathNoEndSeparator("~user/"));
336 
337         assertEquals("a/b", FilenameUtils.getFullPathNoEndSeparator("a/b/c.txt"));
338         assertEquals("/a/b", FilenameUtils.getFullPathNoEndSeparator("/a/b/c.txt"));
339         assertEquals(DRIVE_C, FilenameUtils.getFullPathNoEndSeparator("C:a"));
340         assertEquals("C:a/b", FilenameUtils.getFullPathNoEndSeparator("C:a/b/c.txt"));
341         assertEquals("C:/a/b", FilenameUtils.getFullPathNoEndSeparator("C:/a/b/c.txt"));
342         assertEquals("//server/a/b", FilenameUtils.getFullPathNoEndSeparator("//server/a/b/c.txt"));
343         assertEquals("~/a/b", FilenameUtils.getFullPathNoEndSeparator("~/a/b/c.txt"));
344         assertEquals("~user/a/b", FilenameUtils.getFullPathNoEndSeparator("~user/a/b/c.txt"));
345     }
346 
347     /**
348      * Test for https://issues.apache.org/jira/browse/IO-248
349      */
350     @Test
351     void testGetFullPathNoEndSeparator_IO_248() {
352 
353         // Test single separator
354         assertEquals("/", FilenameUtils.getFullPathNoEndSeparator("/"));
355         assertEquals("\\", FilenameUtils.getFullPathNoEndSeparator("\\"));
356 
357         // Test one level directory
358         assertEquals("/", FilenameUtils.getFullPathNoEndSeparator("/abc"));
359         assertEquals("\\", FilenameUtils.getFullPathNoEndSeparator("\\abc"));
360 
361         // Test one level directory
362         assertEquals("/abc", FilenameUtils.getFullPathNoEndSeparator("/abc/xyz"));
363         assertEquals("\\abc", FilenameUtils.getFullPathNoEndSeparator("\\abc\\xyz"));
364     }
365 
366     @Test
367     void testGetName() {
368         assertNull(FilenameUtils.getName(null));
369         assertEquals("noseparator.inthispath", FilenameUtils.getName("noseparator.inthispath"));
370         assertEquals("c.txt", FilenameUtils.getName("a/b/c.txt"));
371         assertEquals("c", FilenameUtils.getName("a/b/c"));
372         assertEquals("", FilenameUtils.getName("a/b/c/"));
373         assertEquals("c", FilenameUtils.getName("a\\b\\c"));
374     }
375 
376     @Test
377     void testGetPath() {
378         assertNull(FilenameUtils.getPath(null));
379         assertEquals("", FilenameUtils.getPath("noseparator.inthispath"));
380         assertEquals("", FilenameUtils.getPath("/noseparator.inthispath"));
381         assertEquals("", FilenameUtils.getPath("\\noseparator.inthispath"));
382         assertEquals("a/b/", FilenameUtils.getPath("a/b/c.txt"));
383         assertEquals("a/b/", FilenameUtils.getPath("a/b/c"));
384         assertEquals("a/b/c/", FilenameUtils.getPath("a/b/c/"));
385         assertEquals("a\\b\\", FilenameUtils.getPath("a\\b\\c"));
386 
387         assertNull(FilenameUtils.getPath(":"));
388         assertNull(FilenameUtils.getPath("1:/a/b/c.txt"));
389         assertNull(FilenameUtils.getPath("1:"));
390         assertNull(FilenameUtils.getPath("1:a"));
391         assertNull(FilenameUtils.getPath("///a/b/c.txt"));
392         assertNull(FilenameUtils.getPath("//a"));
393 
394         assertEquals("", FilenameUtils.getPath(""));
395         assertEquals("", FilenameUtils.getPath(DRIVE_C));
396         assertEquals("", FilenameUtils.getPath("C:/"));
397         assertEquals("", FilenameUtils.getPath("//server/"));
398         assertEquals("", FilenameUtils.getPath("~"));
399         assertEquals("", FilenameUtils.getPath("~/"));
400         assertEquals("", FilenameUtils.getPath("~user"));
401         assertEquals("", FilenameUtils.getPath("~user/"));
402 
403         assertEquals("a/b/", FilenameUtils.getPath("a/b/c.txt"));
404         assertEquals("a/b/", FilenameUtils.getPath("/a/b/c.txt"));
405         assertEquals("", FilenameUtils.getPath("C:a"));
406         assertEquals("a/b/", FilenameUtils.getPath("C:a/b/c.txt"));
407         assertEquals("a/b/", FilenameUtils.getPath("C:/a/b/c.txt"));
408         assertEquals("a/b/", FilenameUtils.getPath("//server/a/b/c.txt"));
409         assertEquals("a/b/", FilenameUtils.getPath("~/a/b/c.txt"));
410         assertEquals("a/b/", FilenameUtils.getPath("~user/a/b/c.txt"));
411     }
412 
413     @Test
414     void testGetPath_with_null_character() {
415         assertThrows(IllegalArgumentException.class, () -> FilenameUtils.getPath("~user/a/\u0000b/c.txt"));
416     }
417 
418     @Test
419     void testGetPathNoEndSeparator() {
420         assertNull(FilenameUtils.getPath(null));
421         assertEquals("", FilenameUtils.getPath("noseparator.inthispath"));
422         assertEquals("", FilenameUtils.getPathNoEndSeparator("/noseparator.inthispath"));
423         assertEquals("", FilenameUtils.getPathNoEndSeparator("\\noseparator.inthispath"));
424         assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("a/b/c.txt"));
425         assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("a/b/c"));
426         assertEquals("a/b/c", FilenameUtils.getPathNoEndSeparator("a/b/c/"));
427         assertEquals("a\\b", FilenameUtils.getPathNoEndSeparator("a\\b\\c"));
428 
429         assertNull(FilenameUtils.getPathNoEndSeparator(":"));
430         assertNull(FilenameUtils.getPathNoEndSeparator("1:/a/b/c.txt"));
431         assertNull(FilenameUtils.getPathNoEndSeparator("1:"));
432         assertNull(FilenameUtils.getPathNoEndSeparator("1:a"));
433         assertNull(FilenameUtils.getPathNoEndSeparator("///a/b/c.txt"));
434         assertNull(FilenameUtils.getPathNoEndSeparator("//a"));
435 
436         assertEquals("", FilenameUtils.getPathNoEndSeparator(""));
437         assertEquals("", FilenameUtils.getPathNoEndSeparator(DRIVE_C));
438         assertEquals("", FilenameUtils.getPathNoEndSeparator("C:/"));
439         assertEquals("", FilenameUtils.getPathNoEndSeparator("//server/"));
440         assertEquals("", FilenameUtils.getPathNoEndSeparator("~"));
441         assertEquals("", FilenameUtils.getPathNoEndSeparator("~/"));
442         assertEquals("", FilenameUtils.getPathNoEndSeparator("~user"));
443         assertEquals("", FilenameUtils.getPathNoEndSeparator("~user/"));
444 
445         assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("a/b/c.txt"));
446         assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("/a/b/c.txt"));
447         assertEquals("", FilenameUtils.getPathNoEndSeparator("C:a"));
448         assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("C:a/b/c.txt"));
449         assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("C:/a/b/c.txt"));
450         assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("//server/a/b/c.txt"));
451         assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("~/a/b/c.txt"));
452         assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("~user/a/b/c.txt"));
453     }
454 
455     @Test
456     void testGetPathNoEndSeparator_with_null_character() {
457         assertThrows(IllegalArgumentException.class, () -> FilenameUtils.getPathNoEndSeparator("~user/a\u0000/b/c.txt"));
458     }
459 
460     @Test
461     void testGetPrefix() {
462         assertNull(FilenameUtils.getPrefix(null));
463         assertNull(FilenameUtils.getPrefix(":"));
464         assertNull(FilenameUtils.getPrefix("1:\\a\\b\\c.txt"));
465         assertNull(FilenameUtils.getPrefix("1:"));
466         assertNull(FilenameUtils.getPrefix("1:a"));
467         assertNull(FilenameUtils.getPrefix("\\\\\\a\\b\\c.txt"));
468         assertNull(FilenameUtils.getPrefix("\\\\a"));
469 
470         assertEquals("", FilenameUtils.getPrefix(""));
471         assertEquals("\\", FilenameUtils.getPrefix("\\"));
472 
473         if (SystemUtils.IS_OS_WINDOWS) {
474             assertEquals(DRIVE_C, FilenameUtils.getPrefix(DRIVE_C));
475         }
476         if (SystemUtils.IS_OS_LINUX) {
477             assertEquals("", FilenameUtils.getPrefix(DRIVE_C));
478         }
479 
480         assertEquals("C:\\", FilenameUtils.getPrefix("C:\\"));
481         assertEquals("//server/", FilenameUtils.getPrefix("//server/"));
482         assertEquals("~/", FilenameUtils.getPrefix("~"));
483         assertEquals("~/", FilenameUtils.getPrefix("~/"));
484         assertEquals("~user/", FilenameUtils.getPrefix("~user"));
485         assertEquals("~user/", FilenameUtils.getPrefix("~user/"));
486 
487         assertEquals("", FilenameUtils.getPrefix("a\\b\\c.txt"));
488         assertEquals("\\", FilenameUtils.getPrefix("\\a\\b\\c.txt"));
489         assertEquals("C:\\", FilenameUtils.getPrefix("C:\\a\\b\\c.txt"));
490         assertEquals("\\\\server\\", FilenameUtils.getPrefix("\\\\server\\a\\b\\c.txt"));
491 
492         assertEquals("", FilenameUtils.getPrefix("a/b/c.txt"));
493         assertEquals("/", FilenameUtils.getPrefix("/a/b/c.txt"));
494         assertEquals("C:/", FilenameUtils.getPrefix("C:/a/b/c.txt"));
495         assertEquals("//server/", FilenameUtils.getPrefix("//server/a/b/c.txt"));
496         assertEquals("~/", FilenameUtils.getPrefix("~/a/b/c.txt"));
497         assertEquals("~user/", FilenameUtils.getPrefix("~user/a/b/c.txt"));
498 
499         assertEquals("", FilenameUtils.getPrefix("a\\b\\c.txt"));
500         assertEquals("\\", FilenameUtils.getPrefix("\\a\\b\\c.txt"));
501         assertEquals("~\\", FilenameUtils.getPrefix("~\\a\\b\\c.txt"));
502         assertEquals("~user\\", FilenameUtils.getPrefix("~user\\a\\b\\c.txt"));
503     }
504 
505     @Test
506     void testGetPrefix_with_null_character() {
507         assertThrows(IllegalArgumentException.class, () -> FilenameUtils.getPrefix("~u\u0000ser\\a\\b\\c.txt"));
508     }
509 
510     @Test
511     void testGetPrefixLength() {
512         assertEquals(-1, FilenameUtils.getPrefixLength(null));
513         assertEquals(-1, FilenameUtils.getPrefixLength(":"));
514         assertEquals(-1, FilenameUtils.getPrefixLength("1:\\a\\b\\c.txt"));
515         assertEquals(-1, FilenameUtils.getPrefixLength("1:"));
516         assertEquals(-1, FilenameUtils.getPrefixLength("1:a"));
517         assertEquals(-1, FilenameUtils.getPrefixLength("\\\\\\a\\b\\c.txt"));
518         assertEquals(-1, FilenameUtils.getPrefixLength("\\\\a"));
519 
520         assertEquals(0, FilenameUtils.getPrefixLength(""));
521         assertEquals(1, FilenameUtils.getPrefixLength("\\"));
522 
523         if (SystemUtils.IS_OS_WINDOWS) {
524             assertEquals(2, FilenameUtils.getPrefixLength(DRIVE_C));
525         }
526         if (SystemUtils.IS_OS_LINUX) {
527             assertEquals(0, FilenameUtils.getPrefixLength(DRIVE_C));
528         }
529 
530         assertEquals(3, FilenameUtils.getPrefixLength("C:\\"));
531         assertEquals(9, FilenameUtils.getPrefixLength("//server/"));
532         assertEquals(2, FilenameUtils.getPrefixLength("~"));
533         assertEquals(2, FilenameUtils.getPrefixLength("~/"));
534         assertEquals(6, FilenameUtils.getPrefixLength("~user"));
535         assertEquals(6, FilenameUtils.getPrefixLength("~user/"));
536 
537         assertEquals(0, FilenameUtils.getPrefixLength("a\\b\\c.txt"));
538         assertEquals(1, FilenameUtils.getPrefixLength("\\a\\b\\c.txt"));
539         assertEquals(2, FilenameUtils.getPrefixLength("C:a\\b\\c.txt"));
540         assertEquals(3, FilenameUtils.getPrefixLength("C:\\a\\b\\c.txt"));
541         assertEquals(9, FilenameUtils.getPrefixLength("\\\\server\\a\\b\\c.txt"));
542 
543         assertEquals(0, FilenameUtils.getPrefixLength("a/b/c.txt"));
544         assertEquals(1, FilenameUtils.getPrefixLength("/a/b/c.txt"));
545         assertEquals(3, FilenameUtils.getPrefixLength("C:/a/b/c.txt"));
546         assertEquals(9, FilenameUtils.getPrefixLength("//server/a/b/c.txt"));
547         assertEquals(2, FilenameUtils.getPrefixLength("~/a/b/c.txt"));
548         assertEquals(6, FilenameUtils.getPrefixLength("~user/a/b/c.txt"));
549 
550         assertEquals(0, FilenameUtils.getPrefixLength("a\\b\\c.txt"));
551         assertEquals(1, FilenameUtils.getPrefixLength("\\a\\b\\c.txt"));
552         assertEquals(2, FilenameUtils.getPrefixLength("~\\a\\b\\c.txt"));
553         assertEquals(6, FilenameUtils.getPrefixLength("~user\\a\\b\\c.txt"));
554 
555         assertEquals(9, FilenameUtils.getPrefixLength("//server/a/b/c.txt"));
556         assertEquals(-1, FilenameUtils.getPrefixLength("\\\\\\a\\b\\c.txt"));
557         assertEquals(-1, FilenameUtils.getPrefixLength("///a/b/c.txt"));
558 
559         assertEquals(1, FilenameUtils.getPrefixLength("/:foo"));
560         assertEquals(1, FilenameUtils.getPrefixLength("/:/"));
561         assertEquals(1, FilenameUtils.getPrefixLength("/:::::::.txt"));
562 
563         assertEquals(12, FilenameUtils.getPrefixLength("\\\\127.0.0.1\\a\\b\\c.txt"));
564         assertEquals(6, FilenameUtils.getPrefixLength("\\\\::1\\a\\b\\c.txt"));
565         assertEquals(21, FilenameUtils.getPrefixLength("\\\\server.example.org\\a\\b\\c.txt"));
566         assertEquals(10, FilenameUtils.getPrefixLength("\\\\server.\\a\\b\\c.txt"));
567 
568         assertEquals(-1, FilenameUtils.getPrefixLength("\\\\-server\\a\\b\\c.txt"));
569         assertEquals(-1, FilenameUtils.getPrefixLength("\\\\.\\a\\b\\c.txt"));
570         assertEquals(-1, FilenameUtils.getPrefixLength("\\\\..\\a\\b\\c.txt"));
571     }
572 
573     @Test
574     void testIndexOfExtension() {
575         assertEquals(-1, FilenameUtils.indexOfExtension(null));
576         assertEquals(-1, FilenameUtils.indexOfExtension("file"));
577         assertEquals(4, FilenameUtils.indexOfExtension("file.txt"));
578         assertEquals(13, FilenameUtils.indexOfExtension("a.txt/b.txt/c.txt"));
579         assertEquals(-1, FilenameUtils.indexOfExtension("a/b/c"));
580         assertEquals(-1, FilenameUtils.indexOfExtension("a\\b\\c"));
581         assertEquals(-1, FilenameUtils.indexOfExtension("a/b.notextension/c"));
582         assertEquals(-1, FilenameUtils.indexOfExtension("a\\b.notextension\\c"));
583 
584         if (FilenameUtils.isSystemWindows()) {
585             // Special case handling for NTFS ADS names
586             final IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> FilenameUtils.indexOfExtension("foo.exe:bar.txt"));
587             assertEquals("NTFS ADS separator (':') in file name is forbidden.", e.getMessage());
588         } else {
589             // Upwards compatibility on other systems
590             assertEquals(11, FilenameUtils.indexOfExtension("foo.exe:bar.txt"));
591         }
592 
593     }
594 
595     @Test
596     void testIndexOfLastSeparator() {
597         assertEquals(-1, FilenameUtils.indexOfLastSeparator(null));
598         assertEquals(-1, FilenameUtils.indexOfLastSeparator("noseparator.inthispath"));
599         assertEquals(3, FilenameUtils.indexOfLastSeparator("a/b/c"));
600         assertEquals(3, FilenameUtils.indexOfLastSeparator("a\\b\\c"));
601     }
602 
603     @Test
604     void testInjectionFailure() {
605         assertThrows(IllegalArgumentException.class, () -> FilenameUtils.getName("a\\b\\\u0000c"));
606     }
607 
608     @Test
609     void testIsExtension() {
610         assertFalse(FilenameUtils.isExtension(null, (String) null));
611         assertFalse(FilenameUtils.isExtension("file.txt", (String) null));
612         assertTrue(FilenameUtils.isExtension("file", (String) null));
613         assertFalse(FilenameUtils.isExtension("file.txt", ""));
614         assertTrue(FilenameUtils.isExtension("file", ""));
615         assertTrue(FilenameUtils.isExtension("file.txt", "txt"));
616         assertFalse(FilenameUtils.isExtension("file.txt", "rtf"));
617 
618         assertFalse(FilenameUtils.isExtension("a/b/file.txt", (String) null));
619         assertFalse(FilenameUtils.isExtension("a/b/file.txt", ""));
620         assertTrue(FilenameUtils.isExtension("a/b/file.txt", "txt"));
621         assertFalse(FilenameUtils.isExtension("a/b/file.txt", "rtf"));
622 
623         assertFalse(FilenameUtils.isExtension("a.b/file.txt", (String) null));
624         assertFalse(FilenameUtils.isExtension("a.b/file.txt", ""));
625         assertTrue(FilenameUtils.isExtension("a.b/file.txt", "txt"));
626         assertFalse(FilenameUtils.isExtension("a.b/file.txt", "rtf"));
627 
628         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt", (String) null));
629         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt", ""));
630         assertTrue(FilenameUtils.isExtension("a\\b\\file.txt", "txt"));
631         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt", "rtf"));
632 
633         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", (String) null));
634         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", ""));
635         assertTrue(FilenameUtils.isExtension("a.b\\file.txt", "txt"));
636         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", "rtf"));
637 
638         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", "TXT"));
639     }
640 
641     @Test
642     void testIsExtension_injection() {
643         assertThrows(IllegalArgumentException.class, () -> FilenameUtils.isExtension("a.b\\fi\u0000le.txt", "TXT"));
644     }
645 
646     @Test
647     void testIsExtensionArray() {
648         assertFalse(FilenameUtils.isExtension(null, (String[]) null));
649         assertFalse(FilenameUtils.isExtension("file.txt", (String[]) null));
650         assertTrue(FilenameUtils.isExtension("file", (String[]) null));
651         assertFalse(FilenameUtils.isExtension("file.txt"));
652         assertTrue(FilenameUtils.isExtension("file.txt", new String[]{"txt"}));
653         assertFalse(FilenameUtils.isExtension("file.txt", new String[]{"rtf"}));
654         assertTrue(FilenameUtils.isExtension("file", "rtf", ""));
655         assertTrue(FilenameUtils.isExtension("file.txt", "rtf", "txt"));
656 
657         assertFalse(FilenameUtils.isExtension("a/b/file.txt", (String[]) null));
658         assertFalse(FilenameUtils.isExtension("a/b/file.txt"));
659         assertTrue(FilenameUtils.isExtension("a/b/file.txt", new String[]{"txt"}));
660         assertFalse(FilenameUtils.isExtension("a/b/file.txt", new String[]{"rtf"}));
661         assertTrue(FilenameUtils.isExtension("a/b/file.txt", "rtf", "txt"));
662 
663         assertFalse(FilenameUtils.isExtension("a.b/file.txt", (String[]) null));
664         assertFalse(FilenameUtils.isExtension("a.b/file.txt"));
665         assertTrue(FilenameUtils.isExtension("a.b/file.txt", new String[]{"txt"}));
666         assertFalse(FilenameUtils.isExtension("a.b/file.txt", new String[]{"rtf"}));
667         assertTrue(FilenameUtils.isExtension("a.b/file.txt", "rtf", "txt"));
668 
669         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt", (String[]) null));
670         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt"));
671         assertTrue(FilenameUtils.isExtension("a\\b\\file.txt", new String[]{"txt"}));
672         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt", new String[]{"rtf"}));
673         assertTrue(FilenameUtils.isExtension("a\\b\\file.txt", "rtf", "txt"));
674 
675         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", (String[]) null));
676         assertFalse(FilenameUtils.isExtension("a.b\\file.txt"));
677         assertTrue(FilenameUtils.isExtension("a.b\\file.txt", new String[]{"txt"}));
678         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", new String[]{"rtf"}));
679         assertTrue(FilenameUtils.isExtension("a.b\\file.txt", "rtf", "txt"));
680 
681         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", new String[]{"TXT"}));
682         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", "TXT", "RTF"));
683     }
684 
685     @Test
686     void testIsExtensionCollection() {
687         assertFalse(FilenameUtils.isExtension(null, (Collection<String>) null));
688         assertFalse(FilenameUtils.isExtension("file.txt", (Collection<String>) null));
689         assertTrue(FilenameUtils.isExtension("file", (Collection<String>) null));
690         assertFalse(FilenameUtils.isExtension("file.txt", new ArrayList<>()));
691         assertTrue(FilenameUtils.isExtension("file.txt", new ArrayList<>(Arrays.asList("txt"))));
692         assertFalse(FilenameUtils.isExtension("file.txt", new ArrayList<>(Arrays.asList("rtf"))));
693         assertTrue(FilenameUtils.isExtension("file", new ArrayList<>(Arrays.asList("rtf", ""))));
694         assertTrue(FilenameUtils.isExtension("file.txt", new ArrayList<>(Arrays.asList("rtf", "txt"))));
695 
696         assertFalse(FilenameUtils.isExtension("a/b/file.txt", (Collection<String>) null));
697         assertFalse(FilenameUtils.isExtension("a/b/file.txt", new ArrayList<>()));
698         assertTrue(FilenameUtils.isExtension("a/b/file.txt", new ArrayList<>(Arrays.asList("txt"))));
699         assertFalse(FilenameUtils.isExtension("a/b/file.txt", new ArrayList<>(Arrays.asList("rtf"))));
700         assertTrue(FilenameUtils.isExtension("a/b/file.txt", new ArrayList<>(Arrays.asList("rtf", "txt"))));
701 
702         assertFalse(FilenameUtils.isExtension("a.b/file.txt", (Collection<String>) null));
703         assertFalse(FilenameUtils.isExtension("a.b/file.txt", new ArrayList<>()));
704         assertTrue(FilenameUtils.isExtension("a.b/file.txt", new ArrayList<>(Arrays.asList("txt"))));
705         assertFalse(FilenameUtils.isExtension("a.b/file.txt", new ArrayList<>(Arrays.asList("rtf"))));
706         assertTrue(FilenameUtils.isExtension("a.b/file.txt", new ArrayList<>(Arrays.asList("rtf", "txt"))));
707 
708         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt", (Collection<String>) null));
709         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt", new ArrayList<>()));
710         assertTrue(FilenameUtils.isExtension("a\\b\\file.txt", new ArrayList<>(Arrays.asList("txt"))));
711         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt", new ArrayList<>(Arrays.asList("rtf"))));
712         assertTrue(FilenameUtils.isExtension("a\\b\\file.txt", new ArrayList<>(Arrays.asList("rtf", "txt"))));
713 
714         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", (Collection<String>) null));
715         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", new ArrayList<>()));
716         assertTrue(FilenameUtils.isExtension("a.b\\file.txt", new ArrayList<>(Arrays.asList("txt"))));
717         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", new ArrayList<>(Arrays.asList("rtf"))));
718         assertTrue(FilenameUtils.isExtension("a.b\\file.txt", new ArrayList<>(Arrays.asList("rtf", "txt"))));
719 
720         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", new ArrayList<>(Arrays.asList("TXT"))));
721         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", new ArrayList<>(Arrays.asList("TXT", "RTF"))));
722     }
723 
724     @Test
725     void testIsExtensionVarArgs() {
726         assertTrue(FilenameUtils.isExtension("file.txt", "txt"));
727         assertFalse(FilenameUtils.isExtension("file.txt", "rtf"));
728         assertTrue(FilenameUtils.isExtension("file", "rtf", ""));
729         assertTrue(FilenameUtils.isExtension("file.txt", "rtf", "txt"));
730 
731         assertTrue(FilenameUtils.isExtension("a/b/file.txt", "txt"));
732         assertFalse(FilenameUtils.isExtension("a/b/file.txt", "rtf"));
733         assertTrue(FilenameUtils.isExtension("a/b/file.txt", "rtf", "txt"));
734 
735         assertTrue(FilenameUtils.isExtension("a.b/file.txt", "txt"));
736         assertFalse(FilenameUtils.isExtension("a.b/file.txt", "rtf"));
737         assertTrue(FilenameUtils.isExtension("a.b/file.txt", "rtf", "txt"));
738 
739         assertTrue(FilenameUtils.isExtension("a\\b\\file.txt", "txt"));
740         assertFalse(FilenameUtils.isExtension("a\\b\\file.txt", "rtf"));
741         assertTrue(FilenameUtils.isExtension("a\\b\\file.txt", "rtf", "txt"));
742 
743         assertTrue(FilenameUtils.isExtension("a.b\\file.txt", "txt"));
744         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", "rtf"));
745         assertTrue(FilenameUtils.isExtension("a.b\\file.txt", "rtf", "txt"));
746 
747         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", "TXT"));
748         assertFalse(FilenameUtils.isExtension("a.b\\file.txt", "TXT", "RTF"));
749     }
750 
751     @Test
752     void testNormalize() {
753         assertNull(FilenameUtils.normalize(null));
754         assertNull(FilenameUtils.normalize(":"));
755         assertNull(FilenameUtils.normalize("1:\\a\\b\\c.txt"));
756         assertNull(FilenameUtils.normalize("1:"));
757         assertNull(FilenameUtils.normalize("1:a"));
758         assertNull(FilenameUtils.normalize("\\\\\\a\\b\\c.txt"));
759         assertNull(FilenameUtils.normalize("\\\\a"));
760 
761         assertEquals("a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("a\\b/c.txt"));
762         assertEquals("" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\a\\b/c.txt"));
763         assertEquals(DRIVE_C + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("C:\\a\\b/c.txt"));
764         assertEquals("" + SEP + "" + SEP + "server" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\\\server\\a\\b/c.txt"));
765         assertEquals("~" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("~\\a\\b/c.txt"));
766         assertEquals("~user" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("~user\\a\\b/c.txt"));
767 
768         assertEquals("a" + SEP + "c", FilenameUtils.normalize("a/b/../c"));
769         assertEquals("c", FilenameUtils.normalize("a/b/../../c"));
770         assertEquals("c" + SEP, FilenameUtils.normalize("a/b/../../c/"));
771         assertNull(FilenameUtils.normalize("a/b/../../../c"));
772         assertEquals("a" + SEP, FilenameUtils.normalize("a/b/.."));
773         assertEquals("a" + SEP, FilenameUtils.normalize("a/b/../"));
774         assertEquals("", FilenameUtils.normalize("a/b/../.."));
775         assertEquals("", FilenameUtils.normalize("a/b/../../"));
776         assertNull(FilenameUtils.normalize("a/b/../../.."));
777         assertEquals("a" + SEP + "d", FilenameUtils.normalize("a/b/../c/../d"));
778         assertEquals("a" + SEP + "d" + SEP, FilenameUtils.normalize("a/b/../c/../d/"));
779         assertEquals("a" + SEP + "b" + SEP + "d", FilenameUtils.normalize("a/b//d"));
780         assertEquals("a" + SEP + "b" + SEP, FilenameUtils.normalize("a/b/././."));
781         assertEquals("a" + SEP + "b" + SEP, FilenameUtils.normalize("a/b/./././"));
782         assertEquals("a" + SEP, FilenameUtils.normalize("./a/"));
783         assertEquals("a", FilenameUtils.normalize("./a"));
784         assertEquals("", FilenameUtils.normalize("./"));
785         assertEquals("", FilenameUtils.normalize("."));
786         assertNull(FilenameUtils.normalize("../a"));
787         assertNull(FilenameUtils.normalize(".."));
788         assertEquals("", FilenameUtils.normalize(""));
789 
790         assertEquals(SEP + "a", FilenameUtils.normalize("/a"));
791         assertEquals(SEP + "a" + SEP, FilenameUtils.normalize("/a/"));
792         assertEquals(SEP + "a" + SEP + "c", FilenameUtils.normalize("/a/b/../c"));
793         assertEquals(SEP + "c", FilenameUtils.normalize("/a/b/../../c"));
794         assertNull(FilenameUtils.normalize("/a/b/../../../c"));
795         assertEquals(SEP + "a" + SEP, FilenameUtils.normalize("/a/b/.."));
796         assertEquals(SEP + "", FilenameUtils.normalize("/a/b/../.."));
797         assertNull(FilenameUtils.normalize("/a/b/../../.."));
798         assertEquals(SEP + "a" + SEP + "d", FilenameUtils.normalize("/a/b/../c/../d"));
799         assertEquals(SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalize("/a/b//d"));
800         assertEquals(SEP + "a" + SEP + "b" + SEP, FilenameUtils.normalize("/a/b/././."));
801         assertEquals(SEP + "a", FilenameUtils.normalize("/./a"));
802         assertEquals(SEP + "", FilenameUtils.normalize("/./"));
803         assertEquals(SEP + "", FilenameUtils.normalize("/."));
804         assertNull(FilenameUtils.normalize("/../a"));
805         assertNull(FilenameUtils.normalize("/.."));
806         assertEquals(SEP + "", FilenameUtils.normalize("/"));
807 
808         assertEquals("~" + SEP + "a", FilenameUtils.normalize("~/a"));
809         assertEquals("~" + SEP + "a" + SEP, FilenameUtils.normalize("~/a/"));
810         assertEquals("~" + SEP + "a" + SEP + "c", FilenameUtils.normalize("~/a/b/../c"));
811         assertEquals("~" + SEP + "c", FilenameUtils.normalize("~/a/b/../../c"));
812         assertNull(FilenameUtils.normalize("~/a/b/../../../c"));
813         assertEquals("~" + SEP + "a" + SEP, FilenameUtils.normalize("~/a/b/.."));
814         assertEquals("~" + SEP + "", FilenameUtils.normalize("~/a/b/../.."));
815         assertNull(FilenameUtils.normalize("~/a/b/../../.."));
816         assertEquals("~" + SEP + "a" + SEP + "d", FilenameUtils.normalize("~/a/b/../c/../d"));
817         assertEquals("~" + SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalize("~/a/b//d"));
818         assertEquals("~" + SEP + "a" + SEP + "b" + SEP, FilenameUtils.normalize("~/a/b/././."));
819         assertEquals("~" + SEP + "a", FilenameUtils.normalize("~/./a"));
820         assertEquals("~" + SEP, FilenameUtils.normalize("~/./"));
821         assertEquals("~" + SEP, FilenameUtils.normalize("~/."));
822         assertNull(FilenameUtils.normalize("~/../a"));
823         assertNull(FilenameUtils.normalize("~/.."));
824         assertEquals("~" + SEP, FilenameUtils.normalize("~/"));
825         assertEquals("~" + SEP, FilenameUtils.normalize("~"));
826 
827         assertEquals("~user" + SEP + "a", FilenameUtils.normalize("~user/a"));
828         assertEquals("~user" + SEP + "a" + SEP, FilenameUtils.normalize("~user/a/"));
829         assertEquals("~user" + SEP + "a" + SEP + "c", FilenameUtils.normalize("~user/a/b/../c"));
830         assertEquals("~user" + SEP + "c", FilenameUtils.normalize("~user/a/b/../../c"));
831         assertNull(FilenameUtils.normalize("~user/a/b/../../../c"));
832         assertEquals("~user" + SEP + "a" + SEP, FilenameUtils.normalize("~user/a/b/.."));
833         assertEquals("~user" + SEP + "", FilenameUtils.normalize("~user/a/b/../.."));
834         assertNull(FilenameUtils.normalize("~user/a/b/../../.."));
835         assertEquals("~user" + SEP + "a" + SEP + "d", FilenameUtils.normalize("~user/a/b/../c/../d"));
836         assertEquals("~user" + SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalize("~user/a/b//d"));
837         assertEquals("~user" + SEP + "a" + SEP + "b" + SEP, FilenameUtils.normalize("~user/a/b/././."));
838         assertEquals("~user" + SEP + "a", FilenameUtils.normalize("~user/./a"));
839         assertEquals("~user" + SEP + "", FilenameUtils.normalize("~user/./"));
840         assertEquals("~user" + SEP + "", FilenameUtils.normalize("~user/."));
841         assertNull(FilenameUtils.normalize("~user/../a"));
842         assertNull(FilenameUtils.normalize("~user/.."));
843         assertEquals("~user" + SEP, FilenameUtils.normalize("~user/"));
844         assertEquals("~user" + SEP, FilenameUtils.normalize("~user"));
845 
846         assertEquals(DRIVE_C + SEP + "a", FilenameUtils.normalize("C:/a"));
847         assertEquals(DRIVE_C + SEP + "a" + SEP, FilenameUtils.normalize("C:/a/"));
848         assertEquals(DRIVE_C + SEP + "a" + SEP + "c", FilenameUtils.normalize("C:/a/b/../c"));
849         assertEquals(DRIVE_C + SEP + "c", FilenameUtils.normalize("C:/a/b/../../c"));
850         assertNull(FilenameUtils.normalize("C:/a/b/../../../c"));
851         assertEquals(DRIVE_C + SEP + "a" + SEP, FilenameUtils.normalize("C:/a/b/.."));
852         assertEquals(DRIVE_C + SEP + "", FilenameUtils.normalize("C:/a/b/../.."));
853         assertNull(FilenameUtils.normalize("C:/a/b/../../.."));
854         assertEquals(DRIVE_C + SEP + "a" + SEP + "d", FilenameUtils.normalize("C:/a/b/../c/../d"));
855         assertEquals(DRIVE_C + SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalize("C:/a/b//d"));
856         assertEquals(DRIVE_C + SEP + "a" + SEP + "b" + SEP, FilenameUtils.normalize("C:/a/b/././."));
857         assertEquals(DRIVE_C + SEP + "a", FilenameUtils.normalize("C:/./a"));
858         assertEquals(DRIVE_C + SEP + "", FilenameUtils.normalize("C:/./"));
859         assertEquals(DRIVE_C + SEP + "", FilenameUtils.normalize("C:/."));
860         assertNull(FilenameUtils.normalize("C:/../a"));
861         assertNull(FilenameUtils.normalize("C:/.."));
862         assertEquals(DRIVE_C + SEP + "", FilenameUtils.normalize("C:/"));
863 
864         assertEquals(DRIVE_C + "a", FilenameUtils.normalize("C:a"));
865         assertEquals(DRIVE_C + "a" + SEP, FilenameUtils.normalize("C:a/"));
866         assertEquals(DRIVE_C + "a" + SEP + "c", FilenameUtils.normalize("C:a/b/../c"));
867         assertEquals(DRIVE_C + "c", FilenameUtils.normalize("C:a/b/../../c"));
868         assertNull(FilenameUtils.normalize("C:a/b/../../../c"));
869         assertEquals(DRIVE_C + "a" + SEP, FilenameUtils.normalize("C:a/b/.."));
870         assertEquals(DRIVE_C + "", FilenameUtils.normalize("C:a/b/../.."));
871         assertNull(FilenameUtils.normalize("C:a/b/../../.."));
872         assertEquals(DRIVE_C + "a" + SEP + "d", FilenameUtils.normalize("C:a/b/../c/../d"));
873         assertEquals(DRIVE_C + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalize("C:a/b//d"));
874         assertEquals(DRIVE_C + "a" + SEP + "b" + SEP, FilenameUtils.normalize("C:a/b/././."));
875         assertEquals(DRIVE_C + "a", FilenameUtils.normalize("C:./a"));
876         assertEquals(DRIVE_C + "", FilenameUtils.normalize("C:./"));
877         assertEquals(DRIVE_C + "", FilenameUtils.normalize("C:."));
878         assertNull(FilenameUtils.normalize("C:../a"));
879         assertNull(FilenameUtils.normalize("C:.."));
880         assertEquals(DRIVE_C + "", FilenameUtils.normalize(DRIVE_C));
881 
882         assertEquals(SEP + SEP + "server" + SEP + "a", FilenameUtils.normalize("//server/a"));
883         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP, FilenameUtils.normalize("//server/a/"));
884         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP + "c", FilenameUtils.normalize("//server/a/b/../c"));
885         assertEquals(SEP + SEP + "server" + SEP + "c", FilenameUtils.normalize("//server/a/b/../../c"));
886         assertNull(FilenameUtils.normalize("//server/a/b/../../../c"));
887         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP, FilenameUtils.normalize("//server/a/b/.."));
888         assertEquals(SEP + SEP + "server" + SEP + "", FilenameUtils.normalize("//server/a/b/../.."));
889         assertNull(FilenameUtils.normalize("//server/a/b/../../.."));
890         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP + "d", FilenameUtils.normalize("//server/a/b/../c/../d"));
891         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalize("//server/a/b//d"));
892         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP + "b" + SEP, FilenameUtils.normalize("//server/a/b/././."));
893         assertEquals(SEP + SEP + "server" + SEP + "a", FilenameUtils.normalize("//server/./a"));
894         assertEquals(SEP + SEP + "server" + SEP + "", FilenameUtils.normalize("//server/./"));
895         assertEquals(SEP + SEP + "server" + SEP + "", FilenameUtils.normalize("//server/."));
896         assertNull(FilenameUtils.normalize("//server/../a"));
897         assertNull(FilenameUtils.normalize("//server/.."));
898         assertEquals(SEP + SEP + "server" + SEP + "", FilenameUtils.normalize("//server/"));
899 
900         assertEquals(SEP + SEP + "127.0.0.1" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\\\127.0.0.1\\a\\b\\c.txt"));
901         assertEquals(SEP + SEP + "::1" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\\\::1\\a\\b\\c.txt"));
902         assertEquals(SEP + SEP + "1::" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\\\1::\\a\\b\\c.txt"));
903         assertEquals(SEP + SEP + "server.example.org" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\\\server.example.org\\a\\b\\c.txt"));
904         assertEquals(SEP + SEP + "server.sub.example.org" + SEP + "a" + SEP + "b" + SEP + "c.txt",
905             FilenameUtils.normalize("\\\\server.sub.example.org\\a\\b\\c.txt"));
906         assertEquals(SEP + SEP + "server." + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\\\server.\\a\\b\\c.txt"));
907         assertEquals(SEP + SEP + "1::127.0.0.1" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\\\1::127.0.0.1\\a\\b\\c.txt"));
908 
909         // not valid IPv4 addresses but technically a valid "reg-name"s according to RFC1034
910         assertEquals(SEP + SEP + "127.0.0.256" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\\\127.0.0.256\\a\\b\\c.txt"));
911         assertEquals(SEP + SEP + "127.0.0.01" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalize("\\\\127.0.0.01\\a\\b\\c.txt"));
912 
913         assertNull(FilenameUtils.normalize("\\\\-server\\a\\b\\c.txt"));
914         assertNull(FilenameUtils.normalize("\\\\.\\a\\b\\c.txt"));
915         assertNull(FilenameUtils.normalize("\\\\..\\a\\b\\c.txt"));
916         assertNull(FilenameUtils.normalize("\\\\127.0..1\\a\\b\\c.txt"));
917         assertNull(FilenameUtils.normalize("\\\\::1::2\\a\\b\\c.txt"));
918         assertNull(FilenameUtils.normalize("\\\\:1\\a\\b\\c.txt"));
919         assertNull(FilenameUtils.normalize("\\\\1:\\a\\b\\c.txt"));
920         assertNull(FilenameUtils.normalize("\\\\1:2:3:4:5:6:7:8:9\\a\\b\\c.txt"));
921         assertNull(FilenameUtils.normalize("\\\\g:2:3:4:5:6:7:8\\a\\b\\c.txt"));
922         assertNull(FilenameUtils.normalize("\\\\1ffff:2:3:4:5:6:7:8\\a\\b\\c.txt"));
923         assertNull(FilenameUtils.normalize("\\\\1:2\\a\\b\\c.txt"));
924         // IO-556
925         assertNull(FilenameUtils.normalize("//../foo"));
926         assertNull(FilenameUtils.normalize("\\\\..\\foo"));
927     }
928 
929     /**
930      */
931     @Test
932     void testNormalize_with_null_character() {
933         assertThrows(IllegalArgumentException.class, () -> FilenameUtils.normalize("a\\b/c\u0000.txt"));
934         assertThrows(IllegalArgumentException.class, () -> FilenameUtils.normalize("\u0000a\\b/c.txt"));
935     }
936 
937     @Test
938     void testNormalizeFromJavaDoc() {
939         // Examples from Javadoc
940         assertEquals(SEP + "foo" + SEP, FilenameUtils.normalize("/foo//"));
941         assertEquals(SEP + "foo" + SEP, FilenameUtils.normalize(SEP + "foo" + SEP + "." + SEP));
942         assertEquals(SEP + "bar", FilenameUtils.normalize(SEP + "foo" + SEP + ".." + SEP + "bar"));
943         assertEquals(SEP + "bar" + SEP, FilenameUtils.normalize(SEP + "foo" + SEP + ".." + SEP + "bar" + SEP));
944         assertEquals(SEP + "baz", FilenameUtils.normalize(SEP + "foo" + SEP + ".." + SEP + "bar" + SEP + ".." + SEP + "baz"));
945         assertEquals(SEP + SEP + "foo" + SEP + "bar", FilenameUtils.normalize("//foo//./bar"));
946         assertNull(FilenameUtils.normalize(SEP + ".." + SEP));
947         assertNull(FilenameUtils.normalize(".." + SEP + "foo"));
948         assertEquals("foo" + SEP, FilenameUtils.normalize("foo" + SEP + "bar" + SEP + ".."));
949         assertNull(FilenameUtils.normalize("foo" + SEP + ".." + SEP + ".." + SEP + "bar"));
950         assertEquals("bar", FilenameUtils.normalize("foo" + SEP + ".." + SEP + "bar"));
951         assertEquals(SEP + SEP + "server" + SEP + "bar", FilenameUtils.normalize(SEP + SEP + "server" + SEP + "foo" + SEP + ".." + SEP + "bar"));
952         assertNull(FilenameUtils.normalize(SEP + SEP + "server" + SEP + ".." + SEP + "bar"));
953         assertEquals(DRIVE_C + SEP + "bar", FilenameUtils.normalize(DRIVE_C + SEP + "foo" + SEP + ".." + SEP + "bar"));
954         assertNull(FilenameUtils.normalize(DRIVE_C + SEP + ".." + SEP + "bar"));
955         assertEquals("~" + SEP + "bar" + SEP, FilenameUtils.normalize("~" + SEP + "foo" + SEP + ".." + SEP + "bar" + SEP));
956         assertNull(FilenameUtils.normalize("~" + SEP + ".." + SEP + "bar"));
957 
958         assertEquals(SEP + SEP + "foo" + SEP + "bar", FilenameUtils.normalize("//foo//./bar"));
959         assertEquals(SEP + SEP + "foo" + SEP + "bar", FilenameUtils.normalize("\\\\foo\\\\.\\bar"));
960     }
961 
962     @Test
963     void testNormalizeNoEndSeparator() {
964         assertNull(FilenameUtils.normalizeNoEndSeparator(null));
965         assertNull(FilenameUtils.normalizeNoEndSeparator(":"));
966         assertNull(FilenameUtils.normalizeNoEndSeparator("1:\\a\\b\\c.txt"));
967         assertNull(FilenameUtils.normalizeNoEndSeparator("1:"));
968         assertNull(FilenameUtils.normalizeNoEndSeparator("1:a"));
969         assertNull(FilenameUtils.normalizeNoEndSeparator("\\\\\\a\\b\\c.txt"));
970         assertNull(FilenameUtils.normalizeNoEndSeparator("\\\\a"));
971 
972         assertEquals("a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalizeNoEndSeparator("a\\b/c.txt"));
973         assertEquals("" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalizeNoEndSeparator("\\a\\b/c.txt"));
974         assertEquals(DRIVE_C + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalizeNoEndSeparator("C:\\a\\b/c.txt"));
975         assertEquals("" + SEP + "" + SEP + "server" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalizeNoEndSeparator("\\\\server\\a\\b/c.txt"));
976         assertEquals("~" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalizeNoEndSeparator("~\\a\\b/c.txt"));
977         assertEquals("~user" + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalizeNoEndSeparator("~user\\a\\b/c.txt"));
978         assertEquals(DRIVE_C + SEP + "a" + SEP + "b" + SEP + "c.txt", FilenameUtils.normalizeNoEndSeparator("C:\\\\a\\\\b\\\\c.txt"));
979 
980         assertEquals("a" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("a/b/../c"));
981         assertEquals("c", FilenameUtils.normalizeNoEndSeparator("a/b/../../c"));
982         assertEquals("c", FilenameUtils.normalizeNoEndSeparator("a/b/../../c/"));
983         assertNull(FilenameUtils.normalizeNoEndSeparator("a/b/../../../c"));
984         assertEquals("a", FilenameUtils.normalizeNoEndSeparator("a/b/.."));
985         assertEquals("a", FilenameUtils.normalizeNoEndSeparator("a/b/../"));
986         assertEquals("", FilenameUtils.normalizeNoEndSeparator("a/b/../.."));
987         assertEquals("", FilenameUtils.normalizeNoEndSeparator("a/b/../../"));
988         assertNull(FilenameUtils.normalizeNoEndSeparator("a/b/../../.."));
989         assertEquals("a" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("a/b/../c/../d"));
990         assertEquals("a" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("a/b/../c/../d/"));
991         assertEquals("a" + SEP + "b" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("a/b//d"));
992         assertEquals("a" + SEP + "b", FilenameUtils.normalizeNoEndSeparator("a/b/././."));
993         assertEquals("a" + SEP + "b", FilenameUtils.normalizeNoEndSeparator("a/b/./././"));
994         assertEquals("a", FilenameUtils.normalizeNoEndSeparator("./a/"));
995         assertEquals("a", FilenameUtils.normalizeNoEndSeparator("./a"));
996         assertEquals("", FilenameUtils.normalizeNoEndSeparator("./"));
997         assertEquals("", FilenameUtils.normalizeNoEndSeparator("."));
998         assertNull(FilenameUtils.normalizeNoEndSeparator("../a"));
999         assertNull(FilenameUtils.normalizeNoEndSeparator(".."));
1000         assertEquals("", FilenameUtils.normalizeNoEndSeparator(""));
1001 
1002         assertEquals(SEP + "a", FilenameUtils.normalizeNoEndSeparator("/a"));
1003         assertEquals(SEP + "a", FilenameUtils.normalizeNoEndSeparator("/a/"));
1004         assertEquals(SEP + "a" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("/a/b/../c"));
1005         assertEquals(SEP + "c", FilenameUtils.normalizeNoEndSeparator("/a/b/../../c"));
1006         assertNull(FilenameUtils.normalizeNoEndSeparator("/a/b/../../../c"));
1007         assertEquals(SEP + "a", FilenameUtils.normalizeNoEndSeparator("/a/b/.."));
1008         assertEquals(SEP + "", FilenameUtils.normalizeNoEndSeparator("/a/b/../.."));
1009         assertNull(FilenameUtils.normalizeNoEndSeparator("/a/b/../../.."));
1010         assertEquals(SEP + "a" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("/a/b/../c/../d"));
1011         assertEquals(SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("/a/b//d"));
1012         assertEquals(SEP + "a" + SEP + "b", FilenameUtils.normalizeNoEndSeparator("/a/b/././."));
1013         assertEquals(SEP + "a", FilenameUtils.normalizeNoEndSeparator("/./a"));
1014         assertEquals(SEP + "", FilenameUtils.normalizeNoEndSeparator("/./"));
1015         assertEquals(SEP + "", FilenameUtils.normalizeNoEndSeparator("/."));
1016         assertNull(FilenameUtils.normalizeNoEndSeparator("/../a"));
1017         assertNull(FilenameUtils.normalizeNoEndSeparator("/.."));
1018         assertEquals(SEP + "", FilenameUtils.normalizeNoEndSeparator("/"));
1019 
1020         assertEquals("~" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("~/a"));
1021         assertEquals("~" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("~/a/"));
1022         assertEquals("~" + SEP + "a" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("~/a/b/../c"));
1023         assertEquals("~" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("~/a/b/../../c"));
1024         assertNull(FilenameUtils.normalizeNoEndSeparator("~/a/b/../../../c"));
1025         assertEquals("~" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("~/a/b/.."));
1026         assertEquals("~" + SEP + "", FilenameUtils.normalizeNoEndSeparator("~/a/b/../.."));
1027         assertNull(FilenameUtils.normalizeNoEndSeparator("~/a/b/../../.."));
1028         assertEquals("~" + SEP + "a" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("~/a/b/../c/../d"));
1029         assertEquals("~" + SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("~/a/b//d"));
1030         assertEquals("~" + SEP + "a" + SEP + "b", FilenameUtils.normalizeNoEndSeparator("~/a/b/././."));
1031         assertEquals("~" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("~/./a"));
1032         assertEquals("~" + SEP, FilenameUtils.normalizeNoEndSeparator("~/./"));
1033         assertEquals("~" + SEP, FilenameUtils.normalizeNoEndSeparator("~/."));
1034         assertNull(FilenameUtils.normalizeNoEndSeparator("~/../a"));
1035         assertNull(FilenameUtils.normalizeNoEndSeparator("~/.."));
1036         assertEquals("~" + SEP, FilenameUtils.normalizeNoEndSeparator("~/"));
1037         assertEquals("~" + SEP, FilenameUtils.normalizeNoEndSeparator("~"));
1038 
1039         assertEquals("~user" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("~user/a"));
1040         assertEquals("~user" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("~user/a/"));
1041         assertEquals("~user" + SEP + "a" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("~user/a/b/../c"));
1042         assertEquals("~user" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("~user/a/b/../../c"));
1043         assertNull(FilenameUtils.normalizeNoEndSeparator("~user/a/b/../../../c"));
1044         assertEquals("~user" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("~user/a/b/.."));
1045         assertEquals("~user" + SEP + "", FilenameUtils.normalizeNoEndSeparator("~user/a/b/../.."));
1046         assertNull(FilenameUtils.normalizeNoEndSeparator("~user/a/b/../../.."));
1047         assertEquals("~user" + SEP + "a" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("~user/a/b/../c/../d"));
1048         assertEquals("~user" + SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("~user/a/b//d"));
1049         assertEquals("~user" + SEP + "a" + SEP + "b", FilenameUtils.normalizeNoEndSeparator("~user/a/b/././."));
1050         assertEquals("~user" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("~user/./a"));
1051         assertEquals("~user" + SEP + "", FilenameUtils.normalizeNoEndSeparator("~user/./"));
1052         assertEquals("~user" + SEP + "", FilenameUtils.normalizeNoEndSeparator("~user/."));
1053         assertNull(FilenameUtils.normalizeNoEndSeparator("~user/../a"));
1054         assertNull(FilenameUtils.normalizeNoEndSeparator("~user/.."));
1055         assertEquals("~user" + SEP, FilenameUtils.normalizeNoEndSeparator("~user/"));
1056         assertEquals("~user" + SEP, FilenameUtils.normalizeNoEndSeparator("~user"));
1057 
1058         assertEquals(DRIVE_C + SEP + "a", FilenameUtils.normalizeNoEndSeparator("C:/a"));
1059         assertEquals(DRIVE_C + SEP + "a", FilenameUtils.normalizeNoEndSeparator("C:/a/"));
1060         assertEquals(DRIVE_C + SEP + "a" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("C:/a/b/../c"));
1061         assertEquals(DRIVE_C + SEP + "c", FilenameUtils.normalizeNoEndSeparator("C:/a/b/../../c"));
1062         assertNull(FilenameUtils.normalizeNoEndSeparator("C:/a/b/../../../c"));
1063         assertEquals(DRIVE_C + SEP + "a", FilenameUtils.normalizeNoEndSeparator("C:/a/b/.."));
1064         assertEquals(DRIVE_C + SEP + "", FilenameUtils.normalizeNoEndSeparator("C:/a/b/../.."));
1065         assertNull(FilenameUtils.normalizeNoEndSeparator("C:/a/b/../../.."));
1066         assertEquals(DRIVE_C + SEP + "a" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("C:/a/b/../c/../d"));
1067         assertEquals(DRIVE_C + SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("C:/a/b//d"));
1068         assertEquals(DRIVE_C + SEP + "a" + SEP + "b", FilenameUtils.normalizeNoEndSeparator("C:/a/b/././."));
1069         assertEquals(DRIVE_C + SEP + "a", FilenameUtils.normalizeNoEndSeparator("C:/./a"));
1070         assertEquals(DRIVE_C + SEP + "", FilenameUtils.normalizeNoEndSeparator("C:/./"));
1071         assertEquals(DRIVE_C + SEP + "", FilenameUtils.normalizeNoEndSeparator("C:/."));
1072         assertNull(FilenameUtils.normalizeNoEndSeparator("C:/../a"));
1073         assertNull(FilenameUtils.normalizeNoEndSeparator("C:/.."));
1074         assertEquals(DRIVE_C + SEP + "", FilenameUtils.normalizeNoEndSeparator("C:/"));
1075 
1076         assertEquals(DRIVE_C + "a", FilenameUtils.normalizeNoEndSeparator("C:a"));
1077         assertEquals(DRIVE_C + "a", FilenameUtils.normalizeNoEndSeparator("C:a/"));
1078         assertEquals(DRIVE_C + "a" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("C:a/b/../c"));
1079         assertEquals(DRIVE_C + "c", FilenameUtils.normalizeNoEndSeparator("C:a/b/../../c"));
1080         assertNull(FilenameUtils.normalizeNoEndSeparator("C:a/b/../../../c"));
1081         assertEquals(DRIVE_C + "a", FilenameUtils.normalizeNoEndSeparator("C:a/b/.."));
1082         assertEquals(DRIVE_C + "", FilenameUtils.normalizeNoEndSeparator("C:a/b/../.."));
1083         assertNull(FilenameUtils.normalizeNoEndSeparator("C:a/b/../../.."));
1084         assertEquals(DRIVE_C + "a" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("C:a/b/../c/../d"));
1085         assertEquals(DRIVE_C + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("C:a/b//d"));
1086         assertEquals(DRIVE_C + "a" + SEP + "b", FilenameUtils.normalizeNoEndSeparator("C:a/b/././."));
1087         assertEquals(DRIVE_C + "a", FilenameUtils.normalizeNoEndSeparator("C:./a"));
1088         assertEquals(DRIVE_C + "", FilenameUtils.normalizeNoEndSeparator("C:./"));
1089         assertEquals(DRIVE_C + "", FilenameUtils.normalizeNoEndSeparator("C:."));
1090         assertNull(FilenameUtils.normalizeNoEndSeparator("C:../a"));
1091         assertNull(FilenameUtils.normalizeNoEndSeparator("C:.."));
1092         assertEquals(DRIVE_C + "", FilenameUtils.normalizeNoEndSeparator(DRIVE_C));
1093 
1094         assertEquals(SEP + SEP + "server" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("//server/a"));
1095         assertEquals(SEP + SEP + "server" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("//server/a/"));
1096         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("//server/a/b/../c"));
1097         assertEquals(SEP + SEP + "server" + SEP + "c", FilenameUtils.normalizeNoEndSeparator("//server/a/b/../../c"));
1098         assertNull(FilenameUtils.normalizeNoEndSeparator("//server/a/b/../../../c"));
1099         assertEquals(SEP + SEP + "server" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("//server/a/b/.."));
1100         assertEquals(SEP + SEP + "server" + SEP + "", FilenameUtils.normalizeNoEndSeparator("//server/a/b/../.."));
1101         assertNull(FilenameUtils.normalizeNoEndSeparator("//server/a/b/../../.."));
1102         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("//server/a/b/../c/../d"));
1103         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP + "b" + SEP + "d", FilenameUtils.normalizeNoEndSeparator("//server/a/b//d"));
1104         assertEquals(SEP + SEP + "server" + SEP + "a" + SEP + "b", FilenameUtils.normalizeNoEndSeparator("//server/a/b/././."));
1105         assertEquals(SEP + SEP + "server" + SEP + "a", FilenameUtils.normalizeNoEndSeparator("//server/./a"));
1106         assertEquals(SEP + SEP + "server" + SEP + "", FilenameUtils.normalizeNoEndSeparator("//server/./"));
1107         assertEquals(SEP + SEP + "server" + SEP + "", FilenameUtils.normalizeNoEndSeparator("//server/."));
1108         assertNull(FilenameUtils.normalizeNoEndSeparator("//server/../a"));
1109         assertNull(FilenameUtils.normalizeNoEndSeparator("//server/.."));
1110         assertEquals(SEP + SEP + "server" + SEP + "", FilenameUtils.normalizeNoEndSeparator("//server/"));
1111     }
1112 
1113     @Test
1114     void testNormalizeNoEndSeparatorUnixWin() {
1115 
1116         // Normalize (Unix Separator)
1117         assertEquals("/a/c", FilenameUtils.normalizeNoEndSeparator("/a/b/../c/", true));
1118         assertEquals("/a/c", FilenameUtils.normalizeNoEndSeparator("\\a\\b\\..\\c\\", true));
1119 
1120         // Normalize (Windows Separator)
1121         assertEquals("\\a\\c", FilenameUtils.normalizeNoEndSeparator("/a/b/../c/", false));
1122         assertEquals("\\a\\c", FilenameUtils.normalizeNoEndSeparator("\\a\\b\\..\\c\\", false));
1123     }
1124 
1125     @Test
1126     void testNormalizeUnixWin() {
1127 
1128         // Normalize (Unix Separator)
1129         assertEquals("/a/c/", FilenameUtils.normalize("/a/b/../c/", true));
1130         assertEquals("/a/c/", FilenameUtils.normalize("\\a\\b\\..\\c\\", true));
1131 
1132         // Normalize (Windows Separator)
1133         assertEquals("\\a\\c\\", FilenameUtils.normalize("/a/b/../c/", false));
1134         assertEquals("\\a\\c\\", FilenameUtils.normalize("\\a\\b\\..\\c\\", false));
1135     }
1136 
1137     @Test
1138     void testRemoveExtension() {
1139         assertNull(FilenameUtils.removeExtension(null));
1140         assertEquals("file", FilenameUtils.removeExtension("file.ext"));
1141         assertEquals("README", FilenameUtils.removeExtension("README"));
1142         assertEquals("domain.dot", FilenameUtils.removeExtension("domain.dot.com"));
1143         assertEquals("image", FilenameUtils.removeExtension("image.jpeg"));
1144         assertEquals("a.b/c", FilenameUtils.removeExtension("a.b/c"));
1145         assertEquals("a.b/c", FilenameUtils.removeExtension("a.b/c.txt"));
1146         assertEquals("a/b/c", FilenameUtils.removeExtension("a/b/c"));
1147         assertEquals("a.b\\c", FilenameUtils.removeExtension("a.b\\c"));
1148         assertEquals("a.b\\c", FilenameUtils.removeExtension("a.b\\c.txt"));
1149         assertEquals("a\\b\\c", FilenameUtils.removeExtension("a\\b\\c"));
1150         assertEquals("C:\\temp\\foo.bar\\README", FilenameUtils.removeExtension("C:\\temp\\foo.bar\\README"));
1151         assertEquals("../filename", FilenameUtils.removeExtension("../filename.ext"));
1152     }
1153 
1154     @Test
1155     void testSeparatorsToSystem() {
1156         if (WINDOWS) {
1157             assertNull(FilenameUtils.separatorsToSystem(null));
1158             assertEquals("\\a\\b\\c", FilenameUtils.separatorsToSystem("\\a\\b\\c"));
1159             assertEquals("\\a\\b\\c.txt", FilenameUtils.separatorsToSystem("\\a\\b\\c.txt"));
1160             assertEquals("\\a\\b\\c", FilenameUtils.separatorsToSystem("\\a\\b/c"));
1161             assertEquals("\\a\\b\\c", FilenameUtils.separatorsToSystem("/a/b/c"));
1162             assertEquals("D:\\a\\b\\c", FilenameUtils.separatorsToSystem("D:/a/b/c"));
1163         } else {
1164             assertNull(FilenameUtils.separatorsToSystem(null));
1165             assertEquals("/a/b/c", FilenameUtils.separatorsToSystem("/a/b/c"));
1166             assertEquals("/a/b/c.txt", FilenameUtils.separatorsToSystem("/a/b/c.txt"));
1167             assertEquals("/a/b/c", FilenameUtils.separatorsToSystem("/a/b\\c"));
1168             assertEquals("/a/b/c", FilenameUtils.separatorsToSystem("\\a\\b\\c"));
1169             assertEquals("D:/a/b/c", FilenameUtils.separatorsToSystem("D:\\a\\b\\c"));
1170         }
1171     }
1172 
1173     @Test
1174     void testSeparatorsToUnix() {
1175         assertNull(FilenameUtils.separatorsToUnix(null));
1176         assertEquals("/a/b/c", FilenameUtils.separatorsToUnix("/a/b/c"));
1177         assertEquals("/a/b/c.txt", FilenameUtils.separatorsToUnix("/a/b/c.txt"));
1178         assertEquals("/a/b/c", FilenameUtils.separatorsToUnix("/a/b\\c"));
1179         assertEquals("/a/b/c", FilenameUtils.separatorsToUnix("\\a\\b\\c"));
1180         assertEquals("D:/a/b/c", FilenameUtils.separatorsToUnix("D:\\a\\b\\c"));
1181     }
1182 
1183     @Test
1184     void testSeparatorsToWindows() {
1185         assertNull(FilenameUtils.separatorsToWindows(null));
1186         assertEquals("\\a\\b\\c", FilenameUtils.separatorsToWindows("\\a\\b\\c"));
1187         assertEquals("\\a\\b\\c.txt", FilenameUtils.separatorsToWindows("\\a\\b\\c.txt"));
1188         assertEquals("\\a\\b\\c", FilenameUtils.separatorsToWindows("\\a\\b/c"));
1189         assertEquals("\\a\\b\\c", FilenameUtils.separatorsToWindows("/a/b/c"));
1190         assertEquals("D:\\a\\b\\c", FilenameUtils.separatorsToWindows("D:/a/b/c"));
1191     }
1192 }