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

jQuery.isPlainObject( { ... } ) can be tricked by manipulating Symbol.toStringTag #1182

Open
Andrew-Cottrell opened this issue Feb 2, 2021 · 6 comments

Comments

@Andrew-Cottrell
Copy link

The documentation for isPlainObject indicates the following evaluates to true, but in jQuery v3.5.1 it evaluates to false.

jQuery.isPlainObject( { [Symbol.toStringTag]: "Tag" } );

I suggest the documentation be changed to clarify the behaviour when an otherwise plain object has a [Symbol.toStringTag] property unequal to "Object".

@timmywil timmywil transferred this issue from jquery/jquery Mar 1, 2021
@timmywil timmywil changed the title [documentation] Surprising jQuery.isPlainObject( { ... } ) evaluates to false jQuery.isPlainObject( { ... } ) can be tricked by manipulating Symbol.toStringTag Mar 1, 2021
@Andrew-Cottrell
Copy link
Author

Andrew-Cottrell commented Mar 8, 2021

https://github.com/jquery/jquery/blob/3.6.0/src/core.js#L223

It's not clear to me that the toString.call( obj ) !== "[object Object]" check is needed. The rest of the implementation appears to implement the documented behavior. This check appears to be an optimisation that inadvertently changes the behavior.

@mgol
Copy link
Member

mgol commented Mar 8, 2021

@gibson042 do you know why do we need this part? Tests pass in Chrome & Firefox if you cut it out.

@gibson042
Copy link
Member

Looking at jquery/jquery@e0d3bfa#diff-8ab41fe13597e1554b5d6b4c227b5f123ff2d6726a7f3688a8b8d1224fe1d4f3R231 , there might be/have been supported environments where a window object and/or (IE?) host object had no prototype. Assuming that's not the case now, I have no problem with removing the toString.call( obj ) short-circuit—but note that it will still be possible to trick jQuery.isPlainObject. The function isn't intended to be robust, it's just used in a few places to differentiate "bag of data" input from richer objects like DOM nodes, so it shouldn't actually matter whether an otherwise plain object with a custom ToStringTag is treated as the former or the latter.

@mgol
Copy link
Member

mgol commented Mar 11, 2021

I've just checked; the toString.call( obj ) check is still needed for IE 11.

@mgol
Copy link
Member

mgol commented Mar 15, 2021

@Andrew-Cottrell would you like to submit a PR updating the documentation? I think we won't be able to change the implementation.

@Andrew-Cottrell
Copy link
Author

Andrew-Cottrell commented Mar 16, 2021

Sorry, I have no prior experience with GitHub PRs and I am currently too busy with work to take the time to learn.

I suggest a single sentence is appended to the Note section, just before the Example section.

Objects with a [Symbol.toStringTag] own property unequal to "Object" are not considered to be plain.

The sentence could be expanded

Objects with a [Symbol.toStringTag] own property unequal to "Object" are not considered to be plain and are unsupported by jQuery.

Or perhaps

jQuery does not support non-prototype objects with a [Symbol.toStringTag] own property.

The same, or a similar, sentence might also be added to https://github.com/jquery/jquery/wiki/Won't-Fix

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

No branches or pull requests

3 participants