Revert "Merge pull request #460 from thesnowgoose/master"
This reverts commitf5ba7ae197
, reversing changes made to0fe1bbcd91
. The change fails for /foo/../../bar paths, as it returns bar rather than null
This commit is contained in:
parent
f5ba7ae197
commit
330d21d27f
|
@ -20,11 +20,6 @@ package org.eclipse.jetty.util;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ListIterator;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
|
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
@ -54,7 +49,6 @@ public class URIUtil
|
||||||
public static final String HTTP_COLON="http:";
|
public static final String HTTP_COLON="http:";
|
||||||
public static final String HTTPS="https";
|
public static final String HTTPS="https";
|
||||||
public static final String HTTPS_COLON="https:";
|
public static final String HTTPS_COLON="https:";
|
||||||
private static final Pattern __PATH_SPLIT = Pattern.compile("(?<=\\/)");
|
|
||||||
|
|
||||||
// Use UTF-8 as per http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
|
// Use UTF-8 as per http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
|
||||||
public static final Charset __CHARSET=StandardCharsets.UTF_8 ;
|
public static final Charset __CHARSET=StandardCharsets.UTF_8 ;
|
||||||
|
@ -509,40 +503,130 @@ public class URIUtil
|
||||||
*/
|
*/
|
||||||
public static String canonicalPath(String path)
|
public static String canonicalPath(String path)
|
||||||
{
|
{
|
||||||
if (path == null || path.isEmpty() || !path.contains("."))
|
if (path==null || path.length()==0)
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
if(path.startsWith("/.."))
|
int end=path.length();
|
||||||
return null;
|
int start = path.lastIndexOf('/', end);
|
||||||
|
|
||||||
List<String> directories = new LinkedList<>();
|
search:
|
||||||
Collections.addAll(directories, __PATH_SPLIT.split(path));
|
while (end>0)
|
||||||
|
|
||||||
for(ListIterator<String> iterator = directories.listIterator(); iterator.hasNext();)
|
|
||||||
{
|
{
|
||||||
switch (iterator.next()) {
|
switch(end-start)
|
||||||
case "./":
|
{
|
||||||
case ".":
|
case 2: // possible single dot
|
||||||
if (iterator.hasNext() && directories.get(iterator.nextIndex()).equals("/")) {
|
if (path.charAt(start+1)!='.')
|
||||||
|
break;
|
||||||
|
break search;
|
||||||
|
case 3: // possible double dot
|
||||||
|
if (path.charAt(start+1)!='.' || path.charAt(start+2)!='.')
|
||||||
|
break;
|
||||||
|
break search;
|
||||||
|
}
|
||||||
|
|
||||||
|
end=start;
|
||||||
|
start=path.lastIndexOf('/',end-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have checked the entire string
|
||||||
|
if (start>=end)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
StringBuilder buf = new StringBuilder(path);
|
||||||
|
int delStart=-1;
|
||||||
|
int delEnd=-1;
|
||||||
|
int skip=0;
|
||||||
|
|
||||||
|
while (end>0)
|
||||||
|
{
|
||||||
|
switch(end-start)
|
||||||
|
{
|
||||||
|
case 2: // possible single dot
|
||||||
|
if (buf.charAt(start+1)!='.')
|
||||||
|
{
|
||||||
|
if (skip>0 && --skip==0)
|
||||||
|
{
|
||||||
|
delStart=start>=0?start:0;
|
||||||
|
if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
|
||||||
|
delStart++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
iterator.remove();
|
|
||||||
|
if(start<0 && buf.length()>2 && buf.charAt(1)=='/' && buf.charAt(2)=='/')
|
||||||
break;
|
break;
|
||||||
case "../":
|
|
||||||
case "..":
|
if(delEnd<0)
|
||||||
if(iterator.previousIndex() == 0) {
|
delEnd=end;
|
||||||
return null;
|
delStart=start;
|
||||||
}
|
if (delStart<0 || delStart==0&&buf.charAt(delStart)=='/')
|
||||||
iterator.remove();
|
{
|
||||||
iterator.previous();
|
delStart++;
|
||||||
iterator.remove();
|
if (delEnd<buf.length() && buf.charAt(delEnd)=='/')
|
||||||
|
delEnd++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (end==buf.length())
|
||||||
|
delStart++;
|
||||||
|
|
||||||
|
end=start--;
|
||||||
|
while (start>=0 && buf.charAt(start)!='/')
|
||||||
|
start--;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 3: // possible double dot
|
||||||
|
if (buf.charAt(start+1)!='.' || buf.charAt(start+2)!='.')
|
||||||
|
{
|
||||||
|
if (skip>0 && --skip==0)
|
||||||
|
{ delStart=start>=0?start:0;
|
||||||
|
if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
|
||||||
|
delStart++;
|
||||||
}
|
}
|
||||||
if (directories.isEmpty() && path.startsWith("/"))
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
delStart=start;
|
||||||
|
if (delEnd<0)
|
||||||
|
delEnd=end;
|
||||||
|
|
||||||
|
skip++;
|
||||||
|
end=start--;
|
||||||
|
while (start>=0 && buf.charAt(start)!='/')
|
||||||
|
start--;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (skip>0 && --skip==0)
|
||||||
|
{
|
||||||
|
delStart=start>=0?start:0;
|
||||||
|
if(delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
|
||||||
|
delStart++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the delete
|
||||||
|
if (skip<=0 && delStart>=0 && delEnd>=delStart)
|
||||||
|
{
|
||||||
|
buf.delete(delStart,delEnd);
|
||||||
|
delStart=delEnd=-1;
|
||||||
|
if (skip>0)
|
||||||
|
delEnd=end;
|
||||||
|
}
|
||||||
|
|
||||||
|
end=start--;
|
||||||
|
while (start>=0 && buf.charAt(start)!='/')
|
||||||
|
start--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Too many ..
|
||||||
|
if (skip>0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return String.join("", directories);
|
// Do the delete
|
||||||
|
if (delEnd>=0)
|
||||||
|
buf.delete(delStart,delEnd);
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
Loading…
Reference in New Issue