Skip to content

[UPSTREAM] binary/convert TYPE_BINARY ignora bin/head al copiar (regresion red/red 6a58eed4c) #4

@anlaco

Description

@anlaco

Nota: Este issue documenta un bug originario del proyecto upstream red/red. Anlaco no contribuye al upstream, pero se registra aquí para awareness del equipo y como referencia del fix local aplicado en 9d1d5dd2e.

Resumen

runtime/datatypes/binary.reds:1007 — el handler TYPE_BINARY de binary/convert, introducido por upstream en commit 6a58eed4c ("FEAT: improves INSERT and APPEND implementation for binary! series."), calcula la longitud restando bin/head correctamente, pero move-memory copia desde s2/offset (head del buffer subyacente) en vez de s2/offset + bin/head.

Código afectado (pre-fix)

TYPE_BINARY [
    bin: as red-binary! value
    s2: GET_BUFFER(bin)
    added: (as-integer s2/tail - s2/offset) - bin/head    ;-- length OK, descuenta head
    if all [part > 0 part < added][added: part]
    if mode = MODE_COUNT [return added]
    move-memory p as byte-ptr! s2/offset added            ;-- BUG: ignora bin/head
    added
]

Síntoma

append sobre un binary! que ha sido skip-eado (y opcionalmente reverse-eado in-place) copia desde el inicio del buffer subyacente, no desde la posición skipped. Resultado: copia bytes equivocados —típicamente ceros o datos pre-reverse.

Reproductor real (este repo)

system2/utils/int-to-bin.red define:

to-bin16: func [v [integer!]][reverse skip to binary! to integer! v 2]
to-bin32: func [v [integer!]][reverse to binary! to integer! v]

Usado por system2/formats/ELF64.red y PE.red para construir headers binarios:

append job/buffer to-bin16 2     ;-- e_type EXEC
append job/buffer to-bin16 62    ;-- e_machine EM_X86_64

Tras compilar system2/tests/x64/hello.reds con el red recién builkdeado de master, el ELF64 generado tiene e_type=0, e_machine=0, e_ehsize=0, e_phentsize=0, e_phnum=0. El kernel rechaza con "Formato de ejecutable incorrecto":

$ file ./hello
./hello: ELF 64-bit LSB no file type, no machine, version 1 (GNU/Linux)
$ ./hello
bash: ./hello: no se puede ejecutar fichero binario: Formato de ejecutable incorrecto

Dump del header corrupto:

00000010: 0000 0000 0100 0000 2001 4000 0000 0000
          ^^^^_^^^^_^^^^^^^^_^^^^^^^^^^^^^^^^^^^^
          e_type | e_machine | e_version | e_entry
            0    |     0     |     1     | 0x401200

e_type y e_machine deberían ser 02 00 y 3E 00 (LE 2 y LE 62). Aparecen como ceros porque to-bin16 produce un binario con bytes correctos en posición 3-4 del buffer subyacente, pero append copia desde posición 1-2 (los ceros del entero original).

Fix

-                move-memory p as byte-ptr! s2/offset added
+                move-memory p (as byte-ptr! s2/offset) + bin/head added

Verificación

Tras el fix:

  • to-bin16 2 → append correcto de 02 00.
  • e_type=2, e_machine=62 correctos en el ELF.
  • ./hello ejecuta y produce "hello, x64 linux" con exit 0.
  • file ./hello reporta "ELF 64-bit LSB executable, x86-64".

Alcance del bug en upstream

Cualquier consumidor de append <buf> (skip-ed binary) está afectado. En particular:

  • system2/formats/ELF64.red (Linux x86-64).
  • system2/formats/PE.red (Windows): líneas 760, 799, 1084, 1102, 1121, 1132, 1144, 1155, 1207. Probable que builds de Windows con master post-6a58eed4c produzcan PEs corruptos.

Referencias

  • Fix local: commit 9d1d5dd2e en rama rsc2-x64.
  • Auditoría general de la migración x64: docs/plans/auditoria-x64.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingupstreamBug/info originario de red/red upstream; documentado aqui para awareness, no se contribuye upstream

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions