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.
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:
- 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.
- Escribe `powershell` y pulsa enter.
- 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:
- Si todavía estás en powershell, escribe `exit` para salir.
- Use el comando `wusa / uninstall / kb: 3104002` para desinstalar el parche
- ¡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