@angular/platform-browser 4.4.6 → 4.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import * as tslib_1 from "tslib";
2
2
  /**
3
- * @license Angular v4.4.6
3
+ * @license Angular v4.4.7
4
4
  * (c) 2010-2017 Google, Inc. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v4.4.6
2
+ * @license Angular v4.4.7
3
3
  * (c) 2010-2017 Google, Inc. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v4.4.6
2
+ * @license Angular v4.4.7
3
3
  * (c) 2010-2017 Google, Inc. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v4.4.6
2
+ * @license Angular v4.4.7
3
3
  * (c) 2010-2017 Google, Inc. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1,6 +1,6 @@
1
1
  import * as tslib_1 from "tslib";
2
2
  /**
3
- * @license Angular v4.4.6
3
+ * @license Angular v4.4.7
4
4
  * (c) 2010-2017 Google, Inc. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -3343,6 +3343,174 @@ KeyEventsPlugin.decorators = [
3343
3343
  KeyEventsPlugin.ctorParameters = function () { return [
3344
3344
  { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT$1,] },] },
3345
3345
  ]; };
3346
+ /**
3347
+ * @license
3348
+ * Copyright Google Inc. All Rights Reserved.
3349
+ *
3350
+ * Use of this source code is governed by an MIT-style license that can be
3351
+ * found in the LICENSE file at https://angular.io/license
3352
+ */
3353
+ /**
3354
+ * This helper class is used to get hold of an inert tree of DOM elements containing dirty HTML
3355
+ * that needs sanitizing.
3356
+ * Depending upon browser support we must use one of three strategies for doing this.
3357
+ * Support: Safari 10.x -> XHR strategy
3358
+ * Support: Firefox -> DomParser strategy
3359
+ * Default: InertDocument strategy
3360
+ */
3361
+ var InertBodyHelper = (function () {
3362
+ /**
3363
+ * @param {?} defaultDoc
3364
+ * @param {?} DOM
3365
+ */
3366
+ function InertBodyHelper(defaultDoc, DOM) {
3367
+ this.defaultDoc = defaultDoc;
3368
+ this.DOM = DOM;
3369
+ var inertDocument = this.DOM.createHtmlDocument();
3370
+ this.inertBodyElement = inertDocument.body;
3371
+ if (this.inertBodyElement == null) {
3372
+ // usually there should be only one body element in the document, but IE doesn't have any, so
3373
+ // we need to create one.
3374
+ var inertHtml = this.DOM.createElement('html', inertDocument);
3375
+ this.inertBodyElement = this.DOM.createElement('body', inertDocument);
3376
+ this.DOM.appendChild(inertHtml, this.inertBodyElement);
3377
+ this.DOM.appendChild(inertDocument, inertHtml);
3378
+ }
3379
+ this.DOM.setInnerHTML(this.inertBodyElement, '<svg><g onload="this.parentNode.remove()"></g></svg>');
3380
+ if (this.inertBodyElement.querySelector && !this.inertBodyElement.querySelector('svg')) {
3381
+ // We just hit the Safari 10.1 bug - which allows JS to run inside the SVG G element
3382
+ // so use the XHR strategy.
3383
+ this.getInertBodyElement = this.getInertBodyElement_XHR;
3384
+ return;
3385
+ }
3386
+ this.DOM.setInnerHTML(this.inertBodyElement, '<svg><p><style><img src="</style><img src=x onerror=alert(1)//">');
3387
+ if (this.inertBodyElement.querySelector && this.inertBodyElement.querySelector('svg img')) {
3388
+ // We just hit the Firefox bug - which prevents the inner img JS from being sanitized
3389
+ // so use the DOMParser strategy, if it is available.
3390
+ // If the DOMParser is not available then we are not in Firefox (Server/WebWorker?) so we
3391
+ // fall through to the default strategy below.
3392
+ if (isDOMParserAvailable()) {
3393
+ this.getInertBodyElement = this.getInertBodyElement_DOMParser;
3394
+ return;
3395
+ }
3396
+ }
3397
+ // None of the bugs were hit so it is safe for us to use the default InertDocument strategy
3398
+ this.getInertBodyElement = this.getInertBodyElement_InertDocument;
3399
+ }
3400
+ /**
3401
+ * Use XHR to create and fill an inert body element (on Safari 10.1)
3402
+ * See
3403
+ * https://github.com/cure53/DOMPurify/blob/a992d3a75031cb8bb032e5ea8399ba972bdf9a65/src/purify.js#L439-L449
3404
+ * @param {?} html
3405
+ * @return {?}
3406
+ */
3407
+ InertBodyHelper.prototype.getInertBodyElement_XHR = function (html) {
3408
+ // We add these extra elements to ensure that the rest of the content is parsed as expected
3409
+ // e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the
3410
+ // `<head>` tag.
3411
+ html = '<body><remove></remove>' + html + '</body>';
3412
+ try {
3413
+ html = encodeURI(html);
3414
+ }
3415
+ catch (e) {
3416
+ return null;
3417
+ }
3418
+ var /** @type {?} */ xhr = new XMLHttpRequest();
3419
+ xhr.responseType = 'document';
3420
+ xhr.open('GET', 'data:text/html;charset=utf-8,' + html, false);
3421
+ xhr.send(null);
3422
+ var /** @type {?} */ body = xhr.response.body;
3423
+ body.removeChild(/** @type {?} */ ((body.firstChild)));
3424
+ return body;
3425
+ };
3426
+ /**
3427
+ * Use DOMParser to create and fill an inert body element (on Firefox)
3428
+ * See https://github.com/cure53/DOMPurify/releases/tag/0.6.7
3429
+ *
3430
+ * @param {?} html
3431
+ * @return {?}
3432
+ */
3433
+ InertBodyHelper.prototype.getInertBodyElement_DOMParser = function (html) {
3434
+ // We add these extra elements to ensure that the rest of the content is parsed as expected
3435
+ // e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the
3436
+ // `<head>` tag.
3437
+ html = '<body><remove></remove>' + html + '</body>';
3438
+ try {
3439
+ var /** @type {?} */ body = (new ((window))
3440
+ .DOMParser()
3441
+ .parseFromString(html, 'text/html')
3442
+ .body);
3443
+ body.removeChild(/** @type {?} */ ((body.firstChild)));
3444
+ return body;
3445
+ }
3446
+ catch (e) {
3447
+ return null;
3448
+ }
3449
+ };
3450
+ /**
3451
+ * Use an HTML5 `template` element, if supported, or an inert body element created via
3452
+ * `createHtmlDocument` to create and fill an inert DOM element.
3453
+ * This is the default sane strategy to use if the browser does not require one of the specialised
3454
+ * strategies above.
3455
+ * @param {?} html
3456
+ * @return {?}
3457
+ */
3458
+ InertBodyHelper.prototype.getInertBodyElement_InertDocument = function (html) {
3459
+ // Prefer using <template> element if supported.
3460
+ var /** @type {?} */ templateEl = this.DOM.createElement('template');
3461
+ if ('content' in templateEl) {
3462
+ this.DOM.setInnerHTML(templateEl, html);
3463
+ return templateEl;
3464
+ }
3465
+ this.DOM.setInnerHTML(this.inertBodyElement, html);
3466
+ // Support: IE 9-11 only
3467
+ // strip custom-namespaced attributes on IE<=11
3468
+ if (this.defaultDoc.documentMode) {
3469
+ this.stripCustomNsAttrs(this.inertBodyElement);
3470
+ }
3471
+ return this.inertBodyElement;
3472
+ };
3473
+ /**
3474
+ * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1'
3475
+ * attribute to declare ns1 namespace and prefixes the attribute with 'ns1' (e.g.
3476
+ * 'ns1:xlink:foo').
3477
+ *
3478
+ * This is undesirable since we don't want to allow any of these custom attributes. This method
3479
+ * strips them all.
3480
+ * @param {?} el
3481
+ * @return {?}
3482
+ */
3483
+ InertBodyHelper.prototype.stripCustomNsAttrs = function (el) {
3484
+ var _this = this;
3485
+ this.DOM.attributeMap(el).forEach(function (_, attrName) {
3486
+ if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) {
3487
+ _this.DOM.removeAttribute(el, attrName);
3488
+ }
3489
+ });
3490
+ for (var _i = 0, _a = this.DOM.childNodesAsList(el); _i < _a.length; _i++) {
3491
+ var n = _a[_i];
3492
+ if (this.DOM.isElementNode(n))
3493
+ this.stripCustomNsAttrs(/** @type {?} */ (n));
3494
+ }
3495
+ };
3496
+ return InertBodyHelper;
3497
+ }());
3498
+ /**
3499
+ * We need to determine whether the DOMParser exists in the global context.
3500
+ * The try-catch is because, on some browsers, trying to access this property
3501
+ * on window can actually throw an error.
3502
+ *
3503
+ * @suppress {uselessCode}
3504
+ * @return {?}
3505
+ */
3506
+ function isDOMParserAvailable() {
3507
+ try {
3508
+ return !!((window)).DOMParser;
3509
+ }
3510
+ catch (e) {
3511
+ return false;
3512
+ }
3513
+ }
3346
3514
  /**
3347
3515
  * @license
3348
3516
  * Copyright Google Inc. All Rights Reserved.
@@ -3409,38 +3577,6 @@ function sanitizeSrcset(srcset) {
3409
3577
  * Use of this source code is governed by an MIT-style license that can be
3410
3578
  * found in the LICENSE file at https://angular.io/license
3411
3579
  */
3412
- /**
3413
- * A <body> element that can be safely used to parse untrusted HTML. Lazily initialized below.
3414
- */
3415
- var inertElement = null;
3416
- /**
3417
- * Lazily initialized to make sure the DOM adapter gets set before use.
3418
- */
3419
- var DOM = null;
3420
- /**
3421
- * Returns an HTML element that is guaranteed to not execute code when creating elements in it.
3422
- * @return {?}
3423
- */
3424
- function getInertElement() {
3425
- if (inertElement)
3426
- return inertElement;
3427
- DOM = getDOM();
3428
- // Prefer using <template> element if supported.
3429
- var /** @type {?} */ templateEl = DOM.createElement('template');
3430
- if ('content' in templateEl)
3431
- return templateEl;
3432
- var /** @type {?} */ doc = DOM.createHtmlDocument();
3433
- inertElement = DOM.querySelector(doc, 'body');
3434
- if (inertElement == null) {
3435
- // usually there should be only one body element in the document, but IE doesn't have any, so we
3436
- // need to create one.
3437
- var /** @type {?} */ html = DOM.createElement('html', doc);
3438
- inertElement = DOM.createElement('body', doc);
3439
- DOM.appendChild(html, inertElement);
3440
- DOM.appendChild(doc, html);
3441
- }
3442
- return inertElement;
3443
- }
3444
3580
  /**
3445
3581
  * @param {?} tags
3446
3582
  * @return {?}
@@ -3516,6 +3652,7 @@ var SanitizingHtmlSerializer = (function () {
3516
3652
  function SanitizingHtmlSerializer() {
3517
3653
  this.sanitizedSomething = false;
3518
3654
  this.buf = [];
3655
+ this.DOM = getDOM();
3519
3656
  }
3520
3657
  /**
3521
3658
  * @param {?} el
@@ -3525,33 +3662,33 @@ var SanitizingHtmlSerializer = (function () {
3525
3662
  // This cannot use a TreeWalker, as it has to run on Angular's various DOM adapters.
3526
3663
  // However this code never accesses properties off of `document` before deleting its contents
3527
3664
  // again, so it shouldn't be vulnerable to DOM clobbering.
3528
- var /** @type {?} */ current = ((el.firstChild));
3665
+ var /** @type {?} */ current = ((this.DOM.firstChild(el)));
3529
3666
  while (current) {
3530
- if (DOM.isElementNode(current)) {
3667
+ if (this.DOM.isElementNode(current)) {
3531
3668
  this.startElement(/** @type {?} */ (current));
3532
3669
  }
3533
- else if (DOM.isTextNode(current)) {
3534
- this.chars(/** @type {?} */ ((DOM.nodeValue(current))));
3670
+ else if (this.DOM.isTextNode(current)) {
3671
+ this.chars(/** @type {?} */ ((this.DOM.nodeValue(current))));
3535
3672
  }
3536
3673
  else {
3537
3674
  // Strip non-element, non-text nodes.
3538
3675
  this.sanitizedSomething = true;
3539
3676
  }
3540
- if (DOM.firstChild(current)) {
3541
- current = ((DOM.firstChild(current)));
3677
+ if (this.DOM.firstChild(current)) {
3678
+ current = ((this.DOM.firstChild(current)));
3542
3679
  continue;
3543
3680
  }
3544
3681
  while (current) {
3545
3682
  // Leaving the element. Walk up and to the right, closing tags as we go.
3546
- if (DOM.isElementNode(current)) {
3683
+ if (this.DOM.isElementNode(current)) {
3547
3684
  this.endElement(/** @type {?} */ (current));
3548
3685
  }
3549
- var /** @type {?} */ next = checkClobberedElement(current, /** @type {?} */ ((DOM.nextSibling(current))));
3686
+ var /** @type {?} */ next = this.checkClobberedElement(current, /** @type {?} */ ((this.DOM.nextSibling(current))));
3550
3687
  if (next) {
3551
3688
  current = next;
3552
3689
  break;
3553
3690
  }
3554
- current = checkClobberedElement(current, /** @type {?} */ ((DOM.parentElement(current))));
3691
+ current = this.checkClobberedElement(current, /** @type {?} */ ((this.DOM.parentElement(current))));
3555
3692
  }
3556
3693
  }
3557
3694
  return this.buf.join('');
@@ -3562,14 +3699,14 @@ var SanitizingHtmlSerializer = (function () {
3562
3699
  */
3563
3700
  SanitizingHtmlSerializer.prototype.startElement = function (element) {
3564
3701
  var _this = this;
3565
- var /** @type {?} */ tagName = DOM.nodeName(element).toLowerCase();
3702
+ var /** @type {?} */ tagName = this.DOM.nodeName(element).toLowerCase();
3566
3703
  if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
3567
3704
  this.sanitizedSomething = true;
3568
3705
  return;
3569
3706
  }
3570
3707
  this.buf.push('<');
3571
3708
  this.buf.push(tagName);
3572
- DOM.attributeMap(element).forEach(function (value, attrName) {
3709
+ this.DOM.attributeMap(element).forEach(function (value, attrName) {
3573
3710
  var /** @type {?} */ lower = attrName.toLowerCase();
3574
3711
  if (!VALID_ATTRS.hasOwnProperty(lower)) {
3575
3712
  _this.sanitizedSomething = true;
@@ -3593,7 +3730,7 @@ var SanitizingHtmlSerializer = (function () {
3593
3730
  * @return {?}
3594
3731
  */
3595
3732
  SanitizingHtmlSerializer.prototype.endElement = function (current) {
3596
- var /** @type {?} */ tagName = DOM.nodeName(current).toLowerCase();
3733
+ var /** @type {?} */ tagName = this.DOM.nodeName(current).toLowerCase();
3597
3734
  if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
3598
3735
  this.buf.push('</');
3599
3736
  this.buf.push(tagName);
@@ -3605,19 +3742,19 @@ var SanitizingHtmlSerializer = (function () {
3605
3742
  * @return {?}
3606
3743
  */
3607
3744
  SanitizingHtmlSerializer.prototype.chars = function (chars) { this.buf.push(encodeEntities(chars)); };
3745
+ /**
3746
+ * @param {?} node
3747
+ * @param {?} nextNode
3748
+ * @return {?}
3749
+ */
3750
+ SanitizingHtmlSerializer.prototype.checkClobberedElement = function (node, nextNode) {
3751
+ if (nextNode && this.DOM.contains(node, nextNode)) {
3752
+ throw new Error("Failed to sanitize html because the element is clobbered: " + this.DOM.getOuterHTML(node));
3753
+ }
3754
+ return nextNode;
3755
+ };
3608
3756
  return SanitizingHtmlSerializer;
3609
3757
  }());
3610
- /**
3611
- * @param {?} node
3612
- * @param {?} nextNode
3613
- * @return {?}
3614
- */
3615
- function checkClobberedElement(node, nextNode) {
3616
- if (nextNode && DOM.contains(node, nextNode)) {
3617
- throw new Error("Failed to sanitize html because the element is clobbered: " + DOM.getOuterHTML(node));
3618
- }
3619
- return nextNode;
3620
- }
3621
3758
  // Regular Expressions for parsing tags and attributes
3622
3759
  var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
3623
3760
  // ! to ~ is the ASCII range.
@@ -3640,27 +3777,7 @@ function encodeEntities(value) {
3640
3777
  .replace(/</g, '&lt;')
3641
3778
  .replace(/>/g, '&gt;');
3642
3779
  }
3643
- /**
3644
- * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1'
3645
- * attribute to declare ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo').
3646
- *
3647
- * This is undesirable since we don't want to allow any of these custom attributes. This method
3648
- * strips them all.
3649
- * @param {?} el
3650
- * @return {?}
3651
- */
3652
- function stripCustomNsAttrs(el) {
3653
- DOM.attributeMap(el).forEach(function (_, attrName) {
3654
- if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) {
3655
- DOM.removeAttribute(el, attrName);
3656
- }
3657
- });
3658
- for (var _i = 0, _a = DOM.childNodesAsList(el); _i < _a.length; _i++) {
3659
- var n = _a[_i];
3660
- if (DOM.isElementNode(n))
3661
- stripCustomNsAttrs(/** @type {?} */ (n));
3662
- }
3663
- }
3780
+ var inertBodyHelper;
3664
3781
  /**
3665
3782
  * Sanitizes the given unsafe, untrusted HTML fragment, and returns HTML text that is safe to add to
3666
3783
  * the DOM in a browser environment.
@@ -3669,10 +3786,13 @@ function stripCustomNsAttrs(el) {
3669
3786
  * @return {?}
3670
3787
  */
3671
3788
  function sanitizeHtml(defaultDoc, unsafeHtmlInput) {
3789
+ var /** @type {?} */ DOM = getDOM();
3790
+ var /** @type {?} */ inertBodyElement = null;
3672
3791
  try {
3673
- var /** @type {?} */ containerEl = getInertElement();
3792
+ inertBodyHelper = inertBodyHelper || new InertBodyHelper(defaultDoc, DOM);
3674
3793
  // Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime).
3675
3794
  var /** @type {?} */ unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : '';
3795
+ inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
3676
3796
  // mXSS protection. Repeatedly parse the document to make sure it stabilizes, so that a browser
3677
3797
  // trying to auto-correct incorrect HTML cannot cause formerly inert HTML to become dangerous.
3678
3798
  var /** @type {?} */ mXSSAttempts = 5;
@@ -3683,30 +3803,25 @@ function sanitizeHtml(defaultDoc, unsafeHtmlInput) {
3683
3803
  }
3684
3804
  mXSSAttempts--;
3685
3805
  unsafeHtml = parsedHtml;
3686
- DOM.setInnerHTML(containerEl, unsafeHtml);
3687
- if (defaultDoc.documentMode) {
3688
- // strip custom-namespaced attributes on IE<=11
3689
- stripCustomNsAttrs(containerEl);
3690
- }
3691
- parsedHtml = DOM.getInnerHTML(containerEl);
3806
+ parsedHtml = DOM.getInnerHTML(inertBodyElement);
3807
+ inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
3692
3808
  } while (unsafeHtml !== parsedHtml);
3693
3809
  var /** @type {?} */ sanitizer = new SanitizingHtmlSerializer();
3694
- var /** @type {?} */ safeHtml = sanitizer.sanitizeChildren(DOM.getTemplateContent(containerEl) || containerEl);
3695
- // Clear out the body element.
3696
- var /** @type {?} */ parent = DOM.getTemplateContent(containerEl) || containerEl;
3697
- for (var _i = 0, _a = DOM.childNodesAsList(parent); _i < _a.length; _i++) {
3698
- var child = _a[_i];
3699
- DOM.removeChild(parent, child);
3700
- }
3810
+ var /** @type {?} */ safeHtml = sanitizer.sanitizeChildren(DOM.getTemplateContent(inertBodyElement) || inertBodyElement);
3701
3811
  if (isDevMode() && sanitizer.sanitizedSomething) {
3702
3812
  DOM.log('WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).');
3703
3813
  }
3704
3814
  return safeHtml;
3705
3815
  }
3706
- catch (e) {
3816
+ finally {
3707
3817
  // In case anything goes wrong, clear out inertElement to reset the entire DOM structure.
3708
- inertElement = null;
3709
- throw e;
3818
+ if (inertBodyElement) {
3819
+ var /** @type {?} */ parent = DOM.getTemplateContent(inertBodyElement) || inertBodyElement;
3820
+ for (var _i = 0, _a = DOM.childNodesAsList(parent); _i < _a.length; _i++) {
3821
+ var child = _a[_i];
3822
+ DOM.removeChild(parent, child);
3823
+ }
3824
+ }
3710
3825
  }
3711
3826
  }
3712
3827
  /**
@@ -4403,7 +4518,7 @@ var By = (function () {
4403
4518
  /**
4404
4519
  * \@stable
4405
4520
  */
4406
- var VERSION = new Version('4.4.6');
4521
+ var VERSION = new Version('4.4.7');
4407
4522
  /**
4408
4523
  * @license
4409
4524
  * Copyright Google Inc. All Rights Reserved.