Skip to content

fix(util): escape null byte unambiguously in quote()#1492

Open
spokodev wants to merge 1 commit into
google:mainfrom
spokodev:w32/zx-quote-nul
Open

fix(util): escape null byte unambiguously in quote()#1492
spokodev wants to merge 1 commit into
google:mainfrom
spokodev:w32/zx-quote-nul

Conversation

@spokodev

@spokodev spokodev commented Jul 2, 2026

Copy link
Copy Markdown

Description

quote() escapes a NUL byte as \0. In bash ANSI-C quoting ($'...'), \0 is a variable-length octal escape that greedily absorbs up to three following octal digits. So a NUL followed by octal digits is misdecoded.

quote('\0' + '123') // => "$'\0123'"

Bash reads $'\0123' as \012 (octal for newline, 0x0a) followed by 3. The intended NUL is silently turned into a newline and the following 123 is corrupted. Confirmed end to end through zx: $`printf '%s' ${'a\0123'}` yields the bytes a, 0x0a, 3 instead of a clean value.

Fix

Emit a fixed three-digit octal \000 instead of \0. Bash octal escapes are at most three digits, so \000 cannot absorb following digits and the value stays intact.

-      .replace(/\0/g, '\\0') +
+      .replace(/\0/g, '\\000') +

Test

Extended the quote() null-byte case in test/util.test.js. It fails before the change ($'\0123', ambiguous) and passes after ($'\000123').

…merge

In bash ANSI-C quoting ($'...'), \0 is a variable-length octal escape that
greedily consumes up to three following octal digits. Emitting a NUL as \0
therefore merges with subsequent digits: quote('\0' + '123') produced
$'\0123', which bash reads as octal \012 (newline) followed by '3' instead of
NUL followed by '123'. Emitting a fixed three-digit \000 keeps the escape
unambiguous, since bash octal escapes are at most three digits.
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.

1 participant