Skip to content

Commit c481c61

Browse files
committed
Guard against invalid registry url. Closes #1522.
1 parent a857141 commit c481c61

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

src/lib/initOptions.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ function parseFilterExpression(filterExpression: FilterPattern | undefined): Fil
3030
}
3131
}
3232

33+
/** Checks if a string is a valid URL. */
34+
function isValidUrl(url: string): boolean {
35+
try {
36+
// eslint-disable-next-line no-new
37+
new URL(url)
38+
return true
39+
} catch {
40+
return false
41+
}
42+
}
43+
3344
/** Initializes, validates, sets defaults, and consolidates program options. */
3445
async function initOptions(runOptions: RunOptions, { cli }: { cli?: boolean } = {}): Promise<Options> {
3546
const { default: chalkDefault, Chalk } = await import('chalk')
@@ -120,6 +131,7 @@ async function initOptions(runOptions: RunOptions, { cli }: { cli?: boolean } =
120131
const filterVersion = parseFilterExpression(options.filterVersion)
121132
const reject = parseFilterExpression(options.reject)
122133
const rejectVersion = parseFilterExpression(options.rejectVersion)
134+
const registryType = options.registryType || (options.registry?.endsWith('.json') ? 'json' : 'npm')
123135

124136
// convert to string for comparison purposes
125137
// otherwise ['a b'] will not match ['a', 'b']
@@ -167,6 +179,8 @@ async function initOptions(runOptions: RunOptions, { cli }: { cli?: boolean } =
167179
options,
168180
'When --registryType json is specified, you must provide the path for the registry file with --registry. Run "ncu --help registryType" for details.',
169181
)
182+
} else if (registryType !== 'json' && options.registry && !isValidUrl(options.registry)) {
183+
programError(options, `--registry must be a valid URL. Invalid value: "${options.registry}"`)
170184
}
171185

172186
const target: Target = options.target || 'latest'
@@ -203,7 +217,7 @@ async function initOptions(runOptions: RunOptions, { cli }: { cli?: boolean } =
203217
),
204218
}
205219
: null),
206-
registryType: options.registryType || (options.registry?.endsWith('.json') ? 'json' : 'npm'),
220+
registryType,
207221
}
208222
resolvedOptions.cacher = await cacher(resolvedOptions)
209223

src/lib/queryVersions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ async function queryVersions(packageMap: Index<VersionSpec>, options: Options =
104104
options.retry
105105
} retry attempts failed. Either your internet connection is down, the registry is inaccessible, the authentication credentials are invalid, or the package does not exist.`,
106106
}
107+
} else if (err.code === 'ERR_INVALID_URL') {
108+
return {
109+
error: errorMessage || 'Invalid URL',
110+
}
107111
} else {
108112
// print a hint about the --timeout option for network timeout errors
109113
if (!process.env.NCU_TESTS && /(Response|network) timeout/i.test(errorMessage)) {

0 commit comments

Comments
 (0)