@@ -159,23 +159,43 @@ func (s *CVE) removeLegacyFeeds() error {
159159 return nil
160160}
161161
162+ func parseAndFormatForNVD (raw string ) (string , error ) {
163+ raw = strings .TrimSpace (raw )
164+
165+ // Try parsing with timezone
166+ if t , err := time .Parse (time .RFC3339Nano , raw ); err == nil {
167+ return t .UTC ().Format ("2006-01-02T15:04:05.000Z" ), nil
168+ }
169+
170+ // Try parsing without timezone
171+ if t , err := time .Parse ("2006-01-02T15:04:05.000" , raw ); err == nil {
172+ return t .UTC ().Format ("2006-01-02T15:04:05.000Z" ), nil
173+ }
174+
175+ return "" , fmt .Errorf ("unrecognized timestamp format: %q" , raw )
176+ }
177+
162178// update downloads all the new CVE updates since the last synchronization.
163179func (s * CVE ) update (ctx context.Context ) error {
164180 // Load the lastModStartDate from the previous synchronization.
165181 lastModStartDate_ , err := os .ReadFile (s .lastModStartDateFilePath ())
166182 if err != nil {
167183 return err
168184 }
169- lastModStartDate := string (lastModStartDate_ )
185+
186+ lastModStartDate , err := parseAndFormatForNVD (string (lastModStartDate_ ))
187+ if err != nil {
188+ return fmt .Errorf ("invalid last_mod_start_date.txt format: %w" , err )
189+ }
170190
171191 // Get the new CVE updates since the previous synchronization.
172- lastModStartDate , err = s .sync (ctx , & lastModStartDate )
192+ newLastModStartDate , err : = s .sync (ctx , & lastModStartDate )
173193 if err != nil {
174194 return err
175195 }
176196
177197 // Update the lastModStartDate for the next synchronization.
178- if err := s .writeLastModStartDateFile (lastModStartDate ); err != nil {
198+ if err := s .writeLastModStartDateFile (newLastModStartDate ); err != nil {
179199 return err
180200 }
181201
@@ -312,14 +332,16 @@ func (s *CVE) updateVulnCheckYearFile(year int, cves []VulnCheckCVE, modCount, a
312332
313333// writeLastModStartDateFile writes the lastModStartDate to a file in the local DB directory.
314334func (s * CVE ) writeLastModStartDateFile (lastModStartDate string ) error {
315- if err := os .WriteFile (
316- s .lastModStartDateFilePath (),
317- []byte (lastModStartDate ),
318- constant .DefaultWorldReadableFileMode ,
319- ); err != nil {
335+ normalized , err := parseAndFormatForNVD (lastModStartDate )
336+ if err != nil {
320337 return err
321338 }
322- return nil
339+
340+ return os .WriteFile (
341+ s .lastModStartDateFilePath (),
342+ []byte (normalized ),
343+ constant .DefaultWorldReadableFileMode ,
344+ )
323345}
324346
325347// httpClient wraps an http.Client to allow for debug and setting a request context.
@@ -374,7 +396,7 @@ func (s *CVE) sync(ctx context.Context, lastModStartDate *string) (newLastModSta
374396 cvesByYear = make (map [int ][]nvdapi.CVEItem )
375397 retryAttempts = 0
376398 lastModEndDate * string
377- now = time .Now ().UTC ().Format ("2006-01-02T15:04:05.000 " )
399+ now = time .Now ().UTC ().Format ("2006-01-02T15:04:05.000Z " )
378400 vulnerabilitiesReceived = 0
379401 )
380402 if lastModStartDate != nil {
0 commit comments