@@ -4,7 +4,6 @@ package main
44import (
55 "crypto/rand"
66 "encoding/hex"
7- "encoding/json"
87 "flag"
98 "fmt"
109 "io"
@@ -17,9 +16,10 @@ import (
1716 "strings"
1817 "time"
1918
20- "github.com/google/osv-scanner/pkg/models "
19+ "github.com/goccy/go-yaml "
2120 "github.com/google/osv/vulnfeeds/utility/logger"
22- "gopkg.in/yaml.v2"
21+ "github.com/ossf/osv-schema/bindings/go/osvschema"
22+ "google.golang.org/protobuf/encoding/protojson"
2323)
2424
2525const (
@@ -112,16 +112,16 @@ func assignID(prefix, path string, format fileFormat, yearCounters map[int]int,
112112 // If the vulnerability has a published date, use the year from that.
113113 // Otherwise, just default to the current year.
114114 year := defaultYear
115- if ! vuln .Published . IsZero () {
116- year = vuln .Published .Year ()
115+ if vuln .GetPublished () != nil {
116+ year = vuln .GetPublished (). AsTime () .Year ()
117117 }
118118
119119 // Allocate a new ID and write the new file.
120120 id := yearCounters [year ] + 1
121121 yearCounters [year ] = id
122122
123- vuln .ID = fmt .Sprintf ("%s-%d-%d" , prefix , year , id )
124- newPath := filepath .Join (filepath .Dir (path ), vuln .ID + formatToExtension [format ])
123+ vuln .Id = fmt .Sprintf ("%s-%d-%d" , prefix , year , id )
124+ newPath := filepath .Join (filepath .Dir (path ), vuln .GetId () + formatToExtension [format ])
125125
126126 writef , err := os .Create (newPath )
127127 if err != nil {
@@ -193,37 +193,64 @@ func assignIDs(prefix, dir string, format fileFormat) error {
193193 return os .WriteFile (filepath .Join (dir , conflictFile ), []byte (hex .EncodeToString (b )), 0600 )
194194}
195195
196- func readVulnWithFormat (r io.Reader , format fileFormat ) (* models.Vulnerability , error ) {
197- var v models.Vulnerability
196+ func readVulnWithFormat (r io.Reader , format fileFormat ) (* osvschema.Vulnerability , error ) {
197+ data , err := io .ReadAll (r )
198+ if err != nil {
199+ return nil , err
200+ }
201+
202+ var jsonBytes []byte
198203 switch format {
199204 case fileFormatJSON :
200- dec := json .NewDecoder (r )
201- if err := dec .Decode (& v ); err != nil {
202- return nil , err
203- }
205+ jsonBytes = data
204206 case fileFormatYAML :
205- dec : = yaml .NewDecoder ( r )
206- if err := dec . Decode ( & v ); err != nil {
207+ jsonBytes , err = yaml .YAMLToJSON ( data )
208+ if err != nil {
207209 return nil , err
208210 }
209211 default :
210212 return nil , fmt .Errorf ("unknown file format: %v" , format )
211213 }
212214
215+ var v osvschema.Vulnerability
216+ if err := protojson .Unmarshal (jsonBytes , & v ); err != nil {
217+ return nil , err
218+ }
219+
213220 return & v , nil
214221}
215222
216- func writeVulnWithFormat (v * models.Vulnerability , w io.Writer , format fileFormat ) error {
223+ func writeVulnWithFormat (v * osvschema.Vulnerability , w io.Writer , format fileFormat ) error {
224+ marshaler := protojson.MarshalOptions {
225+ Multiline : true ,
226+ Indent : " " ,
227+ }
228+
229+ jsonBytes , err := marshaler .Marshal (v )
230+ if err != nil {
231+ return err
232+ }
233+
234+ var data []byte
217235 switch format {
218236 case fileFormatJSON :
219- enc := json .NewEncoder (w )
220- enc .SetIndent ("" , " " )
221-
222- return enc .Encode (v )
237+ data = jsonBytes
223238 case fileFormatYAML :
224- enc := yaml .NewEncoder (w )
225- return enc .Encode (v )
239+ data , err = yaml .JSONToYAML (jsonBytes )
240+ if err != nil {
241+ return err
242+ }
226243 default :
227244 return fmt .Errorf ("unknown file format: %v" , format )
228245 }
246+
247+ // Ensure the output has a trailing newline to match the behavior of
248+ // json.Encoder, which was previously used.
249+ if len (data ) > 0 && data [len (data )- 1 ] != '\n' {
250+ data = append (data , '\n' )
251+ }
252+
253+ _ , err = w .Write (data )
254+
255+ return err
229256}
0 commit comments