-
-
Notifications
You must be signed in to change notification settings - Fork 9
Description
Currently, nextv()
can only signal the natural end of an iterator by yielding an empty array. In the fallback _nextv()
implementation below, when _next()
signals end by yielding an undefined key and/or value (line 147), this means _nextv()
does not signal end (line 148, unless acc
is empty). Consequently, a consumer will call nextv()
again, which means we call _next()
again (line 160) which has already signaled end.
Whether that's a problem depends on implementation. It is in many-level
(the replacement for multileveldown
that I'm working on atm, and can easily have its own fix) and could be in others too. It's not a problem for implementations written so far (memory-level
, classic-level
, browser-level
) because those implement their own optimized _nextv()
.
Solution: set a new private kEnded
property to true on line 148, and check that it's false before calling _next()
. A seek()
should reset it to false. Maybe use kEnded
in more places, as a general protection.
abstract-level/abstract-iterator.js
Lines 142 to 161 in 601b47c
_nextv (size, options, callback) { | |
const acc = [] | |
const onnext = (err, key, value) => { | |
if (err) { | |
return callback(err) | |
} else if (this[kLegacy] ? key === undefined && value === undefined : key === undefined) { | |
return callback(null, acc) | |
} | |
acc.push(this[kLegacy] ? [key, value] : key) | |
if (acc.length === size) { | |
callback(null, acc) | |
} else { | |
this._next(onnext) | |
} | |
} | |
this._next(onnext) | |
} |
Metadata
Metadata
Assignees
Labels
Type
Projects
Status