From b6b88239de1660c66d96a8d5efcc6c336c5674ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Fri, 10 Jul 2026 10:46:13 +0200 Subject: [PATCH] Only render a marker url field as a link when the whole value is a URL Before this commit, renderMarkerFieldValue linkified any url-format field whose value started with `http(s)://`, using the entire value as the href. But it might be possible to have a string that starts with a URL and then continues with a regular text. This commit covers this case as well so it doesn't incorrectly turns invalid urls into clickable links. Now we require the value to be entirely a URL before rendering a link. otherwise fall back to plain text. --- src/components/tooltip/Marker.tsx | 11 +++++--- .../__snapshots__/marker-schema.test.ts.snap | 25 +++++++++++++++++++ src/test/unit/marker-schema.test.ts | 7 ++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/components/tooltip/Marker.tsx b/src/components/tooltip/Marker.tsx index 613df41c92..a7728ca21a 100644 --- a/src/components/tooltip/Marker.tsx +++ b/src/components/tooltip/Marker.tsx @@ -580,8 +580,10 @@ class MarkerTooltipContents extends React.PureComponent { } } -// This regexp is used to test for URLs and remove their scheme for display. -const URL_SCHEME_REGEXP = /^http(s?):\/\//; +// Matches a value that is *entirely* a single http(s) URL. We only render a +// clickable link when the whole string is a URL, so a longer descriptive +// string is never turned into a broken link. +const URL_REGEXP = /^(https?:\/\/)\S+$/; /** * This function may return structured markup for some types suchs as table, @@ -689,7 +691,8 @@ export function renderMarkerFieldValue( ); case 'url': { - if (!URL_SCHEME_REGEXP.test(value)) { + const match = URL_REGEXP.exec(value); + if (!match) { return value; } return ( @@ -699,7 +702,7 @@ export function renderMarkerFieldValue( rel="noreferrer" className="marker-link-value" > - {value.replace(URL_SCHEME_REGEXP, '')} + {value.slice(match[1].length)} ); } diff --git a/src/test/unit/__snapshots__/marker-schema.test.ts.snap b/src/test/unit/__snapshots__/marker-schema.test.ts.snap index 77eb343601..9f60bce48e 100644 --- a/src/test/unit/__snapshots__/marker-schema.test.ts.snap +++ b/src/test/unit/__snapshots__/marker-schema.test.ts.snap @@ -15,6 +15,31 @@ Array [ , "http://example.com", ], + Array [ + "url", + "https://example.com/path?query=1", + + example.com/path?query=1 + , + "https://example.com/path?query=1", + ], + Array [ + "url", + "loaded https://example.com successfully", + "loaded https://example.com successfully", + "loaded https://example.com successfully", + ], + Array [ + "url", + "https://example.com then some more text", + "https://example.com then some more text", + "https://example.com then some more text", + ], Array [ "file-path", "/Users/me/gecko", diff --git a/src/test/unit/marker-schema.test.ts b/src/test/unit/marker-schema.test.ts index 2de9a719bc..49c8ed5d3a 100644 --- a/src/test/unit/marker-schema.test.ts +++ b/src/test/unit/marker-schema.test.ts @@ -465,6 +465,13 @@ describe('marker schema formatting', function () { it('supports complex formats', function () { const entries: Array<[MarkerFormatType, unknown]> = [ ['url', 'http://example.com'], + // A whole-string URL is linkified. + ['url', 'https://example.com/path?query=1'], + // A URL embedded in a longer string is left as plain text. + ['url', 'loaded https://example.com successfully'], + // A string that starts with a URL but continues with a text is left as + // plain text. + ['url', 'https://example.com then some more text'], ['file-path', '/Users/me/gecko'], ['file-path', null], ['file-path', undefined],