Skip to content

Commit 8871095

Browse files
authored
Merge pull request #4322 from oleibman/issue4316
Html Writer Allow mailto
2 parents fde46cf + d24325b commit 8871095

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
2828

2929
- Ods Reader Sheet Names with Period. [Issue #4311](https://github.com/PHPOffice/PhpSpreadsheet/issues/4311) [PR #4313](https://github.com/PHPOffice/PhpSpreadsheet/pull/4313)
3030
- Mpdf and Tcpdf Hidden Columns and Merged Cells. [Issue #4319](https://github.com/PHPOffice/PhpSpreadsheet/issues/4319) [PR #4320](https://github.com/PHPOffice/PhpSpreadsheet/pull/4320)
31+
- Html Writer Allow mailto. [Issue #4316](https://github.com/PHPOffice/PhpSpreadsheet/issues/4316) [PR #4322](https://github.com/PHPOffice/PhpSpreadsheet/pull/4322)
3132

3233
## 2025-01-11 - 3.8.0
3334

src/PhpSpreadsheet/Writer/Html.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,10 +1601,15 @@ private function generateRow(Worksheet $worksheet, array $values, int $row, stri
16011601
$urlDecode1 = html_entity_decode($url, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
16021602
$urlTrim = preg_replace('/^\\s+/u', '', $urlDecode1) ?? $urlDecode1;
16031603
$parseScheme = preg_match('/^([\\w\\s]+):/u', strtolower($urlTrim), $matches);
1604-
if ($parseScheme === 1 && !in_array($matches[1], ['http', 'https', 'file', 'ftp', 's3'], true)) {
1604+
if ($parseScheme === 1 && !in_array($matches[1], ['http', 'https', 'file', 'ftp', 'mailto', 's3'], true)) {
16051605
$cellData = htmlspecialchars($url, Settings::htmlEntityFlags());
16061606
} else {
1607-
$cellData = '<a href="' . htmlspecialchars($url, Settings::htmlEntityFlags()) . '" title="' . htmlspecialchars($worksheet->getHyperlink($coordinate)->getTooltip(), Settings::htmlEntityFlags()) . '">' . $cellData . '</a>';
1607+
$tooltip = $worksheet->getHyperlink($coordinate)->getTooltip();
1608+
$tooltipOut = empty($tooltip) ? '' : (' title="' . htmlspecialchars($tooltip) . '"');
1609+
$cellData = '<a href="'
1610+
. htmlspecialchars($url) . '"'
1611+
. $tooltipOut
1612+
. '>' . $cellData . '</a>';
16081613
}
16091614
}
16101615

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Writer\Html;
6+
7+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8+
use PhpOffice\PhpSpreadsheet\Writer\Html as HtmlWriter;
9+
use PHPUnit\Framework\TestCase;
10+
11+
class MailtoTest extends TestCase
12+
{
13+
public function testBadHyperlink(): void
14+
{
15+
$spreadsheet = new Spreadsheet();
16+
$worksheet = $spreadsheet->getActiveSheet();
17+
$worksheet->setCellValue('A1', 'Mail Me!');
18+
$worksheet->getCell('A1')
19+
->getHyperlink()
20+
->setUrl('mailto:me@example.com');
21+
$worksheet->setCellValue('A2', 'Mail You!');
22+
$worksheet->getCell('A2')
23+
->getHyperlink()
24+
->setTooltip('go ahead')
25+
->setUrl('mailto:you@example.com');
26+
$writer = new HtmlWriter($spreadsheet);
27+
$html = $writer->generateHtmlAll();
28+
self::assertStringContainsString('<a href="mailto:me@example.com">Mail Me!</a>', $html);
29+
self::assertStringContainsString('<a href="mailto:you@example.com" title="go ahead">Mail You!</a>', $html);
30+
$spreadsheet->disconnectWorksheets();
31+
}
32+
}

tests/PhpSpreadsheetTests/Writer/Html/NoJavascriptLinksTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function testNoJavascriptLinks(): void
2525

2626
$writer = new Html($spreadsheet);
2727
$html = $writer->generateHTMLAll();
28-
self::assertStringContainsString('<td class="column0 style0 s"><a href="http://www.example.com" title="">Click me</a></td>', $html, 'http hyperlink retained');
28+
self::assertStringContainsString('<td class="column0 style0 s"><a href="http://www.example.com">Click me</a></td>', $html, 'http hyperlink retained');
2929
self::assertStringContainsString('<td class="column0 style0 s">javascript:alert(\'hello1\')</td>', $html, 'javascript hyperlink dropped');
3030
self::assertStringContainsString('<td class="column0 style0 f">javascript:alert(\'hello2\')</td>', $html, 'javascript hyperlink function dropped');
3131
$spreadsheet->disconnectWorksheets();

0 commit comments

Comments
 (0)