mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2026-11-09 12:21:25 -10:00
Compare commits
2
Commits
feat/run-plan
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43ed8eb8fc | ||
|
|
ec6794c2b4 |
No files matched your search
@@ -38,14 +38,11 @@ func NewEntityParser(dir string) (*EntityParser, error) {
|
||||
return parser.ParseFile(fset, filename, src, parser.ParseComments)
|
||||
},
|
||||
}
|
||||
pkgs, err := packages.Load(cfg, ".")
|
||||
|
||||
pkg, err := loadPackage(cfg, ".")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(pkgs) == 0 {
|
||||
return nil, errors.New("no packages found")
|
||||
}
|
||||
pkg := pkgs[0]
|
||||
|
||||
return &EntityParser{
|
||||
syntax: pkg.Syntax,
|
||||
@@ -513,6 +510,7 @@ func (p *EntityParser) extractVarsNConstants() {
|
||||
|
||||
// loadImportedPackages loads all imported packages
|
||||
func (p *EntityParser) loadImportedPackages() error {
|
||||
cfg := &packages.Config{Mode: packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo}
|
||||
// get all import statements
|
||||
// iterate over all imports
|
||||
for _, file := range p.syntax {
|
||||
@@ -522,7 +520,7 @@ func (p *EntityParser) loadImportedPackages() error {
|
||||
// remove the quotes from the path
|
||||
path = path[1 : len(path)-1]
|
||||
// load the package
|
||||
pkg, err := loadPackage(path)
|
||||
pkg, err := loadPackage(cfg, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -543,18 +541,31 @@ func (p *EntityParser) loadImportedPackages() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Load the package containing the type definition
|
||||
// TODO: we don't support named imports yet
|
||||
func loadPackage(pkgPath string) (*packages.Package, error) {
|
||||
cfg := &packages.Config{Mode: packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo}
|
||||
pkgs, err := packages.Load(cfg, pkgPath)
|
||||
// loadPackage loads the package that pattern names.
|
||||
//
|
||||
// packages.Load reports parse, type, and list errors in Package.Errors
|
||||
// rather than in its returned error, so loadPackage converts them into an
|
||||
// error. The parser assumes a complete syntax tree and type information.
|
||||
func loadPackage(cfg *packages.Config, pattern string) (*packages.Package, error) {
|
||||
pkgs, err := packages.Load(cfg, pattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(pkgs) == 0 {
|
||||
return nil, errors.New("no packages found")
|
||||
}
|
||||
return pkgs[0], nil
|
||||
|
||||
pkg := pkgs[0]
|
||||
if len(pkg.Errors) > 0 {
|
||||
errs := make([]error, len(pkg.Errors))
|
||||
for i, e := range pkg.Errors {
|
||||
errs[i] = e
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("package %s: %w", pkg.ID, errors.Join(errs...))
|
||||
}
|
||||
|
||||
return pkg, nil
|
||||
}
|
||||
|
||||
// exprToString converts an expression to a string
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package tsgen
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
// writeModule writes src as the only package of a new Go module and
|
||||
// returns the module directory.
|
||||
func writeModule(t *testing.T, src string) string {
|
||||
t.Helper()
|
||||
|
||||
dir := t.TempDir()
|
||||
files := map[string]string{
|
||||
"go.mod": "module example.com/tsgentest\n\ngo 1.21\n",
|
||||
"example.go": src,
|
||||
}
|
||||
|
||||
for name, content := range files {
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dir, name), []byte(content), 0o600))
|
||||
}
|
||||
|
||||
return dir
|
||||
}
|
||||
|
||||
func TestNewEntityParser(t *testing.T) {
|
||||
const src = `package example
|
||||
|
||||
import "strings"
|
||||
|
||||
// Upper returns s in upper case.
|
||||
func Upper(s string) string { return strings.ToUpper(s) }
|
||||
`
|
||||
|
||||
p, err := NewEntityParser(writeModule(t, src))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, p.Parse())
|
||||
|
||||
entities := p.GetEntities()
|
||||
|
||||
names := make([]string, 0, len(entities))
|
||||
for _, e := range entities {
|
||||
names = append(names, e.Name)
|
||||
}
|
||||
|
||||
require.Contains(t, names, "Upper")
|
||||
}
|
||||
|
||||
func TestNewEntityParserPackageErrors(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
src string
|
||||
}{
|
||||
{name: "syntax error", src: "package example\n\nfunc Broken( {\n\treturn 42\n}\n"},
|
||||
{name: "type error", src: "package example\n\nfunc Broken() int { return undefined }\n"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := NewEntityParser(writeModule(t, tt.src))
|
||||
require.ErrorContains(t, err, "example.go:")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadImportedPackagesMissing(t *testing.T) {
|
||||
const src = `package example; import "example.com/tsgentest/missing"`
|
||||
|
||||
file, err := parser.ParseFile(token.NewFileSet(), "example.go", src, parser.ImportsOnly)
|
||||
require.NoError(t, err)
|
||||
p := &EntityParser{
|
||||
syntax: []*ast.File{file},
|
||||
imports: map[string]*packages.Package{},
|
||||
}
|
||||
|
||||
var pkgErr packages.Error
|
||||
|
||||
require.ErrorAs(t, p.loadImportedPackages(), &pkgErr)
|
||||
require.Contains(t, pkgErr.Msg, "example.com/tsgentest/missing")
|
||||
}
|
||||
Reference in new issue
Block a user