mirror of
https://github.com/anchore/syft.git
synced 2026-11-01 23:16:30 +01:00
Add additional PHP metadata (#753)
* add php related metadata Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * enable decoding of php metadata for syftjson format Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add php metadata to json schema Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
@@ -6,18 +6,12 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
type ComposerLock struct {
|
||||
Packages []Dependency `json:"packages"`
|
||||
PackageDev []Dependency `json:"packages-dev"`
|
||||
}
|
||||
|
||||
type Dependency struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
type composerLock struct {
|
||||
Packages []pkg.PhpComposerJSONMetadata `json:"packages"`
|
||||
PackageDev []pkg.PhpComposerJSONMetadata `json:"packages-dev"`
|
||||
}
|
||||
|
||||
// parseComposerLock is a parser function for Composer.lock contents, returning "Default" php packages discovered.
|
||||
@@ -26,7 +20,7 @@ func parseComposerLock(_ string, reader io.Reader) ([]*pkg.Package, []artifact.R
|
||||
dec := json.NewDecoder(reader)
|
||||
|
||||
for {
|
||||
var lock ComposerLock
|
||||
var lock composerLock
|
||||
if err := dec.Decode(&lock); err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
@@ -36,10 +30,12 @@ func parseComposerLock(_ string, reader io.Reader) ([]*pkg.Package, []artifact.R
|
||||
version := pkgMeta.Version
|
||||
name := pkgMeta.Name
|
||||
packages = append(packages, &pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
Name: name,
|
||||
Version: version,
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkgMeta,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,16 +11,98 @@ import (
|
||||
func TestParseComposerFileLock(t *testing.T) {
|
||||
expected := []*pkg.Package{
|
||||
{
|
||||
Name: "adoy/fastcgi-client",
|
||||
Version: "1.0.2",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
Name: "adoy/fastcgi-client",
|
||||
Version: "1.0.2",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "adoy/fastcgi-client",
|
||||
Version: "1.0.2",
|
||||
Source: pkg.PhpComposerExternalReference{
|
||||
Type: "git",
|
||||
URL: "https://github.com/adoy/PHP-FastCGI-Client.git",
|
||||
Reference: "6d9a552f0206a1db7feb442824540aa6c55e5b27",
|
||||
},
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
Type: "zip",
|
||||
URL: "https://api.github.com/repos/adoy/PHP-FastCGI-Client/zipball/6d9a552f0206a1db7feb442824540aa6c55e5b27",
|
||||
Reference: "6d9a552f0206a1db7feb442824540aa6c55e5b27",
|
||||
},
|
||||
Type: "library",
|
||||
NotificationURL: "https://packagist.org/downloads/",
|
||||
License: []string{
|
||||
"MIT",
|
||||
},
|
||||
Authors: []pkg.PhpComposerAuthors{
|
||||
{
|
||||
Name: "Pierrick Charron",
|
||||
Email: "pierrick@adoy.net",
|
||||
},
|
||||
},
|
||||
Description: "Lightweight, single file FastCGI client for PHP.",
|
||||
Keywords: []string{
|
||||
"fastcgi",
|
||||
"fcgi",
|
||||
},
|
||||
Time: "2019-12-11T13:49:21+00:00",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "alcaeus/mongo-php-adapter",
|
||||
Version: "1.1.11",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
Name: "alcaeus/mongo-php-adapter",
|
||||
Version: "1.1.11",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "alcaeus/mongo-php-adapter",
|
||||
Version: "1.1.11",
|
||||
Source: pkg.PhpComposerExternalReference{
|
||||
Type: "git",
|
||||
URL: "https://github.com/alcaeus/mongo-php-adapter.git",
|
||||
Reference: "43b6add94c8b4cb9890d662cba4c0defde733dcf",
|
||||
},
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
Type: "zip",
|
||||
URL: "https://api.github.com/repos/alcaeus/mongo-php-adapter/zipball/43b6add94c8b4cb9890d662cba4c0defde733dcf",
|
||||
Reference: "43b6add94c8b4cb9890d662cba4c0defde733dcf",
|
||||
},
|
||||
Require: map[string]string{
|
||||
"ext-ctype": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-mongodb": "^1.2.0",
|
||||
"mongodb/mongodb": "^1.0.1",
|
||||
"php": "^5.6 || ^7.0",
|
||||
},
|
||||
Provide: map[string]string{
|
||||
"ext-mongo": "1.6.14",
|
||||
},
|
||||
RequireDev: map[string]string{
|
||||
"phpunit/phpunit": "^5.7.27 || ^6.0 || ^7.0",
|
||||
"squizlabs/php_codesniffer": "^3.2",
|
||||
},
|
||||
Type: "library",
|
||||
NotificationURL: "https://packagist.org/downloads/",
|
||||
License: []string{
|
||||
"MIT",
|
||||
},
|
||||
Authors: []pkg.PhpComposerAuthors{
|
||||
{
|
||||
Name: "alcaeus",
|
||||
Email: "alcaeus@alcaeus.org",
|
||||
},
|
||||
{
|
||||
Name: "Olivier Lechevalier",
|
||||
Email: "olivier.lechevalier@gmail.com",
|
||||
},
|
||||
},
|
||||
Description: "Adapter to provide ext-mongo interface on top of mongo-php-libary",
|
||||
Keywords: []string{
|
||||
"database",
|
||||
"mongodb",
|
||||
},
|
||||
Time: "2019-11-11T20:47:32+00:00",
|
||||
},
|
||||
},
|
||||
}
|
||||
fixture, err := os.Open("test-fixtures/composer.lock")
|
||||
@@ -33,9 +115,8 @@ func TestParseComposerFileLock(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse requirements: %+v", err)
|
||||
}
|
||||
differences := deep.Equal(expected, actual)
|
||||
if differences != nil {
|
||||
t.Errorf("returned package list differed from expectation: %+v", differences)
|
||||
}
|
||||
|
||||
for _, d := range deep.Equal(expected, actual) {
|
||||
t.Errorf("diff: %+v", d)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,19 +12,19 @@ import (
|
||||
|
||||
// Note: composer version 2 introduced a new structure for the installed.json file, so we support both
|
||||
type installedJSONComposerV2 struct {
|
||||
Packages []Dependency `json:"packages"`
|
||||
Packages []pkg.PhpComposerJSONMetadata `json:"packages"`
|
||||
}
|
||||
|
||||
func (w *installedJSONComposerV2) UnmarshalJSON(data []byte) error {
|
||||
type compv2 struct {
|
||||
Packages []Dependency `json:"packages"`
|
||||
Packages []pkg.PhpComposerJSONMetadata `json:"packages"`
|
||||
}
|
||||
compv2er := new(compv2)
|
||||
err := json.Unmarshal(data, &compv2er)
|
||||
if err != nil {
|
||||
// If we had an err or, we may be dealing with a composer v.1 installed.json
|
||||
// which should be all arrays
|
||||
var packages []Dependency
|
||||
var packages []pkg.PhpComposerJSONMetadata
|
||||
err := json.Unmarshal(data, &packages)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -55,10 +55,12 @@ func parseInstalledJSON(_ string, reader io.Reader) ([]*pkg.Package, []artifact.
|
||||
version := pkgMeta.Version
|
||||
name := pkgMeta.Name
|
||||
packages = append(packages, &pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
Name: name,
|
||||
Version: version,
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkgMeta,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,21 +8,118 @@ import (
|
||||
"github.com/go-test/deep"
|
||||
)
|
||||
|
||||
var expectedInstalledJsonPackages = []*pkg.Package{
|
||||
{
|
||||
Name: "asm89/stack-cors",
|
||||
Version: "1.3.0",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "asm89/stack-cors",
|
||||
Version: "1.3.0",
|
||||
Source: pkg.PhpComposerExternalReference{
|
||||
Type: "git",
|
||||
URL: "https://github.com/asm89/stack-cors.git",
|
||||
Reference: "b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
},
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
Type: "zip",
|
||||
URL: "https://api.github.com/repos/asm89/stack-cors/zipball/b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
Reference: "b9c31def6a83f84b4d4a40d35996d375755f0e08",
|
||||
},
|
||||
Require: map[string]string{
|
||||
"php": ">=5.5.9",
|
||||
"symfony/http-foundation": "~2.7|~3.0|~4.0|~5.0",
|
||||
"symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0",
|
||||
},
|
||||
RequireDev: map[string]string{
|
||||
"phpunit/phpunit": "^5.0 || ^4.8.10",
|
||||
"squizlabs/php_codesniffer": "^2.3",
|
||||
},
|
||||
Time: "2019-12-24T22:41:47+00:00",
|
||||
Type: "library",
|
||||
NotificationURL: "https://packagist.org/downloads/",
|
||||
License: []string{
|
||||
"MIT",
|
||||
},
|
||||
Authors: []pkg.PhpComposerAuthors{
|
||||
{
|
||||
Name: "Alexander",
|
||||
Email: "iam.asm89@gmail.com",
|
||||
},
|
||||
},
|
||||
|
||||
Description: "Cross-origin resource sharing library and stack middleware",
|
||||
Homepage: "https://github.com/asm89/stack-cors",
|
||||
Keywords: []string{
|
||||
"cors",
|
||||
"stack",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "behat/mink",
|
||||
Version: "v1.8.1",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
MetadataType: pkg.PhpComposerJSONMetadataType,
|
||||
Metadata: pkg.PhpComposerJSONMetadata{
|
||||
Name: "behat/mink",
|
||||
Version: "v1.8.1",
|
||||
Source: pkg.PhpComposerExternalReference{
|
||||
Type: "git",
|
||||
URL: "https://github.com/minkphp/Mink.git",
|
||||
Reference: "07c6a9fe3fa98c2de074b25d9ed26c22904e3887",
|
||||
},
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
Type: "zip",
|
||||
URL: "https://api.github.com/repos/minkphp/Mink/zipball/07c6a9fe3fa98c2de074b25d9ed26c22904e3887",
|
||||
Reference: "07c6a9fe3fa98c2de074b25d9ed26c22904e3887",
|
||||
},
|
||||
Require: map[string]string{
|
||||
"php": ">=5.3.1",
|
||||
"symfony/css-selector": "^2.7|^3.0|^4.0|^5.0",
|
||||
},
|
||||
RequireDev: map[string]string{
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20",
|
||||
"symfony/debug": "^2.7|^3.0|^4.0",
|
||||
"symfony/phpunit-bridge": "^3.4.38 || ^5.0.5",
|
||||
},
|
||||
Suggest: map[string]string{
|
||||
"behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
|
||||
"behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
|
||||
"behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
|
||||
"behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)",
|
||||
"dmore/chrome-mink-driver": "fast and JS-enabled driver for any app (requires chromium or google chrome)",
|
||||
},
|
||||
Time: "2020-03-11T15:45:53+00:00",
|
||||
Type: "library",
|
||||
NotificationURL: "https://packagist.org/downloads/",
|
||||
License: []string{
|
||||
"MIT",
|
||||
},
|
||||
Authors: []pkg.PhpComposerAuthors{
|
||||
{
|
||||
Name: "Konstantin Kudryashov",
|
||||
Email: "ever.zet@gmail.com",
|
||||
Homepage: "http://everzet.com",
|
||||
},
|
||||
},
|
||||
|
||||
Description: "Browser controller/emulator abstraction for PHP",
|
||||
Homepage: "http://mink.behat.org/",
|
||||
Keywords: []string{
|
||||
"browser",
|
||||
"testing",
|
||||
"web",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestParseInstalledJsonComposerV1(t *testing.T) {
|
||||
expected := []*pkg.Package{
|
||||
{
|
||||
Name: "asm89/stack-cors",
|
||||
Version: "1.3.0",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
},
|
||||
{
|
||||
Name: "behat/mink",
|
||||
Version: "v1.8.1",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
},
|
||||
}
|
||||
|
||||
fixture, err := os.Open("test-fixtures/vendor/composer_1/installed.json")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open fixture: %+v", err)
|
||||
@@ -33,28 +130,13 @@ func TestParseInstalledJsonComposerV1(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse requirements: %+v", err)
|
||||
}
|
||||
differences := deep.Equal(expected, actual)
|
||||
differences := deep.Equal(expectedInstalledJsonPackages, actual)
|
||||
if differences != nil {
|
||||
t.Errorf("returned package list differed from expectation: %+v", differences)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestParseInstalledJsonComposerV2(t *testing.T) {
|
||||
expected := []*pkg.Package{
|
||||
{
|
||||
Name: "asm89/stack-cors",
|
||||
Version: "1.3.0",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
},
|
||||
{
|
||||
Name: "behat/mink",
|
||||
Version: "v1.8.1",
|
||||
Language: pkg.PHP,
|
||||
Type: pkg.PhpComposerPkg,
|
||||
},
|
||||
}
|
||||
fixture, err := os.Open("test-fixtures/vendor/composer_2/installed.json")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open fixture: %+v", err)
|
||||
@@ -65,7 +147,7 @@ func TestParseInstalledJsonComposerV2(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse requirements: %+v", err)
|
||||
}
|
||||
differences := deep.Equal(expected, actual)
|
||||
differences := deep.Equal(expectedInstalledJsonPackages, actual)
|
||||
if differences != nil {
|
||||
t.Errorf("returned package list differed from expectation: %+v", differences)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user