mirror of
https://github.com/anchore/syft.git
synced 2026-11-05 08:56:41 +01:00
feat: Add Wordpress cataloger (#2218)
* Closes #1911 Wordpress cataloger Signed-off-by: disc <a.hacicheant@gmail.com> * Fixed a few unit tests and static analizer notices Signed-off-by: disc <a.hacicheant@gmail.com> * Updated `README.md` Signed-off-by: disc <a.hacicheant@gmail.com> * Fixed `golangci-lint` notices Added integration test for `wordpress-plugin` Signed-off-by: disc <a.hacicheant@gmail.com> * Fixed `gosimports` notices Signed-off-by: disc <a.hacicheant@gmail.com> * Updated `json schema` version Signed-off-by: disc <a.hacicheant@gmail.com> * Fixed CLI tests, increased expected package count Signed-off-by: disc <a.hacicheant@gmail.com> * Read first 4Kb of a plugins file's content Signed-off-by: disc <a.hacicheant@gmail.com> * replace JSON schema version Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * change wording on source info for wordpress packages Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * Minor changes after a huge refactoring Signed-off-by: disc <a.hacicheant@gmail.com> * Removed unused files Signed-off-by: disc <a.hacicheant@gmail.com> * Updated schema Signed-off-by: disc <a.hacicheant@gmail.com> * Fixed integration tests Signed-off-by: disc <a.hacicheant@gmail.com> * fix integration tests Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * Renamed `metadata.Name` to `metadata.PluginInstallDirectory` Signed-off-by: disc <a.hacicheant@gmail.com> * rename fields to be compliant with json conventions Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: disc <a.hacicheant@gmail.com> Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
co-authored by
Alex Goodman
parent
98b700e83c
commit
96ee2db875
@@ -0,0 +1,98 @@
|
||||
package wordpress
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
)
|
||||
|
||||
const contentBufferSize = 4096
|
||||
|
||||
var patterns = map[string]*regexp.Regexp{
|
||||
// match example: "Plugin Name: WP Migration" ---> WP Migration
|
||||
"name": regexp.MustCompile(`(?i)plugin name:\s*(?P<name>.+)`),
|
||||
|
||||
// match example: "Version: 5.3" ---> 5.3
|
||||
"version": regexp.MustCompile(`(?i)version:\s*(?P<version>[\d.]+)`),
|
||||
|
||||
// match example: "License: GPLv3" ---> GPLv3
|
||||
"license": regexp.MustCompile(`(?i)license:\s*(?P<license>\w+)`),
|
||||
|
||||
// match example: "Author: MonsterInsights" ---> MonsterInsights
|
||||
"author": regexp.MustCompile(`(?i)author:\s*(?P<author>.+)`),
|
||||
|
||||
// match example: "Author URI: https://servmask.com/" ---> https://servmask.com/
|
||||
"author_uri": regexp.MustCompile(`(?i)author uri:\s*(?P<author_uri>.+)`),
|
||||
}
|
||||
|
||||
type pluginData struct {
|
||||
Licenses []string `mapstructure:"licenses" json:"licenses,omitempty"`
|
||||
pkg.WordpressPluginEntry `mapstructure:",squash" json:",inline"`
|
||||
}
|
||||
|
||||
func parseWordpressPluginFiles(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
var pkgs []pkg.Package
|
||||
var fields = make(map[string]interface{})
|
||||
buffer := make([]byte, contentBufferSize)
|
||||
|
||||
_, err := reader.Read(buffer)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to read %s file: %w", reader.Location.Path(), err)
|
||||
}
|
||||
|
||||
fileContent := string(buffer)
|
||||
for field, pattern := range patterns {
|
||||
matchMap := internal.MatchNamedCaptureGroups(pattern, fileContent)
|
||||
if value := matchMap[field]; value != "" {
|
||||
fields[field] = value
|
||||
}
|
||||
}
|
||||
|
||||
name, nameOk := fields["name"]
|
||||
version, versionOk := fields["version"]
|
||||
|
||||
// get a plugin name from a plugin's directory name
|
||||
pluginInstallDirectory := filepath.Base(filepath.Dir(reader.RealPath))
|
||||
|
||||
if nameOk && name != "" && versionOk && version != "" {
|
||||
var metadata pluginData
|
||||
|
||||
metadata.PluginInstallDirectory = pluginInstallDirectory
|
||||
|
||||
author, authorOk := fields["author"]
|
||||
if authorOk && author != "" {
|
||||
metadata.Author = author.(string)
|
||||
}
|
||||
|
||||
authorURI, authorURIOk := fields["author_uri"]
|
||||
if authorURIOk && authorURI != "" {
|
||||
metadata.AuthorURI = authorURI.(string)
|
||||
}
|
||||
|
||||
license, licenseOk := fields["license"]
|
||||
if licenseOk && license != "" {
|
||||
licenses := make([]string, 0)
|
||||
licenses = append(licenses, license.(string))
|
||||
metadata.Licenses = licenses
|
||||
}
|
||||
|
||||
pkgs = append(
|
||||
pkgs,
|
||||
newWordpressPluginPackage(
|
||||
name.(string),
|
||||
version.(string),
|
||||
metadata,
|
||||
reader.Location,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return pkgs, nil, nil
|
||||
}
|
||||
Reference in New Issue
Block a user