Re: [whatwg/dom] Define a 'CancellationController' and 'CancellationSignal' interface. (#434)

@annevk @jakearchibald 
Here are the concerns I think are relevant to "detecting if a reason is a cancellation":
 1. hard to screw up accidentally / no collisions: this is why a simple "name" property or similar isn't a good idea; if it's possible to conflict, it's going to cause somebody a problem. Here are some options that satisfy this constraint:
    1. (same realm) `instanceof CancelError`
    1. (cross-realm) cross-realm `Symbol.asInstance` method that does `instanceof` and falls back to a brand check (or just does the brand check)
    1. (cross-realm) new well-known Symbol property, like `[Symbol.isCancelError]: true`
    1. (cross-realm) brand-checking method, like `CancelError.is()`
 1. Cross-realm: values are passed across realms, be they iframes, node's `vm` module, or in the upcoming Realms API. It is done infrequently but nonzero now, but its use will likely go up over time. Here are some options that satisfy this constraint:
    1. (can collide) a string property, like "name", set to a primitive value, like "CancelError".
    1. (no collisions) cross-realm `Symbol.asInstance` method that does `instanceof` and falls back to a brand check
    1. (no collisions) new well-known Symbol property, like `[Symbol.isCancelError]: true`
    1. (no collisions) brand-checking method, like `CancelError.is()`
 1. Unforgeable: this is the constraint that often gets pushback on TC39. There are two classes of concerns here: an "own" lie, or malicious tampering.
    - With "own lie", there's two issues: something claiming to be a CancelError when it's not; and something claiming an individual CancelError is not one, when it is. To be fair, these only really matter if a CancelError has special branded behavior elsewhere.
   - With "malicious tampering", there are also two issues: malicious code making all "somethings" (all `Number`s, all `String`s, all `Error`s, whatever) claim to be a CancelError when they're not; and malicious code making all CancelErrors claim to *not* be CancelErrors when they are. These matter in two cases: one, if there's special branded behavior elsewhere; two, when trying to protect library code against global interference/tampering (tampering done after library parse time, of course)
   - Here are some options that satisfy this constraint:
    1. brand-checking method, like `CancelError.is()`
    1. (cross-realm) cross-realm `Symbol.asInstance` method that does `instanceof` and falls back to a brand check (or just does the brand check)

Here's a matrix of these options and constraints:

… | No Collisions | Cross-Realm | Unforgeable
------------ | ------------- | ------------- | -------------
string property | ❌  | ✅  | ❌ 
`instanceof` | ✅ | ❌ | ❌ 
`Symbol.isCancelError` | ✅   | ✅  | ❌ 
`Symbol.asInstance` | ✅ | ✅ | ✅ 
`CancelError.is()` | ✅ | ✅ | ✅ 

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/pull/434#issuecomment-292640413

Received on Friday, 7 April 2017 20:14:32 UTC