Skip to content

Commit

Permalink
Test if UConverter Exists Without Autoload
Browse files Browse the repository at this point in the history
Fix PHPOffice#2982. That issue is actually closed, but it did expose a problem. Our test environments all enable php-intl, but that extension isn't a formal requirement for PhpSpreadsheet. Perhaps it ought to be. Nevertheless ...

Using UConverter for string translation solved some problems for us. However, it is only available when php-intl is enabled. The code tests if it exists before using it, so no big deal ... except it seems likely that the people reporting the issue not only did not have php-intl, but they do have their own autoloader which issues an exception when the class isn't found. The test for existence of UConverter defaulted to attempting to autoload it if not found. So, on a system without php-intl but with a custom autoloader, there is a problem. Code is changed to suppress autoload when testing UConverter existence.

Pending this fix, the workaround for this issue is to enable php-intl.
  • Loading branch information
oleibman committed Aug 7, 2022
1 parent 641b6d0 commit b00c29a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/Shared/StringHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ public static function controlCharacterPHP2OOXML($textValue)
public static function sanitizeUTF8(string $textValue): string
{
$textValue = str_replace(["\xef\xbf\xbe", "\xef\xbf\xbf"], "\xef\xbf\xbd", $textValue);
if (class_exists(UConverter::class)) {
if (class_exists(UConverter::class, false)) {
$returnValue = UConverter::transcode($textValue, 'UTF-8', 'UTF-8');
if ($returnValue !== false) {
return $returnValue;
Expand Down
40 changes: 38 additions & 2 deletions tests/PhpSpreadsheetTests/Shared/StringHelperInvalidCharTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace PhpOffice\PhpSpreadsheetTests\Shared;

use Exception as Except;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
Expand All @@ -12,13 +13,14 @@ public function testInvalidChar(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$substitution = '';
$substitution = class_exists('UConverter', false) ? '' : '?';
$substitution2 = '';
$array = [
['Normal string', 'Hello', 'Hello'],
['integer', 2, 2],
['float', 2.1, 2.1],
['boolean true', true, true],
['illegal FFFE/FFFF', "H\xef\xbf\xbe\xef\xbf\xbfello", "H{$substitution}{$substitution}ello"],
['illegal FFFE/FFFF', "H\xef\xbf\xbe\xef\xbf\xbfello", "H{$substitution2}{$substitution2}ello"],
['illegal character', "H\xef\x00\x00ello", "H{$substitution}\x00\x00ello"],
['overlong character', "H\xc0\xa0ello", "H{$substitution}{$substitution}ello"],
['Osmanya as single character', "H\xf0\x90\x90\x80ello", 'H𐐀ello'],
Expand All @@ -41,4 +43,38 @@ public function testInvalidChar(): void
);
}
}

public function fakespl(string $name): void
{
if (strlen($name) > 0) {
throw new Except("$name not found");
}
}

public function testClassNotFound(): void
{
// see issue 2982.
// This test will work all the time, but it is valuable
// only if php-intl not available
// and a user-supplied autoloader can issue exception.
/** @var callable */
$fakespl = [$this, 'fakespl'];
spl_autoload_register($fakespl);

try {
self::assertFalse(class_exists('abc123xyz'));
self::fail('Expected exception here');
} catch (Except $e) {
// Nothing to do here
}

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');

$spreadsheet->disconnectWorksheets();

spl_autoload_unregister($fakespl);
self::assertFalse(class_exists('abc123wxyz'));
}
}

0 comments on commit b00c29a

Please sign in to comment.