簡體   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