Skip to content

Commit 3051663

Browse files
committed
Security Patch Control Characters in Protocol
1 parent c9040d9 commit 3051663

File tree

12 files changed

+523
-241
lines changed

12 files changed

+523
-241
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com)
66
and this project adheres to [Semantic Versioning](https://semver.org).
77

8+
# TBD - 1.29.9
9+
10+
### Fixed
11+
12+
- Backported security patch for control characters in protocol.
13+
- Use Composer\Pcre in Xls/Parser. Partial backport of [PR #4203](https://github.com/PHPOffice/PhpSpreadsheet/pull/4203)
14+
815
# 2025-01-11 - 1.29.8
916

1017
### Deprecated

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"ext-xmlwriter": "*",
7676
"ext-zip": "*",
7777
"ext-zlib": "*",
78+
"composer/pcre": "^3.3",
7879
"ezyang/htmlpurifier": "^4.15",
7980
"maennchen/zipstream-php": "^2.1 || ^3.0",
8081
"markbaker/complex": "^3.0",

composer.lock

Lines changed: 80 additions & 80 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

phpstan-baseline.neon

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -315,26 +315,6 @@ parameters:
315315
count: 1
316316
path: src/PhpSpreadsheet/Writer/Xls.php
317317

318-
-
319-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\?\\: ''\\|'\\$', 2\\?\\: non\\-falsy\\-string, 3\\?\\: ''\\|'\\$', 4\\?\\: numeric\\-string\\}\\.$#"
320-
count: 1
321-
path: src/PhpSpreadsheet/Writer/Xls/Parser.php
322-
323-
-
324-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\?\\: ''\\|'\\$', 2\\?\\: numeric\\-string, 3\\?\\: ''\\|'\\$', 4\\?\\: numeric\\-string\\}\\.$#"
325-
count: 1
326-
path: src/PhpSpreadsheet/Writer/Xls/Parser.php
327-
328-
-
329-
message: "#^Offset 4 does not exist on array\\{0\\?\\: string, 1\\?\\: ''\\|'\\$', 2\\?\\: non\\-falsy\\-string, 3\\?\\: ''\\|'\\$', 4\\?\\: numeric\\-string\\}\\.$#"
330-
count: 1
331-
path: src/PhpSpreadsheet/Writer/Xls/Parser.php
332-
333-
-
334-
message: "#^Offset 4 does not exist on array\\{0\\?\\: string, 1\\?\\: ''\\|'\\$', 2\\?\\: numeric\\-string, 3\\?\\: ''\\|'\\$', 4\\?\\: numeric\\-string\\}\\.$#"
335-
count: 1
336-
path: src/PhpSpreadsheet/Writer/Xls/Parser.php
337-
338318
-
339319
message: "#^Parameter \\#2 \\$length of function fread expects int\\<1, max\\>, int\\<0, max\\> given\\.$#"
340320
count: 1

phpstan.neon.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ includes:
33
- phpstan-conditional.php
44
- vendor/phpstan/phpstan-phpunit/extension.neon
55
- vendor/phpstan/phpstan-phpunit/rules.neon
6+
- vendor/composer/pcre/extension.neon
67

78
parameters:
89
level: 8

src/PhpSpreadsheet/Reader/Html.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,10 @@ private function insertImage(Worksheet $sheet, $column, $row, array $attributes)
10841084
$name = $attributes['alt'] ?? null;
10851085

10861086
$drawing = new Drawing();
1087-
$drawing->setPath($src);
1087+
$drawing->setPath($src, false);
1088+
if ($drawing->getPath() === '') {
1089+
return;
1090+
}
10881091
$drawing->setWorksheet($sheet);
10891092
$drawing->setCoordinates($column . $row);
10901093
$drawing->setOffsetX(0);

src/PhpSpreadsheet/Worksheet/Drawing.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public function setPath($path, $verifyFile = true, $zip = null)
115115

116116
$this->path = '';
117117
// Check if a URL has been passed. https://stackoverflow.com/a/2058596/1252979
118-
if (filter_var($path, FILTER_VALIDATE_URL)) {
118+
if (filter_var($path, FILTER_VALIDATE_URL) || (preg_match('/^([\\w\\s\\x00-\\x1f]+):/u', $path) && !preg_match('/^([\\w]+):/u', $path))) {
119119
if (!preg_match('/^(http|https|file|ftp|s3):/', $path)) {
120120
throw new PhpSpreadsheetException('Invalid protocol for linked drawing');
121121
}

src/PhpSpreadsheet/Writer/Html.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,9 +1521,10 @@ private function generateRow(Worksheet $worksheet, array $values, $row, $cellTyp
15211521
$url = $worksheet->getHyperlink($coordinate)->getUrl();
15221522
$urlDecode1 = html_entity_decode($url, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
15231523
$urlTrim = preg_replace('/^\\s+/u', '', $urlDecode1) ?? $urlDecode1;
1524-
$parseScheme = preg_match('/^([\\w\\s]+):/u', strtolower($urlTrim), $matches);
1525-
if ($parseScheme === 1 && !in_array($matches[1], ['http', 'https', 'file', 'ftp', 's3'], true)) {
1524+
$parseScheme = preg_match('/^([\\w\\s\\x00-\\x1f]+):/u', strtolower($urlTrim), $matches);
1525+
if ($parseScheme === 1 && !in_array($matches[1], ['http', 'https', 'file', 'ftp', 'mailto', 's3'], true)) {
15261526
$cellData = htmlspecialchars($url, Settings::htmlEntityFlags());
1527+
$cellData = self::replaceControlChars($cellData);
15271528
} else {
15281529
$cellData = '<a href="' . htmlspecialchars($url, Settings::htmlEntityFlags()) . '" title="' . htmlspecialchars($worksheet->getHyperlink($coordinate)->getTooltip(), Settings::htmlEntityFlags()) . '">' . $cellData . '</a>';
15291530
}
@@ -1568,6 +1569,20 @@ private function generateRow(Worksheet $worksheet, array $values, $row, $cellTyp
15681569
return $html;
15691570
}
15701571

1572+
private static function replaceNonAscii(array $matches): string
1573+
{
1574+
return '&#' . mb_ord($matches[0], 'UTF-8') . ';';
1575+
}
1576+
1577+
private static function replaceControlChars(string $convert): string
1578+
{
1579+
return (string) preg_replace_callback(
1580+
'/[\\x00-\\x1f]/',
1581+
[self::class, 'replaceNonAscii'],
1582+
$convert
1583+
);
1584+
}
1585+
15711586
/**
15721587
* Takes array where of CSS properties / values and converts to CSS string.
15731588
*

0 commit comments

Comments
 (0)