From 7e9c943aa6be7432528be3d3a55de25620e66528 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Tue, 26 Sep 2023 11:56:12 -0400 Subject: [PATCH 1/3] test: Add failing invalid media URL test case --- .../src/audio/test/edit.native.js | 42 ++++++++++++------- .../src/video/test/edit.native.js | 29 +++++++++++++ 2 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 packages/block-library/src/video/test/edit.native.js diff --git a/packages/block-library/src/audio/test/edit.native.js b/packages/block-library/src/audio/test/edit.native.js index b59c36db2f66e..c191fd2fff798 100644 --- a/packages/block-library/src/audio/test/edit.native.js +++ b/packages/block-library/src/audio/test/edit.native.js @@ -1,13 +1,20 @@ /** * External dependencies */ -import { render } from 'test/helpers'; +import { + addBlock, + dismissModal, + fireEvent, + initializeEditor, + render, + screen, + setupCoreBlocks, +} from 'test/helpers'; /** * WordPress dependencies */ import { BlockEdit } from '@wordpress/block-editor'; -import { registerBlockType, unregisterBlockType } from '@wordpress/blocks'; import { subscribeMediaUpload, sendMediaUpload, @@ -16,7 +23,7 @@ import { /** * Internal dependencies */ -import { metadata, settings, name } from '../index'; +import { name } from '../index'; // react-native-aztec shouldn't be mocked because these tests are based on // snapshot testing where we want to keep the original component. @@ -42,18 +49,9 @@ const getTestComponentWithContent = ( attributes = {} ) => { ); }; -describe( 'Audio block', () => { - beforeAll( () => { - registerBlockType( name, { - ...metadata, - ...settings, - } ); - } ); - - afterAll( () => { - unregisterBlockType( name ); - } ); +setupCoreBlocks( [ 'core/audio' ] ); +describe( 'Audio block', () => { it( 'renders placeholder without crashing', () => { const component = getTestComponentWithContent(); const rendered = component.toJSON(); @@ -86,4 +84,20 @@ describe( 'Audio block', () => { const rendered = component.toJSON(); expect( rendered ).toMatchSnapshot(); } ); + + it( 'should gracefully handle invalid URLs', async () => { + await initializeEditor(); + + await addBlock( screen, 'Audio' ); + fireEvent.press( screen.getByText( 'Insert from URL' ) ); + fireEvent.changeText( + screen.getByPlaceholderText( 'Type a URL' ), + 'h://wordpress.org/audio.mp3' + ); + dismissModal( screen.getByTestId( 'bottom-sheet' ) ); + + expect( + screen.getByText( 'Invalid URL. Audio file not found.' ) + ).toBeVisible(); + } ); } ); diff --git a/packages/block-library/src/video/test/edit.native.js b/packages/block-library/src/video/test/edit.native.js new file mode 100644 index 0000000000000..9b7f4b0bdffbb --- /dev/null +++ b/packages/block-library/src/video/test/edit.native.js @@ -0,0 +1,29 @@ +/** + * External dependencies + */ +import { + addBlock, + dismissModal, + fireEvent, + initializeEditor, + screen, + setupCoreBlocks, +} from 'test/helpers'; + +setupCoreBlocks( [ 'core/video' ] ); + +describe( 'Video block', () => { + it( 'should gracefully handle invalid URLs', async () => { + await initializeEditor(); + + await addBlock( screen, 'Video' ); + fireEvent.press( screen.getByText( 'Insert from URL' ) ); + fireEvent.changeText( + screen.getByPlaceholderText( 'Type a URL' ), + 'h://wordpress.org/video.mp4' + ); + dismissModal( screen.getByTestId( 'bottom-sheet' ) ); + + expect( screen.getByText( 'Invalid URL.' ) ).toBeVisible(); + } ); +} ); From 9242f0de2075da1047461722ac15e5ddba307371 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Tue, 26 Sep 2023 11:56:51 -0400 Subject: [PATCH 2/3] fix: Prevent crash from invalid media URLs The `isURL` utility considers URLs using uncommon protocols to be valid, as constructing `URL` with, say, `h://a-path.com` is valid. Contrastingly, the `react-native-video` package only considers a URL using the `http:` or `https:` protocols to be a "network" asset. This leads to an attempt to load the URL as a local asset, which fails as the asset does not exist in the app bundle. https://github.com/react-native-video/react-native-video/blob/81ae785090f5ce3d5e45cc51f68a3360a85be853/Video.js#L277 --- packages/block-library/src/audio/edit.native.js | 4 ++-- packages/block-library/src/video/edit.native.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/audio/edit.native.js b/packages/block-library/src/audio/edit.native.js index fbc39ba190d3e..cbd7f9ff02f8f 100644 --- a/packages/block-library/src/audio/edit.native.js +++ b/packages/block-library/src/audio/edit.native.js @@ -30,7 +30,7 @@ import { audio as icon, replace } from '@wordpress/icons'; import { useState } from '@wordpress/element'; import { useDispatch, useSelect } from '@wordpress/data'; import { store as noticesStore } from '@wordpress/notices'; -import { isURL } from '@wordpress/url'; +import { isURL, getProtocol } from '@wordpress/url'; /** * Internal dependencies @@ -73,7 +73,7 @@ function AudioEdit( { function onSelectURL( newSrc ) { if ( newSrc !== src ) { - if ( isURL( newSrc ) ) { + if ( isURL( newSrc ) && /^https?:/.test( getProtocol( newSrc ) ) ) { setAttributes( { src: newSrc, id: undefined } ); } else { createErrorNotice( __( 'Invalid URL. Audio file not found.' ) ); diff --git a/packages/block-library/src/video/edit.native.js b/packages/block-library/src/video/edit.native.js index 48b5692aee3d7..6c1798756b40c 100644 --- a/packages/block-library/src/video/edit.native.js +++ b/packages/block-library/src/video/edit.native.js @@ -162,7 +162,7 @@ class VideoEdit extends Component { onSelectURL( url ) { const { createErrorNotice, onReplace, setAttributes } = this.props; - if ( isURL( url ) ) { + if ( isURL( url ) && /^https?:/.test( getProtocol( url ) ) ) { // Check if there's an embed block that handles this URL. const embedBlock = createUpgradedEmbedBlock( { attributes: { url }, From 0a540b8acc79c580fdac125035a9621af8116b73 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Tue, 26 Sep 2023 13:16:10 -0400 Subject: [PATCH 3/3] docs: Add change log entry --- packages/react-native-editor/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 70f0605599add..504bad70c8057 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -11,6 +11,7 @@ For each user feature we should also add a importance categorization label to i ## Unreleased - [*] Limit inner blocks nesting depth to avoid call stack size exceeded crash [#54382] +- [*] Prevent crashes when setting an invalid media URL for Video or Audio blocks [#54834] ## 1.104.0 - [*] Fix the obscurred "Insert from URL" input for media blocks when using a device in landscape orientation. [#54096]