Skip to content

Commit 6d8fc67

Browse files
authored
Merge branch 'master' into deprecations
2 parents 624dafa + 7e89ad9 commit 6d8fc67

File tree

9 files changed

+74
-56
lines changed

9 files changed

+74
-56
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org). Thia is a
99

1010
### Breaking Changes
1111

12+
- Images will be loaded from an external source (e.g. http://example.com/img.png) only if the reader is explicitly set to allow it via `$reader->setAllowExternalImages(true)`. We do not believe that loading of external images is a widely used feature.
1213
- Deletion of items deprecated in Release 4. See "removed" below.
14+
- Move some properties from Base Reader to Html Reader. [PR #4551](https://github.com/PHPOffice/PhpSpreadsheet/pull/4551)
15+
- DefaultValueBinder will treat integers with more than 15 digits as strings. [Issue #4522](https://github.com/PHPOffice/PhpSpreadsheet/issues/4522) [PR #4527](https://github.com/PHPOffice/PhpSpreadsheet/pull/4527)
1316

1417
### Added
1518

docs/references/features-cross-reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@
10281028
6. <span id="footnote6">There is very limited support for reading styles from an Ods spreadsheet. Writing styles has better support, although Number Format is incomplete.</span>
10291029
7. <span id="footnote7">In most cases, Html reader processes only inline styles; styles provided by Css classes may be ignored.</span>
10301030
8. <span id="footnote8">Code must [opt in](../topics/recipes.md#array-formulas) to array output.</span>
1031-
9. <span id="footnote9">Starting with release 4.5, code can allow or not external images. In release 4.5 (and in earlier releases which do not offer an option), default is to allow it.</span>
1031+
9. <span id="footnote9">Use with caution - allowing external images may can subject the caller to security exploits. Starting with release 4.5.0 (also earlier releases 3.9.3, 2.3.10, 2.1.11, and 1.29.12), code can allow or not external images. In those starting releases, and in earlier releases which do not offer an option, default is to allow it. In release 5+ (and earlier supported versions 1.30+, 2.1.12+, 2.4+, and 3.10+), the default is to not allow it.</span>
10321032

10331033
## Writers
10341034

src/PhpSpreadsheet/Cell/DefaultValueBinder.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Cell;
44

5+
use Composer\Pcre\Preg;
56
use DateTimeInterface;
67
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
78
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException;
@@ -12,6 +13,9 @@
1213

1314
class DefaultValueBinder implements IValueBinder
1415
{
16+
// 123 456 789 012 345
17+
private const FIFTEEN_NINES = 999_999_999_999_999;
18+
1519
/**
1620
* Bind value to a cell.
1721
*
@@ -49,6 +53,9 @@ public static function dataTypeForValue(mixed $value): string
4953
if ($value === null) {
5054
return DataType::TYPE_NULL;
5155
}
56+
if (is_int($value) && abs($value) > self::FIFTEEN_NINES) {
57+
return DataType::TYPE_STRING;
58+
}
5259
if (is_float($value) || is_int($value)) {
5360
return DataType::TYPE_NUMERIC;
5461
}
@@ -89,13 +96,18 @@ public static function dataTypeForValue(mixed $value): string
8996

9097
return DataType::TYPE_FORMULA;
9198
}
92-
if (preg_match('/^[\+\-]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $value)) {
99+
if (Preg::isMatch('/^[\+\-]?(\d+\.?\d*|\d*\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $value)) {
93100
$tValue = ltrim($value, '+-');
94101
if (strlen($tValue) > 1 && $tValue[0] === '0' && $tValue[1] !== '.') {
95102
return DataType::TYPE_STRING;
96-
} elseif ((!str_contains($value, '.')) && ($value > PHP_INT_MAX)) {
97-
return DataType::TYPE_STRING;
98-
} elseif (!is_numeric($value)) {
103+
}
104+
if (!Preg::isMatch('/[eE.]/', $value)) {
105+
$aValue = abs((float) $value);
106+
if ($aValue > self::FIFTEEN_NINES) {
107+
return DataType::TYPE_STRING;
108+
}
109+
}
110+
if (!is_numeric($value)) {
99111
return DataType::TYPE_STRING;
100112
}
101113

src/PhpSpreadsheet/Reader/BaseReader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ abstract class BaseReader implements IReader
5252
* Improper specification of these within a spreadsheet
5353
* can subject the caller to security exploits.
5454
*/
55-
protected bool $allowExternalImages = true;
55+
protected bool $allowExternalImages = false;
5656

5757
/**
5858
* IReadFilter instance.

src/PhpSpreadsheet/Writer/BaseWriter.php

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Writer;
44

5-
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
6-
75
abstract class BaseWriter implements IWriter
86
{
97
/**
@@ -19,18 +17,6 @@ abstract class BaseWriter implements IWriter
1917
*/
2018
protected bool $preCalculateFormulas = true;
2119

22-
/**
23-
* Table formats
24-
* Enables table formats in writer, disabled here, must be enabled in writer via a setter.
25-
*/
26-
protected bool $tableFormats = false;
27-
28-
/**
29-
* Conditional Formatting
30-
* Enables conditional formatting in writer, disabled here, must be enabled in writer via a setter.
31-
*/
32-
protected bool $conditionalFormatting = false;
33-
3420
/**
3521
* Use disk caching where possible?
3622
*/
@@ -72,34 +58,6 @@ public function setPreCalculateFormulas(bool $precalculateFormulas): self
7258
return $this;
7359
}
7460

75-
public function getTableFormats(): bool
76-
{
77-
return $this->tableFormats;
78-
}
79-
80-
public function setTableFormats(bool $tableFormats): self
81-
{
82-
if ($tableFormats) {
83-
throw new PhpSpreadsheetException('Table formatting not implemented for this writer');
84-
}
85-
86-
return $this;
87-
}
88-
89-
public function getConditionalFormatting(): bool
90-
{
91-
return $this->conditionalFormatting;
92-
}
93-
94-
public function setConditionalFormatting(bool $conditionalFormatting): self
95-
{
96-
if ($conditionalFormatting) {
97-
throw new PhpSpreadsheetException('Conditional Formatting not implemented for this writer');
98-
}
99-
100-
return $this;
101-
}
102-
10361
public function getUseDiskCaching(): bool
10462
{
10563
return $this->useDiskCaching;

src/PhpSpreadsheet/Writer/Html.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,18 @@ class Html extends BaseWriter
162162

163163
protected bool $ltrSheets = false;
164164

165+
/**
166+
* Table formats
167+
* Enables table formats in writer, disabled here, must be enabled in writer via a setter.
168+
*/
169+
protected bool $tableFormats = false;
170+
171+
/**
172+
* Conditional Formatting
173+
* Enables conditional formatting in writer, disabled here, must be enabled in writer via a setter.
174+
*/
175+
protected bool $conditionalFormatting = false;
176+
165177
/**
166178
* Create a new HTML.
167179
*/
@@ -1935,13 +1947,23 @@ public function setUseInlineCss(bool $useInlineCss): static
19351947
return $this;
19361948
}
19371949

1950+
public function getTableFormats(): bool
1951+
{
1952+
return $this->tableFormats;
1953+
}
1954+
19381955
public function setTableFormats(bool $tableFormats): self
19391956
{
19401957
$this->tableFormats = $tableFormats;
19411958

19421959
return $this;
19431960
}
19441961

1962+
public function getConditionalFormatting(): bool
1963+
{
1964+
return $this->conditionalFormatting;
1965+
}
1966+
19451967
public function setConditionalFormatting(bool $conditionalFormatting): self
19461968
{
19471969
$this->conditionalFormatting = $conditionalFormatting;

tests/PhpSpreadsheetTests/Reader/Html/HtmlImage2Test.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,19 @@
55
namespace PhpOffice\PhpSpreadsheetTests\Reader\Html;
66

77
use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
8+
use PhpOffice\PhpSpreadsheet\Reader\Html as HtmlReader;
89
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
910
use PHPUnit\Framework\Attributes\DataProvider;
1011
use PHPUnit\Framework\TestCase;
1112

1213
class HtmlImage2Test extends TestCase
1314
{
15+
public function testDefault(): void
16+
{
17+
$reader = new HtmlReader();
18+
self::assertFalse($reader->getAllowExternalImages());
19+
}
20+
1421
public function testCanInsertImageGoodProtocolAllowed(): void
1522
{
1623
if (getenv('SKIP_URL_IMAGE_TEST') === '1') {

tests/PhpSpreadsheetTests/Reader/Xlsx/URLImageTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@
66

77
use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
88
use PhpOffice\PhpSpreadsheet\IOFactory;
9+
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
910
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
1011
use PhpOffice\PhpSpreadsheetTests\Reader\Utility\File;
1112
use PHPUnit\Framework\TestCase;
1213

1314
class URLImageTest extends TestCase
1415
{
16+
public function testDefault(): void
17+
{
18+
$reader = new XlsxReader();
19+
self::assertFalse($reader->getAllowExternalImages());
20+
}
21+
1522
public function testURLImageSourceAllowed(): void
1623
{
1724
if (getenv('SKIP_URL_IMAGE_TEST') === '1') {

tests/PhpSpreadsheetTests/Writer/Xlsx/FloatsRetainedTest.php

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,21 @@
88
use PhpOffice\PhpSpreadsheet\Shared\File;
99
use PhpOffice\PhpSpreadsheet\Spreadsheet;
1010
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as Writer;
11+
use PHPUnit\Framework\Attributes\DataProvider;
1112
use PHPUnit\Framework\TestCase;
1213

1314
class FloatsRetainedTest extends TestCase
1415
{
15-
#[\PHPUnit\Framework\Attributes\DataProvider('providerIntyFloatsRetainedByWriter')]
16-
public function testIntyFloatsRetainedByWriter(float|int $value): void
16+
#[DataProvider('providerIntyFloatsRetainedByWriter')]
17+
public function testIntyFloatsRetainedByWriter(float|int $value, mixed $expected = null): void
1718
{
19+
if ($expected === null) {
20+
$expected = $value;
21+
}
1822
$outputFilename = File::temporaryFilename();
1923
$spreadsheet = new Spreadsheet();
20-
$spreadsheet->getActiveSheet()->getCell('A1')->setValue($value);
24+
$spreadsheet->getActiveSheet()
25+
->getCell('A1')->setValue($value);
2126

2227
$writer = new Writer($spreadsheet);
2328
$writer->save($outputFilename);
@@ -27,7 +32,11 @@ public function testIntyFloatsRetainedByWriter(float|int $value): void
2732
$spreadsheet2 = $reader->load($outputFilename);
2833
unlink($outputFilename);
2934

30-
self::assertSame($value, $spreadsheet2->getActiveSheet()->getCell('A1')->getValue());
35+
self::assertSame(
36+
$expected,
37+
$spreadsheet2->getActiveSheet()
38+
->getCell('A1')->getValue()
39+
);
3140
$spreadsheet2->disconnectWorksheets();
3241
}
3342

@@ -44,10 +53,10 @@ public static function providerIntyFloatsRetainedByWriter(): array
4453
[1.3e-10],
4554
[1e10],
4655
[3.00000000000000000001],
47-
[99999999999999999],
48-
[99999999999999999.0],
49-
[999999999999999999999999999999999999999999],
50-
[999999999999999999999999999999999999999999.0],
56+
'int but too much precision for Excel' => [99_999_999_999_999_999, '99999999999999999'],
57+
[99_999_999_999_999_999.0],
58+
'int > PHP_INT_MAX so stored as float' => [999_999_999_999_999_999_999_999_999_999_999_999_999_999],
59+
[999_999_999_999_999_999_999_999_999_999_999_999_999_999.0],
5160
];
5261
}
5362
}

0 commit comments

Comments
 (0)