Skip to content

Commit 1ae132b

Browse files
committed
fix: svn regex
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
1 parent 2f1a9f8 commit 1ae132b

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

services/apps/packages_worker/src/maven/__tests__/normalize.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,12 @@ describe('normalizeScmUrl', () => {
200200
)
201201
})
202202

203+
it('returns null for a marker-only SVN root with no project segment', () => {
204+
// No trailing slash after "repos/asf" — must not fall through to being
205+
// mis-parsed as project segments ["repos", "asf"] and duplicated.
206+
expect(normalizeScmUrl('https://svn.apache.org/repos/asf')).toBeNull()
207+
})
208+
203209
it('does not map dead services that incidentally match an "svn" text filter', () => {
204210
expect(normalizeScmUrl('http://specs.googlecode.com/svn/trunk')).toBeNull()
205211
})
@@ -585,6 +591,15 @@ describe('normalizeScmUrl', () => {
585591
normalizeScmUrl('https://gerrit.wikimedia.org/r/#/admin/projects/wikidata/query/rdf'),
586592
).toBeNull()
587593
})
594+
595+
it('returns null for non-SCM OpenDaylight URLs instead of mistaking them for a repo', () => {
596+
// A `p` query on some unrelated path is not a gitweb browse link.
597+
expect(
598+
normalizeScmUrl('https://git.opendaylight.org/somewhere?p=netconf.git'),
599+
).toBeNull()
600+
// Single path segment with no .git suffix — e.g. a static asset, not a clone URL.
601+
expect(normalizeScmUrl('https://git.opendaylight.org/favicon.ico')).toBeNull()
602+
})
588603
})
589604

590605
describe('interpolateProperties', () => {

services/apps/packages_worker/src/maven/extract.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -785,9 +785,14 @@ function normalizeGooglesourceUrl(host: string, pathname: string): string | null
785785
const OPENDALIGHT_GERRIT_HOST = 'git.opendaylight.org'
786786

787787
function normalizeOpendaylightGerritUrl(pathname: string, search: string): string | null {
788-
const queryRepo = new URLSearchParams(search).get('p')
788+
// Query extraction only applies to the actual gitweb browse script — a `p` query
789+
// on some unrelated path isn't a repo reference.
790+
const queryRepo = pathname === '/gerrit/gitweb' ? new URLSearchParams(search).get('p') : null
789791
const segments = pathname.split('/').filter(Boolean)
790-
const rawName = queryRepo ?? (segments.length === 1 ? segments[0] : null)
792+
// The one-segment SSH-clone form must end in .git, otherwise any arbitrary
793+
// single-segment path (e.g. /favicon.ico) would be mistaken for a repo.
794+
const rawName =
795+
queryRepo ?? (segments.length === 1 && segments[0].endsWith('.git') ? segments[0] : null)
791796
const name = rawName ? extractGitwebRepoName(rawName) : null
792797
if (!name) return null
793798

@@ -876,9 +881,12 @@ export function isSvnHost(host: string): boolean {
876881
*/
877882
function normalizeSvnUrl(host: string, pathname: string): string | null {
878883
const rest = pathname.replace(/^\/+/, '')
879-
const markerMatch = rest.match(/^(viewvc|viewcvs\.cgi|repos\/asf|svnroot|svn|p)\/(.*)$/)
884+
// The trailing group is optional so a marker-only root (e.g. "/repos/asf" with
885+
// no trailing slash) still matches, leaving an empty remainder instead of
886+
// falling through to be mis-parsed as project segments "repos"/"asf".
887+
const markerMatch = rest.match(/^(viewvc|viewcvs\.cgi|repos\/asf|svnroot|svn|p)(?:\/(.*))?$/)
880888
const scriptPrefix = markerMatch?.[1] ?? null
881-
const afterPrefix = markerMatch ? markerMatch[2] : rest
889+
const afterPrefix = markerMatch ? (markerMatch[2] ?? '') : rest
882890

883891
const segments = afterPrefix.split('/').filter(Boolean)
884892
if (segments.some((s) => /\$\{|%7B/i.test(s))) return null

0 commit comments

Comments
 (0)