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.
Resumen
runtime/datatypes/binary.reds:1007— el handlerTYPE_BINARYdebinary/convert, introducido por upstream en commit6a58eed4c("FEAT: improves INSERT and APPEND implementation for binary! series."), calcula la longitud restandobin/headcorrectamente, peromove-memorycopia desdes2/offset(head del buffer subyacente) en vez des2/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
appendsobre unbinary!que ha sidoskip-eado (y opcionalmentereverse-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.reddefine:Usado por
system2/formats/ELF64.redyPE.redpara construir headers binarios:Tras compilar
system2/tests/x64/hello.redscon elredrecién builkdeado de master, el ELF64 generado tienee_type=0,e_machine=0,e_ehsize=0,e_phentsize=0,e_phnum=0. El kernel rechaza con "Formato de ejecutable incorrecto":Dump del header corrupto:
e_typeye_machinedeberían ser02 00y3E 00(LE 2 y LE 62). Aparecen como ceros porqueto-bin16produce un binario con bytes correctos en posición 3-4 del buffer subyacente, peroappendcopia desde posición 1-2 (los ceros del entero original).Fix
Verificación
Tras el fix:
to-bin16 2→ append correcto de02 00.e_type=2,e_machine=62correctos en el ELF../helloejecuta y produce "hello, x64 linux" con exit 0.file ./helloreporta "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-6a58eed4cproduzcan PEs corruptos.Referencias
9d1d5dd2een ramarsc2-x64.docs/plans/auditoria-x64.md.