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