diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b1b645 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.xml +*.csv +vendor diff --git a/detailedreport/structs.go b/detailedreport/structs.go new file mode 100644 index 0000000..309d8c1 --- /dev/null +++ b/detailedreport/structs.go @@ -0,0 +1,27 @@ +package detailedreport + +type DetailedReport struct { + Severities []Severity `xml:"severity"` +} +type Severity struct { + Level string `xml:"level,attr"` + Categories []Category `xml:"category"` +} +type Category struct { + CWES []CWE `xml:"cwe"` +} +type CWE struct { + ID string `xml:"cweid,attr"` + Name string `xml:"cwename,attr"` + StaticFlaws StaticFlaws `xml:"staticflaws"` + Line string `xml:"line,attr"` +} +type StaticFlaws struct { + Flaws []Flaw `xml:"flaw"` +} +type Flaw struct { + ID string `xml:"issueid,attr"` + SourceFile string `xml:"sourcefile,attr"` + SourceFilePath string `xml:"sourcefilepath,attr"` + Module string `xml:"module,attr"` +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5ca2814 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/relaxnow/go-detailedreport-to-csv + +go 1.15 + +require ( + github.com/davecgh/go-spew v1.1.1 + golang.org/x/net v0.0.0-20200927032502-5d4f70055728 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..41c8656 --- /dev/null +++ b/go.sum @@ -0,0 +1,12 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200927032502-5d4f70055728 h1:5wtQIAulKU5AbLQOkjxl32UufnIOqgBX72pS0AV14H0= +golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/main.go b/main.go new file mode 100644 index 0000000..1ae4eac --- /dev/null +++ b/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "bytes" + "encoding/csv" + "encoding/xml" + "fmt" + "github.com/relaxnow/go-detailedreport-to-csv/detailedreport" + "golang.org/x/net/html/charset" + "io/ioutil" + "os" +) + + +func main() { + xmlFilePath := os.Args[1] + + // Open our xmlFile + xmlFile, err := os.Open(xmlFilePath) + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + fmt.Println("Successfully Opened " + xmlFilePath) + // defer the closing of our xmlFile so that we can parse it later on + defer xmlFile.Close() + + // read our opened xmlFile as a byte array. + byteValue, _ := ioutil.ReadAll(xmlFile) + + + // we initialize our Users array + var report detailedreport.DetailedReport + + reader := bytes.NewReader(byteValue) + decoder := xml.NewDecoder(reader) + decoder.CharsetReader = charset.NewReaderLabel + err = decoder.Decode(&report) + + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + //spew.Dump(report); + rows := [][]string{{"Flaw ID", "CWE ID", "CWE Name", "Module", "Source File", "Severity"}} + for i := 0; i < len(report.Severities); i++ { + var severity = report.Severities[i] + for j := 0; j < len(severity.Categories); j++ { + var category = severity.Categories[j]; + for k := 0; k < len(category.CWES); k++ { + var CWE = category.CWES[k]; + for l := 0; l < len(CWE.StaticFlaws.Flaws); l++ { + var flaw = CWE.StaticFlaws.Flaws[l]; + + rows = append(rows, []string{ + flaw.ID, + CWE.ID, + CWE.Name, + flaw.Module, + flaw.SourceFile, + severity.Level}) + } + } + } + } + + //spew.Dump(rows) + + csvfile,err := os.Create("output.csv") + + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + csvwriter := csv.NewWriter(csvfile) + csvwriter.Comma = ';' + + for _, row := range rows { + _ = csvwriter.Write(row) + } + + csvwriter.Flush() + + csvfile.Close() + fmt.Println("Wrote output.csv") + fmt.Println("All done") +}