Closed
Labels
confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.errorsIssues and PRs related to JavaScript errors originating in Node.js core.Issues and PRs related to JavaScript errors originating in Node.js core.
Description
backtrace truncated if msg contains null character \0
$ node main.js
abcdef
/main/t02.js:6
throw new Error(a);
^
Error: abc
with this program
function test(){
var a = "abc\0def"
var a2 = "abcdef"
console.log(a); // not truncated
if(true) // change to false and backtrace works
throw new Error(a); // backtrace msg truncated at `\0`, the whole stack frames are missing
else
throw new Error(a2); // backtrace shown correctly
}
test()without the \0 the backtrace shows fine:
abcdef
/main/t02.js:8
throw new Error(a2);
^
Error: abcdef
at test (/main/t02.js:8:11)
at Object.<anonymous> (/main/t02.js:11:1)
at Module._compile (internal/modules/cjs/loader.js:774:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:785:10)
at Module.load (internal/modules/cjs/loader.js:641:32)
at Function.Module._load (internal/modules/cjs/loader.js:556:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:837:10)
at internal/main/run_main_module.js:17:11
node -v
v12.3.1
uname -a
Darwin 18.5.0 Darwin Kernel Version 18.5.0
note
according to https://stackoverflow.com/questions/13698677/null-character-in-strings
a NUL byte should simply be "yet another character value" and have no special meaning, as opposed to other languages where it might end a SV (String value).
console.log correctly shows the string (no truncation) but the backtrace doesn't work when running node on cmd line.
note that on a browser (eg chrome) it works: no truncation:
throw new Error("abc\0def");
VM9405:1 Uncaught Error: abcοΏ½def
at <anonymous>:1:7
Metadata
Metadata
Assignees
Labels
confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.errorsIssues and PRs related to JavaScript errors originating in Node.js core.Issues and PRs related to JavaScript errors originating in Node.js core.
Activity
joyeecheung commentedon Jul 19, 2019
I guess the question is:
\0, or include any other special characters? (off the top of my head, we would not want to escape\n), or make that configuration somehow?addaleax commentedon Jul 19, 2019
Iβd just print the error-message as-is, but including the
\0character.joyeecheung commentedon Jul 19, 2019
BTW chrome prints this by ignoring
\0.Do we want to special case for BOM or invalid surrogate characters as well? I guess whatever we do we should try to be consistent.
joyeecheung commentedon Jul 19, 2019
The OP says:
On the latest chrome canary I get this though
addaleax commentedon Jul 19, 2019
@joyeecheung That seems like a much more widely scoped issue than this bug for me β¦ the problem here is, afaict, we convert the error information from JS strings to UTF-8 like we always do, but then use
snprintfandfprintfto prepare/print out the bytes that we actually print, and those functions special-case\0as the end-of-string. Itβs just that weβre not keeping track of the string length while doing soβ¦We can think about escaping characters or introducing special handling for some, but that seems more like a feature request and isnβt about correct vs incorrect behaviour?
timotheecour commentedon Jul 19, 2019
we should preserve the '\0' without escaping, it makes it easier to debug in case user tries to see why there is a null char (in my case it was from here: nim-lang/Nim#11788)
also, that's what console.log does: it preserves the
'\0'solution: use
fwriteinstead ofsnprintfhttps://stackoverflow.com/questions/6943928/show-special-characters-in-unix-while-using-less-command
joyeecheung commentedon Jul 19, 2019
To preserve it in the output we need to escape it (replace it with
\\0).Doesn't that also apply to
\n,\rand\t?joyeecheung commentedon Jul 19, 2019
There are three handling that I can think of:
\0inerr.message(while not escaping\n,\rand friends)\0inerr.message- what browsers andconsole.logdo\n,\rand friends)addaleax commentedon Jul 19, 2019
@joyeecheung Can you explain why we need to escape it? Why is it not enough to just print the
\0character as-is, even if most terminals wonβt display it (basically, like @timotheecour said, act likeconsole.log()here)?joyeecheung commentedon Jul 19, 2019
@addaleax By
print the \0 character as-isdo you mean we pass the original string with\0intosnprintf/fprintf? I think that is why they are truncated?addaleax commentedon Jul 19, 2019
@joyeecheung Yes, thatβs why they are currently truncated as well β What Iβm having in mind is that we shouldnβt use the standard C
snprintf/fprintffunctions for these strings, and instead use maybe a more C++-y equivalent ofsnprintfthat can deal with e.g.std::strings, and for writing to stderr something likefwriteas suggested by @timotheecour.joyeecheung commentedon Jul 19, 2019
@addaleax I see, I thought the request was to print
new Error('test\0test')as literallytest\0test, sorry about the confusion!In that case I think we just need to stop doing variadic arguments in
PrintErrorStringas that's the source of the C-style interpretation of the stringstimotheecour commentedon Jul 19, 2019
@addaleax
unless you're using any format string arguments
fwriteshould be enough (but maybe I'm missing something?)4 remaining items
addaleax commentedon Jul 27, 2019
@himself65 Yeah, itβs quite a bit of work but Iβm up for it β itβs not hard, itβs pretty straightforward, just a lot to do.
src: use custom fprintf alike to write errors to stderr
src: use custom fprintf alike to write errors to stderr
src: add C++-style sprintf utility
src: use custom fprintf alike to write errors to stderr
src: add C++-style sprintf utility
src: use custom fprintf alike to write errors to stderr
src: add C++-style sprintf utility