Refine purl parsing and tests

This commit is contained in:
Justin Holguín
2024-04-28 20:33:37 +00:00
committed by GitHub
parent 1dd418bcb3
commit fcc66c23b3
6 changed files with 85 additions and 49 deletions
Generated Vendored
+36 -28
View File
@@ -873,8 +873,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parsePURL = exports.PurlSchema = void 0;
const z = __importStar(__nccwpck_require__(3301));
// the basic purl type, containing ecosystem, namespace, name, and version.
// other than ecosystem, all fields are nullable. this is for maximum flexibility
// the basic purl type, containing type, namespace, name, and version.
// other than type, all fields are nullable. this is for maximum flexibility
// at the cost of strict adherence to the package-url spec.
exports.PurlSchema = z.object({
type: z.string(),
@@ -884,7 +884,7 @@ exports.PurlSchema = z.object({
original: z.string(),
error: z.string().nullable()
});
const PURL_ECOSYSTEM = /pkg:([a-zA-Z0-9-_]+)\/.*/;
const PURL_TYPE = /pkg:([a-zA-Z0-9-_]+)\/.*/;
function parsePURL(purl) {
const result = {
type: '',
@@ -895,19 +895,19 @@ function parsePURL(purl) {
error: null
};
if (!purl.startsWith('pkg:')) {
result.error = 'purl must start with "pkg:"';
result.error = 'package-url must start with "pkg:"';
return result;
}
const ecosystem = purl.match(PURL_ECOSYSTEM);
if (ecosystem === null) {
result.error = 'purl must contain an ecosystem';
const type = purl.match(PURL_TYPE);
if (!type) {
result.error = 'package-url must contain a type';
return result;
}
result.type = ecosystem[1];
result.type = type[1];
const parts = purl.split('/');
// the first 'part' should be 'pkg:ecosystem'
if (parts.length < 2 || parts[1].length === 0) {
result.error = 'purl must contain a namespace or name';
if (parts.length < 2 || !parts[1]) {
result.error = 'package-url must contain a namespace or name';
return result;
}
let namePlusRest;
@@ -919,13 +919,17 @@ function parsePURL(purl) {
namePlusRest = parts[2];
}
const name = namePlusRest.match(/([^@#?]+)[@#?]?.*/);
if (name === null) {
if (!result.namespace && !name) {
result.error = 'package-url must contain a namespace or name';
return result;
}
if (!name) {
// we're done here
return result;
}
result.name = decodeURIComponent(name[1]);
const version = namePlusRest.match(/@([^#?]+)[#?]?.*/);
if (version === null) {
if (!version) {
return result;
}
result.version = decodeURIComponent(version[1]);
@@ -981,7 +985,7 @@ const PackageURL = z
if (purl.error) {
context.addIssue({
code: z.ZodIssueCode.custom,
message: `Error parsing purl: ${purl.error}`
message: `Error parsing package-url: ${purl.error}`
});
}
});
@@ -1000,7 +1004,7 @@ const PackageURLWithNamespace = z
if (purl.namespace === null) {
context.addIssue({
code: z.ZodIssueCode.custom,
message: `purl must have a namespace, and the namespace must be followed by '/'`
message: `package-url must have a namespace, and the namespace must be followed by '/'`
});
}
});
@@ -49894,8 +49898,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parsePURL = exports.PurlSchema = void 0;
const z = __importStar(__nccwpck_require__(3301));
// the basic purl type, containing ecosystem, namespace, name, and version.
// other than ecosystem, all fields are nullable. this is for maximum flexibility
// the basic purl type, containing type, namespace, name, and version.
// other than type, all fields are nullable. this is for maximum flexibility
// at the cost of strict adherence to the package-url spec.
exports.PurlSchema = z.object({
type: z.string(),
@@ -49905,7 +49909,7 @@ exports.PurlSchema = z.object({
original: z.string(),
error: z.string().nullable()
});
const PURL_ECOSYSTEM = /pkg:([a-zA-Z0-9-_]+)\/.*/;
const PURL_TYPE = /pkg:([a-zA-Z0-9-_]+)\/.*/;
function parsePURL(purl) {
const result = {
type: '',
@@ -49916,19 +49920,19 @@ function parsePURL(purl) {
error: null
};
if (!purl.startsWith('pkg:')) {
result.error = 'purl must start with "pkg:"';
result.error = 'package-url must start with "pkg:"';
return result;
}
const ecosystem = purl.match(PURL_ECOSYSTEM);
if (ecosystem === null) {
result.error = 'purl must contain an ecosystem';
const type = purl.match(PURL_TYPE);
if (!type) {
result.error = 'package-url must contain a type';
return result;
}
result.type = ecosystem[1];
result.type = type[1];
const parts = purl.split('/');
// the first 'part' should be 'pkg:ecosystem'
if (parts.length < 2 || parts[1].length === 0) {
result.error = 'purl must contain a namespace or name';
if (parts.length < 2 || !parts[1]) {
result.error = 'package-url must contain a namespace or name';
return result;
}
let namePlusRest;
@@ -49940,13 +49944,17 @@ function parsePURL(purl) {
namePlusRest = parts[2];
}
const name = namePlusRest.match(/([^@#?]+)[@#?]?.*/);
if (name === null) {
if (!result.namespace && !name) {
result.error = 'package-url must contain a namespace or name';
return result;
}
if (!name) {
// we're done here
return result;
}
result.name = decodeURIComponent(name[1]);
const version = namePlusRest.match(/@([^#?]+)[#?]?.*/);
if (version === null) {
if (!version) {
return result;
}
result.version = decodeURIComponent(version[1]);
@@ -50002,7 +50010,7 @@ const PackageURL = z
if (purl.error) {
context.addIssue({
code: z.ZodIssueCode.custom,
message: `Error parsing purl: ${purl.error}`
message: `Error parsing package-url: ${purl.error}`
});
}
});
@@ -50021,7 +50029,7 @@ const PackageURLWithNamespace = z
if (purl.namespace === null) {
context.addIssue({
code: z.ZodIssueCode.custom,
message: `purl must have a namespace, and the namespace must be followed by '/'`
message: `package-url must have a namespace, and the namespace must be followed by '/'`
});
}
});
Generated Vendored
+1 -1
View File
File diff suppressed because one or more lines are too long