diff options
author | Sven Gothel <[email protected]> | 2012-04-02 17:23:31 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2012-04-02 17:23:31 +0200 |
commit | 924e2eefd99b2c93d50c19db146253c85e04fe6d (patch) | |
tree | 1cec506c776754bd2cfcc03f5691667a8f35d835 /src | |
parent | 28814ae3946cf13619b70ddaf08c564f88252519 (diff) |
Fix IOUtil: Handle all '../' and './' cases by reducing the path.
Diffstat (limited to 'src')
6 files changed, 79 insertions, 32 deletions
diff --git a/src/java/com/jogamp/common/net/AssetURLContext.java b/src/java/com/jogamp/common/net/AssetURLContext.java index 00c7df7..411d986 100644 --- a/src/java/com/jogamp/common/net/AssetURLContext.java +++ b/src/java/com/jogamp/common/net/AssetURLContext.java @@ -8,8 +8,6 @@ import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; -import jogamp.common.Debug; - import com.jogamp.common.os.AndroidVersion; import com.jogamp.common.util.IOUtil; @@ -17,7 +15,7 @@ import com.jogamp.common.util.IOUtil; * See {@link PiggybackURLConnection} for description and examples. */ public abstract class AssetURLContext implements PiggybackURLContext { - private static final boolean DEBUG = Debug.isPropertyDefined("jogamp.debug.IOUtil", true); + private static final boolean DEBUG = IOUtil.DEBUG; /** The <i>asset URL</i> protocol name <code>asset</code> */ public static final String asset_protocol = "asset"; @@ -154,13 +152,14 @@ public abstract class AssetURLContext implements PiggybackURLContext { if(DEBUG) { System.err.println("AssetURLContext.resolve: <"+path+">"); } + path = IOUtil.cleanPathString(path); try { // lookup as valid sub-protocol url = new URL(path); conn = open(url); type = null != conn ? 1 : -1; - } catch(MalformedURLException e1) { if(DEBUG) { System.err.println("ERR: "+e1.getMessage()); } } + } catch(MalformedURLException e1) { if(DEBUG) { System.err.println("ERR(0): "+e1.getMessage()); } } if(null == conn && null != cl) { // lookup via ClassLoader .. cleanup leading '/' @@ -185,7 +184,7 @@ public abstract class AssetURLContext implements PiggybackURLContext { conn = open(url); type = null != conn ? 3 : -1; } - } catch (Throwable e) { if(DEBUG) { System.err.println("ERR: "+e.getMessage()); } } + } catch (Throwable e) { if(DEBUG) { System.err.println("ERR(1): "+e.getMessage()); } } } if(DEBUG) { diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java index 891453e..8fa4373 100644 --- a/src/java/com/jogamp/common/util/IOUtil.java +++ b/src/java/com/jogamp/common/util/IOUtil.java @@ -54,7 +54,7 @@ import com.jogamp.common.os.MachineDescription; import com.jogamp.common.os.Platform; public class IOUtil { - private static final boolean DEBUG = Debug.isPropertyDefined("jogamp.debug.IOUtil", true); + public static final boolean DEBUG = Debug.debug("IOUtil"); /** Std. temporary directory property key <code>java.io.tmpdir</code> */ public static final String java_io_tmpdir_propkey = "java.io.tmpdir"; @@ -208,15 +208,27 @@ public class IOUtil { * */ - public static String slashify(String path, boolean startWithSlash, boolean endWithSlash) { - String p = path.replace('\\', '/'); // unify file seperator + /** + * + * @param path + * @param startWithSlash + * @param endWithSlash + * @return + * @throws RuntimeException if final path is empty or has no parent directory available while resolving <code>../</code> + */ + public static String slashify(String path, boolean startWithSlash, boolean endWithSlash) throws RuntimeException { + String p = path.replace('\\', '/'); // unify file seperator if (startWithSlash && !p.startsWith("/")) { p = "/" + p; } if (endWithSlash && !p.endsWith("/")) { p = p + "/"; } - return p; + try { + return cleanPathString(p); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } } /** Using the proper advertised conversion via File -> URI -> URL */ @@ -322,7 +334,9 @@ public class IOUtil { /** * Locating a resource using {@link #getResource(String, ClassLoader)}: * <ul> - * <li><i>relative</i>: <code>context</code>'s package name-path plus <code>resourcePath</code> via <code>context</code>'s ClassLoader. This allows locations relative to JAR- and other URLs. </li> + * <li><i>relative</i>: <code>context</code>'s package name-path plus <code>resourcePath</code> via <code>context</code>'s ClassLoader. + * This allows locations relative to JAR- and other URLs. + * The <code>resourcePath</code> may start with <code>../</code> to navigate to parent folder.</li> * <li><i>absolute</i>: <code>context</code>'s ClassLoader and the <code>resourcePath</code> as is (filesystem)</li> * </ul> * @@ -337,16 +351,15 @@ public class IOUtil { public static URLConnection getResource(Class<?> context, String resourcePath) { if(null == resourcePath) { return null; - } + } ClassLoader contextCL = (null!=context)?context.getClassLoader():IOUtil.class.getClassLoader(); URLConnection conn = null; if(null != context) { - // scoping the path within the class's package - String className = context.getName().replace('.', '/'); - int lastSlash = className.lastIndexOf('/'); + // scoping the path within the class's package + final String className = context.getName().replace('.', '/'); + final int lastSlash = className.lastIndexOf('/'); if (lastSlash >= 0) { - String tmpPath = className.substring(0, lastSlash + 1) + resourcePath; - conn = getResource(tmpPath, contextCL); + conn = getResource(className.substring(0, lastSlash + 1) + resourcePath, contextCL); } if(DEBUG) { System.err.println("IOUtil: found <"+resourcePath+"> within class package: "+(null!=conn)); @@ -416,10 +429,6 @@ public class IOUtil { } if (baseLocation != null) { - while (relativeFile.startsWith("../")) { - baseLocation = baseLocation.getParentFile(); - relativeFile = relativeFile.substring(3); - } final File file = new File(baseLocation, relativeFile); // Handle things on Windows return slashify(file.getPath(), false, false); @@ -430,7 +439,7 @@ public class IOUtil { /** * @param path assuming a slashified path beginning with "/" as it's root directory, either denotes a file or directory. * @return parent of path - * @throws MalformedURLException if path is empty or has parent directory available + * @throws MalformedURLException if path is empty or has parent no directory available */ public static String getParentOf(String path) throws MalformedURLException { final int pl = null!=path ? path.length() : 0; @@ -460,6 +469,22 @@ public class IOUtil { } /** + * @param path assuming a slashified path beginning with "/" as it's root directory, either denotes a file or directory. + * @return clean path string where <code>../</code> and <code>./</code> is resolved. + * @throws MalformedURLException if path is empty or has no parent directory available while resolving <code>../</code> + */ + public static String cleanPathString(String path) throws MalformedURLException { + int idx; + while ( ( idx = path.indexOf("../") ) >= 0 ) { + path = getParentOf(path.substring(0, idx)) + path.substring(idx+3); + } + while ( ( idx = path.indexOf("./") ) >= 0 ) { + path = path.substring(0, idx) + path.substring(idx+2); + } + return path; + } + + /** * Generates a path for the 'relativeFile' relative to the 'baseLocation', * hence the result is a absolute location. * @@ -477,10 +502,6 @@ public class IOUtil { if(!path.endsWith("/")) { path = getParentOf(path); } - while (relativeFile.startsWith("../")) { - path = getParentOf(path); - relativeFile = relativeFile.substring(3); - } return compose(scheme, auth, path, relativeFile, query, fragment); } @@ -508,7 +529,7 @@ public class IOUtil { sb.append("#"); sb.append(fragment); } - return new URL(sb.toString()); + return new URL(cleanPathString(sb.toString())); } /** diff --git a/src/junit/com/jogamp/common/net/AssetURLConnectionBase.java b/src/junit/com/jogamp/common/net/AssetURLConnectionBase.java index 80f9bd4..cb3fe14 100644 --- a/src/junit/com/jogamp/common/net/AssetURLConnectionBase.java +++ b/src/junit/com/jogamp/common/net/AssetURLConnectionBase.java @@ -31,6 +31,10 @@ public abstract class AssetURLConnectionBase extends JunitTracer { protected static final String test_asset_test3a_url = "asset:com/jogamp/common/net/data/RelativeData.txt"; protected static final String test_asset_test3b_url = "asset:/com/jogamp/common/net/data/RelativeData.txt"; protected static final String test_asset_test3_entry = "com/jogamp/common/net/data/RelativeData.txt"; + protected static final String test_asset_test4_rel = "../data2/RelativeData2.txt"; + protected static final String test_asset_test4a_url = "asset:com/jogamp/common/net/data2/RelativeData2.txt"; + protected static final String test_asset_test4b_url = "asset:/com/jogamp/common/net/data2/RelativeData2.txt"; + protected static final String test_asset_test4_entry = "com/jogamp/common/net/data2/RelativeData2.txt"; protected static void testAssetConnection(URLConnection c, String entry_name) throws IOException { Assert.assertNotNull(c); diff --git a/src/junit/com/jogamp/common/net/AssetURLConnectionRegisteredTest.java b/src/junit/com/jogamp/common/net/AssetURLConnectionRegisteredTest.java index 7b8d1a4..edf1592 100644 --- a/src/junit/com/jogamp/common/net/AssetURLConnectionRegisteredTest.java +++ b/src/junit/com/jogamp/common/net/AssetURLConnectionRegisteredTest.java @@ -46,6 +46,11 @@ public class AssetURLConnectionRegisteredTest extends AssetURLConnectionBase { Assert.assertNotNull(url1); Assert.assertEquals(test_asset_test3a_url, url1.toExternalForm()); testAssetConnection(url1.openConnection(), test_asset_test3_entry); + + final URL url2 = IOUtil.getRelativeOf(urlConn0.getURL(), test_asset_test4_rel); + Assert.assertNotNull(url1); + Assert.assertEquals(test_asset_test4a_url, url2.toExternalForm()); + testAssetConnection(url2.openConnection(), test_asset_test4_entry); } @Test @@ -59,6 +64,11 @@ public class AssetURLConnectionRegisteredTest extends AssetURLConnectionBase { Assert.assertNotNull(url1); Assert.assertEquals(test_asset_test3b_url, url1.toExternalForm()); testAssetConnection(url1.openConnection(), test_asset_test3_entry); + + final URL url2 = IOUtil.getRelativeOf(urlConn0.getURL(), test_asset_test4_rel); + Assert.assertNotNull(url1); + Assert.assertEquals(test_asset_test4b_url, url2.toExternalForm()); + testAssetConnection(url2.openConnection(), test_asset_test4_entry); } URLConnection createAssetURLConnection(String path) throws IOException { diff --git a/src/junit/com/jogamp/common/net/AssetURLConnectionUnregisteredTest.java b/src/junit/com/jogamp/common/net/AssetURLConnectionUnregisteredTest.java index 6db8c17..cf26da4 100644 --- a/src/junit/com/jogamp/common/net/AssetURLConnectionUnregisteredTest.java +++ b/src/junit/com/jogamp/common/net/AssetURLConnectionUnregisteredTest.java @@ -39,6 +39,10 @@ public class AssetURLConnectionUnregisteredTest extends AssetURLConnectionBase { final URL url1 = IOUtil.getRelativeOf(urlConn0.getURL(), test_asset_test3_rel); Assert.assertNotNull(url1); // JARFile URL .. testAssetConnection(url1.openConnection(), test_asset_test3_entry); + + final URL url2 = IOUtil.getRelativeOf(urlConn0.getURL(), test_asset_test4_rel); + Assert.assertNotNull(url1); + testAssetConnection(url2.openConnection(), test_asset_test4_entry); } protected static URLConnection createAssetURLConnection(String path, ClassLoader cl) throws IOException { diff --git a/src/junit/com/jogamp/common/net/URLCompositionTest.java b/src/junit/com/jogamp/common/net/URLCompositionTest.java index fb6d298..36b38ab 100644 --- a/src/junit/com/jogamp/common/net/URLCompositionTest.java +++ b/src/junit/com/jogamp/common/net/URLCompositionTest.java @@ -33,11 +33,19 @@ public class URLCompositionTest extends JunitTracer { testURLCompositioning(new URL("jar:file:/web1/file1.jar!/rootDir/file1.txt")); testURLCompositioning(new URL("asset:gluegen-test/info.txt")); testURLCompositioning(new URL("asset:/gluegen-test/info.txt")); - testURLCompositioning(new URL("asset:jar:file:/web1/file1.jar!/rootDir/file1.txt")); testURLCompositioning(new URL("http://domain.com:1234/web1/index.html?lala=23&lili=24#anchor")); + + final URL file1URL = new URL("asset:jar:file:/web1/file1.jar!/rootDir/file1.txt"); + testURLCompositioning(file1URL); + testURLCompositioning(file1URL, new URL("asset:jar:file:/web1/file1.jar!/rootDir/./file1.txt")); + testURLCompositioning(file1URL, new URL("asset:jar:file:/web1/file1.jar!/rootDir/dummyParent/../file1.txt")); + } + + static void testURLCompositioning(URL u) throws MalformedURLException { + testURLCompositioning(u, u); } - static void testURLCompositioning(URL u) throws MalformedURLException { + static void testURLCompositioning(URL refURL, URL u) throws MalformedURLException { final String scheme = u.getProtocol(); final String auth = u.getAuthority(); String path = u.getPath(); @@ -47,12 +55,13 @@ public class URLCompositionTest extends JunitTracer { System.err.println("scheme <"+scheme+">, auth <"+auth+">, path <"+path+">, query <"+query+">, fragment <"+fragment+">"); URL u2 = IOUtil.compose(scheme, auth, path, null, query, fragment); - System.err.println("URL-equals: "+u.equals(u2)); - System.err.println("URL-same : "+u.sameFile(u2)); + System.err.println("URL-equals: "+refURL.equals(u2)); + System.err.println("URL-same : "+refURL.sameFile(u2)); + System.err.println("URL-ref : <"+refURL+">"); System.err.println("URL-orig : <"+u+">"); System.err.println("URL-comp : <"+u2+">"); - Assert.assertEquals(u, u2); - Assert.assertTrue(u.sameFile(u2)); + Assert.assertEquals(refURL, u2); + Assert.assertTrue(refURL.sameFile(u2)); } public static void main(String args[]) throws IOException { |