@@ -64,6 +64,8 @@ func (c *ContainersRealtimeService) RunContainersRealtimeScan(filePath string) (
6464 return & ContainerImageResults {Images : []ContainerImage {}}, nil
6565 }
6666
67+ images = splitLocationsToSeparateResults (images )
68+
6769 result , err := c .scanImages (images , filePath )
6870 if err != nil {
6971 logger .PrintfIfVerbose ("Failed to scan images via realtime service: %v" , err )
@@ -73,6 +75,22 @@ func (c *ContainersRealtimeService) RunContainersRealtimeScan(filePath string) (
7375 return result , nil
7476}
7577
78+ func splitLocationsToSeparateResults (images []types.ImageModel ) []types.ImageModel {
79+ for i := 0 ; i < len (images ); {
80+ if len (images [i ].ImageLocations ) > 1 {
81+ for _ , loc := range images [i ].ImageLocations {
82+ newImage := images [i ]
83+ newImage .ImageLocations = []types.ImageLocation {loc }
84+ images = append (images , newImage )
85+ }
86+ images = append (images [:i ], images [i + 1 :]... )
87+ } else {
88+ i ++
89+ }
90+ }
91+ return images
92+ }
93+
7694// parseContainersFile parses the containers file and returns a list of images.
7795func parseContainersFile (filePath string ) ([]types.ImageModel , error ) {
7896 extractor := imagesExtractor .NewImagesExtractor ()
@@ -106,7 +124,13 @@ func (c *ContainersRealtimeService) scanImages(images []types.ImageModel, filePa
106124 logger .PrintfIfVerbose ("Scanning %d images for vulnerabilities" , len (images ))
107125
108126 var requestImages []wrappers.ContainerImageRequestItem
127+ var imagesWithSha []wrappers.ContainerImageResponseItem
109128 for _ , img := range images {
129+ if img .IsSha {
130+ logger .PrintfIfVerbose ("Skipping image with SHA: %s" , img .Name )
131+ addShaImage (& imagesWithSha , img )
132+ continue
133+ }
110134 imageName , imageTag := splitToImageAndTag (img .Name )
111135
112136 logger .PrintfIfVerbose ("Processing image: %s:%s" , imageName , imageTag )
@@ -128,19 +152,54 @@ func (c *ContainersRealtimeService) scanImages(images []types.ImageModel, filePa
128152
129153 logger .PrintfIfVerbose ("Received scan results for %d images" , len (response .Images ))
130154
131- result := c .buildContainerImageResults (response .Images , images , filePath )
155+ result := c .buildContainerImageResults (response .Images , imagesWithSha , images , filePath )
132156 return & result , nil
133157}
134158
159+ func addShaImage (images * []wrappers.ContainerImageResponseItem , img types.ImageModel ) {
160+ imageName , imageTag := splitToImageAndSha (img .Name )
161+
162+ * images = append (* images , wrappers.ContainerImageResponseItem {
163+ ImageName : imageName ,
164+ ImageTag : imageTag ,
165+ Status : "Unknown" ,
166+ Vulnerabilities : []wrappers.ContainerImageVulnerability {},
167+ })
168+ }
169+
170+ func splitToImageAndSha (image string ) (imageName , imageTag string ) {
171+ atIndex := strings .Index (image , "@" )
172+ if atIndex == - 1 {
173+ return splitToImageAndTag (image )
174+ }
175+
176+ nameAndTag := image [:atIndex ]
177+ shaPart := image [atIndex + 1 :]
178+
179+ colonIndex := strings .LastIndex (nameAndTag , ":" )
180+ if colonIndex != - 1 {
181+ imageName = nameAndTag [:colonIndex ]
182+ tag := nameAndTag [colonIndex + 1 :]
183+ imageTag = tag + "@" + shaPart
184+ } else {
185+ imageName = nameAndTag
186+ imageTag = shaPart
187+ }
188+ return
189+ }
190+
135191// buildContainerImageResults builds ContainerImageResults from response and images
136- func (c * ContainersRealtimeService ) buildContainerImageResults (responseImages []wrappers.ContainerImageResponseItem , images []types.ImageModel , filePath string ) ContainerImageResults {
192+ func (c * ContainersRealtimeService ) buildContainerImageResults (responseImages , imagesWithSha []wrappers.ContainerImageResponseItem , images []types.ImageModel , filePath string ) ContainerImageResults {
137193 var result ContainerImageResults
138- for i , respImg := range responseImages {
139- var locations []realtimeengine.Location
140- if i < len (images ) {
141- locations = convertLocations (images [i ].ImageLocations )
142- }
143194
195+ result = mergeImagesToResults (responseImages , result , & images , filePath )
196+ result = mergeImagesToResults (imagesWithSha , result , & images , filePath )
197+ return result
198+ }
199+
200+ func mergeImagesToResults (listOfImages []wrappers.ContainerImageResponseItem , result ContainerImageResults , images * []types.ImageModel , filePath string ) ContainerImageResults {
201+ for _ , respImg := range listOfImages {
202+ locations := getImageLocations (images , respImg .ImageName , respImg .ImageTag )
144203 containerImage := ContainerImage {
145204 ImageName : respImg .ImageName ,
146205 ImageTag : respImg .ImageTag ,
@@ -154,6 +213,17 @@ func (c *ContainersRealtimeService) buildContainerImageResults(responseImages []
154213 return result
155214}
156215
216+ func getImageLocations (images * []types.ImageModel , imageName , imageTag string ) []realtimeengine.Location {
217+ for i , img := range * images {
218+ if img .Name == imageName + ":" + imageTag || img .Name == imageName + "@" + imageTag {
219+ location := convertLocations (& img .ImageLocations )
220+ * images = append ((* images )[:i ], (* images )[i + 1 :]... )
221+ return location
222+ }
223+ }
224+ return []realtimeengine.Location {}
225+ }
226+
157227// splitToImageAndTag splits the image string into name and tag components.
158228func splitToImageAndTag (image string ) (imageName , imageTag string ) {
159229 // Split the image string by the last colon to separate name and tag
@@ -170,9 +240,9 @@ func splitToImageAndTag(image string) (imageName, imageTag string) {
170240}
171241
172242// convertLocations converts types locations to realtimeengine locations.
173- func convertLocations (locations []types.ImageLocation ) []realtimeengine.Location {
243+ func convertLocations (locations * []types.ImageLocation ) []realtimeengine.Location {
174244 var result []realtimeengine.Location
175- for _ , loc := range locations {
245+ for _ , loc := range * locations {
176246 line := loc .Line
177247 startIndex := loc .StartIndex
178248 endIndex := loc .EndIndex
0 commit comments