github.com/google/osv-scalibr@v0.4.1/extractor/standalone/windows/dismpatch/dismparser/dism_parser.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package dismparser has methods that can be used to parse DISM output 16 package dismparser 17 18 import ( 19 "errors" 20 "regexp" 21 "strings" 22 ) 23 24 var ( 25 // ErrParsingError indicates an error while parsing the DISM output. 26 ErrParsingError = errors.New("could not parse DISM output successfully") 27 28 versionRegexp = regexp.MustCompile(`~(\d+\.\d+\.\d+\.\d+)$`) 29 ) 30 31 // DismPkg reports information about a package as reported by the DISM tool. 32 type DismPkg struct { 33 PackageIdentity string 34 PackageVersion string 35 State string 36 ReleaseType string 37 InstallTime string 38 } 39 40 var ( 41 pkgExpFinder = regexp.MustCompile("entity :(.*)\n*State :(.*)\n*Release Type :(.*)\n*Install Time :(.*)\n*") 42 imgVerFinder = regexp.MustCompile("Image Version: (.*)") 43 ) 44 45 // Parse parses dism output into an array of dismPackages. 46 func Parse(input string) ([]DismPkg, string, error) { 47 packages := strings.Split(input, "Package Id") 48 49 imgVersion := "" 50 dismPackages := []DismPkg{} 51 52 for _, pkg := range packages { 53 matches := pkgExpFinder.FindStringSubmatch(pkg) 54 if len(matches) > 4 { 55 dismPkg := DismPkg{ 56 PackageIdentity: strings.TrimSpace(matches[1]), 57 State: strings.TrimSpace(matches[2]), 58 ReleaseType: strings.TrimSpace(matches[3]), 59 InstallTime: strings.TrimSpace(matches[4]), 60 } 61 dismPkg.PackageVersion = findVersion(dismPkg.PackageIdentity) 62 dismPackages = append(dismPackages, dismPkg) 63 } else { 64 // this is the first entry that has the image version 65 matches = imgVerFinder.FindStringSubmatch(pkg) 66 if len(matches) > 1 { 67 imgVersion = strings.TrimSpace(matches[1]) 68 } 69 } 70 } 71 72 if len(dismPackages) == 0 { 73 return nil, "", ErrParsingError 74 } 75 76 return dismPackages, imgVersion, nil 77 } 78 79 func findVersion(identity string) string { 80 pkgVer := versionRegexp.FindStringSubmatch(identity) 81 if len(pkgVer) > 1 { 82 return pkgVer[1] 83 } 84 return "" 85 }