{"action":"created","comment":{"url":"https://api.github.com/repos/facebook/react/pulls/comments/42023564","id":42023564,"diff_hunk":"@@ -15,6 +15,11 @@ var ReactCurrentOwner = require('ReactCurrentOwner');\n \n var assign = require('Object.assign');\n \n+// The Symbol used to tag the ReactElement type. If there is no native Symbol\n+// nor polyfill, then a plain number is used for performance.\n+var TYPE_SYMBOL = (typeof Symbol === 'function' && Symbol.for &&\n+                  Symbol.for('react.element')) || 0xeac7;","path":"src/isomorphic/classic/element/ReactElement.js","position":7,"original_position":7,"commit_id":"031fc24daeae6bcdc5e5f6959b778e1c2ed5f378","original_commit_id":"031fc24daeae6bcdc5e5f6959b778e1c2ed5f378","user":{"login":"STRML","id":1197375,"avatar_url":"https://avatars.githubusercontent.com/u/1197375?v=3","gravatar_id":"","url":"https://api.github.com/users/STRML","html_url":"https://github.com/STRML","followers_url":"https://api.github.com/users/STRML/followers","following_url":"https://api.github.com/users/STRML/following{/other_user}","gists_url":"https://api.github.com/users/STRML/gists{/gist_id}","starred_url":"https://api.github.com/users/STRML/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/STRML/subscriptions","organizations_url":"https://api.github.com/users/STRML/orgs","repos_url":"https://api.github.com/users/STRML/repos","events_url":"https://api.github.com/users/STRML/events{/privacy}","received_events_url":"https://api.github.com/users/STRML/received_events","type":"User","site_admin":false},"body":"Wouldn't `Infinity` be a better magicnum? It can't be JSON-encoded, so we still get the XSS protection on browsers that don't support Symbols.","created_at":"2015-10-14T17:18:57Z","updated_at":"2015-10-14T17:18:57Z","html_url":"https://github.com/facebook/react/pull/4832#discussion_r42023564","pull_request_url":"https://api.github.com/repos/facebook/react/pulls/4832","_links":{"self":{"href":"https://api.github.com/repos/facebook/react/pulls/comments/42023564"},"html":{"href":"https://github.com/facebook/react/pull/4832#discussion_r42023564"},"pull_request":{"href":"https://api.github.com/repos/facebook/react/pulls/4832"}}},"pull_request":{"url":"https://api.github.com/repos/facebook/react/pulls/4832","id":44630614,"html_url":"https://github.com/facebook/react/pull/4832","diff_url":"https://github.com/facebook/react/pull/4832.diff","patch_url":"https://github.com/facebook/react/pull/4832.patch","issue_url":"https://api.github.com/repos/facebook/react/issues/4832","number":4832,"state":"closed","locked":false,"title":"Use a Symbol to tag every ReactElement","user":{"login":"sebmarkbage","id":63648,"avatar_url":"https://avatars.githubusercontent.com/u/63648?v=3","gravatar_id":"","url":"https://api.github.com/users/sebmarkbage","html_url":"https://github.com/sebmarkbage","followers_url":"https://api.github.com/users/sebmarkbage/followers","following_url":"https://api.github.com/users/sebmarkbage/following{/other_user}","gists_url":"https://api.github.com/users/sebmarkbage/gists{/gist_id}","starred_url":"https://api.github.com/users/sebmarkbage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebmarkbage/subscriptions","organizations_url":"https://api.github.com/users/sebmarkbage/orgs","repos_url":"https://api.github.com/users/sebmarkbage/repos","events_url":"https://api.github.com/users/sebmarkbage/events{/privacy}","received_events_url":"https://api.github.com/users/sebmarkbage/received_events","type":"User","site_admin":false},"body":"Fixes #3473\r\n\r\nI tag each React element with `$$typeof: Symbol.for('react.element')`. We need\r\nthis to be able to safely distinguish these from plain objects that might have\r\ncome from user provided JSON.\r\n\r\nThe idiomatic JavaScript way of tagging an object is for it to inherent some\r\nprototype and then use `instanceof` to test for it.\r\n\r\nHowever, this has limitations since it doesn't work with value types which\r\nrequire `typeof` checks. They also don't work across realms. Which is why there\r\nare alternative tag checks like `Array.isArray` or the `toStringTag`. Another\r\nproblem is that different instances of React that might have been created not knowing about eachother. npm tends to make this kind of problem occur a lot.\r\n\r\nAdditionally, it is our hope that ReactElement will one day be specified in\r\nterms of a \"Value Type\" style record instead of a plain Object.\r\n\r\nThis Value Types proposal by @nikomatsakis is currently on hold but does satisfy all these requirements:\r\n\r\nhttps://github.com/nikomatsakis/typed-objects-explainer/blob/master/valuetypes.md#the-typeof-operator\r\n\r\nAdditionally, there is already a system for coordinating tags across module\r\nsystems and even realms in ES6. Namely using `Symbol.for`. (thx @sebmck)\r\n\r\nCurrently these objects are not able to transfer between Workers but there is\r\nnothing preventing that from being possible in the future. You could imagine\r\neven `Symbol.for` working across Worker boundaries. You could also build a\r\nsystem that coordinates Symbols and Value Types from server to client or through\r\nserialized forms. That's beyond the scope of React itself, and if it was built\r\nit seems like it would belong with the `Symbol` system. A system could override\r\nthe `Symbol.for('react.element')` to return a plain yet\r\ncryptographically random or unique number. That would allow ReactElements to\r\npass through JSON without risking the XSS issue.\r\n\r\nThe fallback solution is a plain well-known number. This makes it unsafe with\r\nregard to the XSS issue described in #3473. We could have used a much more\r\nconvoluted solution to protect against JSON specifically but that would require\r\nsome kind of significant coordination, or change the check to do a\r\n`typeof element.$$typeof === 'function'` check which would not make it unique to\r\nReact. It seems cleaner to just use a fixed number since the protection is just\r\na secondary layer anyway. I'm not sure if this is the right tradeoff.\r\n\r\nIn short, if you want the XSS protection, use a proper Symbol polyfill.\r\n\r\nFinally, the reason for calling it `$$typeof` is to avoid confusion with `.type`\r\nand the use case is to add a tag that the `typeof` operator would refer to.\r\nI would use `@@typeof` but that seems to deopt in JSC. I also don't use\r\n`__typeof` because this is more than a framework private. It should really be\r\npart of the polyfilling layer.\r\n\r\nTest Plan:\r\n\r\n`examples/basic/index.html` works in Chrome and Firefox which both have native Symbols - and in Safari which doesn't.\r\n\r\n`React.createElement('div').$$typeof // Symbol(react.element)`.","created_at":"2015-09-10T05:58:59Z","updated_at":"2015-10-14T17:18:57Z","closed_at":"2015-09-10T06:19:33Z","merged_at":"2015-09-10T06:19:33Z","merge_commit_sha":"03e8baf49d7a8c188f301cef1f8e01a014506da4","assignee":null,"milestone":{"url":"https://api.github.com/repos/facebook/react/milestones/13","html_url":"https://github.com/facebook/react/milestones/0.14","labels_url":"https://api.github.com/repos/facebook/react/milestones/13/labels","id":1035426,"number":13,"title":"0.14","description":null,"creator":{"login":"spicyj","id":6820,"avatar_url":"https://avatars.githubusercontent.com/u/6820?v=3","gravatar_id":"","url":"https://api.github.com/users/spicyj","html_url":"https://github.com/spicyj","followers_url":"https://api.github.com/users/spicyj/followers","following_url":"https://api.github.com/users/spicyj/following{/other_user}","gists_url":"https://api.github.com/users/spicyj/gists{/gist_id}","starred_url":"https://api.github.com/users/spicyj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spicyj/subscriptions","organizations_url":"https://api.github.com/users/spicyj/orgs","repos_url":"https://api.github.com/users/spicyj/repos","events_url":"https://api.github.com/users/spicyj/events{/privacy}","received_events_url":"https://api.github.com/users/spicyj/received_events","type":"User","site_admin":false},"open_issues":0,"closed_issues":74,"state":"closed","created_at":"2015-03-23T23:33:55Z","updated_at":"2015-10-09T17:52:30Z","due_on":null,"closed_at":"2015-10-08T00:19:55Z"},"commits_url":"https://api.github.com/repos/facebook/react/pulls/4832/commits","review_comments_url":"https://api.github.com/repos/facebook/react/pulls/4832/comments","review_comment_url":"https://api.github.com/repos/facebook/react/pulls/comments{/number}","comments_url":"https://api.github.com/repos/facebook/react/issues/4832/comments","statuses_url":"https://api.github.com/repos/facebook/react/statuses/031fc24daeae6bcdc5e5f6959b778e1c2ed5f378","head":{"label":"sebmarkbage:xssfix","ref":"xssfix","sha":"031fc24daeae6bcdc5e5f6959b778e1c2ed5f378","user":{"login":"sebmarkbage","id":63648,"avatar_url":"https://avatars.githubusercontent.com/u/63648?v=3","gravatar_id":"","url":"https://api.github.com/users/sebmarkbage","html_url":"https://github.com/sebmarkbage","followers_url":"https://api.github.com/users/sebmarkbage/followers","following_url":"https://api.github.com/users/sebmarkbage/following{/other_user}","gists_url":"https://api.github.com/users/sebmarkbage/gists{/gist_id}","starred_url":"https://api.github.com/users/sebmarkbage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebmarkbage/subscriptions","organizations_url":"https://api.github.com/users/sebmarkbage/orgs","repos_url":"https://api.github.com/users/sebmarkbage/repos","events_url":"https://api.github.com/users/sebmarkbage/events{/privacy}","received_events_url":"https://api.github.com/users/sebmarkbage/received_events","type":"User","site_admin":false},"repo":{"id":10374314,"name":"react","full_name":"sebmarkbage/react","owner":{"login":"sebmarkbage","id":63648,"avatar_url":"https://avatars.githubusercontent.com/u/63648?v=3","gravatar_id":"","url":"https://api.github.com/users/sebmarkbage","html_url":"https://github.com/sebmarkbage","followers_url":"https://api.github.com/users/sebmarkbage/followers","following_url":"https://api.github.com/users/sebmarkbage/following{/other_user}","gists_url":"https://api.github.com/users/sebmarkbage/gists{/gist_id}","starred_url":"https://api.github.com/users/sebmarkbage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sebmarkbage/subscriptions","organizations_url":"https://api.github.com/users/sebmarkbage/orgs","repos_url":"https://api.github.com/users/sebmarkbage/repos","events_url":"https://api.github.com/users/sebmarkbage/events{/privacy}","received_events_url":"https://api.github.com/users/sebmarkbage/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sebmarkbage/react","description":"React is a JavaScript library for building user interfaces.","fork":true,"url":"https://api.github.com/repos/sebmarkbage/react","forks_url":"https://api.github.com/repos/sebmarkbage/react/forks","keys_url":"https://api.github.com/repos/sebmarkbage/react/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sebmarkbage/react/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sebmarkbage/react/teams","hooks_url":"https://api.github.com/repos/sebmarkbage/react/hooks","issue_events_url":"https://api.github.com/repos/sebmarkbage/react/issues/events{/number}","events_url":"https://api.github.com/repos/sebmarkbage/react/events","assignees_url":"https://api.github.com/repos/sebmarkbage/react/assignees{/user}","branches_url":"https://api.github.com/repos/sebmarkbage/react/branches{/branch}","tags_url":"https://api.github.com/repos/sebmarkbage/react/tags","blobs_url":"https://api.github.com/repos/sebmarkbage/react/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sebmarkbage/react/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sebmarkbage/react/git/refs{/sha}","trees_url":"https://api.github.com/repos/sebmarkbage/react/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sebmarkbage/react/statuses/{sha}","languages_url":"https://api.github.com/repos/sebmarkbage/react/languages","stargazers_url":"https://api.github.com/repos/sebmarkbage/react/stargazers","contributors_url":"https://api.github.com/repos/sebmarkbage/react/contributors","subscribers_url":"https://api.github.com/repos/sebmarkbage/react/subscribers","subscription_url":"https://api.github.com/repos/sebmarkbage/react/subscription","commits_url":"https://api.github.com/repos/sebmarkbage/react/commits{/sha}","git_commits_url":"https://api.github.com/repos/sebmarkbage/react/git/commits{/sha}","comments_url":"https://api.github.com/repos/sebmarkbage/react/comments{/number}","issue_comment_url":"https://api.github.com/repos/sebmarkbage/react/issues/comments{/number}","contents_url":"https://api.github.com/repos/sebmarkbage/react/contents/{+path}","compare_url":"https://api.github.com/repos/sebmarkbage/react/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sebmarkbage/react/merges","archive_url":"https://api.github.com/repos/sebmarkbage/react/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sebmarkbage/react/downloads","issues_url":"https://api.github.com/repos/sebmarkbage/react/issues{/number}","pulls_url":"https://api.github.com/repos/sebmarkbage/react/pulls{/number}","milestones_url":"https://api.github.com/repos/sebmarkbage/react/milestones{/number}","notifications_url":"https://api.github.com/repos/sebmarkbage/react/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sebmarkbage/react/labels{/name}","releases_url":"https://api.github.com/repos/sebmarkbage/react/releases{/id}","created_at":"2013-05-30T03:09:16Z","updated_at":"2014-10-16T16:21:48Z","pushed_at":"2015-10-01T01:28:59Z","git_url":"git://github.com/sebmarkbage/react.git","ssh_url":"git@github.com:sebmarkbage/react.git","clone_url":"https://github.com/sebmarkbage/react.git","svn_url":"https://github.com/sebmarkbage/react","homepage":"http://facebook.github.io/react/","size":44361,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"facebook:master","ref":"master","sha":"a05691f0ad9d20fc9ffb1fc04d531e257e37d55b","user":{"login":"facebook","id":69631,"avatar_url":"https://avatars.githubusercontent.com/u/69631?v=3","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"repo":{"id":10270250,"name":"react","full_name":"facebook/react","owner":{"login":"facebook","id":69631,"avatar_url":"https://avatars.githubusercontent.com/u/69631?v=3","gravatar_id":"","url":"https://api.github.com/users/facebook","html_url":"https://github.com/facebook","followers_url":"https://api.github.com/users/facebook/followers","following_url":"https://api.github.com/users/facebook/following{/other_user}","gists_url":"https://api.github.com/users/facebook/gists{/gist_id}","starred_url":"https://api.github.com/users/facebook/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/facebook/subscriptions","organizations_url":"https://api.github.com/users/facebook/orgs","repos_url":"https://api.github.com/users/facebook/repos","events_url":"https://api.github.com/users/facebook/events{/privacy}","received_events_url":"https://api.github.com/users/facebook/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/facebook/react","description":"A declarative, efficient, and flexible JavaScript library for building user interfaces.","fork":false,"url":"https://api.github.com/repos/facebook/react","forks_url":"https://api.github.com/repos/facebook/react/forks","keys_url":"https://api.github.com/repos/facebook/react/keys{/key_id}","collaborators_url":"https://api.github.com/repos/facebook/react/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/facebook/react/teams","hooks_url":"https://api.github.com/repos/facebook/react/hooks","issue_events_url":"https://api.github.com/repos/facebook/react/issues/events{/number}","events_url":"https://api.github.com/repos/facebook/react/events","assignees_url":"https://api.github.com/repos/facebook/react/assignees{/user}","branches_url":"https://api.github.com/repos/facebook/react/branches{/branch}","tags_url":"https://api.github.com/repos/facebook/react/tags","blobs_url":"https://api.github.com/repos/facebook/react/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/facebook/react/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/facebook/react/git/refs{/sha}","trees_url":"https://api.github.com/repos/facebook/react/git/trees{/sha}","statuses_url":"https://api.github.com/repos/facebook/react/statuses/{sha}","languages_url":"https://api.github.com/repos/facebook/react/languages","stargazers_url":"https://api.github.com/repos/facebook/react/stargazers","contributors_url":"https://api.github.com/repos/facebook/react/contributors","subscribers_url":"https://api.github.com/repos/facebook/react/subscribers","subscription_url":"https://api.github.com/repos/facebook/react/subscription","commits_url":"https://api.github.com/repos/facebook/react/commits{/sha}","git_commits_url":"https://api.github.com/repos/facebook/react/git/commits{/sha}","comments_url":"https://api.github.com/repos/facebook/react/comments{/number}","issue_comment_url":"https://api.github.com/repos/facebook/react/issues/comments{/number}","contents_url":"https://api.github.com/repos/facebook/react/contents/{+path}","compare_url":"https://api.github.com/repos/facebook/react/compare/{base}...{head}","merges_url":"https://api.github.com/repos/facebook/react/merges","archive_url":"https://api.github.com/repos/facebook/react/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/facebook/react/downloads","issues_url":"https://api.github.com/repos/facebook/react/issues{/number}","pulls_url":"https://api.github.com/repos/facebook/react/pulls{/number}","milestones_url":"https://api.github.com/repos/facebook/react/milestones{/number}","notifications_url":"https://api.github.com/repos/facebook/react/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/facebook/react/labels{/name}","releases_url":"https://api.github.com/repos/facebook/react/releases{/id}","created_at":"2013-05-24T16:15:54Z","updated_at":"2015-10-14T16:35:53Z","pushed_at":"2015-10-14T16:36:31Z","git_url":"git://github.com/facebook/react.git","ssh_url":"git@github.com:facebook/react.git","clone_url":"https://github.com/facebook/react.git","svn_url":"https://github.com/facebook/react","homepage":"https://facebook.github.io/react/","size":117357,"stargazers_count":29559,"watchers_count":29559,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":4514,"mirror_url":null,"open_issues_count":564,"forks":4514,"open_issues":564,"watchers":29559,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/facebook/react/pulls/4832"},"html":{"href":"https://github.com/facebook/react/pull/4832"},"issue":{"href":"https://api.github.com/repos/facebook/react/issues/4832"},"comments":{"href":"https://api.github.com/repos/facebook/react/issues/4832/comments"},"review_comments":{"href":"https://api.github.com/repos/facebook/react/pulls/4832/comments"},"review_comment":{"href":"https://api.github.com/repos/facebook/react/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/facebook/react/pulls/4832/commits"},"statuses":{"href":"https://api.github.com/repos/facebook/react/statuses/031fc24daeae6bcdc5e5f6959b778e1c2ed5f378"}}}}