diff --git a/packages/core/src/sanitization/inert_body.ts b/packages/core/src/sanitization/inert_body.ts
index c460c5dc65..4086956ac6 100644
--- a/packages/core/src/sanitization/inert_body.ts
+++ b/packages/core/src/sanitization/inert_body.ts
@@ -16,7 +16,8 @@ import {trustedHTMLFromString} from '../util/security/trusted_types';
* Fallback: InertDocument strategy
*/
export function getInertBodyHelper(defaultDoc: Document): InertBodyHelper {
- return isDOMParserAvailable() ? new DOMParserHelper() : new InertDocumentHelper(defaultDoc);
+ const inertDocumentHelper = new InertDocumentHelper(defaultDoc);
+ return isDOMParserAvailable() ? new DOMParserHelper(inertDocumentHelper) : inertDocumentHelper;
}
export interface InertBodyHelper {
@@ -31,6 +32,8 @@ export interface InertBodyHelper {
* This is the default strategy used in browsers that support it.
*/
class DOMParserHelper implements InertBodyHelper {
+ constructor(private inertDocumentHelper: InertBodyHelper) {}
+
getInertBodyElement(html: string): HTMLElement|null {
// We add these extra elements to ensure that the rest of the content is parsed as expected
// e.g. leading whitespace is maintained and tags like `` do not get hoisted to the
@@ -41,6 +44,12 @@ class DOMParserHelper implements InertBodyHelper {
const body = new window.DOMParser()
.parseFromString(trustedHTMLFromString(html) as string, 'text/html')
.body as HTMLBodyElement;
+ if (body === null) {
+ // In some browsers (e.g. Mozilla/5.0 iPad AppleWebKit Mobile) the `body` property only
+ // becomes available in the following tick of the JS engine. In that case we fall back to
+ // the `inertDocumentHelper` instead.
+ return this.inertDocumentHelper.getInertBodyElement(html);
+ }
body.removeChild(body.firstChild!);
return body;
} catch {
diff --git a/packages/core/test/sanitization/html_sanitizer_spec.ts b/packages/core/test/sanitization/html_sanitizer_spec.ts
index aae4a18421..01d805c9be 100644
--- a/packages/core/test/sanitization/html_sanitizer_spec.ts
+++ b/packages/core/test/sanitization/html_sanitizer_spec.ts
@@ -252,5 +252,14 @@ function sanitizeHtml(defaultDoc: any, unsafeHtmlInput: string): string {
.toMatch(/CLICKME<\/a>/);
});
}
+
+ if (isDOMParserAvailable()) {
+ it('should work even if DOMParser returns a null body', () => {
+ // Simulate `DOMParser.parseFromString()` returning a null body.
+ // See https://github.com/angular/angular/issues/39834
+ spyOn(window.DOMParser.prototype, 'parseFromString').and.returnValue({body: null} as any);
+ expect(sanitizeHtml(defaultDoc, 'Hello, World')).toEqual('Hello, World');
+ });
+ }
});
}