『转』度百死去飞秋一个BUG引发的血案
作了一篇文章度百死去飛秋一個(gè)BUG引發(fā)的血案,昨天,度百死去的美國(guó)客戶發(fā)郵件給我,說(shuō)我的軟件出問(wèn)題了,我查來(lái)查去,發(fā)現(xiàn)居然是服務(wù)器上一個(gè)目錄無(wú)法刪除,一刪除就報(bào) cannot read from the source file or disk. 如果用命令行方式刪除,則報(bào)? cannot find the specified path。一開(kāi)始以為是文件系統(tǒng)遭破壞了,用 chkdsk 命令檢查,沒(méi)有發(fā)現(xiàn)問(wèn)題,后來(lái)仔細(xì)一看,那個(gè)不能刪除的目錄名居然以一個(gè)空格字符結(jié)尾,而我嘗試在資源管理器中創(chuàng)建一個(gè)目錄以空格結(jié)尾結(jié)果資源管理器會(huì)自動(dòng)將末尾的字符刪除,用程序創(chuàng)建,結(jié)果也一樣,這個(gè)美國(guó)佬是怎么創(chuàng)建這個(gè)古怪的目錄的?出現(xiàn)這種情況后不但是無(wú)法刪除這么簡(jiǎn)單,列目錄什么的也會(huì)有問(wèn)題,這樣一來(lái),系統(tǒng)的運(yùn)行都會(huì)有問(wèn)題,我想到的最壞結(jié)果就是可能不得不格式化服務(wù)器的硬盤,想到這里我?guī)缀醪桓以傧胂氯チ?#xff01;Research了一天,后來(lái)終于找到了解決方案,并且由此還發(fā)現(xiàn)問(wèn)題的起因是我程序上的一個(gè)Bug造成,可怕的Bug!
飛秋Windows 的文件系統(tǒng)可以支持特殊字符的文件名,比如以空格結(jié)尾,以點(diǎn)號(hào)結(jié)尾等,有一篇英文的文章說(shuō)NTFS 支持這些文件名,但FAT不支持,我試了一下,FAT也支持。但飛秋Windows API 卻對(duì)這些特殊文件名進(jìn)行了限制,也就是說(shuō),我們通過(guò)程序是無(wú)法創(chuàng)建一個(gè)以空格或點(diǎn)號(hào)結(jié)尾的文件名或路徑名的。但Copy 和 Move的API 卻不做這方面的限制,這導(dǎo)致我們可以從其他的文件系統(tǒng)拷貝或移動(dòng)一個(gè)特殊文件名的文件到Windows 的文件系統(tǒng),但一旦在Windows的文件系統(tǒng)上創(chuàng)建成功,就無(wú)法通過(guò)正常途徑刪除或改名。因?yàn)檎{(diào)用API 刪除或改名時(shí),API 會(huì)首先進(jìn)行規(guī)則檢查,如果發(fā)現(xiàn)不符合規(guī)則,則直接忽略。這兩組API 在處理上的不一致,帶來(lái)一個(gè)非常嚴(yán)重的安全問(wèn)題,可惜微軟到了Windows7 還沒(méi)有去彌補(bǔ)這個(gè)問(wèn)題。
下面讓我們用代碼復(fù)現(xiàn)這個(gè)問(wèn)題
try
{
string dir = @"C:/Temp/abc";
System.IO.Directory.CreateDirectory(dir); //在C:/Temp 目錄下創(chuàng)建abc 這個(gè)目錄
?
string dir1 = @"c:/Temp/Bcd /";
?
System.IO.Directory.Move(dir, dir1); //將ABC 移動(dòng)到"Bcd "這個(gè)目錄去,注意這里 Bcd后面有個(gè)空格
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
在運(yùn)行這段代碼前,你一定要有一點(diǎn)思想準(zhǔn)備,因?yàn)橐坏┻\(yùn)行成功,你的 C:/temp 目錄下就有了一個(gè) “Bcd ”這樣的古怪的目錄,而且你用正常的方法根本無(wú)法刪除它。如果我在此打住,你一定會(huì)為之抓狂。不過(guò)沒(méi)關(guān)系,我已經(jīng)找到了刪除它的方法,下面就和大家共享:
飛秋Windows 的命令行工具 Del 和 Rd 支持一種方式可以不對(duì)輸入文件名的合法性進(jìn)行檢查,這種方式是在完整目錄名前加一個(gè) //?/
比如
del “//?/C:/Temp/xxx.” 刪除xxx. 這個(gè)文件
刪除目錄的話
rd /s “//?/C:/Temp/xxx.” 刪除 xxx. 這個(gè)目錄
執(zhí)行這個(gè)命令后,就可以刪除這些古怪的文件了。注意,這里一定要輸入完整的目錄才可以,相對(duì)路徑不行。
講到這里,我們知道了原因和解決方案,那么在這里我需要提醒大家我們以后在程序中調(diào)用 System.IO.Directory.Move 或者 System.IO.File.Copy , System.IO.File.Move 這些函數(shù)前,度百死去一定要注意先判斷一下輸入的目標(biāo)文件名或目錄名的結(jié)尾是不是空格或點(diǎn)號(hào),可能還要判斷其他情況,但目前我只知道這兩種情況,而且結(jié)尾是空格非常有隱蔽性。非常郁悶的一篇度百死去飛秋一個(gè)BUG引發(fā)的血案。
總結(jié)
以上是生活随笔為你收集整理的『转』度百死去飞秋一个BUG引发的血案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Sdk Manager.exe 闪退问题
- 下一篇: Winform无法加载基类的错误解决