繁体   English   中英

带有尾部“..”的Java文件canonicalPath会导致行为不一致

[英]Java file canonicalPath with tailing '.. ' leads to inconsistent behavior

我正在调查一些与pathTraversal相关的安全机制,并遇到了java.io.File.getCanonicalPath()的奇怪行为。 我认为CanonicalPath将始终代表抽象底层文件的真正唯一路径。 但是,如果文件名包含两个点后跟一个空格,则CanonicalPath似乎不再代表正确的路径。

这是一个例子:

File root = new File("c:/git/");
String relative = ".. /.. \\";
File concatFile = new File (root.getCanonicalPath(), relative);

System.out.println("ConcatFileAbsolute: '" + concatFile.getAbsolutePath() + "'");
System.out.println("ConcatFileCanonical: '" + concatFile.getCanonicalPath() + "'");

File canonFile = new File(concatFile.getCanonicalPath());
System.out.println("\ncanonFileCanonical: '" + canonFile.getCanonicalPath() + "'");
System.out.println("canonFileAbsolute: '" + canonFile.getAbsolutePath() + "'");
System.out.println("canonFileName: '" + canonFile.getName() + "'\n");

for (File file : canonFile.listFiles()) {
    System.out.println("canon: '" + file.getCanonicalPath() + "' - absolute: '" + file.getAbsolutePath()+ "'");
}

控制台输出:

ConcatFileAbsolute: 'C:\git\.. \.. '
ConcatFileCanonical: 'C:\git\.. \'

canonFileCanonical: 'C:\git\'
canonFileAbsolute: 'C:\git\.. '
canonFileName: '.. '

canon: 'C:\git\.. \$Recycle.Bin' - absolute: 'C:\git\.. \$Recycle.Bin'
canon: 'C:\git\.. \.m2' - absolute: 'C:\git\.. \.m2'
canon: 'C:\git\.. \boot' - absolute: 'C:\git\.. \boot'
...other content of C:/ 

正如您所看到的,虽然canonFile的canonicalPath清楚地表明它在C:\\ git \\中的位置,但.listFiles列出了C:中的所有文件。

只有在我使用新的File(String,String)构造函数时才会发生这种情况。 如果我将第三行更改为File concatFile = new File(root.getCanonicalPath()+ relative); 然后输出符合预期:

ConcatFileAbsolute: 'C:\git.. \.. '
ConcatFileCanonical: 'C:\git\' 
- The following output then lists files under C:\git\

我不知道在unix类系统上这种行为是否类似。

有人可以澄清这种行为吗? 这是有意的吗?

先谢谢!

恭喜! 您发现了WinAPI可能存在的错误(或功能?)。

更具体地说,您的问题可以简化为一行代码:

为什么new File("c:\\\\temp\\\\.. ").getCanonicalPath()返回c:\\temp\\而不是c:\\

答案很简单:因为经过尾矿空间的.. (是的,你是上面提到的)。

答案很长:如果我们将查看底层类的Java实现,我们会发现对于Windows它是WinNTFileSystem类,其中本机方法canonicalize0("c:\\\\temp\\\\.. ")返回此破坏的值。 为什么? 为了测试它,我编写了简单的VBS代码来测试Win API:

Dim folderName
folderName = "c:\temp\.. "

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim fullpath
fullpath = fso.GetAbsolutePathName(folderName)

WScript.Echo "fullpath:    " & fullpath

它给出了完全相同的结果:

fullpath:    C:\temp

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM