donaldp 2002/10/30 16:27:53
Modified: loader/src/java/org/apache/excalibur/loader/builder
DefaultLoaderResolver.java
Log:
Resolve base directory before trying to use it in the patterns
Revision Changes Path
1.2 +163 -3
jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/builder/DefaultLoaderResolver.java
Index: DefaultLoaderResolver.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/builder/DefaultLoaderResolver.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DefaultLoaderResolver.java 30 Oct 2002 22:58:50 -0000 1.1
+++ DefaultLoaderResolver.java 31 Oct 2002 00:27:53 -0000 1.2
@@ -73,8 +73,9 @@
{
//woefully inefficient .. but then again - no need
//for efficency here
- final String[] newIncludes = prefixPatterns( baseDirectory, includes );
- final String[] newExcludes = prefixPatterns( baseDirectory, excludes );
+ final String newBaseDirectory = normalize( baseDirectory );
+ final String[] newIncludes = prefixPatterns( newBaseDirectory, includes );
+ final String[] newExcludes = prefixPatterns( newBaseDirectory, excludes );
final PathMatcher matcher = new PathMatcher( newIncludes, newExcludes );
final ArrayList urls = new ArrayList();
@@ -149,5 +150,164 @@
newPatterns[ i ] = prefix + "/" + newPatterns[ i ];
}
return newPatterns;
+ }
+
+ /**
+ * Normalize a path. That means:
+ * <ul>
+ * <li>changes to unix style if under windows</li>
+ * <li>eliminates "/../" and "/./"</li>
+ * <li>if path is absolute (starts with '/') and there are
+ * too many occurences of "../" (would then have some kind
+ * of 'negative' path) returns null.</li>
+ * <li>If path is relative, the exceeding ../ are kept at
+ * the begining of the path.</li>
+ * </ul>
+ * <br><br>
+ *
+ * <b>Note:</b> note that this method has been tested with unix and windows
only.
+ *
+ * <p>Eg:</p>
+ * <pre>
+ * /foo// --> /foo/
+ * /foo/./ --> /foo/
+ * /foo/../bar --> /bar
+ * /foo/../bar/ --> /bar/
+ * /foo/../bar/../baz --> /baz
+ * //foo//./bar --> /foo/bar
+ * /../ --> null
+ * </pre>
+ *
+ * @param path the path to be normalized.
+ * @return the normalized path or null.
+ * @throws NullPointerException if path is null.
+ */
+ private static final String normalize( String path )
+ {
+ if( path.length() < 2 )
+ {
+ return path;
+ }
+
+ StringBuffer buff = new StringBuffer( path );
+
+ int length = path.length();
+
+ // this whole prefix thing is for windows compatibility only.
+ String prefix = null;
+
+ if( length > 2 && buff.charAt( 1 ) == ':' )
+ {
+ prefix = path.substring( 0, 2 );
+ buff.delete( 0, 2 );
+ path = path.substring( 2 );
+ length -= 2;
+ }
+
+ boolean startsWithSlash = length > 0 && ( buff.charAt( 0 ) == '/' ||
buff.charAt( 0 ) == '\\' );
+
+ boolean expStart = true;
+ int ptCount = 0;
+ int lastSlash = length + 1;
+ int upLevel = 0;
+
+ for( int i = length - 1; i >= 0; i-- )
+ switch( path.charAt( i ) )
+ {
+ case '\\':
+ buff.setCharAt( i, '/' );
+ case '/':
+ if( lastSlash == i + 1 )
+ {
+ buff.deleteCharAt( i );
+ }
+
+ switch( ptCount )
+ {
+ case 1:
+ buff.delete( i, lastSlash );
+ break;
+
+ case 2:
+ upLevel++;
+ break;
+
+ default:
+ if( upLevel > 0 && lastSlash != i + 1 )
+ {
+ buff.delete( i, lastSlash + 3 );
+ upLevel--;
+ }
+ break;
+ }
+
+ ptCount = 0;
+ expStart = true;
+ lastSlash = i;
+ break;
+
+ case '.':
+ if( expStart )
+ {
+ ptCount++;
+ }
+ break;
+
+ default:
+ ptCount = 0;
+ expStart = false;
+ break;
+ }
+
+ switch( ptCount )
+ {
+ case 1:
+ buff.delete( 0, lastSlash );
+ break;
+
+ case 2:
+ break;
+
+ default:
+ if( upLevel > 0 )
+ {
+ if( startsWithSlash )
+ {
+ return null;
+ }
+ else
+ {
+ upLevel = 1;
+ }
+ }
+
+ while( upLevel > 0 )
+ {
+ buff.delete( 0, lastSlash + 3 );
+ upLevel--;
+ }
+ break;
+ }
+
+ length = buff.length();
+ boolean isLengthNull = length == 0;
+ char firstChar = isLengthNull?(char)0:buff.charAt( 0 );
+
+ if( !startsWithSlash && !isLengthNull && firstChar == '/' )
+ {
+ buff.deleteCharAt( 0 );
+ }
+ else if( startsWithSlash &&
+ ( isLengthNull || ( !isLengthNull && firstChar != '/' ) ) )
+ {
+ buff.insert( 0, '/' );
+ }
+
+ if( prefix != null )
+ {
+ buff.insert( 0, prefix );
+ }
+
+ return buff.toString();
}
}
--
To unsubscribe, e-mail: <mailto:avalon-cvs-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-cvs-help@;jakarta.apache.org>