Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
16 changes: 13 additions & 3 deletions rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -937,9 +937,19 @@ func (ws *xlsxWorksheet) checkRow() error {
}
rowData.C[idx].R, _ = CoordinatesToCellName(rCount, rowIdx+1)
}
lastCol, _, err := CellNameToCoordinates(rowData.C[colCount-1].R)
if err != nil {
return err
// Cells are not guaranteed to be in ascending column order, so the
// highest column in the row is not necessarily the last element. Take
// the maximum, otherwise a cell that sorts later than the final element
// is scattered past the end of the rebuilt slice below.
var lastCol int
Comment thread
xuri marked this conversation as resolved.
Outdated
for cellIdx := range rowData.C {
colNum, _, err := CellNameToCoordinates(rowData.C[cellIdx].R)
if err != nil {
return err
Comment thread
xuri marked this conversation as resolved.
Outdated
}
if colNum > lastCol {
lastCol = colNum
}
}

if colCount < lastCol {
Expand Down
28 changes: 28 additions & 0 deletions rows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1267,3 +1267,31 @@ func trimSliceSpace(s []string) []string {
}
return s
}

func TestCheckRowOutOfOrderColumns(t *testing.T) {
// Cells are not always stored in ascending column order. Here Z1 precedes
// C1, so the highest column is not the last element and sizing the rebuilt
// slice from that element leaves Z1 without a slot.
ws := &xlsxWorksheet{}
ws.SheetData.Row = []xlsxRow{{
R: 1,
C: []xlsxC{{R: "Z1", V: "z"}, {R: "C1", V: "c"}},
}}
assert.NoError(t, ws.checkRow())
assert.Len(t, ws.SheetData.Row[0].C, 26)
assert.Equal(t, "z", ws.SheetData.Row[0].C[25].V)
assert.Equal(t, "c", ws.SheetData.Row[0].C[2].V)

// Reading such a sheet through the public API must not panic.
f := NewFile()
f.Sheet.Store("xl/worksheets/sheet1.xml", &xlsxWorksheet{
Comment thread
xuri marked this conversation as resolved.
Outdated
SheetData: xlsxSheetData{Row: []xlsxRow{{
R: 1,
C: []xlsxC{{R: "Z1", T: "str", V: "z"}, {R: "C1", T: "str", V: "c"}},
}}},
})
value, err := f.GetCellValue("Sheet1", "Z1")
assert.NoError(t, err)
assert.Equal(t, "z", value)
assert.NoError(t, f.Close())
}