diff options
author | Sven Gothel <[email protected]> | 2015-10-03 11:44:02 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-10-03 11:44:02 +0200 |
commit | 026875dd5256051d4e3504f1d9b01f7ce2bb70ff (patch) | |
tree | d7d1bd386c870787ffcf737ca6baaeaa6f73ef11 /src/java/com | |
parent | 48cef027ec727d3e03b78f577208d1ce10b705d1 (diff) |
Bug 1243 - Fix IOUtil.cleanPathString(..) special case ; Allow IOUtil and Uri to handle relative path
Fix IOUtil.cleanPathString(..) special case:
Special case '/a/./../b' -> '/b'
requires to resolve './' before '../'.
Allow IOUtil and Uri to handle relative path:
- IOUtil.getParentOf(..)
- IOUtil.cleanPathString(..)
Handle cases:
'a/./../b' -> 'b'
'.././b' -> '../b'
- Uri: Handle null scheme
Diffstat (limited to 'src/java/com')
-rw-r--r-- | src/java/com/jogamp/common/ExceptionUtils.java | 32 | ||||
-rw-r--r-- | src/java/com/jogamp/common/net/Uri.java | 9 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/IOUtil.java | 44 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/JarUtil.java | 6 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/SourcedInterruptedException.java | 6 |
5 files changed, 67 insertions, 30 deletions
diff --git a/src/java/com/jogamp/common/ExceptionUtils.java b/src/java/com/jogamp/common/ExceptionUtils.java index 108b466..295a59c 100644 --- a/src/java/com/jogamp/common/ExceptionUtils.java +++ b/src/java/com/jogamp/common/ExceptionUtils.java @@ -65,26 +65,26 @@ public class ExceptionUtils { void printStackTrace(final PrintStream s); } - public static int dumpCause(final PrintStream s, final String causeStr, Throwable cause, int causeDepth) { - for( ; null != cause; cause = cause.getCause() ) { + public static int dumpCause(final PrintStream s, final String causeStr, Throwable cause, int causeIdx, final int causeDepth, final int stackDepth) { + for(int i=0; null != cause && ( -1 == causeDepth || i < causeDepth ); cause = cause.getCause(), i++) { if( cause instanceof CustomStackTrace ) { - ((CustomStackTrace)cause).dumpCauseStack(s, causeStr, causeDepth); + ((CustomStackTrace)cause).dumpCauseStack(s, causeStr, causeIdx); } else { - s.println(causeStr+"["+causeDepth+"] by "+cause.getClass().getSimpleName()+": "+cause.getMessage()+" on thread "+Thread.currentThread().getName()); - dumpStack(s, cause.getStackTrace(), 0, -1); + s.println(causeStr+"["+causeIdx+"] by "+cause.getClass().getSimpleName()+": "+cause.getMessage()+" on thread "+Thread.currentThread().getName()); + dumpStack(s, cause.getStackTrace(), 0, stackDepth); } - causeDepth++; + causeIdx++; } - return causeDepth; + return causeIdx; } - public static void printStackTrace(final PrintStream s, final Throwable t) { + public static void printStackTrace(final PrintStream s, final Throwable t, final int causeDepth, final int stackDepth) { if( t instanceof CustomStackTrace ) { ((CustomStackTrace)t).printStackTrace(s); } else { s.println(t.getClass().getSimpleName()+": "+t.getMessage()+" on thread "+Thread.currentThread().getName()); - dumpStack(s, t.getStackTrace(), 0, -1); - dumpCause(s, "Caused", t.getCause(), 1); + dumpStack(s, t.getStackTrace(), 0, stackDepth); + dumpCause(s, "Caused", t.getCause(), 1, causeDepth, stackDepth); } } @@ -96,7 +96,17 @@ public class ExceptionUtils { * </p> */ public static void dumpThrowable(final String additionalDescr, final Throwable t) { + dumpThrowable(additionalDescr, t, -1, -1); + } + /** + * Dumps a {@link Throwable} in a decorating message including the current thread name, + * and its {@link #dumpStack(PrintStream, StackTraceElement[], int, int) stack trace}. + * <p> + * Implementation will iterate through all {@link Throwable#getCause() causes}. + * </p> + */ + public static void dumpThrowable(final String additionalDescr, final Throwable t, final int causeDepth, final int stackDepth) { System.err.print("Caught "+additionalDescr+" "); - printStackTrace(System.err, t); + printStackTrace(System.err, t, causeDepth, stackDepth); } } diff --git a/src/java/com/jogamp/common/net/Uri.java b/src/java/com/jogamp/common/net/Uri.java index 6bafba2..a6fd4fe 100644 --- a/src/java/com/jogamp/common/net/Uri.java +++ b/src/java/com/jogamp/common/net/Uri.java @@ -1232,7 +1232,12 @@ public class Uri { /** Returns true, if this instance is a {@code file} {@code scheme}, otherwise false. */ public final boolean isFileScheme() { - return FILE_SCHEME.equals( scheme.get() ); + return null != scheme && FILE_SCHEME.equals( scheme.get() ); + } + + /** Returns true, if this instance is a {@code jar} {@code scheme}, otherwise false. */ + public final boolean isJarScheme() { + return null != scheme && JAR_SCHEME.equals( scheme.get() ); } /** @@ -1386,7 +1391,7 @@ public class Uri { if( !emptyString(schemeSpecificPart) ) { final StringBuilder sb = new StringBuilder(); - if( scheme.equals(JAR_SCHEME) ) { + if( isJarScheme() ) { final int idx = schemeSpecificPart.lastIndexOf(JAR_SCHEME_SEPARATOR); if (0 > idx) { throw new URISyntaxException(input.get(), "missing jar separator"); diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java index 7853555..653520d 100644 --- a/src/java/com/jogamp/common/util/IOUtil.java +++ b/src/java/com/jogamp/common/util/IOUtil.java @@ -620,7 +620,7 @@ public class IOUtil { } /** - * @param path assuming a slashified path beginning with "/" as it's root directory, either denotes a file or directory. + * @param path assuming a slashified path, either denotes a file or directory, either relative or absolute. * @return parent of path * @throws URISyntaxException if path is empty or has no parent directory available */ @@ -632,11 +632,11 @@ public class IOUtil { final int e = path.lastIndexOf("/"); if( e < 0 ) { - throw new URISyntaxException(path, "path contains no '/'"); + throw new URISyntaxException(path, "path contains no '/': <"+path+">"); } if( e == 0 ) { // path is root directory - throw new URISyntaxException(path, "path has no parents"); + throw new URISyntaxException(path, "path has no parents: <"+path+">"); } if( e < pl - 1 ) { // path is file, return it's parent directory @@ -646,23 +646,45 @@ public class IOUtil { // path is a directory .. final int p = path.lastIndexOf("/", e-1); if( p >= j) { + // parent itself has '/' - post '!' or no '!' at all return path.substring(0, p+1); + } else { + // parent itself has no '/' + final String parent = path.substring(j, e); + if( parent.equals("..") ) { + throw new URISyntaxException(path, "parent is unresolved: <"+path+">"); + } else { + // parent is '!' or empty (relative path) + return path.substring(0, j); + } } - throw new URISyntaxException(path, "parent of path contains no '/'"); } /** - * @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. + * @param path assuming a slashified path, either denoting a file or directory, either relative or absolute. + * @return clean path string where {@code ./} and {@code ../} is resolved, + * while keeping a starting {@code ../} at the beginning of a relative path. * @throws URISyntaxException if path is empty or has no parent directory available while resolving <code>../</code> */ public static String cleanPathString(String path) throws URISyntaxException { - int idx; - while ( ( idx = path.indexOf("../") ) >= 0 ) { - path = getParentOf(path.substring(0, idx)) + path.substring(idx+3); + // Resolve './' before '../' to handle case 'parent/./../a.txt' properly. + int idx = path.length() - 1; + while ( idx >= 1 && ( idx = path.lastIndexOf("./", idx) ) >= 0 ) { + if( 0 < idx && path.charAt(idx-1) == '.' ) { + idx-=2; // skip '../' -> idx upfront + } else { + path = path.substring(0, idx) + path.substring(idx+2); + idx--; // idx upfront + } } - while ( ( idx = path.indexOf("./") ) >= 0 ) { - path = path.substring(0, idx) + path.substring(idx+2); + idx = 0; + while ( ( idx = path.indexOf("../", idx) ) >= 0 ) { + if( 0 == idx ) { + idx += 3; // skip starting '../' + } else { + path = getParentOf(path.substring(0, idx)) + path.substring(idx+3); + idx = 0; + } } return path; } diff --git a/src/java/com/jogamp/common/util/JarUtil.java b/src/java/com/jogamp/common/util/JarUtil.java index 745dd12..2580714 100644 --- a/src/java/com/jogamp/common/util/JarUtil.java +++ b/src/java/com/jogamp/common/util/JarUtil.java @@ -163,7 +163,7 @@ public class JarUtil { } } } - if( !uri.scheme.equals( Uri.JAR_SCHEME ) ) { + if( !uri.isJarScheme() ) { throw new IllegalArgumentException("Uri is not using scheme "+Uri.JAR_SCHEME+": <"+uri+">"); } if(DEBUG) { @@ -190,7 +190,7 @@ public class JarUtil { if(null == classJarUri) { throw new IllegalArgumentException("Uri is null"); } - if( !classJarUri.scheme.equals(Uri.JAR_SCHEME) ) { + if( !classJarUri.isJarScheme() ) { throw new IllegalArgumentException("Uri is not using scheme "+Uri.JAR_SCHEME+": <"+classJarUri+">"); } Uri.Encoded ssp = classJarUri.schemeSpecificPart; @@ -262,7 +262,7 @@ public class JarUtil { if(null == classJarUri) { throw new IllegalArgumentException("Uri is null"); } - if( !classJarUri.scheme.equals(Uri.JAR_SCHEME) ) { + if( !classJarUri.isJarScheme() ) { throw new IllegalArgumentException("Uri is not a using scheme "+Uri.JAR_SCHEME+": <"+classJarUri+">"); } final Uri.Encoded uriSSP = classJarUri.schemeSpecificPart; diff --git a/src/java/com/jogamp/common/util/SourcedInterruptedException.java b/src/java/com/jogamp/common/util/SourcedInterruptedException.java index 49dcd86..2483d5b 100644 --- a/src/java/com/jogamp/common/util/SourcedInterruptedException.java +++ b/src/java/com/jogamp/common/util/SourcedInterruptedException.java @@ -150,7 +150,7 @@ public class SourcedInterruptedException extends InterruptedException implements s.println(s0+" by "+getClass().getSimpleName()+": "+getMessage()+" on thread "+Thread.currentThread().getName()); ExceptionUtils.dumpStack(s, getStackTrace(), 0, -1); if( null != interruptSource ) { - ExceptionUtils.dumpCause(s, s0, interruptSource, 1); + ExceptionUtils.dumpCause(s, s0, interruptSource, 1, -1, -1); } } @@ -158,9 +158,9 @@ public class SourcedInterruptedException extends InterruptedException implements public final void printStackTrace(final PrintStream s) { s.println(getClass().getSimpleName()+": "+getMessage()+" on thread "+Thread.currentThread().getName()); ExceptionUtils.dumpStack(s, getStackTrace(), 0, -1); - final int causeDepth = ExceptionUtils.dumpCause(s, "Caused", getCause(), 1); + final int causeDepth = ExceptionUtils.dumpCause(s, "Caused", getCause(), 1, -1, -1); if( null != interruptSource ) { - ExceptionUtils.dumpCause(s, "InterruptSource", interruptSource, causeDepth); + ExceptionUtils.dumpCause(s, "InterruptSource", interruptSource, causeDepth, -1, -1); } } } |