mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
finalize gemspec parser + update json schema to match
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
46c74865e5
commit
398d8903e7
@ -40,6 +40,9 @@
|
|||||||
"architecture": {
|
"architecture": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"authors": {
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -48,31 +51,38 @@
|
|||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"items": {
|
"items": {
|
||||||
"properties": {
|
"anyOf": [
|
||||||
"checksum": {
|
{
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"ownerGid": {
|
{
|
||||||
"type": "string"
|
"properties": {
|
||||||
},
|
"checksum": {
|
||||||
"ownerUid": {
|
"type": "string"
|
||||||
"type": "string"
|
},
|
||||||
},
|
"ownerGid": {
|
||||||
"path": {
|
"type": "string"
|
||||||
"type": "string"
|
},
|
||||||
},
|
"ownerUid": {
|
||||||
"permissions": {
|
"type": "string"
|
||||||
"type": "string"
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"permissions": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"checksum",
|
||||||
|
"ownerGid",
|
||||||
|
"ownerUid",
|
||||||
|
"path",
|
||||||
|
"permissions"
|
||||||
|
],
|
||||||
|
"type": "object"
|
||||||
}
|
}
|
||||||
},
|
]
|
||||||
"required": [
|
|
||||||
"checksum",
|
|
||||||
"ownerGid",
|
|
||||||
"ownerUid",
|
|
||||||
"path",
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"type": "object"
|
|
||||||
},
|
},
|
||||||
"type": "array"
|
"type": "array"
|
||||||
},
|
},
|
||||||
@ -85,6 +95,12 @@
|
|||||||
"license": {
|
"license": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"licenses": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
"maintainer": {
|
"maintainer": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -8,13 +8,13 @@ package cataloger
|
|||||||
import (
|
import (
|
||||||
"github.com/anchore/stereoscope/pkg/file"
|
"github.com/anchore/stereoscope/pkg/file"
|
||||||
"github.com/anchore/syft/syft/cataloger/apkdb"
|
"github.com/anchore/syft/syft/cataloger/apkdb"
|
||||||
"github.com/anchore/syft/syft/cataloger/bundler"
|
|
||||||
"github.com/anchore/syft/syft/cataloger/deb"
|
"github.com/anchore/syft/syft/cataloger/deb"
|
||||||
"github.com/anchore/syft/syft/cataloger/golang"
|
"github.com/anchore/syft/syft/cataloger/golang"
|
||||||
"github.com/anchore/syft/syft/cataloger/java"
|
"github.com/anchore/syft/syft/cataloger/java"
|
||||||
"github.com/anchore/syft/syft/cataloger/javascript"
|
"github.com/anchore/syft/syft/cataloger/javascript"
|
||||||
"github.com/anchore/syft/syft/cataloger/python"
|
"github.com/anchore/syft/syft/cataloger/python"
|
||||||
"github.com/anchore/syft/syft/cataloger/rpmdb"
|
"github.com/anchore/syft/syft/cataloger/rpmdb"
|
||||||
|
"github.com/anchore/syft/syft/cataloger/ruby"
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
"github.com/anchore/syft/syft/scope"
|
"github.com/anchore/syft/syft/scope"
|
||||||
)
|
)
|
||||||
@ -36,7 +36,7 @@ type Cataloger interface {
|
|||||||
// ImageCatalogers returns a slice of locally implemented catalogers that are fit for detecting installations of packages.
|
// ImageCatalogers returns a slice of locally implemented catalogers that are fit for detecting installations of packages.
|
||||||
func ImageCatalogers() []Cataloger {
|
func ImageCatalogers() []Cataloger {
|
||||||
return []Cataloger{
|
return []Cataloger{
|
||||||
bundler.NewGemSpecCataloger(),
|
ruby.NewGemSpecCataloger(),
|
||||||
python.NewPythonCataloger(), // TODO: split and replace me
|
python.NewPythonCataloger(), // TODO: split and replace me
|
||||||
javascript.NewJavascriptCataloger(), // TODO: split and replace me
|
javascript.NewJavascriptCataloger(), // TODO: split and replace me
|
||||||
deb.NewDpkgdbCataloger(),
|
deb.NewDpkgdbCataloger(),
|
||||||
@ -50,7 +50,7 @@ func ImageCatalogers() []Cataloger {
|
|||||||
// DirectoryCatalogers returns a slice of locally implemented catalogers that are fit for detecting packages from index files (and select installations)
|
// DirectoryCatalogers returns a slice of locally implemented catalogers that are fit for detecting packages from index files (and select installations)
|
||||||
func DirectoryCatalogers() []Cataloger {
|
func DirectoryCatalogers() []Cataloger {
|
||||||
return []Cataloger{
|
return []Cataloger{
|
||||||
bundler.NewGemFileLockCataloger(),
|
ruby.NewGemFileLockCataloger(),
|
||||||
python.NewPythonCataloger(), // TODO: split and replace me
|
python.NewPythonCataloger(), // TODO: split and replace me
|
||||||
javascript.NewJavascriptCataloger(), // TODO: split and replace me
|
javascript.NewJavascriptCataloger(), // TODO: split and replace me
|
||||||
deb.NewDpkgdbCataloger(),
|
deb.NewDpkgdbCataloger(),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Package bundler provides a concrete Cataloger implementation for Ruby Gemfile.lock bundler files.
|
Package bundler provides a concrete Cataloger implementation for Ruby Gemfile.lock bundler files.
|
||||||
*/
|
*/
|
||||||
package bundler
|
package ruby
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/anchore/syft/syft/cataloger/common"
|
"github.com/anchore/syft/syft/cataloger/common"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package bundler
|
package ruby
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package bundler
|
package ruby
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@ -1,11 +1,11 @@
|
|||||||
package bundler
|
package ruby
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
@ -48,6 +48,7 @@ var postProcessors = map[string]postProcessor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func processList(s string) []string {
|
func processList(s string) []string {
|
||||||
|
// nolint:prealloc
|
||||||
var results []string
|
var results []string
|
||||||
for _, item := range strings.Split(s, ",") {
|
for _, item := range strings.Split(s, ",") {
|
||||||
results = append(results, strings.Trim(item, "\" "))
|
results = append(results, strings.Trim(item, "\" "))
|
||||||
@ -106,47 +107,19 @@ func parseGemSpecEntries(_ string, reader io.Reader) ([]pkg.Package, error) {
|
|||||||
|
|
||||||
// renderUtf8 takes any string escaped string sub-sections from the ruby string and replaces those sections with the UTF8 runes.
|
// renderUtf8 takes any string escaped string sub-sections from the ruby string and replaces those sections with the UTF8 runes.
|
||||||
func renderUtf8(s string) string {
|
func renderUtf8(s string) string {
|
||||||
pattern := regexp.MustCompile(`\\u(?P<unicode>[0-9A-F]{4,8})`)
|
pattern := regexp.MustCompile(`\\u(?P<unicode>[0-9A-F]{4})`)
|
||||||
fullReplacement := replaceAllStringSubmatchFunc(pattern, s, func(unicodeSection []string) string {
|
fullReplacement := pattern.ReplaceAllStringFunc(s, func(unicodeSection string) string {
|
||||||
replacement := ""
|
var replacement string
|
||||||
if len(unicodeSection) == 1 {
|
// note: the json parser already has support for interpreting hex-representations of unicode escaped strings as unicode runes.
|
||||||
return unicodeSection[0]
|
// we can do this ourselves with strconv.Atoi, or leverage the existing json package.
|
||||||
}
|
if err := json.Unmarshal([]byte(`"`+unicodeSection+`"`), &replacement); err != nil {
|
||||||
for idx, m := range unicodeSection {
|
return unicodeSection
|
||||||
if idx == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
value, err := strconv.ParseInt(m, 16, 64)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: log?
|
|
||||||
panic(err)
|
|
||||||
//return unicodeSection[0]
|
|
||||||
}
|
|
||||||
replacement = strings.ReplaceAll(unicodeSection[0], "\\u"+m, string(rune(value)))
|
|
||||||
}
|
}
|
||||||
return replacement
|
return replacement
|
||||||
})
|
})
|
||||||
return fullReplacement
|
return fullReplacement
|
||||||
}
|
}
|
||||||
|
|
||||||
// replaceAllStringSubmatchFunc finds and replaces the given capture groups from the
|
|
||||||
func replaceAllStringSubmatchFunc(re *regexp.Regexp, str string, repl func([]string) string) string {
|
|
||||||
result := ""
|
|
||||||
lastIndex := 0
|
|
||||||
|
|
||||||
for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) {
|
|
||||||
var groups []string
|
|
||||||
for i := 0; i < len(v); i += 2 {
|
|
||||||
groups = append(groups, str[v[i]:v[i+1]])
|
|
||||||
}
|
|
||||||
|
|
||||||
result += str[lastIndex:v[0]] + repl(groups)
|
|
||||||
lastIndex = v[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
return result + str[lastIndex:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// matchCaptureGroups takes a regular expression and string and returns all of the named capture group results in a map.
|
// matchCaptureGroups takes a regular expression and string and returns all of the named capture group results in a map.
|
||||||
func matchCaptureGroups(regEx *regexp.Regexp, str string) map[string]string {
|
func matchCaptureGroups(regEx *regexp.Regexp, str string) map[string]string {
|
||||||
match := regEx.FindStringSubmatch(str)
|
match := regEx.FindStringSubmatch(str)
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package bundler
|
package ruby
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@ -19,7 +19,7 @@ func TestParseGemspec(t *testing.T) {
|
|||||||
Name: "bundler",
|
Name: "bundler",
|
||||||
Version: "2.1.4",
|
Version: "2.1.4",
|
||||||
Files: []string{"exe/bundle", "exe/bundler"},
|
Files: []string{"exe/bundle", "exe/bundler"},
|
||||||
Authors: []string{"André Arko", "Samuel Giddins", "Colby Swandale", "Hiroshi Shibata", "David Rodréguez", "Grey Baker", "Stephanie Morillo", "Chris Morris", "James Wen", "Tim Moore", "André Medeiros", "Jessica Lynn Suttles", "Terence Lee", "Carl Lerche", "Yehuda Katz"},
|
Authors: []string{"André Arko", "Samuel Giddins", "Colby Swandale", "Hiroshi Shibata", "David Rodríguez", "Grey Baker", "Stephanie Morillo", "Chris Morris", "James Wen", "Tim Moore", "André Medeiros", "Jessica Lynn Suttles", "Terence Lee", "Carl Lerche", "Yehuda Katz"},
|
||||||
Licenses: []string{"MIT"},
|
Licenses: []string{"MIT"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
type GemMetadata struct {
|
type GemMetadata struct {
|
||||||
Name string `mapstructure:"name" json:"name"`
|
Name string `mapstructure:"name" json:"name"`
|
||||||
Version string `mapstructure:"version" json:"version"`
|
Version string `mapstructure:"version" json:"version"`
|
||||||
Files []string `mapstructure:"files" json:"files"`
|
Files []string `mapstructure:"files" json:"files"`
|
||||||
Authors []string `mapstructure:"authors" json:"authors"`
|
Authors []string `mapstructure:"authors" json:"authors"`
|
||||||
Licenses []string `mapstructure:"licenses" json:"licenses"`
|
Licenses []string `mapstructure:"licenses" json:"licenses"`
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user