You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
V8 Fatal Error when trying to convert a buffered integer to string #649
I understand what's wrong, haha. I'm just wondering why its giving a scary V8 error like that instead of a generic Javascript error.
In Node 0.10.31:
$ node
> Buffer(5).toString('utf8')
'\u0000 \u0000\u0000\u0000'
> Buffer(Date.now()).toString('utf8')
TypeError: Bad argument
at new Buffer (buffer.js:194:21)
at Buffer (buffer.js:158:12)
at repl:1:2
at REPLServer.self.eval (repl.js:110:21)
at Interface.<anonymous> (repl.js:239:12)
at Interface.emit (events.js:95:17)
at Interface._onLine (readline.js:202:10)
at Interface._line (readline.js:531:8)
at Interface._ttyWrite (readline.js:760:14)
at ReadStream.onkeypress (readline.js:99:10)
There is a logic error in lib/buffer.js: the length argument to the constructor gets coerced to uint32 with length >>> 0, which makes it bypass the length < kMaxLength check because e.g. (1422546646261 >>> 0) < 0x3fffffff.
I think @bnoordhuis found a bug, but I don't think it was this bug. The length > kMaxLength after length >>> 0 check he mentions is part of SlowBuffer(), and that's not called at all in this stack trace.
We just have a plain Buffer (for which util.isNumber(subject) returns true), and when it hits the if (this.length > kMaxLength) check at lib/buffer.js:52 it has a length of 921032252 and a kMaxLength of 1073741823, so it's under the limit at 85% of kMaxLength.
See #657 for a proposed mitigation. It's not perfect because the real issue lies in V8, it aborts when internal operations OOM. For example, Buffer(0x3fffffff-1).toString() still hits the assert.
Also, the cutoff point that's currently in there was chosen after meticulous benchmarking. Here's a basic graph showing what happens to allocation time as string size increases: http://trevnorris.github.io/nodeconf.eu/#/17
Activity
jonathanong commentedon Jan 29, 2015
Date.now()is an integer, so you're creating a buffer withDate.now()bytes... which is gigantic. I think you wantnew Buffer(String(Date.now()))kevinmartin commentedon Jan 29, 2015
I understand what's wrong, haha. I'm just wondering why its giving a scary V8 error like that instead of a generic Javascript error.
In Node 0.10.31:
brendanashworth commentedon Jan 29, 2015
@kevinmartin well, it does have an extraordinary length.
targos commentedon Jan 29, 2015
this issue reminds me of similar crash I had last year on node. I just retried it on iojs and it is still crashing.
test.js :
The gzipped file : ftp://ftp.ncbi.nlm.nih.gov/pubchem/Compound/CURRENT-Full/SDF/Compound_006625001_006650000.sdf.gz
The uncompressed file is valid utf-8.
Could it be a v8 limit on the size (it is 276,9 MB) ?
bnoordhuis commentedon Jan 29, 2015
There is a logic error in lib/buffer.js: the length argument to the constructor gets coerced to uint32 with
length >>> 0, which makes it bypass thelength < kMaxLengthcheck because e.g.(1422546646261 >>> 0) < 0x3fffffff.In short, confirmed. :-)
cjb commentedon Jan 29, 2015
I think @bnoordhuis found a bug, but I don't think it was this bug. The
length > kMaxLengthafterlength >>> 0check he mentions is part ofSlowBuffer(), and that's not called at all in this stack trace.We just have a plain Buffer (for which
util.isNumber(subject)returns true), and when it hits theif (this.length > kMaxLength)check at lib/buffer.js:52 it has a length of921032252and a kMaxLength of1073741823, so it's under the limit at 85% of kMaxLength.bnoordhuis commentedon Jan 29, 2015
See #657 for a proposed mitigation. It's not perfect because the real issue lies in V8, it aborts when internal operations OOM. For example,
Buffer(0x3fffffff-1).toString()still hits the assert.bnoordhuis commentedon Jan 29, 2015
V8 bug report: https://code.google.com/p/v8/issues/detail?id=3853
11 remaining items
trevnorris commentedon Mar 13, 2015
Also, the cutoff point that's currently in there was chosen after meticulous benchmarking. Here's a basic graph showing what happens to allocation time as string size increases: http://trevnorris.github.io/nodeconf.eu/#/17
bnoordhuis commentedon Mar 13, 2015
True, but internal strings aren't UTF-8 either, V8 always decodes them to ASCII or UTF-16.
petkaantonov commentedon Mar 13, 2015
Yes, we are not gaining anything by outsourcing this work to v8. We can do it ourselves and make it external.
trevnorris commentedon Mar 13, 2015
Sure, but do we really want to implement our own encoding parser so we can externalize all strings?
petkaantonov commentedon Mar 13, 2015
We don't have to implement our own, even though it's a fun task.
test: fix test for buffer regression #649
test: fix test for buffer regression #649
test: fix test for buffer regression nodejs#649
test: fix test for buffer regression #649