Skip to content

Commit d7ab0e8

Browse files
author
Stephen Colebourne
committed
Handle encodings in URL to File conversion
bug 32575, from Jason Madden git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/io/trunk@154517 13f79535-47bb-0310-9956-ffa450edef68
1 parent a9aa579 commit d7ab0e8

2 files changed

Lines changed: 54 additions & 8 deletions

File tree

src/java/org/apache/commons/io/FileUtils.java

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2001-2004 The Apache Software Foundation.
2+
* Copyright 2001-2005 The Apache Software Foundation.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -64,7 +64,8 @@
6464
* @author <a href="mailto:jefft@apache.org">Jeff Turner</a>
6565
* @author Matthew Hawthorne
6666
* @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
67-
* @version $Id: FileUtils.java,v 1.39 2004/10/29 21:34:56 bayard Exp $
67+
* @author Stephen Colebourne
68+
* @version $Id$
6869
*/
6970
public class FileUtils {
7071

@@ -306,17 +307,29 @@ public static boolean contentEquals(File file1, File file2)
306307
//-----------------------------------------------------------------------
307308
/**
308309
* Convert from a <code>URL</code> to a <code>File</code>.
310+
* <p>
311+
* From version 1.1 this method will decode the URL.
312+
* Syntax such as <code>file:///my%20docs/file.txt</code> will be
313+
* correctly decoded to <code>/my docs/file.txt</code>.
309314
*
310-
* @param url the file URL to convert
315+
* @param url the file URL to convert, null returns null
311316
* @return the equivalent <code>File</code> object, or <code>null</code>
312317
* if the URL's protocol is not <code>file</code>
318+
* @throws IllegalArgumentException if the file is incorrectly encoded
313319
*/
314320
public static File toFile(URL url) {
315-
if (!url.getProtocol().equals("file")) {
321+
if (url == null || !url.getProtocol().equals("file")) {
316322
return null;
317323
} else {
318-
String filename =
319-
url.getFile().replace('/', File.separatorChar);
324+
String filename = url.getFile().replace('/', File.separatorChar);
325+
int pos =0;
326+
while ((pos = filename.indexOf('%', pos)) >= 0) {
327+
if (pos + 2 < filename.length()) {
328+
String hexStr = filename.substring(pos + 1, pos + 3);
329+
char ch = (char) Integer.parseInt(hexStr, 16);
330+
filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
331+
}
332+
}
320333
return new File(filename);
321334
}
322335
}
@@ -328,10 +341,16 @@ public static File toFile(URL url) {
328341
* If the input is null, an empty array is returned.
329342
* If the input contains null, the output array contains null at the same
330343
* index.
344+
* <p>
345+
* From version 1.1 this method will decode the URL.
346+
* Syntax such as <code>file:///my%20docs/file.txt</code> will be
347+
* correctly decoded to <code>/my docs/file.txt</code>.
331348
*
332349
* @param urls the file URLs to convert, null returns empty array
333350
* @return a non-null array of Files matching the input, with a null item
334351
* if there was a null at that index in the input array
352+
* @throws IllegalArgumentException if any file is not a URL file
353+
* @throws IllegalArgumentException if any file is incorrectly encoded
335354
*/
336355
public static File[] toFiles(URL[] urls) {
337356
if (urls == null || urls.length == 0) {

src/test/org/apache/commons/io/FileUtilsTestCase.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 1999-2004 The Apache Software Foundation.
2+
* Copyright 1999-2005 The Apache Software Foundation.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,7 +34,8 @@
3434
*
3535
* @author Peter Donald
3636
* @author Matthew Hawthorne
37-
* @version $Id: FileUtilsTestCase.java,v 1.24 2004/07/24 09:58:40 scolebourne Exp $
37+
* @author Stephen Colebourne
38+
* @version $Id$
3839
* @see FileUtils
3940
*/
4041
public class FileUtilsTestCase extends FileBasedTestCase {
@@ -108,6 +109,32 @@ public void testWaitFor() {
108109
FileUtils.waitFor(new File(""), 2);
109110
}
110111

112+
//-----------------------------------------------------------------------
113+
public void testToFile1() throws Exception {
114+
URL url = new URL("file", null, "a/b/c/file.txt");
115+
File file = FileUtils.toFile(url);
116+
assertEquals(true, file.toString().indexOf("file.txt") >= 0);
117+
}
118+
119+
public void testToFile2() throws Exception {
120+
URL url = new URL("file", null, "a/b/c/file%20n%61me.tx%74");
121+
File file = FileUtils.toFile(url);
122+
assertEquals(true, file.toString().indexOf("file name.txt") >= 0);
123+
}
124+
125+
public void testToFile3() throws Exception {
126+
assertEquals(null, FileUtils.toFile((URL) null));
127+
assertEquals(null, FileUtils.toFile(new URL("http://jakarta.apache.org")));
128+
}
129+
130+
public void testToFile4() throws Exception {
131+
URL url = new URL("file", null, "a/b/c/file%2Xn%61me.txt");
132+
try {
133+
FileUtils.toFile(url);
134+
fail();
135+
} catch (IllegalArgumentException ex) {}
136+
}
137+
111138
// toFiles
112139

113140
public void testToFiles1() throws Exception {

0 commit comments

Comments
 (0)