From 42c59ffaad65721ab5d05346dfb995e99ad806aa Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Wed, 7 Jul 2021 14:15:52 -0400 Subject: [PATCH] DevTooks: Don't dehydrate hook source fileNames This can cause long file names (URLs) to be truncated which in turn will break named hooks code (since it needs to load those file names). Also fix an issue where an absolute URL was being converted into an incorrect URL. --- .../src/parseHookNames.js | 20 +------------------ .../src/backend/renderer.js | 11 ++++++++++ .../react-devtools-shared/src/hydration.js | 7 ++++++- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/react-devtools-extensions/src/parseHookNames.js b/packages/react-devtools-extensions/src/parseHookNames.js index dc2b8b3c4bc92..9d183375e8052 100644 --- a/packages/react-devtools-extensions/src/parseHookNames.js +++ b/packages/react-devtools-extensions/src/parseHookNames.js @@ -27,7 +27,6 @@ import type {Thenable} from 'shared/ReactTypes'; import type {SourceConsumer} from './astUtils'; const SOURCE_MAP_REGEX = / ?sourceMappingURL=([^\s'"]+)/gm; -const ABSOLUTE_URL_REGEX = /^https?:\/\//i; const MAX_SOURCE_LENGTH = 100_000_000; type AST = mixed; @@ -282,14 +281,7 @@ function extractAndLoadSourceMaps( } let url = sourceMappingURLs[i].split('=')[1]; - if (ABSOLUTE_URL_REGEX.test(url)) { - const baseURL = url.slice(0, url.lastIndexOf('/')); - url = `${baseURL}/${url}`; - - if (!isValidUrl(url)) { - throw new Error(`Invalid source map URL "${url}"`); - } - } else if (!url.startsWith('/')) { + if (!url.startsWith('http') && !url.startsWith('/')) { // Resolve paths relative to the location of the file name const lastSlashIdx = runtimeSourceURL.lastIndexOf('/'); if (lastSlashIdx !== -1) { @@ -440,16 +432,6 @@ function findHookNames( return map; } -function isValidUrl(possibleURL: string): boolean { - try { - // eslint-disable-next-line no-new - new URL(possibleURL); - } catch (_) { - return false; - } - return true; -} - function loadSourceFiles( locationKeyToHookSourceData: Map, ): Promise<*> { diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index d56819a8ba0bd..57b3de2e08a49 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -3240,6 +3240,17 @@ export function attach( // Never dehydrate the "hooks" object at the top levels. return true; } + + if ( + path[path.length - 2] === 'hookSource' && + path[path.length - 1] === 'fileName' + ) { + // It's important to preserve the full file name (URL) for hook sources + // in case the user has enabled the named hooks feature. + // Otherwise the frontend may end up with a partial URL which it can't load. + return true; + } + if ( path[path.length - 1] === 'subHooks' || path[path.length - 2] === 'subHooks' diff --git a/packages/react-devtools-shared/src/hydration.js b/packages/react-devtools-shared/src/hydration.js index 2c2d696089371..0b936462d5fe2 100644 --- a/packages/react-devtools-shared/src/hydration.js +++ b/packages/react-devtools-shared/src/hydration.js @@ -160,7 +160,12 @@ export function dehydrate( }; case 'string': - return data.length <= 500 ? data : data.slice(0, 500) + '...'; + isPathAllowedCheck = isPathAllowed(path); + if (isPathAllowedCheck) { + return data; + } else { + return data.length <= 500 ? data : data.slice(0, 500) + '...'; + } case 'bigint': cleaned.push(path);