Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: convert PaymentMethodData.data #812

Closed
wants to merge 6 commits into from
Closed

Conversation

marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Nov 23, 2018

Closes #813

Part 1 of #753

Converts PaymentMethodData.data to IDL type or object.

The following tasks have been completed:

Implementation commitment:

  • Safari
  • Chrome - Implemented
  • Firefox - Implemented
  • Edge (public signal)

Optional, Impact on Payment Handler spec?


Preview | Diff

@marcoscaceres
Copy link
Member Author

Both Chrome and Firefox do the IDL conversion already.

index.html Outdated Show resolved Hide resolved
index.html Outdated Show resolved Hide resolved
@marcoscaceres
Copy link
Member Author

@domenic hopefully good now.

@marcoscaceres
Copy link
Member Author

@domenic, because in implementations, PaymentMethod.data's JS-to-IDL conversion happens in the PaymentRequest constructor (instead of on .show()), it means we don't need the [[serialized*]] data internal slots because:

  • We can do the "JSON serializable" check at construction time and when updateWith() is called: this gives us assurances that .data doesn't contain any un-serializable JSON types and circular references....and, if ever needed, .data can be serialized to a string in the future.
  • And because of the above, we can just internally hold converted IDL values for each PaymentRequest instance, without the need to hold them in string form.

This also fixes what would otherwise be a mess when show()ing or updateWith()ing a payment sheet: the [[serializedModifierData]] array positions would need to match the position of the deleted .data members.

So, with this PR, when a payment handler shows or gets updated, it always operates on its expected IDL type, without needing to redo any redundant JSON parsing, re-conversions, etc.

Copy link
Collaborator

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you separate the editorial changes (removing lots of data-lts) from the normative ones, to make this easier to review? I think I found the big normative change and the issue with it, but it's hard to tell what else might be there.

<var>serializedData</var>) to
<var>serializedMethodData</var>.
<li>Append <var>paymentMethod</var> to
<var>paymentMethods</var>.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the problem with not storing the JSON serialized version is that the JSON serialization now becomes meaningless. Consider the following:

const bcr1 = { supportedNetworks: new Set("foo", "bar") };

With the new spec, the JSON-serialization will be { "supportedNetworks": {} }. But the value stored in paymentMethods will be { supportedNetworks: ["foo", "bar"] } since Web IDL dictionary conversion converts all iterables to sequences.

This means that if someone, e.g., passed the JSON serialization across a process boundary and used it to attempt to reconstruct the result on the other side, they would not be able to match the spec. I thought our original spec was motivated exactly by that design.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the original design was motivated by some kind of security concern that was supposed to be mitigated by doing a JSON serialization on .data whose type is object to remove things like Function being added as properties.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be good to check with implementations then. But a spec that JSON serializes then disregards the result seems incoherent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gecko only does the IDL conversion, because we don't care about any payment method apart from "Basic Card". So, we don't store any [[serializedMethodData]] in our code... in fact, I don't see is doing any we JSON serialization of data at all in Gecko's code (@edenchuang?).

From the constructor, we check the method's details:
https://github.com/mozilla/gecko-dev/blob/master/dom/payments/PaymentRequest.cpp#L574

We then just check IsValidBasicCardRequest:
https://github.com/mozilla/gecko-dev/blob/master/dom/payments/PaymentRequest.cpp#L293

And then we convert it (to check throw if it fails):
https://github.com/mozilla/gecko-dev/blob/master/dom/payments/BasicCardPayment.cpp#L53

WebKit does do the serialization and stores it. However, @aestes also seems to suggest a preference to not store the JSON serialization: "Browsers could convert from a JS object directly to a IDL dictionary rather than the current JS object > JSON string > JS object > IDL dictionary conversion algorithm".

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. @rsolomakhin?

@marcoscaceres
Copy link
Member Author

Went back to look at #346 ... I'd forgotten that the ideas was to support actually sending the JSON-serialized data no just across process boundaries (which I was imagining was just as per-origin process isolation) - but to other native applications acting as payment handlers.

As such, I concur that it still makes sense to keep the JSON serialization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants