{"action":"created","comment":{"url":"https://api.github.com/repos/angular/angular/pulls/comments/62061265","id":62061265,"diff_hunk":"@@ -0,0 +1,239 @@\n+import {getDOM, DomAdapter} from '../dom/dom_adapter';\n+import {sanitizeUrl} from './url_sanitizer';\n+\n+/** A <body> element that can be safely used to parse untrusted HTML. Lazily initialized below. */\n+let inertBody: HTMLElement = null;\n+/** Lazily initialized to make sure the DOM adapter gets set before use. */\n+let DOM: DomAdapter = null;\n+\n+/**\n+ * Returns an HTML document <body> that is guaranteed to not execute code when creating elements in\n+ * it.\n+ */\n+function getInertBody() {\n+  if (inertBody) return inertBody;\n+  DOM = getDOM();\n+  let doc = DOM.createHtmlDocument();\n+  inertBody = DOM.querySelector(doc, 'body');\n+  if (inertBody == null) {\n+    // usually there should be only one body element in the document, but IE doesn't have any, so we\n+    // need to create one.\n+    let html = DOM.createElement('html', doc);\n+    inertBody = DOM.createElement('body', doc);\n+    DOM.appendChild(html, inertBody);\n+    DOM.appendChild(doc, html);\n+  }\n+  return inertBody;\n+}\n+\n+function tagSet(tags: string): {[k: string]: boolean} {\n+  let res: {[k: string]: boolean} = {};\n+  for (let t of tags.split(',')) res[t.toLowerCase()] = true;\n+  return res;\n+}\n+\n+function merge(...sets: { [k: string]: boolean }[]): {[k: string]: boolean} {\n+  let res: {[k: string]: boolean} = {};\n+  for (let s of sets) {\n+    for (let v in s) {\n+      if (s.hasOwnProperty(v)) res[v] = true;\n+    }\n+  }\n+  return res;\n+}\n+\n+// Good source of info about elements and attributes\n+// http://dev.w3.org/html5/spec/Overview.html#semantics\n+// http://simon.html5.org/html-elements\n+\n+// Safe Void Elements - HTML5\n+// http://dev.w3.org/html5/spec/Overview.html#void-elements\n+const VOID_ELEMENTS = tagSet(\"area,br,col,hr,img,wbr\");\n+\n+// Elements that you can, intentionally, leave open (and which close themselves)\n+// http://dev.w3.org/html5/spec/Overview.html#optional-tags\n+const OPTIONAL_END_TAG_BLOCK_ELEMENTS = tagSet(\"colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr\");\n+const OPTIONAL_END_TAG_INLINE_ELEMENTS = tagSet(\"rp,rt\");\n+const OPTIONAL_END_TAG_ELEMENTS =\n+    merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, OPTIONAL_END_TAG_BLOCK_ELEMENTS);\n+\n+// Safe Block Elements - HTML5\n+const BLOCK_ELEMENTS = merge(\n+    OPTIONAL_END_TAG_BLOCK_ELEMENTS,\n+    tagSet(\n+        \"address,article,\" +\n+        \"aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,\" +\n+        \"h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul\"));\n+\n+// Inline Elements - HTML5\n+const INLINE_ELEMENTS = merge(\n+    OPTIONAL_END_TAG_INLINE_ELEMENTS,\n+    tagSet(\"a,abbr,acronym,b,\" +\n+           \"bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,\" +\n+           \"samp,small,span,strike,strong,sub,sup,time,tt,u,var\"));\n+\n+const VALID_ELEMENTS =\n+    merge(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS);\n+\n+// Attributes that have href and hence need to be sanitized\n+const URI_ATTRS = tagSet(\"background,cite,href,longdesc,src,xlink:href\");","path":"modules/@angular/platform-browser/src/security/html_sanitizer.ts","position":79,"original_position":79,"commit_id":"d873286aef9f923c63a53eac00e34f2ddf7929fd","original_commit_id":"d873286aef9f923c63a53eac00e34f2ddf7929fd","user":{"login":"mprobst","id":7208,"avatar_url":"https://avatars.githubusercontent.com/u/7208?v=3","gravatar_id":"","url":"https://api.github.com/users/mprobst","html_url":"https://github.com/mprobst","followers_url":"https://api.github.com/users/mprobst/followers","following_url":"https://api.github.com/users/mprobst/following{/other_user}","gists_url":"https://api.github.com/users/mprobst/gists{/gist_id}","starred_url":"https://api.github.com/users/mprobst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mprobst/subscriptions","organizations_url":"https://api.github.com/users/mprobst/orgs","repos_url":"https://api.github.com/users/mprobst/repos","events_url":"https://api.github.com/users/mprobst/events{/privacy}","received_events_url":"https://api.github.com/users/mprobst/received_events","type":"User","site_admin":false},"body":"Ah sorry, I'm used to the newer clang-format version automatically single-quoting strings. Fixed.","created_at":"2016-05-04T15:32:56Z","updated_at":"2016-05-04T15:32:56Z","html_url":"https://github.com/angular/angular/pull/8453#discussion_r62061265","pull_request_url":"https://api.github.com/repos/angular/angular/pulls/8453","_links":{"self":{"href":"https://api.github.com/repos/angular/angular/pulls/comments/62061265"},"html":{"href":"https://github.com/angular/angular/pull/8453#discussion_r62061265"},"pull_request":{"href":"https://api.github.com/repos/angular/angular/pulls/8453"}}},"pull_request":{"url":"https://api.github.com/repos/angular/angular/pulls/8453","id":68801194,"html_url":"https://github.com/angular/angular/pull/8453","diff_url":"https://github.com/angular/angular/pull/8453.diff","patch_url":"https://github.com/angular/angular/pull/8453.patch","issue_url":"https://api.github.com/repos/angular/angular/issues/8453","number":8453,"state":"open","locked":false,"title":"feat(security): Add an HTML sanitizer","user":{"login":"mprobst","id":7208,"avatar_url":"https://avatars.githubusercontent.com/u/7208?v=3","gravatar_id":"","url":"https://api.github.com/users/mprobst","html_url":"https://github.com/mprobst","followers_url":"https://api.github.com/users/mprobst/followers","following_url":"https://api.github.com/users/mprobst/following{/other_user}","gists_url":"https://api.github.com/users/mprobst/gists{/gist_id}","starred_url":"https://api.github.com/users/mprobst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mprobst/subscriptions","organizations_url":"https://api.github.com/users/mprobst/orgs","repos_url":"https://api.github.com/users/mprobst/repos","events_url":"https://api.github.com/users/mprobst/events{/privacy}","received_events_url":"https://api.github.com/users/mprobst/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-05-04T01:44:42Z","updated_at":"2016-05-04T15:32:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5eb3c691554800df335bb9feb52b46e310a49c06","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/angular/angular/pulls/8453/commits","review_comments_url":"https://api.github.com/repos/angular/angular/pulls/8453/comments","review_comment_url":"https://api.github.com/repos/angular/angular/pulls/comments{/number}","comments_url":"https://api.github.com/repos/angular/angular/issues/8453/comments","statuses_url":"https://api.github.com/repos/angular/angular/statuses/d873286aef9f923c63a53eac00e34f2ddf7929fd","head":{"label":"mprobst:html-sanitizer","ref":"html-sanitizer","sha":"d873286aef9f923c63a53eac00e34f2ddf7929fd","user":{"login":"mprobst","id":7208,"avatar_url":"https://avatars.githubusercontent.com/u/7208?v=3","gravatar_id":"","url":"https://api.github.com/users/mprobst","html_url":"https://github.com/mprobst","followers_url":"https://api.github.com/users/mprobst/followers","following_url":"https://api.github.com/users/mprobst/following{/other_user}","gists_url":"https://api.github.com/users/mprobst/gists{/gist_id}","starred_url":"https://api.github.com/users/mprobst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mprobst/subscriptions","organizations_url":"https://api.github.com/users/mprobst/orgs","repos_url":"https://api.github.com/users/mprobst/repos","events_url":"https://api.github.com/users/mprobst/events{/privacy}","received_events_url":"https://api.github.com/users/mprobst/received_events","type":"User","site_admin":false},"repo":{"id":31006722,"name":"angular","full_name":"mprobst/angular","owner":{"login":"mprobst","id":7208,"avatar_url":"https://avatars.githubusercontent.com/u/7208?v=3","gravatar_id":"","url":"https://api.github.com/users/mprobst","html_url":"https://github.com/mprobst","followers_url":"https://api.github.com/users/mprobst/followers","following_url":"https://api.github.com/users/mprobst/following{/other_user}","gists_url":"https://api.github.com/users/mprobst/gists{/gist_id}","starred_url":"https://api.github.com/users/mprobst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mprobst/subscriptions","organizations_url":"https://api.github.com/users/mprobst/orgs","repos_url":"https://api.github.com/users/mprobst/repos","events_url":"https://api.github.com/users/mprobst/events{/privacy}","received_events_url":"https://api.github.com/users/mprobst/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mprobst/angular","description":"","fork":true,"url":"https://api.github.com/repos/mprobst/angular","forks_url":"https://api.github.com/repos/mprobst/angular/forks","keys_url":"https://api.github.com/repos/mprobst/angular/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mprobst/angular/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mprobst/angular/teams","hooks_url":"https://api.github.com/repos/mprobst/angular/hooks","issue_events_url":"https://api.github.com/repos/mprobst/angular/issues/events{/number}","events_url":"https://api.github.com/repos/mprobst/angular/events","assignees_url":"https://api.github.com/repos/mprobst/angular/assignees{/user}","branches_url":"https://api.github.com/repos/mprobst/angular/branches{/branch}","tags_url":"https://api.github.com/repos/mprobst/angular/tags","blobs_url":"https://api.github.com/repos/mprobst/angular/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mprobst/angular/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mprobst/angular/git/refs{/sha}","trees_url":"https://api.github.com/repos/mprobst/angular/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mprobst/angular/statuses/{sha}","languages_url":"https://api.github.com/repos/mprobst/angular/languages","stargazers_url":"https://api.github.com/repos/mprobst/angular/stargazers","contributors_url":"https://api.github.com/repos/mprobst/angular/contributors","subscribers_url":"https://api.github.com/repos/mprobst/angular/subscribers","subscription_url":"https://api.github.com/repos/mprobst/angular/subscription","commits_url":"https://api.github.com/repos/mprobst/angular/commits{/sha}","git_commits_url":"https://api.github.com/repos/mprobst/angular/git/commits{/sha}","comments_url":"https://api.github.com/repos/mprobst/angular/comments{/number}","issue_comment_url":"https://api.github.com/repos/mprobst/angular/issues/comments{/number}","contents_url":"https://api.github.com/repos/mprobst/angular/contents/{+path}","compare_url":"https://api.github.com/repos/mprobst/angular/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mprobst/angular/merges","archive_url":"https://api.github.com/repos/mprobst/angular/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mprobst/angular/downloads","issues_url":"https://api.github.com/repos/mprobst/angular/issues{/number}","pulls_url":"https://api.github.com/repos/mprobst/angular/pulls{/number}","milestones_url":"https://api.github.com/repos/mprobst/angular/milestones{/number}","notifications_url":"https://api.github.com/repos/mprobst/angular/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mprobst/angular/labels{/name}","releases_url":"https://api.github.com/repos/mprobst/angular/releases{/id}","deployments_url":"https://api.github.com/repos/mprobst/angular/deployments","created_at":"2015-02-19T08:23:36Z","updated_at":"2016-04-28T18:26:33Z","pushed_at":"2016-05-04T01:59:41Z","git_url":"git://github.com/mprobst/angular.git","ssh_url":"git@github.com:mprobst/angular.git","clone_url":"https://github.com/mprobst/angular.git","svn_url":"https://github.com/mprobst/angular","homepage":null,"size":21172,"stargazers_count":0,"watchers_count":0,"language":"TypeScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"angular:master","ref":"master","sha":"9485f5a81363a49ad5f5fc4a0bdd20ed94f6c6d8","user":{"login":"angular","id":139426,"avatar_url":"https://avatars.githubusercontent.com/u/139426?v=3","gravatar_id":"","url":"https://api.github.com/users/angular","html_url":"https://github.com/angular","followers_url":"https://api.github.com/users/angular/followers","following_url":"https://api.github.com/users/angular/following{/other_user}","gists_url":"https://api.github.com/users/angular/gists{/gist_id}","starred_url":"https://api.github.com/users/angular/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/angular/subscriptions","organizations_url":"https://api.github.com/users/angular/orgs","repos_url":"https://api.github.com/users/angular/repos","events_url":"https://api.github.com/users/angular/events{/privacy}","received_events_url":"https://api.github.com/users/angular/received_events","type":"Organization","site_admin":false},"repo":{"id":24195339,"name":"angular","full_name":"angular/angular","owner":{"login":"angular","id":139426,"avatar_url":"https://avatars.githubusercontent.com/u/139426?v=3","gravatar_id":"","url":"https://api.github.com/users/angular","html_url":"https://github.com/angular","followers_url":"https://api.github.com/users/angular/followers","following_url":"https://api.github.com/users/angular/following{/other_user}","gists_url":"https://api.github.com/users/angular/gists{/gist_id}","starred_url":"https://api.github.com/users/angular/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/angular/subscriptions","organizations_url":"https://api.github.com/users/angular/orgs","repos_url":"https://api.github.com/users/angular/repos","events_url":"https://api.github.com/users/angular/events{/privacy}","received_events_url":"https://api.github.com/users/angular/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/angular/angular","description":"","fork":false,"url":"https://api.github.com/repos/angular/angular","forks_url":"https://api.github.com/repos/angular/angular/forks","keys_url":"https://api.github.com/repos/angular/angular/keys{/key_id}","collaborators_url":"https://api.github.com/repos/angular/angular/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/angular/angular/teams","hooks_url":"https://api.github.com/repos/angular/angular/hooks","issue_events_url":"https://api.github.com/repos/angular/angular/issues/events{/number}","events_url":"https://api.github.com/repos/angular/angular/events","assignees_url":"https://api.github.com/repos/angular/angular/assignees{/user}","branches_url":"https://api.github.com/repos/angular/angular/branches{/branch}","tags_url":"https://api.github.com/repos/angular/angular/tags","blobs_url":"https://api.github.com/repos/angular/angular/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/angular/angular/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/angular/angular/git/refs{/sha}","trees_url":"https://api.github.com/repos/angular/angular/git/trees{/sha}","statuses_url":"https://api.github.com/repos/angular/angular/statuses/{sha}","languages_url":"https://api.github.com/repos/angular/angular/languages","stargazers_url":"https://api.github.com/repos/angular/angular/stargazers","contributors_url":"https://api.github.com/repos/angular/angular/contributors","subscribers_url":"https://api.github.com/repos/angular/angular/subscribers","subscription_url":"https://api.github.com/repos/angular/angular/subscription","commits_url":"https://api.github.com/repos/angular/angular/commits{/sha}","git_commits_url":"https://api.github.com/repos/angular/angular/git/commits{/sha}","comments_url":"https://api.github.com/repos/angular/angular/comments{/number}","issue_comment_url":"https://api.github.com/repos/angular/angular/issues/comments{/number}","contents_url":"https://api.github.com/repos/angular/angular/contents/{+path}","compare_url":"https://api.github.com/repos/angular/angular/compare/{base}...{head}","merges_url":"https://api.github.com/repos/angular/angular/merges","archive_url":"https://api.github.com/repos/angular/angular/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/angular/angular/downloads","issues_url":"https://api.github.com/repos/angular/angular/issues{/number}","pulls_url":"https://api.github.com/repos/angular/angular/pulls{/number}","milestones_url":"https://api.github.com/repos/angular/angular/milestones{/number}","notifications_url":"https://api.github.com/repos/angular/angular/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/angular/angular/labels{/name}","releases_url":"https://api.github.com/repos/angular/angular/releases{/id}","deployments_url":"https://api.github.com/repos/angular/angular/deployments","created_at":"2014-09-18T16:12:01Z","updated_at":"2016-05-04T15:32:55Z","pushed_at":"2016-05-04T10:43:33Z","git_url":"git://github.com/angular/angular.git","ssh_url":"git@github.com:angular/angular.git","clone_url":"https://github.com/angular/angular.git","svn_url":"https://github.com/angular/angular","homepage":"https://angular.io","size":591139,"stargazers_count":11464,"watchers_count":11464,"language":"TypeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2976,"mirror_url":null,"open_issues_count":1587,"forks":2976,"open_issues":1587,"watchers":11464,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/angular/angular/pulls/8453"},"html":{"href":"https://github.com/angular/angular/pull/8453"},"issue":{"href":"https://api.github.com/repos/angular/angular/issues/8453"},"comments":{"href":"https://api.github.com/repos/angular/angular/issues/8453/comments"},"review_comments":{"href":"https://api.github.com/repos/angular/angular/pulls/8453/comments"},"review_comment":{"href":"https://api.github.com/repos/angular/angular/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/angular/angular/pulls/8453/commits"},"statuses":{"href":"https://api.github.com/repos/angular/angular/statuses/d873286aef9f923c63a53eac00e34f2ddf7929fd"}}}}