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

🐛Restrict checking cached ampDoc reference to AMP elements. #25000

Merged
merged 6 commits into from Oct 15, 2019

Conversation

sparhami
Copy link

@sparhami sparhami commented Oct 9, 2019

This fixes a bug where the compiled (renamed) property for ampDoc_
could conflict with a form field name. Rather than blacklist form,
whitelist amp- elements in case anything else has this behavior (like
window and Element ids).

Fixes #24995

This fixes a bug where the compiled (renamed) property for `ampDoc_`
could conflict with a form field name. Rather than blacklist `form`,
whitelist `amp-` elements in case anything else has this behavior (like
`window` and Element `id`s).
@sparhami sparhami marked this pull request as ready for review October 9, 2019 22:32
@jpettitt
Copy link
Contributor

Woohoo PR number 25000

Copy link

@dreamofabear dreamofabear left a comment

Choose a reason for hiding this comment

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

Interesting bug, thanks for investigating and fixing. 👍

The way we fixed a similar DOM clobbering issue was to use property names that the validator bans in form[name], [id], etc. I.e.

const cached = node['__amp_doc']; // __amp_* is an invalid value for form[name].

We can try extending the window-property-name.js eslint rule to try to catch these generally, though it may have precision problems.

@sparhami
Copy link
Author

sparhami commented Oct 10, 2019

Interesting bug, thanks for investigating and fixing.

The way we fixed a similar DOM clobbering issue was to use property names that the validator bans in form[name], [id], etc. I.e.

const cached = node['__amp_doc']; // __amp_* is an invalid value for form[name].

We can try extending the window-property-name.js eslint rule to try to catch these generally, though it may have precision problems.

I considered using a string constant, but the problem here is that we are relying on the fact that we are relying on this matching the ampDoc_ property named here:

/**
* Ampdoc can only be looked up when an element is attached.
* @private {?./service/ampdoc-impl.AmpDoc}
*/
this.ampdoc_ = null;

Since this is set on an HTMLElement (since it is a custom element), and we are accessing it from a Node (a super class of HTMLElement), Closure Compiler will ensure consistent property renaming for the set of this property and the read elsewhere.

Perhaps calling it a cached value is not quite correct, since it isn't cached after a lookup. Rather, it is saved when the element is upgraded as we already know which AmpDoc it belongs to.

@dreamofabear
Copy link

Another alternative is to avoid accessing private ivars.

const cached = typeof node.getAmpDoc === 'function' ? node.getAmpDoc() : null;

Would need a change to dodge the devAssert.

@sparhami
Copy link
Author

Another alternative is to avoid accessing private ivars.

const cached = typeof node.getAmpDoc === 'function' ? node.getAmpDoc() : null;

Would need a change to dodge the devAssert.

I'm not sure how much of a problem this is, since getAmpDoc has a devAssert requiring the node be connected, if specified. This means that it should also have an ampDoc_. The one case where this doesn't hold is the getAmpDocIfAvailable entry point (which only has one usage), which explicitly does not require the node to be connected,

@sparhami
Copy link
Author

Changed to use getAmpDoc, but also guarded with everAttached, so we should never hit the devAssert where ampDoc_ is null.

src/service/ampdoc-impl.js Outdated Show resolved Hide resolved
@sparhami sparhami merged commit 4e363c8 into ampproject:master Oct 15, 2019
@sparhami sparhami deleted the ampdoc_cached_value branch October 15, 2019 23:20
joshuarrrr pushed a commit to Parsely/amphtml that referenced this pull request Oct 22, 2019
…ct#25000)

This fixes a bug where the compiled (renamed) property for `ampDoc_`
could conflict with a form field name.
micajuine-ho pushed a commit to micajuine-ho/amphtml that referenced this pull request Dec 27, 2019
…ct#25000)

This fixes a bug where the compiled (renamed) property for `ampDoc_`
could conflict with a form field name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Form submit service failed: %s: Cannot read property 'fire' of undefined
5 participants