基於 ADODB.Stream(高性能二進制/文本流)與 Scripting.FileSystemObject(目錄管理)雙引擎,構建生產可用的文件操作核心庫,含上傳漏洞防範、圖片真偽鑒別、擴展名白名單等安全模塊。
' 讀取文本文件(指定編碼,默認 GB2312)
Function LoadFile(ByVal File)
Dim objStream
On Error Resume Next
Set objStream = Server.CreateObject("ADODB.Stream")
If Err.Number = -2147221005 Then
Response.Write "宿主不支持 ADODB.Stream"
Response.End
End If
With objStream
.Type = 2 ' adTypeText
.Mode = 3 ' adModeReadWrite
.Open
.LoadFromFile File
If Err.Number <> 0 Then
Response.Write "文件無法打開: " & File
Response.End
End If
.Charset = "GB2312"
.Position = 0 ' 讀取從頭開始(原代碼 Position=2 會丟失首字符)
LoadFile = .ReadText
.Close
End With
Set objStream = Nothing
End Function
' 寫入文本文件(覆蓋模式)
Function SaveToFile(ByVal strBody, ByVal File)
Dim objStream
On Error Resume Next
Set objStream = Server.CreateObject("ADODB.Stream")
If Err.Number = -2147221005 Then
Response.Write "宿主不支持 ADODB.Stream"
Response.End
End If
With objStream
.Type = 2
.Open
.Charset = "GB2312"
.Position = 0
.WriteText strBody
.SaveToFile File, 2 ' 2=adSaveCreateOverWrite
.Close
End With
Set objStream = Nothing
End Function
' 刪除文件
Function DelFile(ByVal File)
Dim objFilesys
On Error Resume Next
Set objFilesys = Server.CreateObject("Scripting.FileSystemObject")
If objFilesys.FileExists(File) Then objFilesys.DeleteFile File
If Err.Number <> 0 Then
Response.Write "文件刪除失敗: " & File
Response.End
End If
Set objFilesys = Nothing
End Function
Function CheckFile(sFileName)
Dim objFilesys
Set objFilesys = Server.CreateObject("Scripting.FileSystemObject")
CheckFile = objFilesys.FileExists(sFileName)
Set objFilesys = Nothing
End Function
Function CheckFolder(Chk_Path)
Dim fso : Set fso = Server.CreateObject("Scripting.FileSystemObject")
CheckFolder = fso.FolderExists(Chk_Path)
Set fso = Nothing
End Function
Function GetFileExt(sFileName)
GetFileExt = UCase(Mid(sFileName, InStrRev(sFileName, ".") + 1))
End Function
' 檢測文件名是否包含空字節 (Chr(0)),防止 00 截斷繞過
Function IsTrueFileName(sFileName)
Dim pos, strLen
strLen = Len(sFileName)
pos = InStr(sFileName, Chr(0))
' 空字節不存在,或在末尾(某些系統添加),視為合法
IsTrueFileName = (pos = 0 Or pos = strLen)
End Function
Function IsImgFile(sFileName)
Const adTypeBinary = 1
Dim stream, ext, header, i, match, sigs
' 文件頭特徵碼表
sigs = Array( _
Array("jpg", Array(&HFF, &HD8)), _
Array("jpeg", Array(&HFF, &HD8)), _
Array("png", Array(&H89, &H50, &H4E, &H47)), _
Array("gif", Array(&H47, &H49, &H46, &H38, &H39, &H61)), _
Array("bmp", Array(&H42, &H4D)) _
)
On Error Resume Next
ext = LCase(GetFileExt(sFileName))
match = False
' 只驗證已知圖片擴展名
For Each sig In sigs
If sig(0) = ext Then
Set stream = Server.CreateObject("ADODB.Stream")
stream.Type = adTypeBinary
stream.Open
stream.LoadFromFile sFileName
stream.Position = 0
header = stream.Read(UBound(sig(1)) + 1)
stream.Close
match = True
For i = 0 To UBound(sig(1))
If AscB(MidB(header, i+1, 1)) <> sig(1)(i) Then match = False : Exit For
Next
Set stream = Nothing
Exit For
End If
Next
If Err.Number <> 0 Then match = False
IsImgFile = match
End Function
' blnAllow=True: 白名單模式(只允許列表內)
' blnAllow=False: 黑名單模式(禁止列表內)
Function CheckFileExt(sFileExt, strExtList, blnAllow)
Dim extArr, ext, allowed
extArr = Split(strExtList, "|")
allowed = False
For Each ext In extArr
If LCase(ext) = LCase(sFileExt) Then allowed = True : Exit For
Next
If blnAllow Then
CheckFileExt = allowed ' 白名單:在列表內才通過
Else
CheckFileExt = Not allowed ' 黑名單:不在列表內才通過
End If
End Function
' 用法
If Not CheckFileExt(GetFileExt(uploadName), "jpg|jpeg|png|gif|pdf|doc", True) Then
Response.Write "禁止的文件類型"
Response.End
End If
maxAllowedContentLength + 代碼雙重校驗。ADODB.Stream 讀取頭部字節判斷真實類型。此庫已在多個高併發 CMS 系統穩定運行,建議作為項目基礎設施組件統一引用。