码迷,mamicode.com
首页 > Web开发 > 详细

一个能防止改名木马漏洞的无组件上传类

时间:2015-08-25 16:23:35      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:

现在流行的asp上传组件除了无惧的化境之外,最多的可能就是ewebEditor 和Fckeditor的上传是,但是经过测试都很难防止改名为gif和asp文件上传,在FckEditor中改名后的asp木马不能直接上传,系统会检测到 <%等字符而拒绝,但是经过修改后的asp木马再改名为gif后却可以顺利上传,如在文件前端加上许多空行,或对木马进行加密处理。当然有人会认为木马传到服务器后会被杀掉,但是做过免杀的木马却会漏网。基于这些原因,本人开发了一个可以从根本上解决这个问题的无组件上传类。经过测试常用的文件格式均可通过。做法是对上传的文件进行格式分析,不符合的格式不允许上传,这样就从根本上解决了这个问题。现贴上来请大家指教。

1、文件upfile.asp

************************************************************************** *  类文件名称:upfile.asp *  作者:马如风(Melon) *  邮箱:mqmelon0@163.com *  版权:=====筱风工作室(R)2004.1-2004.3===== *  内容:不用组件上传文件类 *  用法:在接收表单内容的文件中定义UpFileClass类对象,用GetData方法 *      读取文件内容,并使用FileInfo类的SaveToFile方法存入指定文件 *  例子:set FileUP=new UpFileClass * FileUp.GetData *      set file1=FileUP.upFile("表单元素名") * filename=path&filename *      file1.SaveToFile(server.mappath(filename)) *      set FileUp=nothing ************************************************************************** 
%> 
<% 
response.charset="gb2312" 

Dim BinaStream 全局变量 dim FileSavePath    

Class UpFileClass  类别名称 定义Dictionary变量,用于保存上传的信息 
Dim upForm,upFile 

 类初始化过程 
private sub Class_Initialize 
判断传递的数据,如无,则退出 
if Request.TotalBytes <1 Then 
Exit sub 
End if 
FileSavePath=""  ‘全局变量负值 
set BinaStream=Server.CreateObject("adodb.stream") 
set upForm=New DictionaryClass 
set upFile=New DictionaryClass 
End sub 

类清除过程 
Private sub Class_Terminate 
upFile.RemoveAll 
upForm.RemoveAll 
set upFile=nothing 
set upForm=nothing 
BinaStream.Close 
set BinaStream=nothing 
FileSavePath="" 
End sub 

获取数据过程 
Public sub GetData 
Dim oFileInfo 用于保存文件信息的类对象 
Dim oDataSeprator 用于保存分隔符信息,为二进制字符串 
Dim oFindStart,oFindEnd 寻找指针 
Dim oCrLf  CHRB(13)&CHRB(10), 分隔数字 
Dim oFormData  表单数据描述信息,文本串 
Dim oFileStart  文件开始位置 
Dim otmpStream  临时Stream 对象,用于中间周转字符串 
Dim otmpBinaData  临时二进制字符串,用于中间周转 
Dim oDataAllSize  所有二进制数值大小 
Dim oFormName  表单元素名称 
Dim oFormContent  表单元素内容 
Dim oFormStart  表单元素开始位置 
Dim oFormEnd  表单元素结束位置 
Dim oFileFullName  带路径文件名 

变量初始化 
set oFileInfo=new FileInfo 
oDataSeprator="" 
oFindStart=Clng(0) 
oFindEnd=Clng(0) 
oCrLf=chrB(13)&chrB(10) 
oFormData="" 
oFileStart=Clng(0) 
set otmpStream=Server.CreateObject("adodb.stream") 
otmpBinaData="" 
oDataAllSize=Clng(0) 
oFormName="" 
oFormcontent="" 
oFormStart=Clng(0) 
oFormEnd=Clng(0) 
oFileFullName="" 
 获得传递过来的二进制数据 
if Request.TotalBytes <1 then 
Error_Msg("发生数据错误,传递数据空或丢失!") 
Exit sub 
End if 
BinaStream.Type=1 二进制 
BinaStream.Mode=3 读写模式,1-读,2-写,3-读写 
BinaStream.Open  打开对象,准备读写 开始读取所有上传的数据 Thankful long(yrl031715@163.com) Fix upload large file. **********************************************  修正作者:long  联系邮件: yrl031715@163.com  修正时间:2007年5月6日  修正说明:由于iis6的Content-Length 头信息中包含的请求长度超过了 AspMaxRequestEntityAllowed 的值(默认200K), IIS 将返回一个 403 错误信息.           直接导致在iis6下调试FCKeditor上传功能时,一旦文件超过200K,上传文件时文件管理器失去响应,受此影响,文件的快速上传功能也存在在缺陷。           在参考 宝玉 的 Asp无组件上传带进度条 演示程序后作出如下修改,以修正在iis6下的错误。 

Dim nTotalBytes, nPartBytes, ReadBytes 
ReadBytes = 0 
nTotalBytes = Request.TotalBytes 
循环分块读取 
Do While ReadBytes < nTotalBytes 
分块读取 
nPartBytes = 64 * 1024 分成每块64k 
If nPartBytes + ReadBytes > nTotalBytes Then 
nPartBytes = nTotalBytes - ReadBytes 
End If 
BinaStream.Write Request.BinaryRead(nPartBytes) 
ReadBytes = ReadBytes + nPartBytes 
Loop 
读取完毕 
BinaStream.Position=0 
otmpBinaData=BinaStream.Read 
oDataAllSize=BinaStream.Size 
获得分隔符 
oDataSeprator=MidB(otmpBinaData,1,InstrB(1,otmpBinaData,oCrLf)-1) 
给寻找指针付值 
oFindStart=Lenb(oDataSeprator)+2 
oFindEnd=oFindStart 
分解名项目,且保存其值 
While oFindStart+2 <oDataAllSize 
otmpStream.Type=1 
otmpStream.MOde=3 
otmpStream.Open 
oFindEnd=InstrB(oFindStart,otmpBinaData,oCrLf&oCrLf)+3 
此时,oFindEnd指向内容,oFindStart指向描述 
BinaStream.Position=oFindStart 
BinaStream.CopyTo otmpStream,oFindEnd-oFindStart 
把表单描述存入oFormData 
otmpStream.Position=0 
otmpStream.Type=2 设为文本类型数据 
otmpStream.Charset="gb2312" 设字符集为中文 
oFormData=otmpStream.ReadText 保存数据为文本 查找表单项目名称 
oFormStart=Instr(1,oFormData,"name=",1)+len("name=")+1 
oFormEnd=Instr(oFormStart,oFormData,"""",1) 
oFormName=Mid(oFormData,oFormStart,oFormEnd-oFormStart) 
调试开始 open_appe_txt "debug.txt","oFormData="&chr(13)&chr(10)&oFormData open_appe_txt "debug.txt","判断前:"&chr(13)&chr(10)&"oFormStart="&oFormStart&"oFormEnd="&oFormEnd&"oFormName="&oFormName 调试结束 判断是否为文件 
if Instr(oFormEnd,oFormData,"filename=",1)>0 Then 
是文件,则取文件属性 找到文件名字 
oFormStart=Instr(oFormEnd,oFormData,"filename=",1)+len("filename=")+1 
加1是为了去掉文件名字前面的引号 
oFormEnd=Instr(oFormStart,oFormData,"""",1) 
此时,oFormEnd指向下一个描述的前一个位置,减1是为去掉引号 获得文件信息 获得带路径文件名称 
oFileFullName=Mid(oFormData,oFormStart,oFormEnd-oFormStart) 
分解文件名称 
oFileInfo.FileName=GetFileName(oFileFullName) 
oFileInfo.FileExt=GetFileExt(oFileFullName) 
oFileInfo.FilePath=GetFilePath(oFileFullName) 
获得文件类型 
oFormStart=Instr(oFormEnd,oFormData,"Content-Type:",1)+len("Content-Type:") 
oFormEnd=Instr(oFormStart,oFormData,chr(13)&chr(10),1) 
oFileInfo.FileType=Mid(oFormData,oFormStart,oFormEnd-oFormStart) 
获得文件内容起始点 
oFileInfo.FileStart=oFindEnd 
oFindStart=InstrB(oFindEnd,otmpBinaData,oDataSeprator) 
此时,oFindStart指向分隔符位置 
oFileInfo.FileSize=oFindStart-oFindEnd-3 
oFileInfo.FormName=oFormName 
把数据加入到upFile[Dictionary对象]中保存 调试开始 open_appe_txt "debug.txt","循环中(文件):"&chr(13)&chr(10)&"oFindStart="&oFindStart&"oFormName="&oFormName 调试结束 
upFile.add oFormName,oFileInfo 
Else 
如果是表单元素,则取元素值 关闭otmpStream对象,以便重新读取内容 
otmpStream.Close 
otmpStream.Type=1 
otmpStream.Mode=3 
otmpStream.Open 
找到内容结束位置 
oFindStart=InstrB(oFindEnd,otmpBinaData,oDataSeprator) 
读出内容 
BinaStream.Position=oFindEnd 
BinaStream.CopyTo otmpStream,oFindStart-oFindEnd-3 
otmpStream.Position=0 
otmpStream.Type=2 
otmpStream.Charset="gb2312" 
oFormContent=otmpStream.ReadText 
upForm.add oFormName,oFormContent 
End if 
调整寻找指针位置 
oFindStart=oFindStart+LenB(oDataSeprator)+1 
此时,寻找指针均指向下一描述 
otmpStream.Close 
WEnd 循环返回 变量清空 
otmpBinaData="" 
set otmpBinaData=nothing 
end sub 子程序到此结束

获得文件路径程序 
Private Function GetFilePath(FullPath) 
if FullPath <>"" Then 
GetFilePath=Left(FullPath,InstrRev(FullPath,"/")) 
Else 
GetFilePath="" 
End if 
End Function 

获得文件名程序 
Private Function GetFileName(FullPath) 
if FullPath <>"" Then 
GetfileName=Mid(FullPath,InstrRev(FullPath,"/")+1) 
Else 
GetFileName="" 
End if 
End Function 

获得文件扩展名 
Private Function GetFileExt(FullPath) 
if FullPath <>"" Then 
GetFileExt=Mid(FullPath,InstrRev(FullPath,".")+1) 
Else 
GetFileExt="" 
End if 
End Function 

类定义结束 
End Class 

文件属性类定义开始 
Class FileInfo 
Dim FileName,FileSize,FileStart,FilePath,FileExt,FileType,FormName 
Dim FileSaveName 

Private sub Class_Initialize 
FileName="" 
FileSize=0 
FileStart=0 
FilePath="" 
FileExt="" 
FileType="" 
FormName="" 
End sub 

Private sub Class_Terminate 
空子程序 
End sub 


把内容存入到服务器上指定位置和名称的文件 
Public Function SaveToFile(tmpFileName) 
Dim FileSaveStream,tmpStream,tmpReadStream,FullPath 
Dim filePath,FileFullName,SpcPosition 
使用服务器路径 
tmpFileName=s_SavePath&tmpFileName 
FullPath=server.mappath(tmpFileName) 
加入 
Dim mfileExt,tmpData 
mfileExt=Mid(FullPath,InstrRev(FullPath,".")+1,Len(FullPath)) 
加入2009.3.27 

SaveFile=-1 
if FullPath="" or Right(FullPath,1)="/" Then 
Call Error_Msg("Error Occured when Save the file to appointed directory and fileName!:/n The fileName is not valid!") 
Exit Function 
Else 
替换/为/ 
FullPath=Replace(FullPath,"/","/") 
取出保存的目录 
SpcPosition=InStrrev(FullPath,"/") 
If spcposition=0 Then 
filePath=s_curPath 使用程序所在目录 
FileFullName=FullPath 
Else 
filePath=Mid(FullPath,1,SpcPosition-1) 
FileFullName=Mid(FullPath,spcPosition+1,Len(Fullpath)) 
End if 


If i_AutoRename=1 Then 
如果存在同名,则自动更名 
tmpFileName=s_SavePath& autoRename(filePath,FileFullName) 
FullPath=server.mappath(tmpFileName) 
End if 
End if 

set FileSaveStream=Server.CreateObject("adodb.stream") 
FileSaveStream.Type=1 
FileSaveStream.Mode=3 
fileSaveStream.Open 
BinaStream.position=FileStart 
BinaStream.CopyTo FileSaveStream,FileSize 

BinaStream.position=FileStart 
tmpData=BinaStream.read(30) 

If mfileExt <>"" Then 
If SniffPic(mfileExt,tmpData)=False Then 
saveToFile=-1 
Exit function 
End if 
End If 

FileSaveStream.SaveToFile FullPath,2 
FileSaveStream.Close 
set FileSaveStream=nothing 

SaveToFile=0 

End Function 

获得文件保存的内容,返回二进制数据,可以用来存入数据库中 
Public Function GetFileData() 
BinaStream.Position=FileStart 
GetFileData=BinaStream.Read(Filesize) 
End Function 

测试一个文件是否存在 
function AutoRename(filePath,FileFullName) 
如果一个文件存在,则自动更名 
Dim oFSO,testFileName,testFileExt,extPosition,iCounter,sFileName 
返回值,默认直接返回 
AutoRename=fileFullName 
取得文件名 
extPosition=InstrRev(FileFullName,".") 
If extPosition>0 Then 
testFileName=Mid(FileFullName,1,extPosition-1) 
testFileExt=Mid(FileFullName,extPosition+1,Len(FileFullName)) 
Else 
testFileName=FileFullName 
testFileExt="" 
End If 
sFileName=fileFullName 
Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" ) 
测试指定目录是否存在 
if not (oFSO.FolderExists( filePath)) then 
不存在,则生成目录,然后退出 
oFSO.CreateFolder(filePath) 
else 
iCounter = 0 

Do While ( True ) 
Dim sFilePath 
sFilePath = filePath & "/" & sFileName 

If ( oFSO.FileExists( sFilePath ) ) Then 
iCounter = iCounter + 1 
sFileName =  testFileName & "(" & iCounter & ")." & testFileExt 
Else 
Exit Do 
End If 
Loop 

If iCounter>0 Then 
AutoRename=sFileName 
End if 
end if 
End function 

End Class 
FileInfo类定义结束 
%> 
<% 
function open_appe_txt(txt_name,txt_content) 
dim MyFileObject,MyTextFile 
set MyFileObject=server.CreateObject("Scripting.FileSystemObject") 
set MyTextFile=MyFileObject.OpenTextFile(server.MapPath(txt_name),8,true) 
MyTextFile.WriteLine(txt_content) 
MyTextFile.Close 
set MyTxtFile=nothing 
set MyFileObject=nothing 
end function 
%> 
<% 
显示错误信息程序 
sub Error_Msg(eMsg,eUrl) 
%> 
<script> 
alert( <%=eMsg%>‘); 
if (""== <%=eUrl%>‘) 
history.back(); 
else 
document.location= <%=eUrl%>‘; 
</script> 
<% 
End Sub 


马如风2009.3.26 
Function Bin2Str(Bin) 
  Dim I, Str 
  For I=1 to LenB(Bin) 
    clow=MidB(Bin,I,1) 
    if AscB(clow) <128 then 
      Str = Str & Chr(ASCB(clow)) 
    Else 
      I=I+1 
      if I <= LenB(Bin) then Str = Str & Chr(ASCW(MidB(Bin,I,1)&clow)) 
    end If 
  Next 
  Bin2Str = Str 
End Function 

function binToNum(bin) 
    二进制转为 Numeric 
        dim i:binToNum=0 
        for i=lenB(bin) to 1 step -1 
            binToNum=binToNum*256+ascB(midB(bin,i,1)) 
        next shawl.qiu code‘ 

end function 

Function SniffPic(sFileExt,sData) 
SniffPic=false 
If sfileExt="" Then 
Exit function 
End if 

Dim tmpExt,tmpData,tmpI,tmpSource 

tmpExt=UCase(sFileExt) 
If lenb(sData) <10 Then 
Exit Function 
End If 

Select Case tmpExt 
Case "GIF" 
For tmpI=1 To 3 
tmpData=tmpData & Hex(binToNum(Midb(sData,tmpI,1))) 
Next 
tmpSource=Hex("&H47") & Hex("&H49") & Hex("&H46") 
If tmpData=tmpSource Then 
SniffPic=true 
End if 
Case "JPG" 
For tmpI=1 To 3 
tmpData=tmpData & Hex(binToNum(Midb(sData,tmpI,1))) 
next 
tmpSource=CStr(Hex("&HFF")) & CStr(Hex("&HD8")) & CStr(Hex("&HFF")) 
If tmpData=tmpSource Then 
SniffPic=true 
End if 
Case "PNG" 
For tmpI=1 To 4 
tmpData=tmpData & Hex(binToNum(Midb(sData,tmpI,1))) 
next 
tmpSource=CStr(Hex("&H89")) & CStr(Hex("&H50")) & CStr(Hex("&H4E")) & CStr(Hex("&H47")) 
If tmpData=tmpSource Then 
SniffPic=true 
End if 
Case "BMP" 
For tmpI=1 To 2 
tmpData=tmpData & Hex(binToNum(Midb(sData,tmpI,1))) 
next 
tmpSource=CStr(Hex("&H42")) & CStr(Hex("&H4D")) 
If tmpData=tmpSource Then 
SniffPic=true 
End if 
Case "PCX" 
For tmpI=1 To 4 
tmpData=tmpData & Hex(binToNum(Midb(sData,tmpI,1))) 
next 
tmpSource=CStr(Hex("&H0A")) & CStr(Hex("&H05")) & CStr(Hex("&H01")) & CStr(Hex("&H08")) 
If tmpData=tmpSource Then 
SniffPic=true 
End if 
Case "TIF" 
For tmpI=1 To 4 
tmpData=tmpData & Hex(binToNum(Midb(sData,tmpI,1))) 
next 
tmpSource=CStr(Hex("&H49")) & CStr(Hex("&H49")) & CStr(Hex("&H2A")) & CStr(Hex("&H00")) 
If tmpData=tmpSource Then 
SniffPic=true 
End If 
Case "DOC" 
For tmpI=1 To 8 
tmpData=tmpData & Hex(binToNum(Midb(sData,tmpI,1))) 
next 
tmpSource=CStr(Hex("&HD0")) & CStr(Hex("&HCF")) & CStr(Hex("&H11")) & CStr(Hex("&HE0")) & CStr(Hex("&HA1")) 
tmpSource=tmpSource & CStr(Hex("&HB1")) & CStr(Hex("&H1A")) & CStr(Hex("&HE1")) 
If tmpData=tmpSource Then 
SniffPic=true 
End If 
Case "XLS" 
For tmpI=1 To 8 
tmpData=tmpData & Hex(binToNum(Midb(sData,tmpI,1))) 
next 
tmpSource=CStr(Hex("&HD0")) & CStr(Hex("&HCF")) & CStr(Hex("&H11")) & CStr(Hex("&HE0")) & CStr(Hex("&HA1")) 
tmpSource=tmpSource & CStr(Hex("&HB1")) & CStr(Hex("&H1A")) & CStr(Hex("&HE1")) 
If tmpData=tmpSource Then 
SniffPic=true 
End If 
Case "RAR" 
For tmpI=1 To 10 
tmpData=tmpData & Hex(binToNum(Midb(sData,tmpI,1))) 
next 
tmpSource=CStr(Hex("&H52")) & CStr(Hex("&H61")) & CStr(Hex("&H72")) & CStr(Hex("&H21")) & CStr(Hex("&H1A")) & CStr(Hex("&H07")) 
tmpSource=tmpSource & CStr(Hex("&H00")) & CStr(Hex("&HCF")) & CStr(Hex("&H90")) & CStr(Hex("&H73")) 
If tmpData=tmpSource Then 
SniffPic=true 
End If 
Case Else 
sniffpic=true 
End Select 
End function 
马如风2009.3.26 
%> 
2、up.asp 
<%@codepage=936%> 
<html> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> 
<body topmargin=0  rightmargin=0  leftmargin=0> 
<% 
******************************************* * 文件:up.asp * 功能:上传文件 * 输入:无 * 输出:无 * 修改日期:2004.3.5 * 作者:马如风 * 版权声明:筱风工作室版权所有(2004-2005) ******************************************* 
%> 
<!--#include file="upfile.asp"--> 
<!--#include file="dic.asp"--> 
<!--#include file="setup.asp"--> 

<% 
fname=""&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&"" 
if request("up_act")="up_files" then 

set FileUP=new upFileClass 
FileUP.GetData 

set file1=FileUP.upFile.item("file1") 
If i_rename=0 then 
filename=s_SavePath&fname&"."&file1.FileExt 
filename=fname&"."&file1.FileExt 
else 
filename=file1.filename 
End if 

对文件格式进行判断处理 
If InStr(S_FileExt,UCase(file1.fileExt))=0 then 
error_msg "Your File"&Chr(96)& "s Type is not allowed!/n","" 
response.End() 
end if 

if int(file1.filesize/1024)>i_upSize then 
Error_Msg "The FileSize is Exceed "&i_upSize&"KB!/n","" 
response.End() 
end if 

 
Dim tmpResult 
tmpResult=file1.SaveToFile(server.mappath(filename)) 
tmpResult=file1.SaveToFile(fileName) 
set FileUP=Nothing 

If tmpResult=0 then 

img=filename 
response.write (" <SCRIPT>parent.document.getElementById("""& s_inputName &""").value+=‘/n"&img&"‘;history.back(); </SCRIPT>") 

Else 

error_msg "Sorry!File"&Chr(96)& "s Type is not correct!/n","" 
response.End() 
End if 

Else 
If i_upfile=1 And i_Author=1 then 
%> 

<table cellpadding=0 cellspacing=0 border="0"> 
<tr> 
<form enctype=multipart/form-data method=post action=up.asp?up_act=up_files> 
<td> <input type=file style="FONT-SIZE:9pt;cursor:hand;" name=file1 size="20"> 
<input style="FONT-SIZE:9pt;cursor:hand;" type="submit" value=" 上 传 " name=Submit> 
</form> </td> </tr> </table> 
<% 
ElseIf i_Author=0 Then 

%> 
<table cellpadding=0 cellspacing=0 border="0"> 
<tr> <td style="font-size:12px;height:24px;" valign="middle">请登录后再使用上传功能。 </td> </tr> </table> 
<% 
else 
%> 
<table cellpadding=0 cellspacing=0 border="0"> 
<tr> <td style="font-size:12px;height:24px;" valign="middle">不允许上传文件. </td> </tr> </table> 
<% 
End if 
end if 
%>

3、dic.asp 
<% 
Class DictionaryClass 
Dim ArryObj()    使用该二维数组来做存放数据的字典 
Dim MaxIndex      MaxIndex则是ArryObj开始的最大上标 
Dim CurIndex      字典指针,用来指向ArryObj的指针 
Dim C_ErrCode      错误代码号 


Private Sub Class_Initialize 
CurIndex=0      从下标0开始 
C_ErrCode=0      0表示没有任何错误 
MaxIndex=100      默认的大小 
Redim ArryObj(1,MaxIndex)  定义一个二维的数组 
End Sub 

Private Sub Class_Terminate 
Erase ArryObj  清除数组 
End Sub 

Public Property Get ErrCode 返回错误代码 
ErrCode=C_ErrCode 
End Property 

Public Property Get Count  返回数据的总数,只返回CurIndex当前值-1即可. 
Count=CurIndex 
End Property 

Public Property Get Keys  返回字典数据的全部Keys,返回数组. 
Dim KeyCount,ArryKey(),I 
KeyCount=CurIndex-1 
Redim ArryKey(KeyCount) 

For I=0 To KeyCount 
    ArryKey(I)=ArryObj(0,I) 
    Next 

Keys=ArryKey 
Erase ArryKey 
End Property 

Public Property Get Items  返回字典数据的全部Values,返回数组. 
  Dim KeyCount,ArryItem(),I 
  KeyCount=CurIndex-1 
  Redim ArryItem(KeyCount) 

  For I=0 To KeyCount 
      If isObject(ArryObj(1,I)) Then 
      Set ArryItem(I)=ArryObj(1,I) 
  Else 
        ArryItem(I)=ArryObj(1,I) 
  End If 
  Next 

  Items=ArryItem 
  Erase ArryItem 
End Property 

Public Property Let Item(sKey,sVal) 取得sKey为Key的字典数据 
  If sIsEmpty(sKey) Then 
  Exit Property 
  End If 

  Dim i,iType 

  iType=GetType(sKey) 
  If iType=1 Then 如果sKey为数值型的则检查范围 
  If sKey>CurIndex Or sKey <1 Then 
  C_ErrCode=2 
Exit Property 
End If 
  End If 

  If iType=0 Then 
  For i=0 to CurIndex-1 
    If ArryObj(0,i)=sKey Then 
    If isObject(sVal) Then 
      Set ArryObj(1,i)=sVal 
  Else 
    ArryObj(1,i)=sVal 
  End If 
  Exit Property 
  End If 
  Next 
  ElseIf iType=1 Then 
      sKey=sKey-1 
    If isObject(sVal) Then 
      Set ArryObj(1,sKey)=sVal 
  Else 
    ArryObj(1,sKey)=sVal 
  End If 
  Exit Property 
  End If 
  C_ErrCode=2        ErrCode为2则是替换或个为sKey的字典数据时找不到数据 
End Property 

Public Property Get Item(sKey) 
  If sIsEmpty(sKey) Then 
    Item=Null 
  Exit Property 
End If 
  
Dim i,iType 
  
iType=GetType(sKey) 
If iType=1 Then 如果sKey为数值型的则检查范围 
  If sKey>CurIndex Or sKey <1 Then 
    Item=Null 
  Exit Property 
End If 
  End If 

If iType=0 Then 
For i=0 to CurIndex-1 
    If ArryObj(0,i)=sKey Then 
    If isObject(ArryObj(1,i)) Then 
      Set Item=ArryObj(1,i) 
  Else 
    Item=ArryObj(1,i) 
  End If 
  Exit Property 
  End If 
  Next 
  ElseIf iType=1 Then 
    sKey=sKey-1 
    If isObject(ArryObj(1,sKey)) Then 
      Set Item=ArryObj(1,sKey) 
  Else 
    Item=ArryObj(1,sKey) 
  End If 
  Exit Property 
  End If 

  Item=Null 
End Property 

Public Sub Add(sKey,sVal) 添加字典 
  On Error Resume Next 
  If Exists(sKey) Or C_ErrCode=9 Then 
  C_ErrCode=1          Key值不唯一(空的Key值也不能添加数字) 
  Exit Sub 
End If 

  If CurIndex>MaxIndex Then 
  MaxIndex=MaxIndex+1      每次增加一个标数,可以按场合需求改为所需量 
  Redim Preserve ArryObj(1,MaxIndex) 
End If 

ArryObj(0,CurIndex)=Cstr(sKey)    sKey是标识值,将Key以字符串类型保存 
if isObject(sVal) Then 
  Set ArryObj(1,CurIndex)=sVal    sVal是数据 
Else 
  ArryObj(1,CurIndex)=sVal    sVal是数据 
End If 

CurIndex=CurIndex+1 
End Sub 

Public Sub Insert(sKey,nKey,nVal,sMethod) 
If Not Exists(sKey) Then 
C_ErrCode=4 
Exit Sub 
End If 

If Exists(nKey) Or C_ErrCode=9 Then 
C_ErrCode=4          Key值不唯一(空的Key值也不能添加数字) 
Exit Sub 
End If 

sType=GetType(sKey)        取得sKey的变量类型 

Dim ArryResult(),I,sType,subIndex,sAdd 

ReDim ArryResult(1,CurIndex)  定义一个数组用来做临时存放地 

if sIsEmpty(sMethod) Then sMethod="b"  为空的数据则默认是"b" 
sMethod=lcase(cstr(sMethod)) 
subIndex=CurIndex-1 
sAdd=0 
If sType=0 Then            字符串类型比较 
If sMethod="1" Or sMethod="b" Or sMethod="back" Then 将数据插入sKey的后面 
For I=0 TO subIndex 
ArryResult(0,sAdd)=ArryObj(0,I) 

If IsObject(ArryObj(1,I)) Then 
Set ArryResult(1,sAdd)=ArryObj(1,I) 
Else 
ArryResult(1,sAdd)=ArryObj(1,I) 
End If 

If ArryObj(0,I)=sKey Then 插入数据 
sAdd=sAdd+1 
ArryResult(0,sAdd)=nKey 
If IsObject(nVal) Then 
Set ArryResult(1,sAdd)=nVal 
Else 
ArryResult(1,sAdd)=nVal 
End If 
End If 

sAdd=sAdd+1 
Next 

Else 
For I=0 TO subIndex 
If ArryObj(0,I)=sKey Then 插入数据 
ArryResult(0,sAdd)=nKey 
If IsObject(nVal) Then 
Set ArryResult(1,sAdd)=nVal 
Else 
ArryResult(1,sAdd)=nVal 
End If 
sAdd=sAdd+1 
End If 
ArryResult(0,sAdd)=ArryObj(0,I) 

If IsObject(ArryObj(1,I)) Then 
Set ArryResult(1,sAdd)=ArryObj(1,I) 
Else 
ArryResult(1,sAdd)=ArryObj(1,I) 
End If 

sAdd=sAdd+1 
Next 
End If 
ElseIf sType=1 Then 
sKey=sKey-1            减1是为了符合日常习惯(从1开始) 

If sMethod="1" Or sMethod="b" Or sMethod="back" Then 将数据插入sKey的后面 
For I=0 TO sKey        取sKey前面部分数据 
ArryResult(0,I)=ArryObj(0,I) 
If IsObject(ArryObj(1,I)) Then 
Set ArryResult(1,I)=ArryObj(1,I) 
Else 
ArryResult(1,I)=ArryObj(1,I) 
End If 
Next 
插入新的数据 
ArryResult(0,sKey+1)=nKey 
If IsObject(nVal) Then 
Set ArryResult(1,sKey+1)=nVal 
Else 
ArryResult(1,sKey+1)=nVal 
End If 
取sKey后面的数据 
For I=sKey+1 TO subIndex 
ArryResult(0,I+1)=ArryObj(0,I) 
If IsObject(ArryObj(1,I)) Then 
Set ArryResult(1,I+1)=ArryObj(1,I) 
Else 
ArryResult(1,I+1)=ArryObj(1,I) 
End If 
Next 
Else 
For I=0 TO sKey-1        取sKey-1前面部分数据 
ArryResult(0,I)=ArryObj(0,I) 
If IsObject(ArryObj(1,I)) Then 
Set ArryResult(1,I)=ArryObj(1,I) 
Else 
ArryResult(1,I)=ArryObj(1,I) 
End If 
Next 
插入新的数据 
ArryResult(0,sKey)=nKey 
If IsObject(nVal) Then 
Set ArryResult(1,sKey)=nVal 
Else 
ArryResult(1,sKey)=nVal 
End If 
取sKey后面的数据 
For I=sKey TO subIndex 
ArryResult(0,I+1)=ArryObj(0,I) 
If IsObject(ArryObj(1,I)) Then 
Set ArryResult(1,I+1)=ArryObj(1,I) 
Else 
ArryResult(1,I+1)=ArryObj(1,I) 
End If 
Next 
End If 
Else 
C_ErrCode=3 
Exit Sub 
End If 

ReDim ArryObj(1,CurIndex) 重置数据 

For I=0 To CurIndex 
ArryObj(0,I)=ArryResult(0,I) 
If isObject(ArryResult(1,I)) Then 
Set ArryObj(1,I)=ArryResult(1,I) 
Else 
ArryObj(1,I)=ArryResult(1,I) 
End If 
Next 

MaxIndex=CurIndex 
Erase ArryResult 
CurIndex=CurIndex+1    Insert后数据指针加一 
End Sub 

Public Function Exists(sKey)  判断存不存在某个字典数据 
If sIsEmpty(sKey) Then 
Exists=False 
Exit Function 
End If 

Dim I,vType 
vType=GetType(sKey) 

If vType=0 Then 
For I=0 To CurIndex-1 
If ArryObj(0,I)=sKey Then 
Exists=True 
Exit Function 
End If 
Next 
ElseIf vType=1 Then 
If sKey <=CurIndex And sKey>0 Then 
Exists=True 
Exit Function 
End If 
End If 

Exists=False 
End Function 

Public Sub Remove(sKey)        根据sKey的值Remove一条字典数据 
If Not Exists(sKey) Then 
C_ErrCode=3 
Exit Sub 
End If 

sType=GetType(sKey)        取得sKey的变量类型 

Dim ArryResult(),I,sType,sAdd 

ReDim ArryResult(1,CurIndex-2)  定义一个数组用来做临时存放地 
sAdd=0 
If sType=0 Then            字符串类型比较 
For I=0 TO CurIndex-1 
If ArryObj(0,I) <>sKey Then 
    ArryResult(0,sAdd)=ArryObj(0,I) 

If IsObject(ArryObj(1,I)) Then 
    Set ArryResult(1,sAdd)=ArryObj(1,I) 
Else 
    ArryResult(1,sAdd)=ArryObj(1,I) 
End If 

sAdd=sAdd+1 
End If 
Next 

ElseIf sType=1 Then 
sKey=sKey-1            减1是为了符合日常习惯(从1开始) 
For I=0 TO CurIndex-1 
If I <>sKey Then 
    ArryResult(0,sAdd)=ArryObj(0,I) 
If IsObject(ArryObj(1,I)) Then 
Set ArryResult(1,sAdd)=ArryObj(1,I) 
Else 
ArryResult(1,sAdd)=ArryObj(1,I) 
  End If 

sAdd=sAdd+1 
End If 
Next 
Else 
C_ErrCode=3 
Exit Sub 
End If 

MaxIndex=CurIndex-2 
ReDim ArryObj(1,MaxIndex) 重置数据 

For I=0 To MaxIndex 
ArryObj(0,I)=ArryResult(0,I) 
If isObject(ArryResult(1,I)) Then 
Set ArryObj(1,I)=ArryResult(1,I) 
Else 
ArryObj(1,I)=ArryResult(1,I) 
End If 
Next 

Erase ArryResult 
CurIndex=CurIndex-1    减一是Remove后数据指针 
End Sub 

Public Sub RemoveAll 全部清空字典数据,只Redim一下就OK了 
Redim ArryObj(MaxIndex) 
CurIndex=0 
End Sub 

Public Sub ClearErr  重置错误 
C_ErrCode=0 
End Sub 

Private Function sIsEmpty(sVal) 判断sVal是否为空值 
If IsEmpty(sVal) Then 
C_ErrCode=9          Key值为空的错误代码 
sIsEmpty=True 
Exit Function 
End If 

If IsNull(sVal) Then 
C_ErrCode=9          Key值为空的错误代码 
sIsEmpty=True 
Exit Function 
End If 

If Trim(sVal)="" Then 
C_ErrCode=9          Key值为空的错误代码 
sIsEmpty=True 
Exit Function 
End If 

sIsEmpty=False 
End Function 

Private Function GetType(sVal)  取得变量sVal的变量类型 
dim sType 
sType=TypeName(sVal) 
Select Case sType 
Case "String" 
GetType=0 
Case "Integer","Long","Single","Double" 
GetType=1 
Case Else 
GetType=-1 
End Select 

End Function 

End Class 

 

4、1.asp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
  <title> new document </title> 
  <meta name="generator" content="editplus" /> 
  <meta name="author" content="" /> 
  <meta name="keywords" content="" /> 
  <meta name="description" content="" /> 
</head> 

<body> 
  <table> 
  <form name="upfile"> 
  <tr> 
  <td> <input type="text" id="filePath" name="filePath" size="40"> </td> 
<td> <iframe height="30" width="320" frameborder="0" scrolling="no" src="up.asp"> </iframe> </td> </tr> </form> </table> </body> </html>

 
说明:upfile.asp为上传类,up.asp为调用文件,1.asp为演示文件,dic.asp为避免iis服务器dictonary组件不可用时的自写义dictonary组件也可以将其修改为iis的dictonary组件

一个能防止改名木马漏洞的无组件上传类

标签:

原文地址:http://www.cnblogs.com/mqmelon/p/4757545.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!