diff --git a/src/layout-manager.js b/src/layout-manager.js index 3937452..66b00bb 100644 --- a/src/layout-manager.js +++ b/src/layout-manager.js @@ -91,11 +91,17 @@ const { ColSpanCell, RowSpanCell } = Cell; table.forEach(function (row, rowIndex) { row.forEach(function (cell) { for (let i = 1; i < cell.rowSpan; i++) { + let targetRow = table[rowIndex + i]; + if (!targetRow) { + // rowSpan extends past the last row; clamp it instead of indexing + // a missing row (mirrors how colSpan past the table width degrades). + break; + } let rowSpanCell = new RowSpanCell(cell); rowSpanCell.x = cell.x; rowSpanCell.y = cell.y + i; rowSpanCell.colSpan = cell.colSpan; - insertCell(rowSpanCell, table[rowIndex + i]); + insertCell(rowSpanCell, targetRow); } }); }); diff --git a/test/issues/rowspan-overflow-test.js b/test/issues/rowspan-overflow-test.js new file mode 100644 index 0000000..b92d6e9 --- /dev/null +++ b/test/issues/rowspan-overflow-test.js @@ -0,0 +1,12 @@ +const Table = require('../..'); + +test('a rowSpan that extends past the last row renders instead of throwing', () => { + const table = new Table(); + table.push([{ content: 'aaaa bbbb', rowSpan: 2 }]); + + let output; + expect(() => { + output = table.toString(); + }).not.toThrow(); + expect(output).toContain('aaaa bbbb'); +});