Skip to content

Commit

Permalink
Add cargo parser (aquasecurity#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
masahiro331 authored and knqyf263 committed May 11, 2019
1 parent c377a53 commit d5d543b
Show file tree
Hide file tree
Showing 8 changed files with 1,607 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -3,6 +3,7 @@ module github.com/knqyf263/go-dep-parser
go 1.12

require (
github.com/BurntSushi/toml v0.3.1
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373
)
3 changes: 3 additions & 0 deletions go.sum
@@ -1,3 +1,6 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373 h1:PPwnA7z1Pjf7XYaBP9GL1VAMZmcIWyFz7QCMSIIa3Bg=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
35 changes: 35 additions & 0 deletions pkg/cargo/parse.go
@@ -0,0 +1,35 @@
package cargo

import (
"io"

"github.com/BurntSushi/toml"
"github.com/knqyf263/go-dep-parser/pkg/types"
"golang.org/x/xerrors"
)

type Lockfile struct {
Packages []struct {
Name string `toml:"name"`
Version string `toml:"version"`
Source string `toml:"source,omitempty"`
Dependencies []string `toml:"dependencies,omitempty"`
} `toml:"package"`
Metadata interface{}
}

func Parse(r io.Reader) ([]types.Library, error) {
var lockfile Lockfile
if _, err := toml.DecodeReader(r, &lockfile); err != nil {
return nil, xerrors.Errorf("decode error: %w", err)
}

var libs []types.Library
for _, pkg := range lockfile.Packages {
libs = append(libs, types.Library{
Name: pkg.Name,
Version: pkg.Version,
})
}
return libs, nil
}
75 changes: 75 additions & 0 deletions pkg/cargo/parse_test.go
@@ -0,0 +1,75 @@
package cargo

import (
"os"
"path"
"sort"
"strings"
"testing"

"github.com/knqyf263/go-dep-parser/pkg/types"
"github.com/kylelemons/godebug/pretty"
)

func TestParse(t *testing.T) {
vectors := []struct {
file string // Test input file
libraries []types.Library
}{
{
file: "testdata/cargo_normal.lock",
libraries: CargoNormal,
},
{
file: "testdata/cargo_many.lock",
libraries: CargoMany,
},
{
file: "testdata/cargo_nickel.lock",
libraries: CargoNickel,
},
}

for _, v := range vectors {
t.Run(path.Base(v.file), func(t *testing.T) {
f, err := os.Open(v.file)
if err != nil {
t.Fatalf("Open() error: %v", err)
}
libList, err := Parse(f)
if err != nil {
t.Fatalf("Parse() error: %v", err)
}

sort.Slice(libList, func(i, j int) bool {
ret := strings.Compare(libList[i].Name, libList[j].Name)
if ret == 0 {
return libList[i].Version < libList[j].Version
}
return ret < 0
})

sort.Slice(v.libraries, func(i, j int) bool {
ret := strings.Compare(v.libraries[i].Name, v.libraries[j].Name)
if ret == 0 {
return v.libraries[i].Version < v.libraries[j].Version
}
return ret < 0
})

if len(libList) != len(v.libraries) {
t.Fatalf("lib length: %s", pretty.Compare(libList, v.libraries))
}

for i, got := range libList {
want := v.libraries[i]
if want.Name != got.Name {
t.Errorf("%d: Name: got %s, want %s", i, got.Name, want.Name)
}
if want.Version != got.Version {
t.Errorf("%d: Version: got %s, want %s", i, got.Version, want.Version)
}
}
})
}
}
187 changes: 187 additions & 0 deletions pkg/cargo/parse_testcase.go
@@ -0,0 +1,187 @@
package cargo

import "github.com/knqyf263/go-dep-parser/pkg/types"

var (
// docker run --name cargo --rm -it rust:1.34 bash
// export USER=cargo
// cargo install cargo-edit
// cargo init normal
// cargo add libc
// cargo update
// cat Cargo.lock| grep checksum | awk '{printf("{\""$2"\", \""$3"\"},\n")}'
// # Add normal package {"normal", "0.1.0"},
CargoNormal = []types.Library{
{"normal", "0.1.0"},
{"libc", "0.2.54"},
}

// docker run --name cargo --rm -it rust:1.34 bash
// export USER=cargo
// cargo install cargo-edit
// cargo init many
// cargo add rand bitflags lazy_static log serde syn regex quote handlebars rocket
// cargo update
// cat Cargo.lock| grep checksum | awk '{printf("{\""$2"\", \""$3"\"},\n")}'
// # Add many package {"many", "0.1.0"},
CargoMany = []types.Library{
{"many", "0.1.0"},
{"aho-corasick", "0.7.3"},
{"autocfg", "0.1.2"},
{"base64", "0.10.1"},
{"base64", "0.9.3"},
{"bitflags", "1.0.4"},
{"block-buffer", "0.7.3"},
{"block-padding", "0.1.4"},
{"byte-tools", "0.3.1"},
{"byteorder", "1.3.1"},
{"cc", "1.0.36"},
{"cfg-if", "0.1.7"},
{"cloudabi", "0.0.3"},
{"cookie", "0.11.1"},
{"devise", "0.2.0"},
{"devise_codegen", "0.2.0"},
{"devise_core", "0.2.0"},
{"digest", "0.8.0"},
{"fake-simd", "0.1.2"},
{"fuchsia-cprng", "0.1.1"},
{"generic-array", "0.12.0"},
{"handlebars", "1.1.0"},
{"httparse", "1.3.3"},
{"hyper", "0.10.16"},
{"idna", "0.1.5"},
{"indexmap", "1.0.2"},
{"isatty", "0.1.9"},
{"itoa", "0.4.4"},
{"language-tags", "0.2.2"},
{"lazy_static", "1.3.0"},
{"libc", "0.2.54"},
{"log", "0.3.9"},
{"log", "0.4.6"},
{"maplit", "1.0.1"},
{"matches", "0.1.8"},
{"memchr", "2.2.0"},
{"mime", "0.2.6"},
{"num_cpus", "1.10.0"},
{"opaque-debug", "0.2.2"},
{"pear", "0.1.2"},
{"pear_codegen", "0.1.2"},
{"percent-encoding", "1.0.1"},
{"pest", "2.1.1"},
{"pest_derive", "2.1.0"},
{"pest_generator", "2.1.0"},
{"pest_meta", "2.1.1"},
{"proc-macro2", "0.4.30"},
{"quick-error", "1.2.2"},
{"quote", "0.6.12"},
{"rand", "0.6.5"},
{"rand_chacha", "0.1.1"},
{"rand_core", "0.3.1"},
{"rand_core", "0.4.0"},
{"rand_hc", "0.1.0"},
{"rand_isaac", "0.1.1"},
{"rand_jitter", "0.1.4"},
{"rand_os", "0.1.3"},
{"rand_pcg", "0.1.2"},
{"rand_xorshift", "0.1.1"},
{"rdrand", "0.4.0"},
{"redox_syscall", "0.1.54"},
{"regex", "1.1.6"},
{"regex-syntax", "0.6.6"},
{"ring", "0.13.5"},
{"rocket", "0.4.0"},
{"rocket_codegen", "0.4.0"},
{"rocket_http", "0.4.0"},
{"ryu", "0.2.8"},
{"safemem", "0.3.0"},
{"same-file", "1.0.4"},
{"serde", "1.0.91"},
{"serde_json", "1.0.39"},
{"sha-1", "0.8.1"},
{"smallvec", "0.6.9"},
{"state", "0.4.1"},
{"syn", "0.15.34"},
{"thread_local", "0.3.6"},
{"time", "0.1.42"},
{"toml", "0.4.10"},
{"traitobject", "0.1.0"},
{"typeable", "0.1.2"},
{"typenum", "1.10.0"},
{"ucd-trie", "0.1.1"},
{"ucd-util", "0.1.3"},
{"unicase", "1.4.2"},
{"unicode-bidi", "0.3.4"},
{"unicode-normalization", "0.1.8"},
{"unicode-xid", "0.1.0"},
{"untrusted", "0.6.2"},
{"url", "1.7.2"},
{"utf8-ranges", "1.0.2"},
{"version_check", "0.1.5"},
{"walkdir", "2.2.7"},
{"winapi", "0.3.7"},
{"winapi-i686-pc-windows-gnu", "0.4.0"},
{"winapi-util", "0.1.2"},
{"winapi-x86_64-pc-windows-gnu", "0.4.0"},
{"yansi", "0.4.0"},
{"yansi", "0.5.0"},
}

// docker run --name cargo --rm -it rust:1.34 bash
// export USER=cargo
// cargo install cargo-edit
// cargo init web
// cargo add nickel
// cargo update
// cat Cargo.lock| grep checksum | awk '{printf("{\""$2"\", \""$3"\"},\n")}'
// # Add web package {"web", "0.1.0"},
CargoNickel = []types.Library{
{"web", "0.1.0"},
{"aho-corasick", "0.7.3"},
{"base64", "0.9.3"},
{"byteorder", "1.3.1"},
{"cfg-if", "0.1.7"},
{"groupable", "0.2.0"},
{"httparse", "1.3.3"},
{"hyper", "0.10.16"},
{"idna", "0.1.5"},
{"itoa", "0.4.4"},
{"language-tags", "0.2.2"},
{"lazy_static", "1.3.0"},
{"libc", "0.2.54"},
{"log", "0.3.9"},
{"log", "0.4.6"},
{"matches", "0.1.8"},
{"memchr", "2.2.0"},
{"mime", "0.2.6"},
{"modifier", "0.1.0"},
{"mustache", "0.9.0"},
{"nickel", "0.11.0"},
{"num_cpus", "1.10.0"},
{"percent-encoding", "1.0.1"},
{"plugin", "0.2.6"},
{"redox_syscall", "0.1.54"},
{"regex", "1.1.6"},
{"regex-syntax", "0.6.6"},
{"ryu", "0.2.8"},
{"safemem", "0.3.0"},
{"serde", "1.0.91"},
{"serde_json", "1.0.39"},
{"smallvec", "0.6.9"},
{"thread_local", "0.3.6"},
{"time", "0.1.42"},
{"traitobject", "0.1.0"},
{"typeable", "0.1.2"},
{"typemap", "0.3.3"},
{"ucd-util", "0.1.3"},
{"unicase", "1.4.2"},
{"unicode-bidi", "0.3.4"},
{"unicode-normalization", "0.1.8"},
{"unsafe-any", "0.4.2"},
{"url", "1.7.2"},
{"utf8-ranges", "1.0.2"},
{"version_check", "0.1.5"},
{"winapi", "0.3.7"},
{"winapi-i686-pc-windows-gnu", "0.4.0"},
{"winapi-x86_64-pc-windows-gnu", "0.4.0"},
}
)

0 comments on commit d5d543b

Please sign in to comment.