From 299225f3eafa57b3095af22f0081e49836986a62 Mon Sep 17 00:00:00 2001 From: PrinsFrank <25006490+PrinsFrank@users.noreply.github.com> Date: Sun, 4 Oct 2026 20:29:07 +0200 Subject: [PATCH] Correctly handle IdentityH encodings with incorrect byte sizes --- src/Document/CMap/ToUnicode/ToUnicodeCMap.php | 9 +++++---- .../PositionedText/TextSegment/TextSegment.php | 4 ++-- .../DictionaryValue/Name/EncodingNameValue.php | 3 --- tests/Samples/files/issue-534/contents.yml | 17 +++++++++++++++++ tests/Samples/files/issue-534/file.pdf | Bin 0 -> 745 bytes 5 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 tests/Samples/files/issue-534/contents.yml create mode 100644 tests/Samples/files/issue-534/file.pdf diff --git a/src/Document/CMap/ToUnicode/ToUnicodeCMap.php b/src/Document/CMap/ToUnicode/ToUnicodeCMap.php index 1d38ca8c..e7e535d9 100644 --- a/src/Document/CMap/ToUnicode/ToUnicodeCMap.php +++ b/src/Document/CMap/ToUnicode/ToUnicodeCMap.php @@ -31,12 +31,13 @@ public function __construct( } /** @throws PdfParserException */ - public function textToUnicode(string $characterGroup): string { + public function textToUnicode(string $binaryString): string { $unicode = ''; - $chunkSize = $this->byteSize * 2; - $nrOfChunks = strlen($characterGroup) / $chunkSize; + $nrOfChunks = strlen($binaryString) / $this->byteSize; for ($i = 0; $i < $nrOfChunks; $i++) { - $unicode .= $this->charToUnicode((int) hexdec(substr($characterGroup, $i * $chunkSize, $chunkSize))) ?? ''; + $binaryChunk = substr($binaryString, $i * $this->byteSize, $this->byteSize); + $charCode = (int) hexdec(bin2hex($binaryChunk)); + $unicode .= $this->charToUnicode($charCode) ?? ''; } return $unicode; diff --git a/src/Document/ContentStream/PositionedText/TextSegment/TextSegment.php b/src/Document/ContentStream/PositionedText/TextSegment/TextSegment.php index 505b2a58..d5e43e20 100644 --- a/src/Document/ContentStream/PositionedText/TextSegment/TextSegment.php +++ b/src/Document/ContentStream/PositionedText/TextSegment/TextSegment.php @@ -37,10 +37,10 @@ private function decode(string $binaryString, ?EncodingNameValue $encoding, ?ToU } if ($toUnicodeCMap !== null) { - return $toUnicodeCMap->textToUnicode(bin2hex($binaryString)); + return $toUnicodeCMap->textToUnicode($binaryString); } - if ($encoding !== null) { + if ($encoding !== null && !in_array($encoding, [EncodingNameValue::IdentityH, EncodingNameValue::IdentityV], true)) { return $encoding->decodeString($binaryString); } diff --git a/src/Document/Dictionary/DictionaryValue/Name/EncodingNameValue.php b/src/Document/Dictionary/DictionaryValue/Name/EncodingNameValue.php index 9f9a2f5d..209a2e62 100644 --- a/src/Document/Dictionary/DictionaryValue/Name/EncodingNameValue.php +++ b/src/Document/Dictionary/DictionaryValue/Name/EncodingNameValue.php @@ -2,7 +2,6 @@ namespace PrinsFrank\PdfParser\Document\Dictionary\DictionaryValue\Name; -use PrinsFrank\PdfParser\Document\CMap\Registry\Adobe\Identity0; use PrinsFrank\PdfParser\Document\Encoding\MacRoman; use PrinsFrank\PdfParser\Document\Encoding\WinAnsi; use PrinsFrank\PdfParser\Exception\ParseFailureException; @@ -16,8 +15,6 @@ enum EncodingNameValue: string implements NameValue { public function decodeString(string $characterGroup): string { return match ($this) { - self::IdentityH, - self::IdentityV => (new Identity0())->getToUnicodeCMap()->textToUnicode($characterGroup), self::WinAnsiEncoding => WinAnsi::textToUnicode($characterGroup), self::MacRomanEncoding => MacRoman::textToUnicode($characterGroup), default => throw new ParseFailureException(sprintf('Unsupported encoding %s', $this->name)), diff --git a/tests/Samples/files/issue-534/contents.yml b/tests/Samples/files/issue-534/contents.yml new file mode 100644 index 00000000..a1a415b4 --- /dev/null +++ b/tests/Samples/files/issue-534/contents.yml @@ -0,0 +1,17 @@ +# yaml-language-server: $schema=../../schema.json +version: '1.7' +userPassword: null +ownerPassword: null +fileEncryptionKey: null +title: null +producer: null +author: null +creator: null +subject: null +keywords: null +creationDate: null +modificationDate: null +pages: + - + text: 'Invoice 2026-0912 reference ABCDEF' + markdown: 'Invoice 2026-0912 reference ABCDEF' diff --git a/tests/Samples/files/issue-534/file.pdf b/tests/Samples/files/issue-534/file.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b2708ac0702069ea385038cb4b0fd6531cfe4e17 GIT binary patch literal 745 zcmaJe?5488YP_=2<@SlZB!At5A6TMcc~5cGyPgf_4umP~D!V84ELTLuGZQ4h`Y zv){Ah&NNE8&O=~1V1r(5t-%0Tdi<2Y#=?l5-T<45jjVtpVFtsYB~?yDy8lgRciiVKF4}9S?PV5p&@dbXw0a8 z9PmgHb?8G`Ww2TWZi}95)BU9WBGtycgYS{M%9K)kSYe7)9YDQw4FRfh8`2!^ChAKU znFMZgziam~UdpvZ$B2!>aTF)_kZvJPNvN&WPKu13B%9IJw%L5YGWDbhw1I`9l1*e( z7Gei1R+-KVg-7aFD%#ZH#>rp}9R b2?1_}*0f~phE_(DruOc+-0F1Vx5WAZY5&Lt literal 0 HcmV?d00001