Skip to content

Commit 44d9d50

Browse files
authored
Check column names in ScanCertStatusMetadataRow (letsencrypt#5776)
This ensures we queried the right set of columns, and didn't get them out of order.
1 parent 98d9a12 commit 44d9d50

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

sa/model.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,20 @@ func CertStatusMetadataFields() []string {
148148
// `CertStatusMetadataFields()`, and the `*core.CerticateStatus` field name
149149
// being copied to.
150150
func ScanCertStatusMetadataRow(rows *sql.Rows, status *CertStatusMetadata) error {
151-
err := rows.Scan(
151+
columns, err := rows.Columns()
152+
if err != nil {
153+
return err
154+
}
155+
expectedColumns := CertStatusMetadataFields()
156+
if len(columns) != len(expectedColumns) {
157+
return fmt.Errorf("incorrect number of columns in scanned rows: got %d, expected %d", len(columns), len(expectedColumns))
158+
}
159+
for i, v := range columns {
160+
if v != expectedColumns[i] {
161+
return fmt.Errorf("incorrect column %d in scanned rows: got %q, expected %q", i, v, expectedColumns[i])
162+
}
163+
}
164+
err = rows.Scan(
152165
&status.ID,
153166
&status.Serial,
154167
&status.Status,

sa/model_test.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,53 @@ func TestPopulateAttemptedFieldsBadJSON(t *testing.T) {
227227
}
228228
}
229229

230-
func TestCerficatesTableContainsDuplicateSerials(t *testing.T) {
230+
func TestScanCertStatusMetadataRow(t *testing.T) {
231+
sa, _, cleanUp := initSA(t)
232+
defer cleanUp()
233+
234+
inputStatus := core.CertificateStatus{
235+
Serial: "ff00ff00",
236+
Status: "good",
237+
}
238+
err := sa.dbMap.Insert(&inputStatus)
239+
test.AssertNotError(t, err, "couldn't insert certificateStatus")
240+
241+
rows, err := sa.dbMap.Query("SELECT serial, status, ocspLastUpdated FROM certificateStatus")
242+
test.AssertNotError(t, err, "selecting")
243+
244+
if !rows.Next() {
245+
t.Fatal("got no rows")
246+
}
247+
var certStatus CertStatusMetadata
248+
err = ScanCertStatusMetadataRow(rows, &certStatus)
249+
250+
if err == nil {
251+
t.Fatal("expected error, got none")
252+
}
253+
expected := "incorrect number of columns in scanned rows: got 3, expected 10"
254+
if err.Error() != expected {
255+
t.Errorf("wrong error: got %q, expected %q", err, expected)
256+
}
257+
258+
rows, err = sa.dbMap.Query("SELECT id, status, serial, ocspLastUpdated, revokedDate, revokedReason, lastExpirationNagSent, notAfter, isExpired, issuerID FROM certificateStatus")
259+
test.AssertNotError(t, err, "selecting")
260+
261+
if !rows.Next() {
262+
t.Fatal("got no rows")
263+
}
264+
265+
err = ScanCertStatusMetadataRow(rows, &certStatus)
266+
267+
if err == nil {
268+
t.Fatal("expected error, got none")
269+
}
270+
expected = "incorrect column 1 in scanned rows: got \"status\", expected \"serial\""
271+
if err.Error() != expected {
272+
t.Errorf("wrong error: got %q, expected %q", err, expected)
273+
}
274+
}
275+
276+
func TestCertificatesTableContainsDuplicateSerials(t *testing.T) {
231277
sa, fc, cleanUp := initSA(t)
232278
defer cleanUp()
233279

0 commit comments

Comments
 (0)