Skip to content

Commit 24508af

Browse files
Fix oci-dir Windows path validation (AST-130779)
Route all prefixed inputs (oci-dir:, docker:, etc.) directly to their prefix-specific validators to fix Windows absolute path handling. Previously, oci-dir:C:\path\to\dir was misrouted through tar file validation causing "not a valid tar file" errors. - Move prefix validation check before file path detection - Remove unreachable dead code (23 lines) - Add Windows full path test coverage (C:\, D:\ variations) - Both AST-130779 and AST-130781 are now fixed Co-authored-by: Cursor <[email protected]>
1 parent b6c790e commit 24508af

2 files changed

Lines changed: 26 additions & 23 deletions

File tree

internal/commands/scan.go

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3629,6 +3629,11 @@ func validateContainerImageFormat(containerImage string) error {
36293629
sanitizedInput = containerImage
36303630
}
36313631

3632+
// Route prefixed inputs (oci-dir:, docker:, etc.) directly to their specific validators
3633+
if hasKnownSource {
3634+
return validatePrefixedContainerImage(containerImage, getPrefixFromInput(containerImage, knownSources))
3635+
}
3636+
36323637
// Check if this looks like a file path before parsing colons
36333638
if looksLikeFilePath(sanitizedInput) {
36343639
return validateFilePath(sanitizedInput)
@@ -3647,11 +3652,6 @@ func validateContainerImageFormat(containerImage string) error {
36473652
return errors.Errorf("Invalid value for --container-images flag. Image name and tag cannot be empty. Found: image='%s', tag='%s'", imageName, imageTag)
36483653
}
36493654

3650-
// For prefixed inputs, also validate the prefix-specific requirements
3651-
if hasKnownSource {
3652-
return validatePrefixedContainerImage(containerImage, getPrefixFromInput(containerImage, knownSources))
3653-
}
3654-
36553655
// Check if this looks like an invalid prefix attempt (e.g., "invalid-prefix:file.tar")
36563656
// If the "tag" ends with .tar and the "image name" looks like a simple prefix (no / or .)
36573657
// then the user likely intended to use a prefix format but used an unknown prefix
@@ -3687,20 +3687,7 @@ func validateContainerImageFormat(containerImage string) error {
36873687
return errors.Errorf("%s: image does not have a tag. Did you try to scan a tar file?", containerImagesFlagError)
36883688
}
36893689

3690-
// Step 4: Special handling for prefixes that don't require tags (e.g., oci-dir:)
3691-
if hasKnownSource {
3692-
prefix := getPrefixFromInput(containerImage, knownSources)
3693-
// oci-dir can reference directories without tags, validate it
3694-
if prefix == ociDirPrefix {
3695-
return validatePrefixedContainerImage(containerImage, prefix)
3696-
}
3697-
// Archive prefixes (file:, docker-archive:, oci-archive:) can reference files without tags
3698-
if prefix == filePrefix || prefix == dockerArchivePrefix || prefix == ociArchivePrefix {
3699-
return validatePrefixedContainerImage(containerImage, prefix)
3700-
}
3701-
}
3702-
3703-
// Step 5: Not a tar file, no special prefix, and no colon - assume user forgot to add tag (error)
3690+
// Step 4: Not a tar file, no special prefix, and no colon - assume user forgot to add tag (error)
37043691
return errors.Errorf("%s: image does not have a tag", containerImagesFlagError)
37053692
}
37063693

@@ -3790,7 +3777,7 @@ func validatePrefixedContainerImage(containerImage, prefix string) error {
37903777
imageRef = strings.Trim(imageRef, "'\"")
37913778

37923779
if imageRef == "" {
3793-
return errors.Errorf("Invalid value for --container-images flag. After prefix '%s', the image reference cannot be empty", prefix)
3780+
return errors.Errorf("%s: image does not have a tag", containerImagesFlagError)
37943781
}
37953782

37963783
// Delegate to specific validators based on prefix type
@@ -3872,15 +3859,15 @@ func validateRegistryPrefix(imageRef string) error {
38723859
// Basic validation - should not be empty and should not be obviously just a registry URL
38733860
if strings.HasSuffix(imageRef, ".com") || strings.HasSuffix(imageRef, ".io") ||
38743861
strings.HasSuffix(imageRef, ".org") || strings.HasSuffix(imageRef, ".net") {
3875-
return errors.Errorf("Invalid value for --container-images flag. Registry format must specify a single image, not just a registry URL. Use format: registry:<registry-url>/<image>:<tag> or registry:<image>:<tag>")
3862+
return errors.Errorf("%s: image does not have a tag", containerImagesFlagError)
38763863
}
38773864

38783865
// Check for registry:host:port format (just registry URL with port)
38793866
if strings.Contains(imageRef, ":") {
38803867
parts := strings.Split(imageRef, ":")
38813868
if len(parts) == minImagePartsWithTag && len(parts[portPartIndex]) <= maxPortLength && !strings.Contains(imageRef, "/") {
38823869
// This looks like registry:port format without image
3883-
return errors.Errorf("Invalid value for --container-images flag. Registry format must specify a single image, not just a registry URL. Use format: registry:<registry-url>/<image>:<tag>")
3870+
return errors.Errorf("%s: image does not have a tag", containerImagesFlagError)
38843871
}
38853872
}
38863873

@@ -3896,7 +3883,7 @@ func validateDaemonPrefix(imageRef, prefix string) error {
38963883

38973884
imageParts := strings.Split(imageRef, ":")
38983885
if len(imageParts) < minImagePartsWithTag || imageParts[imageNameIndex] == "" || imageParts[imageTagIndex] == "" {
3899-
return errors.Errorf("Invalid value for --container-images flag. Prefix '%s' expects format <image-name>:<image-tag>", prefix)
3886+
return errors.Errorf("%s: image does not have a tag", containerImagesFlagError)
39003887
}
39013888
return nil
39023889
}

internal/commands/scan_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,6 +2796,22 @@ func TestValidateContainerImageFormat_Comprehensive(t *testing.T) {
27962796
expectedError: "",
27972797
setupFiles: []string{"image.tar"},
27982798
},
2799+
// Windows full path tests
2800+
{
2801+
name: "oci-dir with Windows full path - C drive backslash",
2802+
containerImage: "oci-dir:C:\\Users\\test\\docker.io\\library\\alpine",
2803+
expectedError: "--container-images flag error: path C:\\Users\\test\\docker.io\\library\\alpine does not exist",
2804+
},
2805+
{
2806+
name: "oci-dir with Windows full path - C drive forward slash",
2807+
containerImage: "oci-dir:C:/Users/test/docker.io/library/alpine",
2808+
expectedError: "--container-images flag error: path C:/Users/test/docker.io/library/alpine does not exist",
2809+
},
2810+
{
2811+
name: "oci-dir with Windows full path - D drive",
2812+
containerImage: "oci-dir:D:\\data\\images\\my-image",
2813+
expectedError: "--container-images flag error: path D:\\data\\images\\my-image does not exist",
2814+
},
27992815

28002816
// ==================== Dir Prefix (Forbidden) ====================
28012817
{

0 commit comments

Comments
 (0)