|
|
@@ -13,6 +13,20 @@ type LibSuite struct{}
|
|
|
|
|
|
var _ = Suite(&LibSuite{})
|
|
|
|
|
|
+// Attempting to open a file without workbook.xml.rels returns an error.
|
|
|
+func (l *LibSuite) TestReadZipReaderWithFileWithNoWorkbookRels(c *C) {
|
|
|
+ _, err := OpenFile("./testdocs/badfile_noWorkbookRels.xlsx")
|
|
|
+ c.Assert(err, NotNil)
|
|
|
+ c.Assert(err.Error(), Equals, "xl/_rels/workbook.xml.rels not found in input xlsx.")
|
|
|
+}
|
|
|
+
|
|
|
+// Attempting to open a file with no worksheets returns an error.
|
|
|
+func (l *LibSuite) TestReadZipReaderWithFileWithNoWorksheets(c *C) {
|
|
|
+ _, err := OpenFile("./testdocs/badfile_noWorksheets.xlsx")
|
|
|
+ c.Assert(err, NotNil)
|
|
|
+ c.Assert(err.Error(), Equals, "Input xlsx contains no worksheets.")
|
|
|
+}
|
|
|
+
|
|
|
// which they are contained from the XLSX file, even when the
|
|
|
// worksheet files have arbitrary, non-numeric names.
|
|
|
func (l *LibSuite) TestReadWorkbookRelationsFromZipFileWithFunnyNames(c *C) {
|
|
|
@@ -225,18 +239,23 @@ func (l *LibSuite) TestMakeRowFromSpan(c *C) {
|
|
|
var rangeString string
|
|
|
var row *Row
|
|
|
var length int
|
|
|
+ var sheet *Sheet
|
|
|
+ sheet = new(Sheet)
|
|
|
rangeString = "1:3"
|
|
|
- row = makeRowFromSpan(rangeString)
|
|
|
+ row = makeRowFromSpan(rangeString, sheet)
|
|
|
length = len(row.Cells)
|
|
|
c.Assert(length, Equals, 3)
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
rangeString = "5:7" // Note - we ignore lower bound!
|
|
|
- row = makeRowFromSpan(rangeString)
|
|
|
+ row = makeRowFromSpan(rangeString, sheet)
|
|
|
length = len(row.Cells)
|
|
|
c.Assert(length, Equals, 7)
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
rangeString = "1:1"
|
|
|
- row = makeRowFromSpan(rangeString)
|
|
|
+ row = makeRowFromSpan(rangeString, sheet)
|
|
|
length = len(row.Cells)
|
|
|
c.Assert(length, Equals, 1)
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
}
|
|
|
|
|
|
func (l *LibSuite) TestReadRowsFromSheet(c *C) {
|
|
|
@@ -300,10 +319,12 @@ func (l *LibSuite) TestReadRowsFromSheet(c *C) {
|
|
|
c.Assert(err, IsNil)
|
|
|
file := new(File)
|
|
|
file.referenceTable = MakeSharedStringRefTable(sst)
|
|
|
- rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
|
|
|
c.Assert(maxRows, Equals, 2)
|
|
|
c.Assert(maxCols, Equals, 2)
|
|
|
row := rows[0]
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
c.Assert(len(row.Cells), Equals, 2)
|
|
|
cell1 := row.Cells[0]
|
|
|
c.Assert(cell1.Value, Equals, "Foo")
|
|
|
@@ -321,6 +342,79 @@ func (l *LibSuite) TestReadRowsFromSheet(c *C) {
|
|
|
c.Assert(pane.YSplit, Equals, 1.0)
|
|
|
}
|
|
|
|
|
|
+// An invalid value in the "r" attribute in a <row> was causing a panic
|
|
|
+// in readRowsFromSheet. This test is a copy of TestReadRowsFromSheet,
|
|
|
+// with the important difference of the value 1048576 below in <row r="1048576", which is
|
|
|
+// higher than the number of rows in the sheet. That number itself isn't significant;
|
|
|
+// it just happens to be the value found to trigger the error in a user's file.
|
|
|
+func (l *LibSuite) TestReadRowsFromSheetBadR(c *C) {
|
|
|
+ var sharedstringsXML = bytes.NewBufferString(`
|
|
|
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
|
+<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="4" uniqueCount="4">
|
|
|
+ <si>
|
|
|
+ <t>Foo</t>
|
|
|
+ </si>
|
|
|
+ <si>
|
|
|
+ <t>Bar</t>
|
|
|
+ </si>
|
|
|
+ <si>
|
|
|
+ <t xml:space="preserve">Baz </t>
|
|
|
+ </si>
|
|
|
+ <si>
|
|
|
+ <t>Quuk</t>
|
|
|
+ </si>
|
|
|
+</sst>`)
|
|
|
+ var sheetxml = bytes.NewBufferString(`
|
|
|
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
|
+<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
|
+ xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
|
+ <dimension ref="A1:B2"/>
|
|
|
+ <sheetViews>
|
|
|
+ <sheetView tabSelected="1" workbookViewId="0">
|
|
|
+ <selection activeCell="C2" sqref="C2"/>
|
|
|
+ <pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/>
|
|
|
+ </sheetView>
|
|
|
+ </sheetViews>
|
|
|
+ <sheetFormatPr baseColWidth="10" defaultRowHeight="15"/>
|
|
|
+ <sheetData>
|
|
|
+ <row r="1" spans="1:2">
|
|
|
+ <c r="A1" t="s">
|
|
|
+ <v>0</v>
|
|
|
+ </c>
|
|
|
+ <c r="B1" t="s">
|
|
|
+ <v>1</v>
|
|
|
+ </c>
|
|
|
+ </row>
|
|
|
+ <row r="1048576" spans="1:2">
|
|
|
+ <c r="A2" t="s">
|
|
|
+ <v>2</v>
|
|
|
+ </c>
|
|
|
+ <c r="B2" t="s">
|
|
|
+ <v>3</v>
|
|
|
+ </c>
|
|
|
+ </row>
|
|
|
+ </sheetData>
|
|
|
+ <pageMargins left="0.7" right="0.7"
|
|
|
+ top="0.78740157499999996"
|
|
|
+ bottom="0.78740157499999996"
|
|
|
+ header="0.3"
|
|
|
+ footer="0.3"/>
|
|
|
+</worksheet>`)
|
|
|
+ worksheet := new(xlsxWorksheet)
|
|
|
+ err := xml.NewDecoder(sheetxml).Decode(worksheet)
|
|
|
+ c.Assert(err, IsNil)
|
|
|
+ sst := new(xlsxSST)
|
|
|
+ err = xml.NewDecoder(sharedstringsXML).Decode(sst)
|
|
|
+ c.Assert(err, IsNil)
|
|
|
+ file := new(File)
|
|
|
+ file.referenceTable = MakeSharedStringRefTable(sst)
|
|
|
+
|
|
|
+ sheet := new(Sheet)
|
|
|
+ // Discarding all return values; this test is a regression for
|
|
|
+ // a panic due to an "index out of range."
|
|
|
+ readRowsFromSheet(worksheet, file, sheet)
|
|
|
+}
|
|
|
+
|
|
|
func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyRows(c *C) {
|
|
|
var sharedstringsXML = bytes.NewBufferString(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
|
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="2" uniqueCount="2"><si><t>ABC</t></si><si><t>DEF</t></si></sst>`)
|
|
|
@@ -363,7 +457,8 @@ func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyRows(c *C) {
|
|
|
|
|
|
file := new(File)
|
|
|
file.referenceTable = MakeSharedStringRefTable(sst)
|
|
|
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
|
|
|
c.Assert(maxRows, Equals, 5)
|
|
|
c.Assert(maxCols, Equals, 1)
|
|
|
|
|
|
@@ -420,7 +515,8 @@ func (l *LibSuite) TestReadRowsFromSheetWithLeadingEmptyCols(c *C) {
|
|
|
|
|
|
file := new(File)
|
|
|
file.referenceTable = MakeSharedStringRefTable(sst)
|
|
|
- rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
|
|
|
c.Assert(maxRows, Equals, 2)
|
|
|
c.Assert(maxCols, Equals, 4)
|
|
|
|
|
|
@@ -526,11 +622,13 @@ func (l *LibSuite) TestReadRowsFromSheetWithEmptyCells(c *C) {
|
|
|
c.Assert(err, IsNil)
|
|
|
file := new(File)
|
|
|
file.referenceTable = MakeSharedStringRefTable(sst)
|
|
|
- rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ rows, cols, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
|
|
|
c.Assert(maxRows, Equals, 3)
|
|
|
c.Assert(maxCols, Equals, 3)
|
|
|
|
|
|
row := rows[2]
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
c.Assert(len(row.Cells), Equals, 3)
|
|
|
|
|
|
cell1 := row.Cells[0]
|
|
|
@@ -568,11 +666,13 @@ func (l *LibSuite) TestReadRowsFromSheetWithTrailingEmptyCells(c *C) {
|
|
|
|
|
|
file := new(File)
|
|
|
file.referenceTable = MakeSharedStringRefTable(sst)
|
|
|
- rows, _, maxCol, maxRow := readRowsFromSheet(worksheet, file)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ rows, _, maxCol, maxRow := readRowsFromSheet(worksheet, file, sheet)
|
|
|
c.Assert(maxCol, Equals, 4)
|
|
|
c.Assert(maxRow, Equals, 8)
|
|
|
|
|
|
row = rows[0]
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
c.Assert(len(row.Cells), Equals, 4)
|
|
|
|
|
|
cell1 = row.Cells[0]
|
|
|
@@ -588,6 +688,7 @@ func (l *LibSuite) TestReadRowsFromSheetWithTrailingEmptyCells(c *C) {
|
|
|
c.Assert(cell4.Value, Equals, "D")
|
|
|
|
|
|
row = rows[1]
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
c.Assert(len(row.Cells), Equals, 4)
|
|
|
|
|
|
cell1 = row.Cells[0]
|
|
|
@@ -675,10 +776,12 @@ func (l *LibSuite) TestReadRowsFromSheetWithMultipleSpans(c *C) {
|
|
|
c.Assert(err, IsNil)
|
|
|
file := new(File)
|
|
|
file.referenceTable = MakeSharedStringRefTable(sst)
|
|
|
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
|
|
|
c.Assert(maxRows, Equals, 2)
|
|
|
c.Assert(maxCols, Equals, 4)
|
|
|
row := rows[0]
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
c.Assert(len(row.Cells), Equals, 4)
|
|
|
cell1 := row.Cells[0]
|
|
|
c.Assert(cell1.Value, Equals, "Foo")
|
|
|
@@ -748,10 +851,12 @@ func (l *LibSuite) TestReadRowsFromSheetWithMultipleTypes(c *C) {
|
|
|
c.Assert(err, IsNil)
|
|
|
file := new(File)
|
|
|
file.referenceTable = MakeSharedStringRefTable(sst)
|
|
|
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
|
|
|
c.Assert(maxRows, Equals, 1)
|
|
|
c.Assert(maxCols, Equals, 6)
|
|
|
row := rows[0]
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
c.Assert(len(row.Cells), Equals, 6)
|
|
|
|
|
|
cell1 := row.Cells[0]
|
|
|
@@ -815,10 +920,12 @@ func (l *LibSuite) TestReadRowsFromSheetWithHiddenColumn(c *C) {
|
|
|
c.Assert(err, IsNil)
|
|
|
file := new(File)
|
|
|
file.referenceTable = MakeSharedStringRefTable(sst)
|
|
|
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
|
|
|
c.Assert(maxRows, Equals, 1)
|
|
|
c.Assert(maxCols, Equals, 2)
|
|
|
row := rows[0]
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
c.Assert(len(row.Cells), Equals, 2)
|
|
|
|
|
|
cell1 := row.Cells[0]
|
|
|
@@ -842,9 +949,11 @@ func (l *LibSuite) TestReadRowFromRaw(c *C) {
|
|
|
cell = xlsxC{R: "A1"}
|
|
|
cell = xlsxC{R: "A2"}
|
|
|
rawRow.C = append(rawRow.C, cell)
|
|
|
- row = makeRowFromRaw(rawRow)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ row = makeRowFromRaw(rawRow, sheet)
|
|
|
c.Assert(row, NotNil)
|
|
|
c.Assert(row.Cells, HasLen, 1)
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
}
|
|
|
|
|
|
// When a cell claims it is at a position greater than its ordinal
|
|
|
@@ -859,9 +968,11 @@ func (l *LibSuite) TestReadRowFromRawWithMissingCells(c *C) {
|
|
|
rawRow.C = append(rawRow.C, cell)
|
|
|
cell = xlsxC{R: "E1"}
|
|
|
rawRow.C = append(rawRow.C, cell)
|
|
|
- row = makeRowFromRaw(rawRow)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ row = makeRowFromRaw(rawRow, sheet)
|
|
|
c.Assert(row, NotNil)
|
|
|
c.Assert(row.Cells, HasLen, 5)
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
}
|
|
|
|
|
|
// We can cope with missing coordinate references
|
|
|
@@ -879,9 +990,11 @@ func (l *LibSuite) TestReadRowFromRawWithPartialCoordinates(c *C) {
|
|
|
rawRow.C = append(rawRow.C, cell)
|
|
|
cell = xlsxC{}
|
|
|
rawRow.C = append(rawRow.C, cell)
|
|
|
- row = makeRowFromRaw(rawRow)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ row = makeRowFromRaw(rawRow, sheet)
|
|
|
c.Assert(row, NotNil)
|
|
|
c.Assert(row.Cells, HasLen, 27)
|
|
|
+ c.Assert(row.Sheet, Equals, sheet)
|
|
|
}
|
|
|
|
|
|
func (l *LibSuite) TestSharedFormulas(c *C) {
|
|
|
@@ -935,7 +1048,8 @@ func (l *LibSuite) TestSharedFormulas(c *C) {
|
|
|
c.Assert(err, IsNil)
|
|
|
|
|
|
file := new(File)
|
|
|
- rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file)
|
|
|
+ sheet := new(Sheet)
|
|
|
+ rows, _, maxCols, maxRows := readRowsFromSheet(worksheet, file, sheet)
|
|
|
c.Assert(maxCols, Equals, 3)
|
|
|
c.Assert(maxRows, Equals, 2)
|
|
|
|