Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 38 additions & 10 deletions internal/analyse/analyse.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import (
type NoteLevel string

const (
NoteLevelWarn NoteLevel = "warn"
NoteLevelError NoteLevel = "error"
NoteLevelWarn NoteLevel = "warn"
NoteLevelError NoteLevel = "error"
fingerprintHeader = "SHA-256 Fingerprint"
commentsHeader = "Comments"
)

type Note struct {
Expand Down Expand Up @@ -53,20 +55,46 @@ func downloadMozillaRemovedCACertsList() ([]removedCertificate, error) {
return nil, err
}
csvReader := csv.NewReader(resp.Body)
csvLines, err := csvReader.ReadAll()
// Read the header first
headers, err := csvReader.Read()
if err != nil {
return nil, err
}

removedCerts := make([]removedCertificate, len(csvLines))
for i, csvLine := range csvLines {
removedCerts[i] = removedCertificate{
// From the CSV format that Mozilla publishes, the 8th column (id 7) is the fingerprint and the 23rd column
// (id 22) is the comment.
Fingerprint: csvLine[7],
Comments: csvLine[22],
// Find column indices by their names from the header
fingerprint := -1
comments := -1
for idx, header := range headers {
switch header {
case fingerprintHeader:
fingerprint = idx
case commentsHeader:
comments = idx
}
}

if fingerprint == -1 {
return nil, fmt.Errorf("required column 'SHA-256 Fingerprint' not found in CSV header")
}
if comments == -1 {
return nil, fmt.Errorf("required column 'Comments' not found in CSV header")
}

// Now process each line individually instead of loading everything into memory
var removedCerts []removedCertificate
for {
record, err := csvReader.Read()
if err != nil {
break // End of file or other error
}

removedCerts = append(removedCerts, removedCertificate{
Fingerprint: record[fingerprint],
Comments: record[comments],
})
}

// All CSV processing is done in the loop above, we already have the removedCerts slice
return removedCerts, nil
}

Expand Down
Loading