Re: Spec for CryptoKey.algorithm and CryptoKey.usages doesn't really make sense

On 7/14/14, 3:40 PM, Ryan Sleevi wrote:
> So, I think we're in violent agreement that any modifications to
> .algorithm / .usages have no effect on the internal object or it's
> behaviour.

Yes, I think we are.

> Where we're in disagreement / where I'm confused about is whether the
> correct behaviour for
>
> var x = ...;  // A CryptoKey
>
> Scenario 1) x.algorithm = { foo: 'bar' };

We're on agreement on this one too.

> Scenario 2) x.algorithm.foo = bar;

This is where things get interesting.

> As it relates to Web IDL, ergo one can presume "every other spec", the
> behaviour of Scenario 1 is to no-op (non-strict mode) or to throw a
> TypeError (strict mode)

Yep.  We agree on that.

> If we had the KeyAlgorithm
> interface (versus dictionary), then Scenario 2 should fold into Scenario
> 1, in as much as .algorithm returns the KeyAlgorithm platform object,
> and .foo is an attempt to invoke a setter on a platform object, ergo
> no-op/TypeError.
>
> Are we in agreement there?

Yes, absolutely.

> If so, then the desired behaviour seems to be to reduce or eliminate the
> distinction between Algorithm-as-a-Dictionary (from the TAG review)
> versus KeyAlgorithm-as-an-interface (the original specification).

It depends on the desired behavior.

At least some members of the TAG will claim that if a web page wants to 
change its view of some CryptoKey's .algorithm, it should be free to do 
that.  As long as it's not changing the underlying data that will be 
used if the CryptoKey is actually used for something, of course, and we 
all agree that a web page should not be able to do that.

It seems like you think a web page should _not_ be able to thus modify 
its view of the object, at least not via doing

   someCryptoKey.algorithm.name = "Spiderman";

but should presumably still be able to do it by doing:

   Object.defineProperty(someCryptoKey.algorithm, "name",
                         { value: "Spiderman" });

in the same way that a web page can do:

   Object.defineProperty(someCryptoKey, "algorithm",
                         { value: { name: "Spock" } });

> So having [[algorithm_copy]] (or whatever) seems to violate that, in
> that it leads to different behaviour that KeyAlgorithm-as-an-interface.

Well, sure.  I mean the TAG was asking for different behavior, right?

>     No, any of those options are fine in Web IDL.  You're confusing
>     whether there is a setter on CryptoKey that would allow you to
>     affect what sort of thing .algorithm involves (or which object it
>     returns), and what the behavior of setting properties on the thing
>     returned from .algorithm is.  We all agree CryptoKey should have no
>     setter for this property.  We're disagreeing about what the getter
>     should return.
>
> Well, I'm not sure I see the two as separable, in that the goal here is
> to maintain the "readonly" aspect of .algorithm, ideally in a way that
> is identical to Web IDL.

Why is this readonliness important, apart from wanting to make sure the 
internal state of a CryptoKey cannot be changed?

> What the getter returns is affected (potentially) by how the setter is
> handled, hence the desire to treat the two together. In an 'ideal'
> world, yes, the getter returns the same object, but I think that's only
> safe if we don't allow the caller to influence that by the setter.

There is no .algorithm setter, and I don't think anyone is suggesting one.

> Perhaps I've been confused by your explanation. If we were to think of
> KeyAlgorithm as an interface (rather than a Dictionary), it would seem
> to align with Option C, in as much as the object is 'frozen' by virtue
> of no setters / setters that throw TypeError, recursively?

Being frozen is actually a much stronger constraint than what WebIDL 
provides by default, hence my mention of variants of (C) to avoid the 
full effects of freezing.  For example, if .algorithm is a frozen object 
then doing this:

   someCryptoKey.algorithm.lettuce = "present";

will be a no-op in non-strict mode and throw in strict mode.

> So the question here, absent the editorial bandwidth in the specs I'm
> using as references, is what is the best way to express this in a way
> that the community has consensus?

I think there is consensus on explicitly calling out internal slot usage.

> Put differently, can you provide specific language that you think should
> be done to address this

I can provide specific language once I know what our exact behavior 
goals are.  The problem is that I can't decide on those behavior goals, 
because I'm not sure what constraints we're operating under in terms of 
the API behavior.

> Otherwise, I feel like I'll be wasting everyone's
> time, mine included, to make a stab here.

Totally agreed.  We should decide what behavior we want before writing 
any spec text.  Then we just write the spec; I'm happy to help with that 
part.

>     2)  Clearly define cloning behavior for any object that has a
>     special set of internal slots.  This cloning behavior needs to
>     define what to do for the value in each slot.
>
> Well, 2) is unclear, especially in light of your comment about "these
> types have internal slots, it's not clear in the spec" above.
>
> As you note, declaring "structured clone" on an IDL type doesn't make
> sense, since "structured clone" doesn't operate on such types.

Well, you just have to define what it does.  For example structured 
cloning of an IDL dictionary that contains only string members might 
create another instance of the same kind of IDL dictionary that copies 
over the values of the members that are present in the one being 
structured cloned.  It's a bit cumbersome to write down, I agree.

> If we say internal slots shouldn't hold IDL types, but converted ES types, well,
> then you have the possibility of global state affecting such IDL types
> throughout all of the spec's algorithms

I'm not quite sure what the concern is here, but I'm not pushing for 
internal slots to hold ES types, by any means.

> - If [[algorithm]] holds an IDL type, such as a dictionary, it can't
> refer to structured clone

More precisely, you just have to hand-define what the [[algorithm]] of 
your clone is set to.  This is what the HTML5 spec does for its internal 
slots.

> - If [[algorithm]] holds an ES type, such as an Object, then every time
> we access [[algorithm]] in the spec (potentially asynchronously, via a
> promise), then we're potentially returning to the ES global in a
> detectable way

Yes.  I don't think you want this.

> - Thus, we seem to need, for every internal slot, a [[foo]] and
> [[foo_copy]] slot, where one holds an IDL type, the other holds an ES object

That's at least one plausible specification strategy, yes.

> HOWEVER, the [[foo]] / [[foo_copy]] doesn't seem to solve the Structured
> Clone problem, in that when I clone, if I structured clone [[foo_copy]],
> the ES global might be able to affect the new object's [[foo_copy]].

You don't clone [[foo_copy]].  You just regenerate it from [[foo]] in 
the new global if someone asks for it.

> Further, since I can't "directly" copy [[foo]], I presumably invoke the
> Web IDL conversion from [[foo_copy]] to recreate [[foo]] on the new
> object.

No, you hand-define the direct copy of [[foo]] as needed.  Perhaps that 
part should move into Web IDL itself in the long term...

-Boris

Received on Monday, 14 July 2014 20:21:24 UTC