diff --git a/packages/core/src/transfer_state.ts b/packages/core/src/transfer_state.ts index d3d4134b814..0cd9cfcafbd 100644 --- a/packages/core/src/transfer_state.ts +++ b/packages/core/src/transfer_state.ts @@ -154,7 +154,7 @@ export function retrieveTransferredState( // Locate the script tag with the JSON data transferred from the server. // The id of the script tag is set to the Angular appId + 'state'. const script = doc.getElementById(appId + '-state'); - if (script?.textContent) { + if (script?.tagName === 'SCRIPT' && script.textContent) { try { // Avoid using any here as it triggers lint errors in google3 (any is not allowed). // Decoding of `<` is done of the box by browsers and node.js, same behaviour as G3 diff --git a/packages/core/test/transfer_state_spec.ts b/packages/core/test/transfer_state_spec.ts index 3108a2eebf9..adb0184834b 100644 --- a/packages/core/test/transfer_state_spec.ts +++ b/packages/core/test/transfer_state_spec.ts @@ -13,7 +13,11 @@ import {DOCUMENT} from '../src/document'; import {makeStateKey, TransferState} from '../src/transfer_state'; function removeScriptTag(doc: Document, id: string) { - doc.getElementById(id)?.remove(); + let node = doc.getElementById(id); + while (node) { + node.remove(); + node = doc.getElementById(id); + } } function addScriptTag(doc: Document, appId: string, data: object | string) { @@ -57,6 +61,24 @@ describe('TransferState', () => { expect(transferState.get(TEST_KEY, 0)).toBe(10); }); + it('ignores non-script elements that clobber the transfer state id', () => { + const id = APP_ID + '-state'; + + const clobberingNode = doc.createElement('div'); + clobberingNode.id = id; + clobberingNode.textContent = '{"test":999}'; + doc.body.appendChild(clobberingNode); + + const script = doc.createElement('script'); + script.id = id; + script.setAttribute('type', 'application/json'); + script.textContent = '{"test":10}'; + doc.body.appendChild(script); + + const transferState: TransferState = TestBed.inject(TransferState); + expect(transferState.get(TEST_KEY, 0)).toBe(0); + }); + it('is initialized to empty state if script tag not found', () => { const transferState: TransferState = TestBed.inject(TransferState); expect(transferState.get(TEST_KEY, 0)).toBe(0);