Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 30 additions & 18 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnFailure="false" cacheDirectory=".phpunit.cache" backupStaticProperties="false" displayDetailsOnTestsThatTriggerWarnings="true">
<php>
<ini name="error_reporting" value="-1"/>
<ini name="zend.enable_gc" value="0"/>
<ini name="error_reporting" value="-1"/>
<ini name="intl.error_level" value="0"/>
<ini name="display_errors" value="On"/>
</php>
<testsuites>
<testsuite name="all">
<directory>tests/PHPUnit</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>src</directory>
</include>
</source>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
backupGlobals="false"
bootstrap="vendor/autoload.php"
colors="true"
processIsolation="false"
stopOnFailure="false"
cacheDirectory=".phpunit.cache"
backupStaticProperties="false"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnWarning="true">
<php>
<ini name="error_reporting" value="-1"/>
<ini name="zend.enable_gc" value="0"/>
<ini name="error_reporting" value="-1"/>
<ini name="intl.error_level" value="0"/>
<ini name="display_errors" value="On"/>
<ini name="memory_limit" value="1G"/>
</php>
<testsuites>
<testsuite name="all">
<directory>tests/PHPUnit</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory>src</directory>
</include>
</source>
</phpunit>
9 changes: 9 additions & 0 deletions src/Smalot/PdfParser/Font.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ public static function uchr($code): string
// note:
// $code was typed as int before, but changed in https://github.com/smalot/pdfparser/pull/623
// because in some cases uchr was called with a float instead of an integer.
//
// A float that is out of integer range (e.g. resulting from a hexdec()
// overflow) cannot be cast to int without raising a "not representable
// as int" warning on PHP 8.1+, and such a value can never be a valid
// Unicode code point, so we treat it as a missing character.
if (\is_float($code) && (!\is_finite($code) || $code < \PHP_INT_MIN || $code > \PHP_INT_MAX)) {
return self::MISSING;
}

$code = (int) $code;

if (!isset(self::$uchrCache[$code])) {
Expand Down
32 changes: 32 additions & 0 deletions tests/PHPUnit/Unit/FontTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,36 @@ public function testDecodeTextIssue597(): void
// compare result with expected value
self::assertEquals('3cc2ab083e', bin2hex($result));
}

/**
* A CMap could contain oversized hex values. hexdec() then returns a float
* larger than PHP_INT_MAX which cannot be cast to int. On PHP 8.5 this
* cast raises a "not representable as int" warning.
*
* Since these values can not represent valid Unicode code points anyway,
* it's safe to return Font::MISSING for them. This test checks that this
* is the case.
*
* The test relies on PhpUnit's failOnWarning="true" in phpunit.xml:
* a warning would error.
*
* @see https://github.com/smalot/pdfparser/pull/623
* @see https://github.com/smalot/pdfparser/pull/825
*/
public function testUchrWithOutOfRangeFloat(): void
{
// a regular code point is still decoded
$this->assertEquals('A', Font::uchr(0x41));

// a float that fits into an integer is still cast and decoded; this is
// the reason uchr() accepts floats in the first place
$this->assertEquals('A', Font::uchr(65.0));

// floats that do not fit into an integer can never be a valid code
// point; the value below is produced by hexdec() of an oversized hex
// string taken from samples/bugs/Issue621.pdf
$this->assertEquals(Font::MISSING, Font::uchr(1.50646556872121E+28));
$this->assertEquals(Font::MISSING, Font::uchr(\INF));
$this->assertEquals(Font::MISSING, Font::uchr(\NAN));
}
}
Loading