yaku icon indicating copy to clipboard operation
yaku copied to clipboard

Bug: Stealing a resolver and using it to trigger reentrancy

Open JakeChampion opened this issue 3 years ago • 3 comments

var Promise = require("yaku");
var assert = require('assert');

var stolenResolver;
var StealingPromiseConstructor = function StealingPromiseConstructor(resolver) {
	stolenResolver = resolver;
	resolver(
		function () {},
		function () {}
	);
};
var iterable = {};
var atAtIterator = '@@iterator'; // on firefox, at least.
iterable[atAtIterator] = function () {
	stolenResolver(null, null);
	throw new Error(0);
};
assert.doesNotThrow(function () {
	Promise.all.call(StealingPromiseConstructor, iterable);
});

It throws this:

AssertionError: Got unwanted exception.
Actual message: "self.reject is not a function"

This test was taken from es6-shim -- https://github.com/paulmillr/es6-shim/blob/4a815033b35a051632e035e1ec95aa3b1b43bfdd/test/promise/simple.js#L34-L51

JakeChampion avatar Sep 29 '20 16:09 JakeChampion

@JakeChampion Thank you for your report. Such an edge case, I wonder how you found it?

ysmood avatar Sep 29 '20 20:09 ysmood

Im implementing a promise library and ran a big test suite on other promise libraries

JakeChampion avatar Sep 29 '20 21:09 JakeChampion

Implementing promise in 2020? For study? 😂

The fix should be easy, but it will decrease the performance a little bit. Other methods like Promise.race also have this bug. I will fix it if I have time. I think people who still use third-party Promise won't care though.

ysmood avatar Sep 29 '20 22:09 ysmood