Преглед на файлове

Fixing exception when filled expression produces out of bounds addresses

main
Rocketsoup преди 1 година
родител
ревизия
040c853287

+ 5
- 1
js/spreadsheet.js Целия файл

@@ -343,6 +343,9 @@ class CellExpressionSet {
343 343
 
344 344
 			case CellExpressionOperation.Reference: {
345 345
 				const refAddress = expr.arguments[0];
346
+				if (refAddress === null) {
347
+					throw new CellEvaluationException(`Invalid cell address`, '#REF');
348
+				}
346 349
 				const cell = this.#grid.cellAt(refAddress);
347 350
 				if (cell === null) {
348 351
 					throw new CellEvaluationException(`No cell at ${refAddress.name}`, '#REF');
@@ -1470,7 +1473,7 @@ class CellExpression {
1470 1473
 		const exp = this.#tryExpression(tokens, start, end - 1, address);
1471 1474
 		const columnIndex = address.columnIndex;
1472 1475
 		exp.fillRanges = [
1473
-			new CellAddressRange(new CellAddress(columnIndex, -1), new CellAddress(columnIndex, -1)),
1476
+			new CellAddressRange(new CellAddress(columnIndex, address.rowIndex), new CellAddress(columnIndex, 999999)),
1474 1477
 		];
1475 1478
 		return exp;
1476 1479
 	}
@@ -1690,6 +1693,7 @@ class CellExpression {
1690 1693
 		if (!tokens[start].type.isPotentialAddress()) return null;
1691 1694
 		const ref = tokens[start].content.toUpperCase();
1692 1695
 		const refAddress = CellAddress.fromString(ref, address, true);
1696
+		if (refAddress === null) return null;
1693 1697
 		return new CellExpression(CellExpressionOperation.Reference, [ refAddress ]);
1694 1698
 	}
1695 1699
 

+ 1
- 1
js/spreadsheet.min.js
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 11
- 0
jstest/spreadsheet/SpreadsheetMarkdownIntegrationTests.js Целия файл

@@ -60,6 +60,17 @@ class SpreadsheetMarkdownIntegrationTests extends BaseTest {
60 60
 		this.assertEqual(expected, actual);
61 61
 	}
62 62
 
63
+	test_observedError2() {
64
+		// A FILLed difference formula in row 2 of `=B2-B1` threw an exception
65
+		// due to a transposed address to the row above of `=B1-B0`.
66
+		const markdown = `| TB | Price | $/TB | Incr |
67
+| --- | --- | --- | --- |
68
+| 2 | $99.99 | =B/A FILL | |
69
+| 4 | $186.41 | | =B2-B1 FILL |
70
+| 6 | $209.99 | | |`;
71
+		const actual = this.md(markdown);
72
+	}
73
+
63 74
 	test_styledValue() {
64 75
 		const markdown = "| A | B | C |\n| --- | --- | --- |\n| **3** | _4_ | =A*B |";
65 76
 		const expected = '<table><thead>' +

+ 5
- 1
php/spreadsheet.php Целия файл

@@ -302,6 +302,9 @@ class CellExpressionSet {
302 302
 
303 303
 			case CellExpressionOperation::Reference: {
304 304
 				$refAddress = $expr->arguments[0];
305
+				if ($refAddress === null) {
306
+					throw new CellEvaluationException("Invalid cell address", '#REF');
307
+				}
305 308
 				$cell = $this->grid->cellAt($refAddress);
306 309
 				if ($cell === null) {
307 310
 					throw new CellEvaluationException("No cell at {$refAddress->name}", '#REF');
@@ -1394,7 +1397,7 @@ class CellExpression {
1394 1397
 		$exp = self::tryExpression($tokens, $start, $end - 1, $address);
1395 1398
 		$columnIndex = $address->columnIndex;
1396 1399
 		$exp->fillRanges = [
1397
-			new CellAddressRange(new CellAddress($columnIndex, -1), new CellAddress($columnIndex, -1)),
1400
+			new CellAddressRange(new CellAddress($columnIndex, $address->rowIndex), new CellAddress($columnIndex, 999999)),
1398 1401
 		];
1399 1402
 		return $exp;
1400 1403
 	}
@@ -1624,6 +1627,7 @@ class CellExpression {
1624 1627
 		if (!$tokens[$start]->type->isPotentialAddress()) return null;
1625 1628
 		$ref = mb_strtoupper($tokens[$start]->content);
1626 1629
 		$refAddress = CellAddress::fromString($ref, $address, true);
1630
+		if ($refAddress === null) return null;
1627 1631
 		return new CellExpression(CellExpressionOperation::Reference, [ $refAddress ]);
1628 1632
 	}
1629 1633
 

+ 8
- 0
phptest/spreadsheet/SpreadsheetMarkdownIntegrationTests.php Целия файл

@@ -74,6 +74,14 @@ final class SpreadsheetMarkdownIntegrationTests extends TestCase {
74 74
 		$this->assertSame($expected, $actual);
75 75
 	}
76 76
 
77
+	public function test_observedError2() {
78
+		// A FILLed difference formula in row 2 of `=B2-B1` threw an exception
79
+		// due to a transposed address to the row above of `=B1-B0`.
80
+		$markdown = "| TB | Price | $/TB | Incr |\n| --- | --- | --- | --- |\n| 2 | $99.99 | =B/A FILL | |\n| 4 | $186.41 | | =B2-B1 FILL |\n| 6 | $209.99 | | |";
81
+		$actual = $this->md($markdown);
82
+		$this->assertTrue(true);
83
+	}
84
+
77 85
 	public function test_styledValue() {
78 86
 		$markdown = "| A | B | C |\n| --- | --- | --- |\n| **3** | _4_ | =A*B |";
79 87
 		$expected = '<table><thead>' .

Loading…
Отказ
Запис