Any.Prototype as a struct-pointer DllCall argument or field value crashes: IsCArrayOf dereferences a null base (since 8fcbf453)

Abierto Apto para principiantes
#380 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
76/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
cpp
Área
backend

Línea de trabajo

Lee Object::IsCArrayOf en source/script_object.cpp y sus llamadores en source/lib/DllCall.cpp; el issue identifica la desreferencia de una base nula y proporciona dos reproducciones. Ejecuta ambas reproducciones en x86 y x64 y, después, comprueba que Int32[3] siga convirtiéndose en Int32.Ptr. La tarea está terminada cuando ambos casos de Any.Prototype generen un TypeError sin provocar un fallo.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

8fcbf453 ("Changed typed properties and DllCall to let S.Array decay to S.Ptr") added Object::IsCArrayOf, which calls aCandidate->Base()->GetStructInfo() without checking the base. Any.Prototype has no base. Both callers reach it with any object they don't otherwise recognize: the XX.Ptr parameter branch in DllCall, and the typed pointer-field setter.

Repro
Out(s) => FileAppend(s "`n", "*")   ; stdout: AutoHotkey64.exe repro.ahk | more
try Out("DllCall: " DllCall("kernel32\lstrlenW", Int32.Ptr, Any.Prototype, "Int"))
catch Error as e
    Out("DllCall: " Type(e) ": " e.Message)
Out("after DllCall")
Out(s) => FileAppend(s "`n", "*")
struct P {
    p : Int32.Ptr
}
s := P()
try s.p := Any.Prototype, Out("field: accepted")
catch Error as e
    Out("field: " Type(e) ": " e.Message)
Out("after field")
  • alpha.33 (x64 and x86): DllCall: TypeError: Expected a Number but got a Prototype. and field: TypeError: Expected an Int32 but got a Prototype., each followed by its after line.
  • alpha.34, alpha.36, alpha.37 and alpha.38 (x64 and x86): "Critical Error: Invalid memory read/write." at the DllCall line and at the field assignment.
Possible fix
 bool Object::IsCArrayOf(IObject *aCandidate, Object *aPrototype)
 {
-	if (!aCandidate)
+	auto base = aCandidate ? aCandidate->Base() : nullptr;
+	if (!base) // Any.Prototype has no base.
 		return false;
-	auto &vsi = *aCandidate->Base()->GetStructInfo();
+	auto &vsi = *base->GetStructInfo();

With this, both repros throw the same TypeError as alpha.33, and an Int32[3] still decays to an Int32.Ptr argument or field value. I've applied it in a fork as TrueCrimeDev/AutoHotkey@a6763d81.

Reproduced with the official AutoHotkey_2.1-alpha.38.zip (AutoHotkey64.exe and AutoHotkey32.exe) and compared with the official alpha.33, alpha.34, alpha.36 and alpha.37 zips. script_object.cpp and DllCall.cpp are unchanged at 42ddbabc.

Lenguaje dominante
C++
Estrellas
13.4k
Forks
1.2k
Merge medio
2 d 4 h
PR fusionados (30 d)
3

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de AutoHotkey/AutoHotkey

Todos los issues de AutoHotkey/AutoHotkey

Issues similares

Más issues de C++

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.