2015-12-09 33 views
17

Zawsze stosować następujący skrypt, aby przesłać pliki w klasycznej asp, ale przestał działać daje mi ten błądPrzesyłanie pliku w klasycznej asp

Błąd VBScript runtime 800a01a8
obiektu wymaganej „produkt (. ..)”

badałem trochę i myślę, że problem jest w upload.asp plików z BuildUploadRequest funkcji, ale ja naprawdę nie mogę zrozumieć, dlaczego

formularz

<form method="POST" action="landing-page.asp" ENCTYPE="multipart/form-data"> 
    <input type="file" name="file"> 
    <input type="hidden" name="key" value="0"> 
    <input type="submit" name="send" value="1"> 
</form> 

strona gdzie wyląduje forma

byteCount = Request.TotalBytes 
RequestBin = Request.BinaryRead(byteCount) 

Dim UploadRequest 
Set UploadRequest = CreateObject("Scripting.Dictionary") 
BuildUploadRequest(RequestBin) '//function defined in upload.asp 
if UploadRequest.Item("key").Item("Value")="0" then '//this is the line giving the error 
    '//code here... 
end if 

upload.asp

Sub BuildUploadRequest(RequestBin) 
    PosBeg = 1 
    PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(13))) 
    boundary = MidB(RequestBin,PosBeg,PosEnd-PosBeg)  
    boundaryPos = InstrB(1,RequestBin,boundary) 

    '//Get all data inside the boundaries 
    Do until (boundaryPos=InstrB(RequestBin,boundary & getByteString("--"))) 
     '//Members variable of objects are put in a dictionary object 
     Dim UploadControl 
     Set UploadControl = CreateObject("Scripting.Dictionary") 
     '//Get an object name 
     Pos = InstrB(BoundaryPos,RequestBin,getByteString("Content-Disposition")) 
     Pos = InstrB(Pos,RequestBin,getByteString("name=")) 
     PosBeg = Pos+6 
     PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(34))) 
     Name = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg)) 
     PosFile = InstrB(BoundaryPos,RequestBin,getByteString("filename=")) 
     PosBound = InstrB(PosEnd,RequestBin,boundary) 
     '//Test if object is of file type 
     If PosFile<>0 AND (PosFile<PosBound) Then 
      '//Get Filename, content-type and content of file 
      PosBeg = PosFile + 10 
      PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(34))) 
      FileName = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg)) 
      '//Add filename to dictionary object 
      UploadControl.Add "FileName", FileName 
      Pos = InstrB(PosEnd,RequestBin,getByteString("Content-Type:")) 
      PosBeg = Pos+14 
      PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(13))) 
      '//Add content-type to dictionary object 
      ContentType = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg)) 
      UploadControl.Add "ContentType",ContentType 
      '//Get content of object 
      PosBeg = PosEnd+4 
      PosEnd = InstrB(PosBeg,RequestBin,boundary)-2 
      Value = MidB(RequestBin,PosBeg,PosEnd-PosBeg) 
     Else 
      '//Get content of object 
      Pos = InstrB(Pos,RequestBin,getByteString(chr(13))) 
      PosBeg = Pos+4 
      PosEnd = InstrB(PosBeg,RequestBin,boundary)-2 
      Value = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg)) 
     End If 
     '//Add content to dictionary object 
     UploadControl.Add "Value" , Value 
     '//Add dictionary object to main dictionary 
     '//response.write name & "<br>" 
     UploadRequest.Add name, UploadControl 
     '//Loop to next object 
     BoundaryPos=InstrB(BoundaryPos+LenB(boundary),RequestBin,boundary) 
    Loop 
End Sub 

'//String to byte string conversion 
Function getByteString(StringStr) 
    For i = 1 to Len(StringStr) 
    charx = Mid(StringStr,i,1) 
    getByteString = getByteString & chrB(AscB(charx)) 
    Next 
End Function 

'//Byte string to string conversion 
Function getString(StringBin) 
getString ="" 
For intCount = 1 to LenB(StringBin) 
    getString = getString & chr(AscB(MidB(StringBin,intCount,1))) 
Next 
End Function 

Ten kod zawsze pracował prawidłowo w każdym projekcie, ale teraz to nie działa wszędzie. Więc nie mogę po prostu edytować i wykorzystywać inną funkcję, muszę zrozumieć, dlaczego to nie działa już

+0

Czy dodałeś komentarze ręcznie? Powód, dla którego pytam, to składnia komentarzy VBScript używa '' 'not' //', która spowoduje błąd skryptu z błędem składni. – Lankymart

+0

Tak, zrobiłem, ponieważ gdyby nie układ pytań wyglądał okropnie –

+1

Dostosowałem go do używania komentarzy VBScript. – Lankymart

Odpowiedz

21

Fix # 1 - Uninstall "KB3104002 Zbiorcza aktualizacja zabezpieczeń dla IE11"

Fix # 2 - Skopiuj wszystkie tablice bajtów w ciąg wartości bajtowych i pracy z tym, lub dostarczyć substytut instrb to robi swoją własną iterację na macierzy.

Function InstrBNew(startPos, inputArray, searchChar) 

    if LenB(searchChar) = 1 Then 
    Dim loc 
    For loc = startPos to Lenb(inputArray) 
     if MidB(inputArray, loc, 1) = searchChar then Exit For 
    Next 
    InstrBNew = loc 
    Else 
    InstrBNew = InstrB(startPos, inputArray, searchChar) 
    End If 
End Function 

Fix # 3 - Microsoft wydała poprawkę. To będzie dotyczyć wszystkich w styczniu 2016 roku. Możesz to zrobić wcześniej. https://support.microsoft.com/en-us/kb/3125446

Problem polega na tym, że funkcja InstrB w vbScript teraz zwraca wartość 1 w następujących warunkach.

  • Gdy szukasz tablicę bajtowy (takich jak Response.BinaryRead). Nie jest to powszechne w ASP lub VBScript, ale przesyłanie plików jest jednym z tych momentów, kiedy to robisz.
  • Gdy szukasz jeden bajt

Jeśli szukasz ciąg, lub jeśli szukasz wzorzec wielobajtową, następnie InstrB działa prawidłowo.

PosEnd = InstrB(PosBeg, ByteArray, chrb(13)) 

Na moich złamanych systemów, ta funkcja zawsze zwraca 1, mimo że nie ma wartości bajt 13 w pozycji 1. Zwraca 1 dla dowolnej wartości podczas przeszukiwania tablicy bajtów.Klasyczne komponenty do przesyłania plików ASP, dlatego wszyscy jesteśmy w tym wątku, napotykają tę sytuację, ponieważ analizują tę tablicę bajtów, szukając ograniczników.

PosEnd = InstrB(PosBeg,ByteArray,getByteString("FormBoundary")) 
PosEnd = InstrB(PosBeg,ByteArray,getByteString(vbCRLF)) 
PosEnd = InstrB(PosBeg,"Normal string", chrb(103)) ' Search for letter g in a string 

Powyższe linie działają poprawnie i zgodnie z oczekiwaniami. Wielobajtowe wyszukiwania i dopasowania względem łańcucha działają w oczekiwaniu.

Ten problem uderzył mnie jednocześnie na wielu serwerach zeszłej nocy. Widziałem, że aktualizacje systemu Windows działały także ostatniej nocy. Zawężając go, okazało się, że MS15-124 (KB3104002 Zbiorcza aktualizacja zabezpieczeń dla IE11) zawiera aktualizację dla vbscript.dll. Usunąłem tę aktualizację i teraz kod powraca do prawidłowego działania.

Złożyłem problem w ich systemie "IE Connect", ponieważ został uwzględniony w aktualizacji IE, ale nie jestem pewien, czy to właściwe miejsce.

Dołączyłem walizkę testową. W uszkodzonych systemach zwróci "5, 1, 5". W systemach roboczych powróci "5, 5, 5"

Nadzieja na naprawę. Część tego starego kodu działa na systemach, do których nie mam dostępu.

' Test.vbs 
Dim byteArray, byteArray2, byteArray3, bPosition 
Dim responseText 

' byte string 
' "hello hello" 
byteArray = chrb(104) & chrb(101) & chrb(108) & chrb(108) & chrb(111) & chrb(32) & chrb(104) & chrb(101) & chrb(108) & chrb(108) & chrb(111) & chrb(0) 

' byte array - What Response.BinaryRead is 
byteArray2 = TextToBytes(byteArray) 

' Vartype: http://stackoverflow.com/questions/3281355/get-the-type-of-a-variable-in-vbscript 
ResponseText = ResponseText + "blen: " & lenb(byteArray) & vbCRLF 
ResponseText = ResponseText + "type: " & vartype(byteArray) & vbCRLF 

ResponseText = ResponseText + "blen: " & lenb(byteArray2) & vbCRLF 
ResponseText = ResponseText + "type: " & vartype(byteArray2) & vbCRLF 

bPosition = instrb(1, byteArray, chrb(111)) 
ResponseText = ResponseText + "Position in string: " & bPosition & vbCRLF 

bPosition = instrb(1, byteArray2, chrb(111)) 
ResponseText = ResponseText + "Position in byte array: " & bPosition & vbCRLF 

bPosition = instrb(1, byteArray2, chrb(111) & chrb(32)) 
ResponseText = ResponseText + "Position in byte array: " & bPosition & vbCRLF 

WScript.Echo ResponseText 

' Converts a string (8) to a vbArray of bytes (8192 + 17) 
' I'm not sure how else to create a vbArray of bytes. It does not seem to be a common data type in vbscript 
Private Function TextToBytes(ByRef pbinBinaryData) 
    Dim lobjRs 
    Dim llngLength 
    Dim lbinBuffer 
    CONST adLongVarBinary = 205 
    llngLength = LenB(pbinBinaryData) 
    Set lobjRs = CreateObject("ADODB.Recordset") 
    Call lobjRs.Fields.Append("BinaryData", adLongVarBinary, llngLength) 
    Call lobjRs.Open() 
    Call lobjRs.AddNew() 
    Call lobjRs.Fields("BinaryData").AppendChunk(pbinBinaryData) 
    Call lobjRs.Update() 
    lbinBuffer = lobjRs.Fields("BinaryData").GetChunk(llngLength) 
    Call lobjRs.Close() 
    Set lobjRs = Nothing 
    TextToBytes = lbinBuffer 
End Function 
+5

Niesamowita praca detektywa! – Lankymart

+3

DZIĘKUJEMY !!!!!!!!!! usunięto aktualizację i zadziałało! oto jak usunąć aktualizację http://windows.microsoft.com/en-us/windows/remove-update#1TC=windows-7 –

+1

Polecam Fix # 3 i zastosować poprawkę zamiast usuwania aktualizacji. – Dijkgraaf

1

Miałem ten sam problem w klasycznym ASP, InStrB nagle powrocie 1 nawet kiedy zatwierdzone debugger, że powinien nie znaczy postać ta została w pozycji 17.

napisałem następującą funkcję zastępczą dla InStrB (tylko do użytku przy szukaniu 1 znaku). Jestem zagorzałym programistą VBS, więc możesz to wyczyścić. Ale to nie wydają się działać ...

Private Function findCharInStrB(startPos, inputArray, searchChar) 
    Dim loc 
    For loc = startPos to Len(inputArray) 
    if MidB(inputArray, loc, 1) = searchChar then Exit For 
    Next 
    findCharInStrB = loc 
End Function 
0

Nie mogę odpowiedzieć na oryginalnym komentarzem powodu niskiej rep, ale w przypadku, gdy nie można usunąć aktualizację przy użyciu zwykłych metod Panel sterowania jak ja mogłam „t (nie stawiła się na liście dezinstalacji) tutaj jest, jak to zrobić z PowerShell, a następnie w wierszu poleceń:

Tymczasowe obejście Odinstaluj«KB3104002 Zbiorcza aktualizacja zabezpieczeń dla IE11»:

Wykonaj następujące czynności, aby sprawdzić, czy aktualizacja została zainstalowana:

  1. Stuknij w klawisz Windows (lub kliknij prawym klawiszem Windows, itd.) I wpisz `cmd` i naciśnij enter.
  2. Wpisz `powershell` i naciśnij enter.
  3. Użyj polecenia `get-hotfix -id KB3104002`, aby sprawdzić, czy aktualizacja jest zainstalowana. Zobaczysz listę zwróconą wraz z datą instalacji aktualizacji, jeśli tak jest.

Jeśli aktualizacja jest zainstalowana, dalej:

  1. Jeśli wciąż jesteś w typie PowerShell `WYPŁYNIĘCIE opuścić.
  2. Użyj polecenia `wusa/uninstall/kb: 3104002`, aby odinstalować poprawkę
  3. Uruchom ponownie!

Zastrzeżenie: KB3104002 jest wymieniony jako „Update krytycznej Bezpieczeństwa” according to Microsoft więc nie polecam ignorując tę ​​aktualizację na zawsze, ale jako tymczasowe rozdzielczości do zagadnień ta aktualizacja powoduje, to co wybrałem zrobić. Myślę, że Microsoft wyda aktualizację tej aktualizacji, która dotyczy rzeź, która najwyraźniej powoduje, że kod ASP jest nadal w użyciu.