mvc form data file-upload vbscript asp-classic

file upload - form - Subiendo un archivo en ASP clásico



upload file web api 2 c# (5)

Microsoft ha lanzado un Hotfix para solucionar este problema.

https://support.microsoft.com/en-us/kb/3125446

Siempre he usado la siguiente secuencia de comandos para cargar archivos en ASP clásico, pero dejó de funcionar y me dio este error.

vbscript runtime error 800a01a8
objeto requerido ''Artículo (...)''

Investigué un poco y creo que el problema está en el archivo upload.asp con la función BuildUploadRequest, pero realmente no puedo entender por qué

formar

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

página donde aterriza el formulario

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

subir.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

Este código siempre ha funcionado correctamente en todos los proyectos, pero ahora no funciona en todas partes. Así que no puedo editar y usar otra función, necesito entender por qué ya no funciona.


No puedo responder al comentario original debido a las bajas repeticiones, pero en caso de que no pueda eliminar la actualización usando los métodos normales del Panel de Control, como no pude (no apareció en la lista de desinstalaciones), aquí está cómo lo haces con Powershell y la línea de comando:

Solución temporal para desinstalar "KB3104002 Actualización de seguridad acumulativa para IE11":

Haga lo siguiente para verificar si hay una actualización instalada:

  1. Toque la tecla de Windows (o haga clic con el botón derecho en el botón de Windows, etc.) y escriba `cmd` y presione enter.
  2. Escribe `powershell` y pulsa enter.
  3. Use el comando `get-hotfix -id KB3104002` para averiguar si la actualización está instalada. Verá una lista devuelta con la fecha de instalación de esta actualización, si es.

Si la actualización está instalada, continúa:

  1. Si todavía estás en powershell, escribe `exit` para salir.
  2. Use el comando `wusa / uninstall / kb: 3104002` para desinstalar el parche
  3. ¡Reiniciar!

Advertencia: KB3104002 aparece como una "Actualización de seguridad crítica" de acuerdo con Microsoft, por lo que no recomendaría ignorar esta actualización para siempre, pero como una resolución temporal a los problemas que causa esta actualización, esto es lo que elegí hacer. Estoy pensando que Microsoft emitirá una actualización de esta actualización que se ocupa de la carnicería que aparentemente está causando con el código ASP todavía en uso.


Pruebe este código de carga (crédito a Lewis Moten) en su lugar: http://planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=8525&lngWId=4

Me encontré con el mismo problema recientemente al migrar un sitio a una versión más nueva de Windows Server. Usar el código de carga de Lewis Moten solucionó el problema.

En caso de que el enlace muera, el código también se publica en esta respuesta .


Tuve el mismo problema en el ASP clásico, InStrB devolvió repentinamente 1, incluso cuando validé en el depurador que no debería, es decir, el carácter en cuestión estaba en la posición 17.

Escribí la siguiente función de reemplazo para InStrB (solo para uso cuando busco 1 char). Soy un programador de VBS de mierda, así que, siéntase libre de limpiar esto. Pero parece funcionar ...

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


Solución # 1 : desinstale "KB3104002 Actualización de seguridad acumulativa para IE11"

Corrección nº 2 : copie todas las matrices de bytes en una cadena de valores de bytes y trabaje con eso, o proporcione un sustituto para instrb que realice su propia iteración sobre la matriz.

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

Solución # 3 : Microsoft ha lanzado una revisión. Esto será para todos en enero de 2016. Puede obtenerlo temprano aquí. https://support.microsoft.com/en-us/kb/3125446

El problema parece ser que la función de InstrB en vbScript ahora devuelve un valor de 1 en las siguientes condiciones.

  • Cuando busca una matriz de bytes (como Response.BinaryRead). Esto no es muy común en ASP o VBScript, pero la carga de archivos es uno de esos momentos en los que lo estás haciendo.
  • Cuando buscas un solo byte

Si está buscando una cadena, o si está buscando un patrón multibyte, entonces InstrB funciona correctamente.

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

En mis sistemas rotos, esta función siempre devuelve un 1, aunque no haya un valor de byte 13 en la posición 1. Devuelve 1 para cualquier valor al buscar una matriz de bytes. Los componentes clásicos de carga de archivos ASP, por lo que todos estamos en este hilo, se encuentran en esta situación porque están analizando esa matriz de bytes en busca de delimitadores.

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

Estas líneas anteriores funcionan bien y como se esperaba. Búsquedas multibyte y coincidencias contra una cadena de trabajo esperada.

Este problema me golpeó simultáneamente en varios servidores anoche. Vi que las actualizaciones del sistema de Windows también funcionaron anoche Al reducirlo, encontré que MS15-124 (KB3104002 Actualización de seguridad acumulativa para IE11) contenía una actualización para vbscript.dll. Quité esta actualización y ahora el código vuelve a funcionar correctamente.

Presenté un problema en su sistema "IE Connect", ya que estaba incluido en una actualización de IE, pero no estoy seguro de que ese sea el lugar correcto.

He adjuntado un caso de prueba. En sistemas rotos, devolverá "5, 1, 5". En sistemas de trabajo devolverá "5, 5, 5"

Esperando una solución. Parte de este código antiguo se ejecuta en sistemas a los que no tengo acceso.

'' 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://.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