Check out Dart's iterators
Claude Pache
claude.pache at gmail.com
Sun Feb 10 18:35:29 PST 2013
Le 10 févr. 2013 à 22:01, David Bruant <bruant.d at gmail.com> a écrit :
> <snip>
>
> I have to note that there is a minor security hazard in code using iterators naively:
> import process from "m";
>
> var a = [1, 2, 3, 4, 5];
> var next = 0;
> var it = {
> next: function(){
> if(next < a.length){
> // If the call to "process" throws StopIteration because it's malicious/buggy,
> // so does this code and that's largely unexpected.
> return process(a[next++]);
> }
> else{
> throw StopIteration;
> }
> }
> }
>
> You can always protect yourself by wrapping the call to "process" with a try/catch block.
> <snip>
Note that the same issue arises with generators:
function* gen(a) {
var next = 0;
if (next < a.length) {
// the iterator will end prematurely if "process" throws a StopIteration
yield process(a[next++]);
}
}
In order to mitigate the problem, instead of throwing a generic StopIteration, I think we ought to throw a specific StopIteration instance with information on which iterator has thrown. More precisely, inside a generator function, a return statement will throw a StopIteration instance with its "source" property set to the generator iterator which was terminated.
For manually throwing a StopIteration from inside a "next" method of an iterator, we could use:
throw new StopIteration(this)
And instead of "e instanceof StopIteration", we may use a more precise check:
e instanceof StopIteration && e.source === it
—Claude
More information about the es-discuss
mailing list