[Webkit-unassigned] [Bug 199540] New: AbortSignal cannot be replaced by a polyfill

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Fri Jul 5 19:21:41 PDT 2019


https://bugs.webkit.org/show_bug.cgi?id=199540

            Bug ID: 199540
           Summary: AbortSignal cannot be replaced by a polyfill
           Product: WebKit
           Version: Safari Technology Preview
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: WebCore JavaScript
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: zhifei_fang at apple.com

In this website: https://www.carvana.com/vehicle/1251874

They use a polyfill for abort signal, I guess the reason is here:
https://bugs.webkit.org/show_bug.cgi?id=174980

Though we already fix this, I guess for a compatible reason, they just do a polyfill for safari everywhere without checking safari's version.


here is the code:

```
                 a = function(e) {
                    function a() {
                        t(this, a);
                        var e = n(this, (a.__proto__ || Object.getPrototypeOf(a)).call(this));
                        return e.aborted = !1, e.onabort = null, e
                    }
                    return function(e, t) {
                        if ("function" !== typeof t && null !== t)
                            throw new TypeError("Super expression must either be null or a function, not " + typeof t);
                        e.prototype = Object.create(t && t.prototype, {
                            constructor: {
                                value: e,
                                enumerable: !1,
                                writable: !0,
                                configurable: !0
                            }
                        }), t && (Object.setPrototypeOf ? Object.setPrototypeOf(e, t) : e.__proto__ = t)
                    }(a, i), r(a, [{
                        key: "toString",
                        value: function() {
                            return "[object AbortSignal]"
                        }
                    }, {
                        key: "dispatchEvent",
                        value: function(e) {
                            "abort" === e.type && (this.aborted = !0, "function" === typeof this.onabort && this.onabort.call(this, e)), function e(t, r, n) {
                                null === t && (t = Function.prototype);
                                var i = Object.getOwnPropertyDescriptor(t, r);
                                if (void 0 === i) {
                                    var a = Object.getPrototypeOf(t);
                                    return null === a ? void 0 : e(a, r, n)
                                }
                                if ("value" in i)
                                    return i.value;
                                var o = i.get;
                                return void 0 !== o ? o.call(n) : void 0
                            }(a.prototype.__proto__ || Object.getPrototypeOf(a.prototype), "dispatchEvent", this).call(this, e)
                        }
                    }]), a
                }(),
                o = function() {
                    function e() {
                        t(this, e), this.signal = new a
                    }
                    return r(e, [{
                        key: "abort",
                        value: function() {
                            var e = void 0;
                            try {
                                e = new Event("abort")
                            } catch (t) {
                                "undefined" !== typeof document ? (e = document.createEvent("Event")).initEvent("abort", !1, !1) : e = {
                                    type: "abort",
                                    bubbles: !1,
                                    cancelable: !1
                                }
                            }
                            this.signal.dispatchEvent(e)
                        }
                    }, {
                        key: "toString",
                        value: function() {
                            return "[object AbortController]"
                        }
                    }]), e
                }();
            "undefined" !== typeof Symbol && Symbol.toStringTag && (o.prototype[Symbol.toStringTag] = "AbortController", a.prototype[Symbol.toStringTag] = "AbortSignal"), function(e) {
                if (!e.AbortController || function(e) {
                    return e.navigator && (e.navigator.vendor && e.navigator.vendor.startsWith("Apple Computer") || e.navigator.userAgent && e.navigator.userAgent.match(/ (crios|gsa|fxios)\//i))
                }(e))
                    if (e.AbortController = o, e.AbortSignal = a, e.fetch) {
```

in here, e is the window, they are using a self defined object (a, o) to replace webkit's AbortContorller and AbortSignal


And in FetchRequest::initialWith 

    if (init.signal) {
        if (auto* signal = JSAbortSignal::toWrapped(scriptExecutionContext()->vm(), init.signal))
            m_signal->follow(*signal);
        else if (!init.signal.isUndefinedOrNull())  {
            if (auto exception = processInvalidSignal(*scriptExecutionContext()))
                return WTFMove(*exception);
        }
    }

We do a JSAbortSignal::toWrapped, this will do a jscDynamicCast, since here it has been replaced by the polyfill, we cannot do that. In result, we have an exception here.

I guess to allow this polyfill, we should call the AbortSignal's interface in js, rather than dynamic cast it here

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20190706/8dcec466/attachment.html>


More information about the webkit-unassigned mailing list