Skip to content

Commit

Permalink
Add additional PHP metadata (anchore#753)
Browse files Browse the repository at this point in the history
* 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>
Signed-off-by: fsl <1171313930@qq.com>
  • Loading branch information
wagoodman authored and fengshunli committed Jan 24, 2022
1 parent c2645dc commit 48d6811
Show file tree
Hide file tree
Showing 10 changed files with 495 additions and 63 deletions.
8 changes: 8 additions & 0 deletions internal/formats/syftjson/model/package.go
Expand Up @@ -118,6 +118,14 @@ func (p *Package) UnmarshalJSON(b []byte) error {
return err
}
p.Metadata = payload
case pkg.PhpComposerJSONMetadataType:
var payload pkg.PhpComposerJSONMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
default:
log.Warnf("unknown package metadata type=%q for packageID=%q", p.MetadataType, p.ID)
}

return nil
Expand Down
1 change: 1 addition & 0 deletions schema/json/generate.go
Expand Up @@ -36,6 +36,7 @@ type artifactMetadataContainer struct {
Rpm pkg.RpmdbMetadata
Cargo pkg.CargoPackageMetadata
Go pkg.GolangBinMetadata
Php pkg.PhpComposerJSONMetadata
}

func main() {
Expand Down
141 changes: 141 additions & 0 deletions schema/json/schema-3.0.1.json
Expand Up @@ -662,6 +662,9 @@
{
"$ref": "#/definitions/NpmPackageJSONMetadata"
},
{
"$ref": "#/definitions/PhpComposerJSONMetadata"
},
{
"$ref": "#/definitions/PythonPackageMetadata"
},
Expand All @@ -674,6 +677,144 @@
"additionalProperties": true,
"type": "object"
},
"PhpComposerAuthors": {
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"homepage": {
"type": "string"
}
},
"additionalProperties": true,
"type": "object"
},
"PhpComposerExternalReference": {
"required": [
"type",
"url",
"reference"
],
"properties": {
"type": {
"type": "string"
},
"url": {
"type": "string"
},
"reference": {
"type": "string"
},
"shasum": {
"type": "string"
}
},
"additionalProperties": true,
"type": "object"
},
"PhpComposerJSONMetadata": {
"required": [
"name",
"version",
"source",
"dist"
],
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"source": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/PhpComposerExternalReference"
},
"dist": {
"$ref": "#/definitions/PhpComposerExternalReference"
},
"require": {
"patternProperties": {
".*": {
"type": "string"
}
},
"type": "object"
},
"provide": {
"patternProperties": {
".*": {
"type": "string"
}
},
"type": "object"
},
"require-dev": {
"patternProperties": {
".*": {
"type": "string"
}
},
"type": "object"
},
"suggest": {
"patternProperties": {
".*": {
"type": "string"
}
},
"type": "object"
},
"type": {
"type": "string"
},
"notification-url": {
"type": "string"
},
"bin": {
"items": {
"type": "string"
},
"type": "array"
},
"license": {
"items": {
"type": "string"
},
"type": "array"
},
"authors": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/PhpComposerAuthors"
},
"type": "array"
},
"description": {
"type": "string"
},
"homepage": {
"type": "string"
},
"keywords": {
"items": {
"type": "string"
},
"type": "array"
},
"time": {
"type": "string"
}
},
"additionalProperties": true,
"type": "object"
},
"PomParent": {
"required": [
"groupId",
Expand Down
24 changes: 10 additions & 14 deletions syft/pkg/cataloger/php/parse_composer_lock.go
Expand Up @@ -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.
Expand All @@ -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 {
Expand All @@ -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,
})
}
}
Expand Down
105 changes: 93 additions & 12 deletions syft/pkg/cataloger/php/parse_composer_lock_test.go
Expand Up @@ -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")
Expand All @@ -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)
}
}
16 changes: 9 additions & 7 deletions syft/pkg/cataloger/php/parse_installed_json.go
Expand Up @@ -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
Expand Down Expand Up @@ -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,
})
}
}
Expand Down

0 comments on commit 48d6811

Please sign in to comment.