Repository navigation
byteOffset argument in buffer indexOf / lastIndexOf has some contradictions in code vs doc vs test #9801
Description
Activity
It seems this big PR concerns all points.
- addedbufferIssues and PRs related to the buffer subsystem.Issues and PRs related to the buffer subsystem.
on Nov 26, 2016 I agree, this certainly looks like a bug. A offset of
nullandundefinedshould result in the same behaviour. Wanna file a PR to fix it in both code and tests?@silverwind #4846 was a big complex PR. Maybe the author wants to do this? This way all the method system will be taken into account. ping @dcposch
Maybe cc #4846 reviewers? @jasnell, @trevnorris.
@vsemozhetbyt @silverwind I have time to look at this today. PR coming soon!
Reacted by Vse Mozhe ButySo it looks like I did that in order to match the behavior of String:
var s = "abcdef" var b = new Buffer("abcdef") s.indexOf('b', null) // prints 1 b.indexOf('b', null) // prints 1 s.lastIndexOf('b', null) // prints -1 b.lastIndexOf('b', null) // prints -1
...in other words, both String and Buffer coerce an offset of
nullto zero.Introducing inconsistency between String and Buffer seems bad. I'll send a PR that fixes the documentation and makes the tests more explicit, while leaving the behavior as is. Thoughts?
After a bit more investigating, it looks like String and Buffer both coerce the offset argument to a number, then use the default offset if the result is NaN. (Using the default offset means searching the whole String or Buffer.)
The bad news is that this leads to some really weird, unintuitive behavior. The good news is that at least they're consistent with each other and with Javascript's unary + operator:
var s = "abcdef" var b = new Buffer("abcdef") console.log('OFFSETS THAT COERCE TO NaN') console.log(+{}) // prints NaN, so this will turn into the default offset console.log(+undefined) // same here // The following statements all print 1, searching the whole String or Buffer s.lastIndexOf('b') s.lastIndexOf('b', undefined) s.lastIndexOf('b', {}) b.lastIndexOf('b') b.lastIndexOf('b', undefined) b.lastIndexOf('b', {}) console.log('OFFSETS THAT COERCE TO 0') console.log(+null) // print 0 console.log(+[]) // same here // The following statements all print -1, because they search from offset 0 s.lastIndexOf('b', null) s.lastIndexOf('b', []) b.lastIndexOf('b', null) b.lastIndexOf('b', [])
Looks like my mistake in the docs was fixed here: 6050bbe
Thanks @vsemozhetbyt
Reacted by Vse Mozhe ButySo, if this is the desired behavior, this comment needs to be fixed:
https://github.com/nodejs/node/blob/master/lib/buffer.js#L593
@vsemozhetbyt good catch. mind commenting directly on that line of the commit that the comment should be removed?
@trevnorris If I get it right, it seems the comment has been changed already.
@vsemozhetbyt thanks for pointing that out.
Reacted by Vse Mozhe Buty- added a commit that references this issue
on Jan 24, 2017 2 remaining items
- added 2 commits that reference this issue
on Jan 28, 2017 - added 6 commits that reference this issue
on Jan 30, 2017 - added 3 commits that reference this issue
on Mar 8, 2017 - added a commit that references this issue
on Jul 27, 2026
Some contradictions in status quo:
buffer.lastIndexOf()code example in doc:Actually, it prints
-1now.buffer.jscoercesbyteOffsetnullto0. However, in the next block it checks ifbyteOffsetisnullto make it defaultbyteOffsetif so.test-buffer-indexof.jsexpectsnullbyteOffsetto return-1, i.e. it expectsnullbyteOffsetnot to be converted into the defaultbyteOffset.Maybe the fix steps could be these:
buffer.jsshould not coercenulltoNumber.test-buffer-indexof.jsshould expectnullbyteOffsetto be converted into the defaultbyteOffset.positionremarks in thefsdoc forfs.read()andfs.write().