Skip to content

fix(edf): use offset instead of stale slice for MarshalEDF length prefix#257

Merged
halturin merged 2 commits intoergo-services:masterfrom
JeroenSoeters:fix/edf-buffer-reallocation
Apr 20, 2026
Merged

fix(edf): use offset instead of stale slice for MarshalEDF length prefix#257
halturin merged 2 commits intoergo-services:masterfrom
JeroenSoeters:fix/edf-buffer-reallocation

Conversation

@JeroenSoeters
Copy link
Copy Markdown
Contributor

When a type registered via RegisterTypeOf implements Marshaler, the encoder reserves a 4-byte length prefix via Extend(4) before calling MarshalEDF. If MarshalEDF writes enough data to trigger lib.Buffer reallocation (via append), the slice returned by Extend points to the old backing array. The length prefix is then written to freed memory, leaving zeros in the actual buffer. The decoder reads length=0 and fails with malformed EDF: end of data.

The fix records the buffer offset before Extend and indexes into b.B[] after MarshalEDF returns, which always references the current backing array regardless of reallocation.

When MarshalEDF writes enough data to trigger lib.Buffer reallocation
(via append), the slice returned by Extend(4) points to freed memory.
The 4-byte length prefix is then written to the old backing array,
leaving zeros in the new buffer. The decoder reads length=0 and fails
with "malformed EDF: end of data".

Fix by recording the buffer offset before Extend and indexing into
b.B[] after MarshalEDF returns, which always references the current
(potentially reallocated) backing array.
Verifies that Encode/Decode roundtrip works correctly when MarshalEDF
writes enough data to trigger lib.Buffer reallocation. Uses a small
initial buffer capacity (64 bytes) to guarantee reallocation occurs.

Without the offset-based fix in register.go, the length prefix is
written to a stale slice and the decoder returns zero-length data.
@halturin
Copy link
Copy Markdown
Collaborator

halturin commented Apr 7, 2026

Such a great catch 👍. Will take a look closer in a week (on a vacation now), but so far looks good

@halturin halturin merged commit 98c0c2d into ergo-services:master Apr 20, 2026
1 check passed
halturin pushed a commit that referenced this pull request Apr 20, 2026
…fix (#257)

* fix(edf): use offset instead of stale slice for MarshalEDF length prefix

When MarshalEDF writes enough data to trigger lib.Buffer reallocation
(via append), the slice returned by Extend(4) points to freed memory.
The 4-byte length prefix is then written to the old backing array,
leaving zeros in the new buffer. The decoder reads length=0 and fails
with "malformed EDF: end of data".

Fix by recording the buffer offset before Extend and indexing into
b.B[] after MarshalEDF returns, which always references the current
(potentially reallocated) backing array.

* test(edf): regression test for MarshalEDF buffer reallocation

Verifies that Encode/Decode roundtrip works correctly when MarshalEDF
writes enough data to trigger lib.Buffer reallocation. Uses a small
initial buffer capacity (64 bytes) to guarantee reallocation occurs.

Without the offset-based fix in register.go, the length prefix is
written to a stale slice and the decoder returns zero-length data.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants