Skip to content

Commit 64ba857

Browse files
committed
fix: improve image parts regex according to spec
1 parent f210fbd commit 64ba857

File tree

2 files changed

+13
-18
lines changed

2 files changed

+13
-18
lines changed

src/scanner/images/index.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,32 +42,27 @@ export async function removePulledImages(images: IPullableImage[]): Promise<void
4242

4343
// Exported for testing
4444
export function getImageParts(imageWithTag: string) : {imageName: string, imageTag: string} {
45-
// we're matching pattern: <registry:port_number>(optional)/<image_name>(mandatory)@<tag_identifier>(optional):<image_tag>(optional)
46-
const regex = /((?:.*(:\d{4})?\/)?(?:[a-z0-9-]+))([@|:].+)?/ig;
45+
// we're matching pattern: <registry:port_number>(optional)/<image_name>(mandatory):<image_tag>(optional)@<tag_identifier>(optional)
46+
// extracted from https://github.com/docker/distribution/blob/master/reference/regexp.go
47+
const regex = /^((?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?\/)?[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?(?:(?:\/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?)(?::([\w][\w.-]{0,127}))?(?:@([A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][A-Fa-f0-9]{32,}))?$/ig;
4748
const groups = regex.exec(imageWithTag);
4849

4950
if(!groups){
5051
logger.error({image: imageWithTag}, 'Image with tag is malformed, cannot extract valid parts');
5152
return {imageName: imageWithTag, imageTag: ''};
5253
}
5354

55+
const IMAGE_NAME_GROUP = 1;
56+
const IMAGE_TAG_GROUP = 2;
57+
const IMAGE_DIGEST_GROUP = 3;
58+
5459
return {
55-
imageName: groups[1],
56-
imageTag: validateAndExtractImageTag(groups[3])
60+
imageName: groups[IMAGE_NAME_GROUP],
61+
// prefer tag over digest
62+
imageTag: groups[IMAGE_TAG_GROUP] || groups[IMAGE_DIGEST_GROUP] || '',
5763
};
5864
}
5965

60-
function validateAndExtractImageTag(imageTagGroup: string | undefined): string {
61-
if(imageTagGroup === undefined){
62-
return '';
63-
}
64-
65-
const imageTagParts: string[]= imageTagGroup.split(':');
66-
67-
//valid formats: image@sha256:hash or image:tag
68-
return imageTagParts.length === 2 ? imageTagParts[1] : '';
69-
}
70-
7166
// Exported for testing
7267
export function constructStaticAnalysisOptions(
7368
fileSystemPath: string,

test/unit/scanner/images.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ tap.test('constructStaticAnalysisOptions() tests', async (t) => {
5959
tap.test('extracted image tag tests', async (t) => {
6060
t.plan(6);
6161

62-
const imageWithSha = 'nginx@sha256:1234567890abcdef';
62+
const imageWithSha = 'nginx@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2';
6363
const imageWithShaResult = scannerImages.getImageParts(imageWithSha);
64-
t.same(imageWithShaResult.imageTag, '1234567890abcdef', 'image sha is returned');
64+
t.same(imageWithShaResult.imageTag, 'sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2', 'image sha is returned');
6565

6666
const imageWithTag = 'nginx:latest';
6767
const imageWithTagResult = scannerImages.getImageParts(imageWithTag);
@@ -88,9 +88,9 @@ tap.test('extracted image name tests', async (t) => {
8888
t.plan(5);
8989

9090
t.same(scannerImages.getImageParts('nginx:latest').imageName, 'nginx', 'removed image:tag');
91-
t.same(scannerImages.getImageParts('nginx:@sha256:1234567890abcdef').imageName, 'nginx', 'removed malformed image:@sha:hex');
9291
t.same(scannerImages.getImageParts('node@sha256:215a9fbef4df2c1ceb7c79481d3cfd94ad8f1f0105bade39f3be907bf386c5e1').imageName, 'node', 'removed image@sha:hex');
9392
t.same(scannerImages.getImageParts('kind-registry:5000/python:rc-buster').imageName, 'kind-registry:5000/python', 'removed repository/image:tag');
9493
// Verify support on image names that contain dashes
9594
t.same(scannerImages.getImageParts('kind-registry:5000/python-27:rc-buster').imageName, 'kind-registry:5000/python-27', 'removed repository/image:tag');
95+
t.same(scannerImages.getImageParts('kind-registry:5000/test/python-27:rc-buster').imageName, 'kind-registry:5000/test/python-27', 'removed repository/image:tag');
9696
});

0 commit comments

Comments
 (0)