github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/wordpress/parse_plugin.go (about) 1 package wordpress 2 3 import ( 4 "context" 5 "fmt" 6 "path/filepath" 7 "regexp" 8 "strings" 9 10 "github.com/anchore/syft/internal" 11 "github.com/anchore/syft/syft/artifact" 12 "github.com/anchore/syft/syft/file" 13 "github.com/anchore/syft/syft/pkg" 14 "github.com/anchore/syft/syft/pkg/cataloger/generic" 15 ) 16 17 const contentBufferSize = 4096 18 19 var patterns = map[string]*regexp.Regexp{ 20 // match example: "Plugin Name: WP Migration" ---> WP Migration 21 "name": regexp.MustCompile(`(?i)plugin name:\s*(?P<name>.+)`), 22 23 // match example: "Version: 5.3" ---> 5.3 24 "version": regexp.MustCompile(`(?i)version:\s*(?P<version>[\d.]+)`), 25 26 // match example: "License: GPLv3" ---> GPLv3 27 "license": regexp.MustCompile(`(?i)license:\s*(?P<license>\w+)`), 28 29 // match example: "Author: MonsterInsights" ---> MonsterInsights 30 "author": regexp.MustCompile(`(?i)author:\s*(?P<author>.+)`), 31 32 // match example: "Author URI: https://servmask.com/" ---> https://servmask.com/ 33 "author_uri": regexp.MustCompile(`(?i)author uri:\s*(?P<author_uri>.+)`), 34 } 35 36 type pluginData struct { 37 Licenses []string `mapstructure:"licenses" json:"licenses,omitempty"` 38 pkg.WordpressPluginEntry `mapstructure:",squash" json:",inline"` 39 } 40 41 func parseWordpressPluginFiles(ctx context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 42 var pkgs []pkg.Package 43 buffer := make([]byte, contentBufferSize) 44 45 _, err := reader.Read(buffer) 46 if err != nil { 47 return nil, nil, fmt.Errorf("failed to read %s file: %w", reader.Path(), err) 48 } 49 50 fields := extractFields(string(buffer)) 51 52 name, nameOk := fields["name"] 53 version, versionOk := fields["version"] 54 55 // get a plugin name from a plugin's directory name 56 pluginInstallDirectory := filepath.Base(filepath.Dir(reader.RealPath)) 57 58 if nameOk && name != "" && versionOk && version != "" { 59 var metadata pluginData 60 61 metadata.PluginInstallDirectory = pluginInstallDirectory 62 63 author, authorOk := fields["author"] 64 if authorOk && author != "" { 65 metadata.Author = author.(string) 66 } 67 68 authorURI, authorURIOk := fields["author_uri"] 69 if authorURIOk && authorURI != "" { 70 metadata.AuthorURI = authorURI.(string) 71 } 72 73 license, licenseOk := fields["license"] 74 if licenseOk && license != "" { 75 licenses := make([]string, 0) 76 licenses = append(licenses, license.(string)) 77 metadata.Licenses = licenses 78 } 79 80 pkgs = append( 81 pkgs, 82 newWordpressPluginPackage( 83 ctx, 84 resolver, 85 name.(string), 86 version.(string), 87 metadata, 88 reader.Location, 89 ), 90 ) 91 } 92 93 return pkgs, nil, nil 94 } 95 96 func extractFields(in string) map[string]any { 97 var fields = make(map[string]interface{}) 98 99 for field, pattern := range patterns { 100 matchMap := internal.MatchNamedCaptureGroups(pattern, in) 101 if value := matchMap[field]; value != "" { 102 fields[field] = strings.TrimSpace(value) 103 } 104 } 105 return fields 106 }