Skip to content

Commit f537eab

Browse files
committed
Update the buildSSA to use the new tools package
Change-Id: I8e8be7a127c4d71ca3eee9ce37a058955d00bd26 Signed-off-by: Cosmin Cojocar <ccojocar@google.com>
1 parent ed925e0 commit f537eab

File tree

1 file changed

+60
-22
lines changed

1 file changed

+60
-22
lines changed

analyzer.go

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import (
3535

3636
"golang.org/x/tools/go/analysis"
3737
"golang.org/x/tools/go/analysis/passes/buildssa"
38+
"golang.org/x/tools/go/analysis/passes/ctrlflow"
39+
"golang.org/x/tools/go/analysis/passes/inspect"
3840
"golang.org/x/tools/go/packages"
3941

4042
"github.com/securego/gosec/v2/analyzers"
@@ -430,7 +432,7 @@ func (gosec *Analyzer) CheckAnalyzers(pkg *packages.Package) {
430432
buildssa.Analyzer: &analyzers.SSAAnalyzerResult{
431433
Config: gosec.Config(),
432434
Logger: gosec.logger,
433-
SSA: ssaResult.(*buildssa.SSA),
435+
SSA: ssaResult,
434436
},
435437
}
436438

@@ -491,7 +493,7 @@ func (gosec *Analyzer) generatedFiles(pkg *packages.Package) map[string]bool {
491493
}
492494

493495
// buildSSA runs the SSA pass which builds the SSA representation of the package. It handles gracefully any panic.
494-
func (gosec *Analyzer) buildSSA(pkg *packages.Package) (interface{}, error) {
496+
func (gosec *Analyzer) buildSSA(pkg *packages.Package) (*buildssa.SSA, error) {
495497
defer func() {
496498
if r := recover(); r != nil {
497499
gosec.logger.Printf(
@@ -500,26 +502,62 @@ func (gosec *Analyzer) buildSSA(pkg *packages.Package) (interface{}, error) {
500502
)
501503
}
502504
}()
503-
ssaPass := &analysis.Pass{
504-
Analyzer: buildssa.Analyzer,
505-
Fset: pkg.Fset,
506-
Files: pkg.Syntax,
507-
OtherFiles: pkg.OtherFiles,
508-
IgnoredFiles: pkg.IgnoredFiles,
509-
Pkg: pkg.Types,
510-
TypesInfo: pkg.TypesInfo,
511-
TypesSizes: pkg.TypesSizes,
512-
ResultOf: nil,
513-
Report: nil,
514-
ImportObjectFact: nil,
515-
ExportObjectFact: nil,
516-
ImportPackageFact: nil,
517-
ExportPackageFact: nil,
518-
AllObjectFacts: nil,
519-
AllPackageFacts: nil,
520-
}
521-
522-
return ssaPass.Analyzer.Run(ssaPass)
505+
if pkg == nil {
506+
return nil, errors.New("nil package provided")
507+
}
508+
if pkg.Types == nil {
509+
return nil, fmt.Errorf("package %s has no type information (compilation failed?)", pkg.Name)
510+
}
511+
if pkg.TypesInfo == nil {
512+
return nil, fmt.Errorf("package %s has no type information", pkg.Name)
513+
}
514+
// The SSA and CtrlFlow builders require architecture sizing (WordSize/MaxAlign).
515+
// If go/packages didn't provide it, we MUST provide a default to prevent panics.
516+
typesSizes := pkg.TypesSizes
517+
if typesSizes == nil {
518+
// Fallback to standard 64-bit sizes (WordSize: 8, MaxAlign: 8)
519+
// This is safe for most analysis contexts.
520+
typesSizes = &types.StdSizes{WordSize: 8, MaxAlign: 8}
521+
}
522+
pass := &analysis.Pass{
523+
Fset: pkg.Fset,
524+
Files: pkg.Syntax,
525+
OtherFiles: pkg.OtherFiles,
526+
IgnoredFiles: pkg.IgnoredFiles,
527+
Pkg: pkg.Types,
528+
TypesInfo: pkg.TypesInfo,
529+
TypesSizes: pkg.TypesSizes,
530+
ResultOf: make(map[*analysis.Analyzer]interface{}),
531+
Report: func(d analysis.Diagnostic) {},
532+
ImportObjectFact: func(obj types.Object, fact analysis.Fact) bool { return false },
533+
ExportObjectFact: func(obj types.Object, fact analysis.Fact) {},
534+
}
535+
536+
pass.Analyzer = inspect.Analyzer
537+
i, err := inspect.Analyzer.Run(pass)
538+
if err != nil {
539+
return nil, fmt.Errorf("running inspect analysis: %w", err)
540+
}
541+
pass.ResultOf[inspect.Analyzer] = i
542+
543+
pass.Analyzer = ctrlflow.Analyzer
544+
cf, err := ctrlflow.Analyzer.Run(pass)
545+
if err != nil {
546+
return nil, fmt.Errorf("running control flow analysis: %w", err)
547+
}
548+
pass.ResultOf[ctrlflow.Analyzer] = cf
549+
550+
pass.Analyzer = buildssa.Analyzer
551+
result, err := buildssa.Analyzer.Run(pass)
552+
if err != nil {
553+
return nil, fmt.Errorf("running SSA analysis: %w", err)
554+
}
555+
556+
ssaResult, ok := result.(*buildssa.SSA)
557+
if !ok {
558+
return nil, fmt.Errorf("unexpected SSA analysis result type: %T", result)
559+
}
560+
return ssaResult, nil
523561
}
524562

525563
// ParseErrors parses the errors from given package

0 commit comments

Comments
 (0)