Skip to content

Commit

Permalink
Use github.com/haya14busa/go-sarif for sarif struct
Browse files Browse the repository at this point in the history
  • Loading branch information
haya14busa committed Jun 16, 2024
1 parent 03193ff commit 52abe98
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 108 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ require (
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/haya14busa/go-sarif v0.0.0-20210102043135-e2c5fed2fa3d // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/prometheus v2.5.0+incompatible // indirect
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/haya14busa/go-actions-toolkit v0.0.0-20200105081403-ca0307860f01 h1:HiJF8Mek+I7PY0Bm+SuhkwaAZSZP83sw6rrTMrgZ0io=
github.com/haya14busa/go-actions-toolkit v0.0.0-20200105081403-ca0307860f01/go.mod h1:1DWDZmeYf0LX30zscWb7K9rUMeirNeBMd5Dum+seUhc=
github.com/haya14busa/go-checkstyle v0.0.0-20170303121022-5e9d09f51fa1/go.mod h1:RsN5RGgVYeXpcXNtWyztD5VIe7VNSEqpJvF2iEH7QvI=
github.com/haya14busa/go-sarif v0.0.0-20210102043135-e2c5fed2fa3d h1:2uCbyMhWNFYI+HkRqXfIeTq5pTPxQM68yG+INJ2gvq8=
github.com/haya14busa/go-sarif v0.0.0-20210102043135-e2c5fed2fa3d/go.mod h1:1Hkn3JseGMB/hv1ywzkapVQDWV3bFgp6POZobZmR/5g=
github.com/haya14busa/secretbox v0.0.0-20180525171038-07c7ecf409f5 h1:ylgozezbuxA/i4uFtWCG/qGKYOZydsS8VUNNwfugn2Q=
github.com/haya14busa/secretbox v0.0.0-20180525171038-07c7ecf409f5/go.mod h1:FGO/dXIFZnan7KvvUSFk1hYMnoVNzB6NTMPrmke8SSI=
Expand Down
168 changes: 61 additions & 107 deletions parser/sarif.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"path/filepath"

"github.com/haya14busa/go-sarif/sarif"
"github.com/reviewdog/reviewdog/proto/rdf"
"github.com/reviewdog/reviewdog/service/serviceutil"
)
Expand All @@ -22,7 +23,7 @@ func NewSarifParser() Parser {
}

func (p *SarifParser) Parse(r io.Reader) ([]*rdf.Diagnostic, error) {
slf := new(SarifJson)
slf := new(sarif.Sarif)
if err := json.NewDecoder(r).Decode(slf); err != nil {
return nil, err
}
Expand All @@ -38,9 +39,12 @@ func (p *SarifParser) Parse(r io.Reader) ([]*rdf.Diagnostic, error) {
tool := run.Tool
driver := tool.Driver
name := driver.Name
informationURI := driver.InformationURI
baseURIs := run.OriginalURIBaseIds
rules := map[string]SarifRule{}
informationURI := ""
if driver.InformationURI != nil {
informationURI = *driver.InformationURI
}
baseURIs := run.OriginalURIBaseIDS
rules := map[string]sarif.ReportingDescriptor{}
for _, rule := range driver.Rules {
rules[rule.ID] = rule
}
Expand All @@ -49,32 +53,38 @@ func (p *SarifParser) Parse(r io.Reader) ([]*rdf.Diagnostic, error) {
if err != nil {
return nil, err
}
message := result.Message.GetText()
ruleID := result.RuleID
rule := rules[ruleID]
level := result.Level
if level == "" {
level = rule.DefaultConfiguration.Level
message := getText(result.Message)
rule := sarif.ReportingDescriptor{}
ruleID := ""
if result.RuleID != nil {
ruleID = *result.RuleID
}
rule = rules[ruleID]
level := ""
if result.Level != nil {
level = string(*result.Level)
} else if rule.DefaultConfiguration != nil && rule.DefaultConfiguration.Level != nil {
level = string(*rule.DefaultConfiguration.Level)
}
suggestionsMap := map[string][]*rdf.Suggestion{}
for _, fix := range result.Fixes {
for _, artifactChange := range fix.ArtifactChanges {
suggestions := []*rdf.Suggestion{}
path, err := artifactChange.ArtifactLocation.GetPath(baseURIs, basedir)
path, err := getPath(artifactChange.ArtifactLocation, baseURIs, basedir)
if err != nil {
// invalid path
return nil, err
}
for _, replacement := range artifactChange.Replacements {
deletedRegion := replacement.DeletedRegion
rng := deletedRegion.GetRdfRange()
if rng == nil {
rng := getRdfRange(deletedRegion)
if rng == nil || replacement.InsertedContent.Text == nil {
// No line information in fix
continue
}
s := &rdf.Suggestion{
Range: rng,
Text: replacement.InsertedContent.Text,
Text: *replacement.InsertedContent.Text,
}
suggestions = append(suggestions, s)
}
Expand All @@ -84,18 +94,27 @@ func (p *SarifParser) Parse(r io.Reader) ([]*rdf.Diagnostic, error) {
for _, location := range result.Locations {
physicalLocation := location.PhysicalLocation
artifactLocation := physicalLocation.ArtifactLocation
path, err := artifactLocation.GetPath(baseURIs, basedir)
loc := sarif.ArtifactLocation{}
if artifactLocation != nil {
loc = *artifactLocation
}
path, err := getPath(loc, baseURIs, basedir)
if err != nil {
// invalid path
return nil, err
}
region := physicalLocation.Region
rng := region.GetRdfRange()
region := sarif.Region{}
if physicalLocation.Region != nil {
region = *physicalLocation.Region
}
rng := getRdfRange(region)
var code *rdf.Code
if ruleID != "" {
code = &rdf.Code{
Value: ruleID,
Url: rule.HelpURI,
}
if rule.HelpURI != nil {
code.Url = *rule.HelpURI
}
}
d := &rdf.Diagnostic{
Expand All @@ -120,65 +139,22 @@ func (p *SarifParser) Parse(r io.Reader) ([]*rdf.Diagnostic, error) {
return ds, nil
}

// SARIF JSON Format
//
// References:
// - https://sarifweb.azurewebsites.net/
type SarifJson struct {
Runs []struct {
OriginalURIBaseIds map[string]SarifOriginalURI `json:"originalUriBaseIds"`
Results []struct {
Level string `json:"level,omitempty"`
Locations []struct {
PhysicalLocation struct {
ArtifactLocation SarifArtifactLocation `json:"artifactLocation,omitempty"`
Region SarifRegion `json:"region,omitempty"`
} `json:"physicalLocation,omitempty"`
} `json:"locations"`
Message SarifText `json:"message"`
RuleID string `json:"ruleId,omitempty"`
Fixes []struct {
Description SarifText `json:"description"`
ArtifactChanges []struct {
ArtifactLocation SarifArtifactLocation `json:"artifactLocation,omitempty"`
Replacements []struct {
DeletedRegion SarifRegion `json:"deletedRegion"`
InsertedContent struct {
Text string `json:"text"`
} `json:"insertedContent,omitempty"`
} `json:"replacements"`
} `json:"artifactChanges"`
} `json:"fixes,omitempty"`
} `json:"results"`
Tool struct {
Driver struct {
FullName string `json:"fullName"`
InformationURI string `json:"informationUri"`
Name string `json:"name"`
Rules []SarifRule `json:"rules"`
} `json:"driver"`
} `json:"tool"`
} `json:"runs"`
}

type SarifOriginalURI struct {
URI string `json:"uri"`
}

type SarifArtifactLocation struct {
URI string `json:"uri,omitempty"`
URIBaseID string `json:"uriBaseId"`
Index int `json:"index,omitempty"`
}

func (l *SarifArtifactLocation) GetPath(
baseURIs map[string]SarifOriginalURI,
func getPath(
l sarif.ArtifactLocation,
baseURIs map[string]sarif.ArtifactLocation,
basedir string,
) (string, error) {
uri := l.URI
baseURI := baseURIs[l.URIBaseID].URI
if baseURI != "" {
if u, err := url.JoinPath(baseURI, uri); err == nil {
uri := ""
if l.URI != nil {
uri = *l.URI
}
urlBaseID := ""
if l.URIBaseID != nil {
urlBaseID = *l.URIBaseID
}
baseURI := baseURIs[urlBaseID].URI
if baseURI != nil && *baseURI != "" {
if u, err := url.JoinPath(*baseURI, uri); err == nil {
uri = u
}
}
Expand All @@ -193,26 +169,17 @@ func (l *SarifArtifactLocation) GetPath(
return path, nil
}

type SarifText struct {
Text string `json:"text,omitempty"`
Markdown *string `json:"markdown,omitempty"`
}

func (t *SarifText) GetText() string {
text := t.Text
if t.Markdown != nil {
text = *t.Markdown
func getText(msg sarif.Message) string {
text := ""
if msg.Text != nil {
text = *msg.Text
}
if msg.Markdown != nil {
text = *msg.Markdown
}
return text
}

type SarifRegion struct {
StartLine *int `json:"startLine"`
StartColumn *int `json:"startColumn,omitempty"`
EndLine *int `json:"endLine,omitempty"`
EndColumn *int `json:"endColumn,omitempty"`
}

// convert SARIF Region to RDF Range
//
// * Supported SARIF: Line + Column Text region
Expand Down Expand Up @@ -277,21 +244,21 @@ type SarifRegion struct {
// -> RDF: { "start": { "line": 1, "column": 1 } }
//
// = { "start": { "line": 1, "column": 1 }, "end": { "line": 1, "column": 1 } }
func (r *SarifRegion) GetRdfRange() *rdf.Range {
func getRdfRange(r sarif.Region) *rdf.Range {
if r.StartLine == nil {
// No line information
return nil
}
startLine := *r.StartLine
startColumn := 1 // default value of startColumn in SARIF is 1
var startColumn int64 = 1 // default value of startColumn in SARIF is 1
if r.StartColumn != nil {
startColumn = *r.StartColumn
}
endLine := startLine // default value of endLine in SARIF is startLine
if r.EndLine != nil {
endLine = *r.EndLine
}
endColumn := 0 // default value of endColumn in SARIF is null (that means EOL)
var endColumn int64 = 0 // default value of endColumn in SARIF is null (that means EOL)
if r.EndColumn != nil {
endColumn = *r.EndColumn
}
Expand Down Expand Up @@ -336,16 +303,3 @@ func (r *SarifRegion) GetRdfRange() *rdf.Range {
}
return rng
}

type SarifRule struct {
ID string `json:"id"`
Name string `json:"name"`
ShortDescription SarifText `json:"shortDescription"`
FullDescription SarifText `json:"fullDescription"`
Help SarifText `json:"help"`
HelpURI string `json:"helpUri"`
DefaultConfiguration struct {
Level string `json:"level"`
Rank int `json:"rank"`
} `json:"defaultConfiguration"`
}
4 changes: 3 additions & 1 deletion parser/sarif_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ var fixtures = [][]string{{
{
"originalUriBaseIds": {
"SRCROOT": {
"description": "uri deleted root"
"description": {
"text": "uri deleted root"
}
}
},
"results": [
Expand Down

0 comments on commit 52abe98

Please sign in to comment.