/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @emails react-core * @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment */ /* eslint-disable no-script-url */ 'use strict'; const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let React; let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; let act; const EXPECTED_SAFE_URL = "javascript:throw new Error('React has blocked a javascript: URL as a security precaution.')"; describe('ReactDOMServerIntegration - Untrusted URLs', () => { // The `itRenders` helpers don't work with the gate pragma, so we have to do // this instead. if (gate(flags => flags.disableJavaScriptURLs)) { it("empty test so Jest doesn't complain", () => {}); return; } function initModules() { React = require('react'); ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); act = require('internal-test-utils').act; // Make them available to the helpers. return { ReactDOMClient, ReactDOMServer, ReactTestUtils, }; } const {resetModules, itRenders} = ReactDOMServerIntegrationUtils(initModules); beforeEach(() => { resetModules(); }); itRenders('a http link with the word javascript in it', async render => { const e = await render( Click me, ); expect(e.tagName).toBe('A'); expect(e.href).toBe('http://javascript:0/thisisfine'); }); itRenders('a javascript protocol href', async render => { // Only the first one warns. The second warning is deduped. const e = await render(
p0wned p0wned again
, 1, ); expect(e.firstChild.href).toBe('javascript:notfine'); expect(e.lastChild.href).toBe('javascript:notfineagain'); }); itRenders('a javascript protocol with leading spaces', async render => { const e = await render( p0wned, 1, ); // We use an approximate comparison here because JSDOM might not parse // \u0000 in HTML properly. expect(e.href).toContain('notfine'); }); itRenders( 'a javascript protocol with intermediate new lines and mixed casing', async render => { const e = await render( p0wned, 1, ); expect(e.href).toBe('javascript:notfine'); }, ); itRenders('a javascript protocol area href', async render => { const e = await render( , 1, ); expect(e.firstChild.href).toBe('javascript:notfine'); }); itRenders('a javascript protocol form action', async render => { const e = await render(
p0wned
, 1); expect(e.action).toBe('javascript:notfine'); }); itRenders('a javascript protocol input formAction', async render => { const e = await render( , 1, ); expect(e.getAttribute('formAction')).toBe('javascript:notfine'); }); itRenders('a javascript protocol button formAction', async render => { const e = await render( , 1, ); expect(e.getAttribute('formAction')).toBe('javascript:notfine'); }); itRenders('a javascript protocol iframe src', async render => { const e = await render(