Skip to content

Write explicit null terminator in Utf8StringArray#482

Open
tolmachev-pravo wants to merge 1 commit into
microsoft:mainfrom
tolmachev-pravo:fix/utf8stringarray-null-terminator
Open

Write explicit null terminator in Utf8StringArray#482
tolmachev-pravo wants to merge 1 commit into
microsoft:mainfrom
tolmachev-pravo:fix/utf8stringarray-null-terminator

Conversation

@tolmachev-pravo

Copy link
Copy Markdown

Fixes #481.

Utf8StringArray reserved a byte for each string's null terminator (the + 1 in the encoding loop) but never wrote the \0 — it relied on the reserved byte already being zero. That holds on the NETFRAMEWORK/NETSTANDARD path (new byte[] is zeroed), but on .NET the buffer is rented from ArrayPool<byte>.Shared, which is not zero-initialized. Once the pool has been used, the terminator byte can contain leftover data, and native node reads each argv entry past its end — e.g. bad option: --disable-wasm-trap-handler<garbage>. It only reproduces after warm-up (dirty pool), which made it hard to track down.

Fix: write the terminator explicitly.

Adds a regression test that dirties ArrayPool<byte>.Shared and verifies the marshaled strings round-trip exactly (fails on main, passes with this change). Testing the internal struct needs InternalsVisibleTo on the test assembly.

Verified: dotnet test --framework net8.0 --filter Utf8StringArrayTests passes with the fix and fails without it.

Utf8StringArray reserved a byte for each string's null terminator but
never wrote it, relying on the buffer already being zero. On .NET the
buffer is rented from ArrayPool<byte>.Shared, which is not
zero-initialized, so once the pool has been used the terminator byte can
hold leftover data. Native node then reads each argv entry past its
intended end, e.g. "bad option: --disable-wasm-trap-handler<garbage>".

Write the terminator explicitly, and add a regression test that
reproduces the failure by dirtying the shared pool before marshaling.

Fixes microsoft#481
@tolmachev-pravo

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

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.

Embedding args occasionally get trailing garbage on .NET (missing null terminator on a pooled buffer)

1 participant