Projects STRLCPY grype Commits 5b7cb1d1
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■
    go.mod
    skipped 7 lines
    8 8   github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
    9 9   github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4
    10 10   github.com/anchore/grype-db v0.0.0-20210928194208-f146397d6cd0
    11  - github.com/anchore/stereoscope v0.0.0-20210817160504-0f4abc2a5a5a
     11 + github.com/anchore/stereoscope v0.0.0-20211005213828-538011008578
    12 12   github.com/anchore/syft v0.24.1
    13 13   github.com/bmatcuk/doublestar/v2 v2.0.4
    14 14   github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
    skipped 26 lines
    41 41   gopkg.in/yaml.v2 v2.3.0
    42 42  )
    43 43   
     44 +replace github.com/anchore/syft => ../syft
     45 + 
  • ■ ■ ■ ■ ■ ■
    go.sum
    skipped 114 lines
    115 115  github.com/alicebob/sqlittle v1.4.0 h1:vgYt0nAjhdf/hg52MjKJ84g/uTzBPfrvI+VUBrIghxA=
    116 116  github.com/alicebob/sqlittle v1.4.0/go.mod h1:Co1L1qxHqCwf41puWhk2HOodojR0mcsAV4BIt8byZh8=
    117 117  github.com/anchore/client-go v0.0.0-20210222170800-9c70f9b80bcf/go.mod h1:FaODhIA06mxO1E6R32JE0TL1JWZZkmjRIAd4ULvHUKk=
    118  -github.com/anchore/go-rpmdb v0.0.0-20210602151223-1f0f707a2894/go.mod h1:8jNYOxCJC5kyD/Ct4MbzsDN2hOhRoCAzQcb/7KdYYGw=
    119 118  github.com/anchore/go-rpmdb v0.0.0-20210914181456-a9c52348da63 h1:C9W/LAydEz/qdUhx1MdjO9l8NEcFKYknkxDVyo9LAoM=
    120 119  github.com/anchore/go-rpmdb v0.0.0-20210914181456-a9c52348da63/go.mod h1:6qH8c6U/3CBVvDDDBZnPSTbTINq3cIdADUYTaVf75EM=
    121 120  github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0vW0nnNKJfJieyH/TZ9UYAnTZs5/gHTdAe8=
    skipped 10 lines
    132 131  github.com/anchore/packageurl-go v0.0.0-20210922164639-b3fa992ebd29/go.mod h1:Oc1UkGaJwY6ND6vtAqPSlYrptKRJngHwkwB6W7l1uP0=
    133 132  github.com/anchore/stereoscope v0.0.0-20210524175238-3b7662f3a66f/go.mod h1:vhh1M99rfWx5ejMvz1lkQiFZUrC5wu32V12R4JXH+ZI=
    134 133  github.com/anchore/stereoscope v0.0.0-20210524175238-3b7662f3a66f/go.mod h1:vhh1M99rfWx5ejMvz1lkQiFZUrC5wu32V12R4JXH+ZI=
    135  -github.com/anchore/stereoscope v0.0.0-20210817160504-0f4abc2a5a5a h1:RQb+Gft1MKxjDfJCnHP/f1mwfy0Jz50Kp9QGgSWKQiY=
    136  -github.com/anchore/stereoscope v0.0.0-20210817160504-0f4abc2a5a5a/go.mod h1:165DfE5jApgEkHTWwu7Bijeml9fofudrgcpuWaD9+tk=
    137  -github.com/anchore/syft v0.19.0/go.mod h1:ktWx72/MizsN9jgEh+Vzl9lfNIUC8tylQHk3ZjKehn0=
    138  -github.com/anchore/syft v0.23.0/go.mod h1:sr+rUnzPjdf97YUwZrbeuD8sebS5VsAZVTp6nXsjOWo=
    139  -github.com/anchore/syft v0.24.1 h1:LAtIn/V5ceoU6nM/nNdDZaEd99ZoAVb5XWc+ceDm6Yg=
    140  -github.com/anchore/syft v0.24.1/go.mod h1:XqVz3ZZYUKng59SXdyypYW6aXlI5fG6ZNR1SGbWGFhA=
     134 +github.com/anchore/stereoscope v0.0.0-20211005213828-538011008578 h1:gSpftl0RWfdTwlPmsOLgEawHIw16xwwG1mFD/wrVDRE=
     135 +github.com/anchore/stereoscope v0.0.0-20211005213828-538011008578/go.mod h1:kL7jfbXblrDcBhu5ja/s+VTYL3Mzof4eQNMJiSqcwXQ=
    141 136  github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
    142 137  github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
    143 138  github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
    skipped 125 lines
    269 264  github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
    270 265  github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
    271 266  github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
     267 +github.com/gabriel-vasile/mimetype v1.3.0 h1:4YOHITFLyYwF+iqG0ybSLGArRItynpfwdlWRmJnd75E=
     268 +github.com/gabriel-vasile/mimetype v1.3.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8=
    272 269  github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
    273 270  github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
    274 271  github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g=
    skipped 19 lines
    294 291  github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
    295 292  github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
    296 293  github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
    297  -github.com/go-restruct/restruct v0.0.0-20191227155143-5734170a48a1/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk=
    298 294  github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc=
    299 295  github.com/go-restruct/restruct v1.2.0-alpha/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk=
    300 296  github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
    skipped 345 lines
    646 642  github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
    647 643  github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
    648 644  github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
    649  -github.com/package-url/packageurl-go v0.1.0/go.mod h1:C/ApiuWpmbpni4DIOECf6WCjFUZV7O1Fx7VAzrZHgBw=
    650 645  github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
    651 646  github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
    652 647  github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
    skipped 78 lines
    731 726  github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak=
    732 727  github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
    733 728  github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM=
    734  -github.com/spdx/tools-golang v0.1.0 h1:iDMNEPqQk6CdiDj6eWDIDw85j0wQ3IR3pH9p0X05TSQ=
    735 729  github.com/spdx/tools-golang v0.1.0/go.mod h1:RO4Y3IFROJnz+43JKm1YOrbtgQNljW4gAPpA/sY2eqo=
    736 730  github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
    737 731  github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
    skipped 206 lines
    944 938  golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
    945 939  golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
    946 940  golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
     941 +golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
    947 942  golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c=
    948 943  golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
    949 944  golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
    skipped 319 lines
  • ■ ■ ■ ■
    grype/pkg/apk_metadata.go
    1 1  package pkg
    2 2   
    3 3  type ApkMetadata struct {
    4  - OriginPackage string
     4 + OriginPackage string `json:"originPackage"`
    5 5  }
    6 6   
  • ■ ■ ■ ■
    grype/pkg/dpkg_metadata.go
    1 1  package pkg
    2 2   
    3 3  type DpkgMetadata struct {
    4  - Source string
     4 + Source string `json:"source"`
    5 5  }
    6 6   
  • ■ ■ ■ ■ ■ ■
    grype/pkg/java_metadata.go
    1 1  package pkg
    2 2   
    3 3  type JavaMetadata struct {
    4  - VirtualPath string
    5  - PomArtifactID string
    6  - PomGroupID string
    7  - ManifestName string
     4 + VirtualPath string `json:"virtualPath"`
     5 + PomArtifactID string `json:"pomArtifactId"`
     6 + PomGroupID string `json:"pomGroupId"`
     7 + ManifestName string `json:"manifestName"`
    8 8  }
    9 9   
  • ■ ■ ■ ■
    grype/pkg/provider.go
    skipped 26 lines
    27 27  // Provide a set of packages and context metadata describing where they were sourced from.
    28 28  func Provide(userInput string, scopeOpt source.Scope, registryOptions *image.RegistryOptions) ([]Package, Context, error) {
    29 29   providers := []provider{
    30  - syftJSONProvider,
     30 + syftSBOMProvider,
    31 31   syftProvider, // important: we should try syft last
    32 32   }
    33 33   
    skipped 42 lines
  • ■ ■ ■ ■ ■ ■
    grype/pkg/rpmdb_metadata.go
    1 1  package pkg
    2 2   
    3 3  type RpmdbMetadata struct {
    4  - SourceRpm string
    5  - Epoch *int
     4 + SourceRpm string `json:"sourceRpm"`
     5 + Epoch *int `json:"epoch"`
    6 6  }
    7 7   
  • ■ ■ ■ ■ ■ ■
    grype/pkg/syft_json_provider.go
    1  -package pkg
    2  - 
    3  -import (
    4  - "encoding/json"
    5  - "fmt"
    6  - "io"
    7  - "os"
    8  - "strings"
    9  - 
    10  - "github.com/anchore/grype/internal/log"
    11  - 
    12  - "github.com/anchore/grype/grype/cpe"
    13  - "github.com/anchore/syft/syft/distro"
    14  - "github.com/anchore/syft/syft/pkg"
    15  - "github.com/anchore/syft/syft/source"
    16  - "github.com/mitchellh/go-homedir"
    17  -)
    18  - 
    19  -type syftSource struct {
    20  - Type string `json:"type"`
    21  - Target interface{} `json:"target"`
    22  -}
    23  - 
    24  -// syftSourceUnpacker is used to unmarshal Source objects
    25  -type syftSourceUnpacker struct {
    26  - Type string `json:"type"`
    27  - Target json.RawMessage `json:"target"`
    28  -}
    29  - 
    30  -// UnmarshalJSON populates a source object from JSON bytes.
    31  -func (s *syftSource) UnmarshalJSON(b []byte) error {
    32  - var unpacker syftSourceUnpacker
    33  - if err := json.Unmarshal(b, &unpacker); err != nil {
    34  - return err
    35  - }
    36  - 
    37  - s.Type = unpacker.Type
    38  - 
    39  - switch s.Type {
    40  - case "directory":
    41  - s.Target = string(unpacker.Target[:])
    42  - case "image":
    43  - var payload source.ImageMetadata
    44  - if err := json.Unmarshal(unpacker.Target, &payload); err != nil {
    45  - return err
    46  - }
    47  - s.Target = payload
    48  - default:
    49  - return fmt.Errorf("unsupported package metadata type: %+v", s.Type)
    50  - }
    51  - 
    52  - return nil
    53  -}
    54  - 
    55  -// ToSourceMetadata takes a syftSource object represented from JSON and creates a source.Metadata object.
    56  -func (s *syftSource) toSourceMetadata() source.Metadata {
    57  - var m source.Metadata
    58  - switch s.Type {
    59  - case "directory":
    60  - m.Scheme = source.DirectoryScheme
    61  - m.Path = s.Target.(string)
    62  - case "image":
    63  - m.Scheme = source.ImageScheme
    64  - m.ImageMetadata = s.Target.(source.ImageMetadata)
    65  - }
    66  - return m
    67  -}
    68  - 
    69  -type syftDistribution struct {
    70  - Name string `json:"name"` // Name of the Linux syftDistribution
    71  - Version string `json:"version"` // Version of the Linux syftDistribution (major or major.minor version)
    72  - IDLike string `json:"idLike"` // the ID_LIKE field found within the /etc/os-release file
    73  -}
    74  - 
    75  -// partialSyftDoc is the final package shape for a select elements from a syft JSON document.
    76  -type partialSyftDoc struct {
    77  - Source syftSource `json:"source"`
    78  - Artifacts []partialSyftPackage `json:"artifacts"`
    79  - Distro syftDistribution `json:"distro"`
    80  -}
    81  - 
    82  -// partialSyftPackage is the final package shape for a select elements from a syft JSON package.
    83  -type partialSyftPackage struct {
    84  - packageBasicMetadata
    85  - packageCustomMetadata
    86  -}
    87  - 
    88  -// packageBasicMetadata contains non-ambiguous values (type-wise) from pkg.Package.
    89  -type packageBasicMetadata struct {
    90  - ID string `json:"id"`
    91  - Name string `json:"name"`
    92  - Version string `json:"version"`
    93  - Type pkg.Type `json:"type"`
    94  - Locations []source.Location `json:"locations"`
    95  - Licenses []string `json:"licenses"`
    96  - Language pkg.Language `json:"language"`
    97  - CPEs []string `json:"cpes"`
    98  - PURL string `json:"purl"`
    99  -}
    100  - 
    101  -// packageCustomMetadata contains ambiguous values (type-wise) from pkg.Package.
    102  -type packageCustomMetadata struct {
    103  - MetadataType pkg.MetadataType `json:"metadataType"`
    104  - Metadata interface{} `json:"metadata"`
    105  -}
    106  - 
    107  -// packageMetadataUnpacker is all values needed from Package to disambiguate ambiguous fields during json unmarshaling.
    108  -type packageMetadataUnpacker struct {
    109  - MetadataType pkg.MetadataType `json:"metadataType"`
    110  - Metadata json.RawMessage `json:"metadata"`
    111  -}
    112  - 
    113  -func (p *packageMetadataUnpacker) String() string {
    114  - return fmt.Sprintf("metadataType: %s, metadata: %s", p.MetadataType, string(p.Metadata))
    115  -}
    116  - 
    117  -// partialSyftJavaMetadata encapsulates all Java ecosystem metadata for a package as well as an (optional) parent relationship.
    118  -type partialSyftJavaMetadata struct {
    119  - VirtualPath string `mapstructure:"VirtualPath" json:"virtualPath"`
    120  - Manifest *partialSyftJavaManifest `mapstructure:"Manifest" json:"manifest,omitempty"`
    121  - PomProperties *partialSyftPomProperties `mapstructure:"PomProperties" json:"pomProperties,omitempty"`
    122  -}
    123  - 
    124  -// partialSyftPomProperties represents the fields of interest extracted from a Java archive's pom.xml file.
    125  -type partialSyftPomProperties struct {
    126  - GroupID string `mapstructure:"groupId" json:"groupId"`
    127  - ArtifactID string `mapstructure:"artifactId" json:"artifactId"`
    128  -}
    129  - 
    130  -// partialSyftJavaManifest represents the fields of interest extracted from a Java archive's META-INF/MANIFEST.MF file.
    131  -type partialSyftJavaManifest struct {
    132  - Main map[string]string `json:"main,omitempty"`
    133  -}
    134  - 
    135  -// String returns the stringer representation for a syft package.
    136  -func (p partialSyftPackage) String() string {
    137  - return fmt.Sprintf("Pkg(type=%s, name=%s, version=%s)", p.Type, p.Name, p.Version)
    138  -}
    139  - 
    140  -// UnmarshalJSON is a custom unmarshaller for handling basic values and values with ambiguous types.
    141  -func (p *partialSyftPackage) UnmarshalJSON(b []byte) error {
    142  - var basic packageBasicMetadata
    143  - if err := json.Unmarshal(b, &basic); err != nil {
    144  - return err
    145  - }
    146  - p.packageBasicMetadata = basic
    147  - 
    148  - var unpacker packageMetadataUnpacker
    149  - if err := json.Unmarshal(b, &unpacker); err != nil {
    150  - log.Warnf("failed to unmarshall into packageMetadataUnpacker: %v", err)
    151  - return err
    152  - }
    153  - 
    154  - p.MetadataType = unpacker.MetadataType
    155  - 
    156  - switch p.MetadataType {
    157  - case pkg.ApkMetadataType:
    158  - var payload ApkMetadata
    159  - if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
    160  - return err
    161  - }
    162  - p.Metadata = payload
    163  - case pkg.RpmdbMetadataType:
    164  - var payload RpmdbMetadata
    165  - if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
    166  - return err
    167  - }
    168  - p.Metadata = payload
    169  - case pkg.DpkgMetadataType:
    170  - var payload DpkgMetadata
    171  - if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
    172  - return err
    173  - }
    174  - p.Metadata = payload
    175  - case pkg.JavaMetadataType:
    176  - var partialPayload partialSyftJavaMetadata
    177  - if err := json.Unmarshal(unpacker.Metadata, &partialPayload); err != nil {
    178  - return err
    179  - }
    180  - 
    181  - var artifact, group, name string
    182  - if partialPayload.PomProperties != nil {
    183  - artifact = partialPayload.PomProperties.ArtifactID
    184  - group = partialPayload.PomProperties.GroupID
    185  - }
    186  - 
    187  - if partialPayload.Manifest != nil {
    188  - if n, ok := partialPayload.Manifest.Main["Name"]; ok {
    189  - name = n
    190  - }
    191  - }
    192  - 
    193  - p.Metadata = JavaMetadata{
    194  - VirtualPath: partialPayload.VirtualPath,
    195  - PomArtifactID: artifact,
    196  - PomGroupID: group,
    197  - ManifestName: name,
    198  - }
    199  - }
    200  - 
    201  - return nil
    202  -}
    203  - 
    204  -// parseSyftJSON attempts to loosely parse the available JSON for only the fields needed, not the exact syft JSON shape.
    205  -// This allows for some resiliency as the syft document shape changes over time (but not fool-proof).
    206  -func parseSyftJSON(reader io.Reader) ([]Package, Context, error) {
    207  - var doc partialSyftDoc
    208  - decoder := json.NewDecoder(reader)
    209  - if err := decoder.Decode(&doc); err != nil {
    210  - return nil, Context{}, errDoesNotProvide
    211  - }
    212  - 
    213  - var packages = make([]Package, len(doc.Artifacts))
    214  - for i, a := range doc.Artifacts {
    215  - cpes, err := cpe.NewSlice(a.CPEs...)
    216  - if err != nil {
    217  - return nil, Context{}, err
    218  - }
    219  - 
    220  - packages[i] = Package{
    221  - ID: ID(a.ID),
    222  - Name: a.Name,
    223  - Version: a.Version,
    224  - Locations: a.Locations,
    225  - Language: a.Language,
    226  - Licenses: a.Licenses,
    227  - Type: a.Type,
    228  - CPEs: cpes,
    229  - PURL: a.PURL,
    230  - Metadata: a.Metadata,
    231  - }
    232  - }
    233  - 
    234  - var theDistro *distro.Distro
    235  - if doc.Distro.Name != "" {
    236  - d, err := distro.NewDistro(distro.Type(doc.Distro.Name), doc.Distro.Version, doc.Distro.IDLike)
    237  - if err != nil {
    238  - return nil, Context{}, err
    239  - }
    240  - theDistro = &d
    241  - }
    242  - 
    243  - srcMetadata := doc.Source.toSourceMetadata()
    244  - 
    245  - return packages, Context{
    246  - Source: &srcMetadata,
    247  - Distro: theDistro,
    248  - }, nil
    249  -}
    250  - 
    251  -// syftJSONProvider extracts the necessary package and package context from syft JSON output. Note that this process carves out
    252  -// only the necessary data needed and does not require unmarshalling the entire syft JSON data shape so this function is somewhat
    253  -// resilient to multiple syft JSON schemas (to a degree).
    254  -// TODO: add version detection and multi-parser support (when needed in the future)
    255  -func syftJSONProvider(config providerConfig) ([]Package, Context, error) {
    256  - reader, err := getSyftJSON(config)
    257  - if err != nil {
    258  - return nil, Context{}, err
    259  - }
    260  - 
    261  - return parseSyftJSON(reader)
    262  -}
    263  - 
    264  -func getSyftJSON(config providerConfig) (io.Reader, error) {
    265  - if config.reader != nil {
    266  - // the caller has explicitly indicated to use the given reader as input
    267  - return config.reader, nil
    268  - }
    269  - 
    270  - if explicitlySpecifyingSBOM(config.userInput) {
    271  - filepath := strings.TrimPrefix(config.userInput, "sbom:")
    272  - 
    273  - sbom, err := openSbom(filepath)
    274  - if err != nil {
    275  - return nil, fmt.Errorf("unable to use specified SBOM: %w", err)
    276  - }
    277  - 
    278  - return sbom, nil
    279  - }
    280  - 
    281  - // as a last resort, see if the raw user input specified an SBOM file
    282  - sbom, err := openSbom(config.userInput)
    283  - if err == nil {
    284  - return sbom, nil
    285  - }
    286  - 
    287  - // no usable SBOM is available
    288  - return nil, errDoesNotProvide
    289  -}
    290  - 
    291  -func openSbom(path string) (*os.File, error) {
    292  - expandedPath, err := homedir.Expand(path)
    293  - if err != nil {
    294  - return nil, fmt.Errorf("unable to open SBOM: %w", err)
    295  - }
    296  - 
    297  - sbom, err := os.Open(expandedPath)
    298  - if err != nil {
    299  - return nil, fmt.Errorf("unable to open SBOM: %w", err)
    300  - }
    301  - 
    302  - return sbom, nil
    303  -}
    304  - 
    305  -func explicitlySpecifyingSBOM(userInput string) bool {
    306  - return strings.HasPrefix(userInput, "sbom:")
    307  -}
    308  - 
  • ■ ■ ■ ■ ■ ■
    grype/pkg/syft_provider.go
    1 1  package pkg
    2 2   
    3 3  import (
     4 + "fmt"
     5 + "io"
     6 + "os"
     7 + "strings"
     8 + 
    4 9   "github.com/anchore/syft/syft"
    5 10   "github.com/anchore/syft/syft/source"
     11 + "github.com/mitchellh/go-homedir"
    6 12  )
    7 13   
    8 14  func syftProvider(config providerConfig) ([]Package, Context, error) {
    skipped 18 lines
    27 33   }, nil
    28 34  }
    29 35   
     36 +func getSBOMReader(config providerConfig) (io.Reader, error) {
     37 + if config.reader != nil {
     38 + // the caller has explicitly indicated to use the given reader as input
     39 + return config.reader, nil
     40 + }
     41 + 
     42 + if explicitlySpecifyingSBOM(config.userInput) {
     43 + filepath := strings.TrimPrefix(config.userInput, "sbom:")
     44 + 
     45 + sbom, err := openSbom(filepath)
     46 + if err != nil {
     47 + return nil, fmt.Errorf("unable to use specified SBOM: %w", err)
     48 + }
     49 + 
     50 + return sbom, nil
     51 + }
     52 + 
     53 + // as a last resort, see if the raw user input specified an SBOM file
     54 + sbom, err := openSbom(config.userInput)
     55 + if err == nil {
     56 + return sbom, nil
     57 + }
     58 + 
     59 + // no usable SBOM is available
     60 + return nil, errDoesNotProvide
     61 +}
     62 + 
     63 +func openSbom(path string) (*os.File, error) {
     64 + expandedPath, err := homedir.Expand(path)
     65 + if err != nil {
     66 + return nil, fmt.Errorf("unable to open SBOM: %w", err)
     67 + }
     68 + 
     69 + sbom, err := os.Open(expandedPath)
     70 + if err != nil {
     71 + return nil, fmt.Errorf("unable to open SBOM: %w", err)
     72 + }
     73 + 
     74 + return sbom, nil
     75 +}
     76 + 
     77 +func explicitlySpecifyingSBOM(userInput string) bool {
     78 + return strings.HasPrefix(userInput, "sbom:")
     79 +}
     80 + 
  • ■ ■ ■ ■ ■ ■
    grype/pkg/syft_sbom_provider.go
     1 +package pkg
     2 + 
     3 +import (
     4 + "fmt"
     5 + 
     6 + "github.com/anchore/syft/syft"
     7 + "github.com/anchore/syft/syft/format"
     8 +)
     9 + 
     10 +func syftSBOMProvider(config providerConfig) ([]Package, Context, error) {
     11 + reader, err := getSBOMReader(config)
     12 + if err != nil {
     13 + return nil, Context{}, err
     14 + }
     15 + 
     16 + catalog, srcMetadata, theDistro, formatOption, err := syft.Decode(reader)
     17 + if err != nil {
     18 + return nil, Context{}, fmt.Errorf("unable to decode sbom: %w", err)
     19 + }
     20 + if formatOption == format.UnknownOption {
     21 + return nil, Context{}, errDoesNotProvide
     22 + }
     23 + 
     24 + return FromCatalog(catalog), Context{
     25 + Source: srcMetadata,
     26 + Distro: theDistro,
     27 + }, nil
     28 +}
     29 + 
  • ■ ■ ■ ■ ■
    grype/pkg/syft_json_provider_test.go grype/pkg/syft_sbom_provider_test.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "os"
     5 + "strings"
    5 6   "testing"
    6 7   
    7 8   "github.com/stretchr/testify/assert"
    skipped 131 lines
    139 140   t.Fatalf("unable to open fixture: %+v", err)
    140 141   }
    141 142   
    142  - pkgs, context, err := parseSyftJSON(fh)
     143 + pkgs, context, err := syftSBOMProvider(providerConfig{reader: fh})
    143 144   if err != nil {
    144 145   t.Fatalf("unable to parse: %+v", err)
    145 146   }
    skipped 2 lines
    148 149   context.Source.ImageMetadata.RawManifest = nil
    149 150   
    150 151   for _, d := range deep.Equal(test.Packages, pkgs) {
     152 + if strings.Contains(d, ".ID: ") {
     153 + // package IDs will never match
     154 + continue
     155 + }
    151 156   t.Errorf("pkg diff: %s", d)
    152 157   }
    153 158   
    skipped 11 lines
    165 170   t.Fatalf("unable to open fixture: %+v", err)
    166 171   }
    167 172   
    168  - pkgs, _, err := parseSyftJSON(fh)
     173 + pkgs, _, err := syftSBOMProvider(providerConfig{reader: fh})
    169 174   assert.NoError(t, err)
    170 175   assert.Len(t, pkgs, 1)
    171 176  }
    skipped 79 lines
  • ■ ■ ■ ■ ■ ■
    grype/presenter/json/test-fixtures/snapshot/TestJsonDirsPresenter.golden
    skipped 53 lines
    54 54   "cpes": [],
    55 55   "purl": "",
    56 56   "metadata": {
    57  - "Source": "a source!"
     57 + "source": "a source!"
    58 58   }
    59 59   }
    60 60   },
    skipped 51 lines
    112 112   "cpes": [],
    113 113   "purl": "",
    114 114   "metadata": {
    115  - "Source": "a source!"
     115 + "source": "a source!"
    116 116   }
    117 117   }
    118 118   },
    skipped 39 lines
    158 158   "cpes": [],
    159 159   "purl": "",
    160 160   "metadata": {
    161  - "Source": "a source!"
     161 + "source": "a source!"
    162 162   }
    163 163   }
    164 164   }
    skipped 16 lines
  • ■ ■ ■ ■ ■ ■
    grype/presenter/json/test-fixtures/snapshot/TestJsonImgsPresenter.golden
    skipped 56 lines
    57 57   ],
    58 58   "purl": "",
    59 59   "metadata": {
    60  - "Source": "a source!"
     60 + "source": "a source!"
    61 61   }
    62 62   }
    63 63   },
    skipped 54 lines
    118 118   ],
    119 119   "purl": "",
    120 120   "metadata": {
    121  - "Source": "a source!"
     121 + "source": "a source!"
    122 122   }
    123 123   }
    124 124   },
    skipped 42 lines
    167 167   ],
    168 168   "purl": "",
    169 169   "metadata": {
    170  - "Source": "a source!"
     170 + "source": "a source!"
    171 171   }
    172 172   }
    173 173   }
    skipped 45 lines
  • ■ ■ ■ ■ ■ ■
    test/integration/utils_test.go
    1 1  package integration
    2 2   
    3 3  import (
    4  - "bufio"
    5  - "bytes"
    6 4   "errors"
    7 5   "fmt"
    8  - "github.com/anchore/grype/grype/match"
    9  - "github.com/scylladb/go-set/strset"
    10 6   "os"
    11 7   "os/exec"
    12 8   "path/filepath"
    13 9   "regexp"
    14 10   "testing"
    15 11   
     12 + "github.com/anchore/grype/grype/match"
     13 + "github.com/anchore/syft/syft/format"
     14 + "github.com/scylladb/go-set/strset"
     15 + 
    16 16   "github.com/anchore/syft/syft"
    17  - "github.com/anchore/syft/syft/presenter/packages"
    18 17   "github.com/anchore/syft/syft/source"
    19 18  )
    20 19   
    skipped 50 lines
    71 70   scope := source.SquashedScope
    72 71   catalog, distro, err := syft.CatalogPackages(src, scope)
    73 72   
    74  - presenter := packages.Presenter(packages.JSONPresenterOption, packages.PresenterConfig{
    75  - SourceMetadata: src.Metadata,
    76  - Catalog: catalog,
    77  - Distro: distro,
    78  - Scope: scope,
    79  - })
    80  - 
    81  - var buf bytes.Buffer
    82  - if err := presenter.Present(bufio.NewWriter(&buf)); err != nil {
    83  - t.Fatalf("presenter failed: %+v", err)
     73 + by, err := syft.Encode(catalog, &src.Metadata, distro, format.JSONOption)
     74 + if err != nil {
     75 + t.Fatalf("can't get the formatted sbom: %+v", err)
    84 76   }
    85 77   
    86  - return buf.String()
     78 + return string(by)
    87 79  }
    88 80   
    89 81  func getMatchSet(matches match.Matches) *strset.Set {
    skipped 7 lines
Please wait...
Page is in error, reload to recover