From 658000d06b68e77a86ba15877623a50497d70a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maia?= Date: Sun, 6 Sep 2026 08:57:09 -0300 Subject: [PATCH 1/9] refactor(jsignpdf): move the hash algorithm resolution to a dedicated class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hash algorithm that signs a document depends on the PDF version, so it is not a valid answer for the other hashes JSignPdf takes: reusing it would send SHA1 to a timestamp authority whenever the document is older than PDF 1.6. Issue #8145 asks for each hash to be resolved on its own, which is hard to guarantee while the rules live inside the handler as private methods. Move getHashAlgorithm(), getHashAlgorithmForPdfVersion(), validateHashAlgorithm() and requiresPdfVersionUpgradeForSha256() to HashAlgorithmResolver, where each hash gets its own entry point and can be tested in isolation. The handler keeps reading the PDF version, the only part that is about the document and not about the policy. No behavior change: the same version thresholds, the same fallback to SHA256 and the same supported algorithms. Signed-off-by: André Maia Assisted-by: Claude Code:claude-opus-5 --- .../SignEngine/HashAlgorithmResolver.php | 86 ++++++++++++++++++ lib/Handler/SignEngine/JSignPdfHandler.php | 5 +- .../SignEngine/HashAlgorithmResolverTest.php | 90 +++++++++++++++++++ .../SignEngine/JSignPdfHandlerTest.php | 4 + 4 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 lib/Handler/SignEngine/HashAlgorithmResolver.php create mode 100644 tests/php/Unit/Handler/SignEngine/HashAlgorithmResolverTest.php diff --git a/lib/Handler/SignEngine/HashAlgorithmResolver.php b/lib/Handler/SignEngine/HashAlgorithmResolver.php new file mode 100644 index 0000000000..3925f692be --- /dev/null +++ b/lib/Handler/SignEngine/HashAlgorithmResolver.php @@ -0,0 +1,86 @@ +getConfiguredAlgorithm(); + /** + * Need to respect the follow code: + * https://github.com/intoolswetrust/jsignpdf/blob/JSignPdf_2_2_2/jsignpdf/src/main/java/net/sf/jsignpdf/types/HashAlgorithm.java#L46-L47 + */ + if ($pdfVersion === null) { + return $this->validate($configuredAlgorithm); + } + + return $this->forPdfVersion($pdfVersion, $configuredAlgorithm); + } + + /** + * PDFs older than 1.6 have to be upgraded before JSignPdf accepts SHA-256. + */ + public function requiresPdfVersionUpgradeForSha256(float $pdfVersion): bool { + if ($pdfVersion >= self::MIN_PDF_VERSION_SHA256) { + return false; + } + + return $this->getConfiguredAlgorithm() === self::DEFAULT_ALGORITHM; + } + + private function forPdfVersion(float $pdfVersion, string $configuredAlgorithm): string { + // Legacy compatibility: JSignPdf still requires SHA1 for very old PDFs (< 1.6). + // The policy still exposes SHA1 for supported legacy workflows, and the runtime + // must continue enforcing this fallback for ancient PDFs that JSignPdf cannot sign otherwise. + if ($pdfVersion < self::MIN_PDF_VERSION_SHA256) { + return 'SHA1'; + } + if ($pdfVersion < self::MIN_PDF_VERSION_SHA1_REJECT) { + return self::DEFAULT_ALGORITHM; + } + if ($configuredAlgorithm === 'SHA1') { + return self::DEFAULT_ALGORITHM; + } + + return $this->validate($configuredAlgorithm); + } + + private function validate(string $algorithm): string { + return in_array($algorithm, self::SUPPORTED_ALGORITHMS, true) ? $algorithm : self::DEFAULT_ALGORITHM; + } + + private function getConfiguredAlgorithm(): string { + return (string)$this->policyService->resolve(SignatureHashAlgorithmPolicy::KEY)->getEffectiveValue(); + } +} diff --git a/lib/Handler/SignEngine/JSignPdfHandler.php b/lib/Handler/SignEngine/JSignPdfHandler.php index 37e027cc7d..8130e8a3bb 100644 --- a/lib/Handler/SignEngine/JSignPdfHandler.php +++ b/lib/Handler/SignEngine/JSignPdfHandler.php @@ -50,6 +50,7 @@ public function __construct( protected CertificateEngineFactory $certificateEngineFactory, protected JavaHelper $javaHelper, private DocMdpConfigService $docMdpConfigService, + private HashAlgorithmResolver $hashAlgorithmResolver, ) { } @@ -205,7 +206,7 @@ private function normalizePdfVersion(string $content): string { // Convert PDFs < 1.6 to 1.6 if using SHA-256 (the default hash algorithm) // This prevents "The chosen hash algorithm (SHA-256) requires a newer PDF version" error - if ($this->requiresPdfVersionUpgradeForSha256($version)) { + if ($this->hashAlgorithmResolver->requiresPdfVersionUpgradeForSha256($version)) { return $this->replacePdfVersion($content, self::TARGET_PDF_VERSION_SHA256); } @@ -248,7 +249,7 @@ public function sign(): File { #[\Override] public function getSignedContent(): string { $normalizedPdf = $this->normalizePdfVersion($this->getInputFile()->getContent()); - $hashAlgorithm = $this->getHashAlgorithm($normalizedPdf); + $hashAlgorithm = $this->hashAlgorithmResolver->forSignature($this->extractPdfVersion($normalizedPdf)); $param = $this->getJSignParam(); $param->setCertificate($this->getCertificate()) ->setPdf($normalizedPdf) diff --git a/tests/php/Unit/Handler/SignEngine/HashAlgorithmResolverTest.php b/tests/php/Unit/Handler/SignEngine/HashAlgorithmResolverTest.php new file mode 100644 index 0000000000..e3cb6f9ebe --- /dev/null +++ b/tests/php/Unit/Handler/SignEngine/HashAlgorithmResolverTest.php @@ -0,0 +1,90 @@ +policyService = $this->createMock(PolicyService::class); + } + + private function getInstance(mixed $configuredAlgorithm): HashAlgorithmResolver { + $this->policyService + ->method('resolve') + ->with(SignatureHashAlgorithmPolicy::KEY) + ->willReturn( + (new ResolvedPolicy()) + ->setPolicyKey(SignatureHashAlgorithmPolicy::KEY) + ->setEffectiveValue($configuredAlgorithm) + ); + + return new HashAlgorithmResolver($this->policyService); + } + + #[DataProvider('providerSignatureHashAlgorithm')] + public function testForSignature(mixed $configuredAlgorithm, ?float $pdfVersion, string $expected): void { + $resolver = $this->getInstance($configuredAlgorithm); + + $this->assertSame($expected, $resolver->forSignature($pdfVersion)); + } + + public static function providerSignatureHashAlgorithm(): array { + return [ + // Unknown PDF version: only the configured algorithm decides. + 'unknown version keeps a supported algorithm' => ['SHA384', null, 'SHA384'], + 'unknown version keeps RIPEMD160' => ['RIPEMD160', null, 'RIPEMD160'], + 'unknown version falls back on an empty algorithm' => ['', null, 'SHA256'], + 'unknown version falls back on an unsupported algorithm' => ['XYZ', null, 'SHA256'], + 'unknown version falls back on an unset policy' => [null, null, 'SHA256'], + // JSignPdf only accepts SHA1 in PDFs older than 1.6. + 'PDF 1.0 is signed with SHA1' => ['SHA256', 1.0, 'SHA1'], + 'PDF 1.5 is signed with SHA1' => ['SHA512', 1.5, 'SHA1'], + // Between 1.6 and 1.7 JSignPdf only accepts SHA256. + 'PDF 1.6 is signed with SHA256' => ['SHA384', 1.6, 'SHA256'], + 'PDF 1.6 ignores an unsupported algorithm' => ['XYZ', 1.6, 'SHA256'], + // From 1.7 on the configured algorithm is used, except SHA1. + 'PDF 1.7 keeps the configured SHA384' => ['SHA384', 1.7, 'SHA384'], + 'PDF 1.7 keeps the configured SHA512' => ['SHA512', 1.7, 'SHA512'], + 'PDF 1.7 keeps the configured RIPEMD160' => ['RIPEMD160', 1.7, 'RIPEMD160'], + 'PDF 1.7 replaces SHA1 with SHA256' => ['SHA1', 1.7, 'SHA256'], + 'PDF 2.0 replaces SHA1 with SHA256' => ['SHA1', 2.0, 'SHA256'], + 'PDF 2.0 falls back on an unsupported algorithm' => ['XYZ', 2.0, 'SHA256'], + 'PDF 2.0 keeps the configured SHA512' => ['SHA512', 2.0, 'SHA512'], + ]; + } + + #[DataProvider('providerPdfVersionUpgrade')] + public function testRequiresPdfVersionUpgradeForSha256(mixed $configuredAlgorithm, float $pdfVersion, bool $expected): void { + $resolver = $this->getInstance($configuredAlgorithm); + + $this->assertSame($expected, $resolver->requiresPdfVersionUpgradeForSha256($pdfVersion)); + } + + public static function providerPdfVersionUpgrade(): array { + return [ + 'SHA256 in a PDF 1.2 needs the upgrade' => ['SHA256', 1.2, true], + 'SHA256 in a PDF 1.5 needs the upgrade' => ['SHA256', 1.5, true], + 'SHA256 in a PDF 1.6 does not need the upgrade' => ['SHA256', 1.6, false], + 'SHA256 in a PDF 1.7 does not need the upgrade' => ['SHA256', 1.7, false], + 'SHA1 in a PDF 1.5 does not need the upgrade' => ['SHA1', 1.5, false], + 'SHA512 in a PDF 1.5 does not need the upgrade' => ['SHA512', 1.5, false], + 'an unset policy in a PDF 1.5 does not need the upgrade' => [null, 1.5, false], + ]; + } +} diff --git a/tests/php/Unit/Handler/SignEngine/JSignPdfHandlerTest.php b/tests/php/Unit/Handler/SignEngine/JSignPdfHandlerTest.php index 5a0d4fa00d..ad031d0441 100644 --- a/tests/php/Unit/Handler/SignEngine/JSignPdfHandlerTest.php +++ b/tests/php/Unit/Handler/SignEngine/JSignPdfHandlerTest.php @@ -14,6 +14,7 @@ use OCA\Libresign\Enum\DocMdpLevel; use OCA\Libresign\Exception\LibresignException; use OCA\Libresign\Handler\CertificateEngine\CertificateEngineFactory; +use OCA\Libresign\Handler\SignEngine\HashAlgorithmResolver; use OCA\Libresign\Handler\SignEngine\JSignPdfHandler; use OCA\Libresign\Helper\JavaHelper; use OCA\Libresign\Service\DocMdp\ConfigService as DocMdpConfigService; @@ -93,6 +94,7 @@ private function getInstance(array $methods = []): JSignPdfHandler|MockObject { // Create mock factory if initialization failed in setUpBeforeClass $certificateEngineFactory = self::$certificateEngineFactory ?? $this->createMock(CertificateEngineFactory::class); + $hashAlgorithmResolver = new HashAlgorithmResolver($policyService); if (empty($methods)) { return new JSignPdfHandler( @@ -104,6 +106,7 @@ private function getInstance(array $methods = []): JSignPdfHandler|MockObject { $certificateEngineFactory, $this->javaHelper, $this->createMock(DocMdpConfigService::class), + $hashAlgorithmResolver, ); } return $this->getMockBuilder(JSignPdfHandler::class) @@ -116,6 +119,7 @@ private function getInstance(array $methods = []): JSignPdfHandler|MockObject { $certificateEngineFactory, $this->javaHelper, $this->createMock(DocMdpConfigService::class), + $hashAlgorithmResolver, ]) ->onlyMethods($methods) ->getMock(); From 7de8eafff94f34a2b88fb0a8956ecd1f5946ad0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maia?= Date: Sun, 6 Sep 2026 11:33:22 -0300 Subject: [PATCH 2/9] refactor(jsignpdf): group the JSignPdf classes in their own namespace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor(jsignpdf): group the JSignPdf classes in their own namespace Both the handler and the resolver carry rules that only make sense for JSignPdf — the PDF version thresholds come from its own HashAlgorithm enum — so they move to SignEngine/JSignPdf/ and the resolver keeps a name that does not need to repeat the engine. Pkcs12Handler used to build the handler class name at runtime from the configured engine ('...\SignEngine\' . ucfirst($property)), a string no static analysis, IDE rename or grep could follow: moving the class would only fail when a document was signed. It now resolves through an explicit map, so a name that is not an engine answers the same friendly error instead of reaching the container. Signed-off-by: André Maia Assisted-by: Claude Code:claude-opus-5 [skip ci] --- .../{ => JSignPdf}/HashAlgorithmResolver.php | 2 +- .../{ => JSignPdf}/JSignPdfHandler.php | 3 +- lib/Handler/SignEngine/Pkcs12Handler.php | 12 +++++- lib/SetupCheck/JSignPdfSetupCheck.php | 2 +- .../HashAlgorithmResolverTest.php | 4 +- .../{ => JSignPdf}/JSignPdfHandlerTest.php | 42 +++++++++---------- .../SetupCheck/JSignPdfSetupCheckTest.php | 2 +- 7 files changed, 38 insertions(+), 29 deletions(-) rename lib/Handler/SignEngine/{ => JSignPdf}/HashAlgorithmResolver.php (98%) rename lib/Handler/SignEngine/{ => JSignPdf}/JSignPdfHandler.php (99%) rename tests/php/Unit/Handler/SignEngine/{ => JSignPdf}/HashAlgorithmResolverTest.php (96%) rename tests/php/Unit/Handler/SignEngine/{ => JSignPdf}/JSignPdfHandlerTest.php (97%) diff --git a/lib/Handler/SignEngine/HashAlgorithmResolver.php b/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php similarity index 98% rename from lib/Handler/SignEngine/HashAlgorithmResolver.php rename to lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php index 3925f692be..c9b1d231cf 100644 --- a/lib/Handler/SignEngine/HashAlgorithmResolver.php +++ b/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php @@ -6,7 +6,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Libresign\Handler\SignEngine; +namespace OCA\Libresign\Handler\SignEngine\JSignPdf; use OCA\Libresign\Service\Policy\PolicyService; use OCA\Libresign\Service\Policy\Provider\SignatureHashAlgorithm\SignatureHashAlgorithmPolicy; diff --git a/lib/Handler/SignEngine/JSignPdfHandler.php b/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php similarity index 99% rename from lib/Handler/SignEngine/JSignPdfHandler.php rename to lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php index 8130e8a3bb..e414b77046 100644 --- a/lib/Handler/SignEngine/JSignPdfHandler.php +++ b/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php @@ -6,13 +6,14 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Libresign\Handler\SignEngine; +namespace OCA\Libresign\Handler\SignEngine\JSignPdf; use Imagick; use ImagickPixel; use OCA\Libresign\AppInfo\Application; use OCA\Libresign\Exception\LibresignException; use OCA\Libresign\Handler\CertificateEngine\CertificateEngineFactory; +use OCA\Libresign\Handler\SignEngine\Pkcs12Handler; use OCA\Libresign\Helper\JavaHelper; use OCA\Libresign\Service\DocMdp\ConfigService as DocMdpConfigService; use OCA\Libresign\Service\SignatureBackgroundService; diff --git a/lib/Handler/SignEngine/Pkcs12Handler.php b/lib/Handler/SignEngine/Pkcs12Handler.php index 3b00dddc7c..46d1a8396d 100644 --- a/lib/Handler/SignEngine/Pkcs12Handler.php +++ b/lib/Handler/SignEngine/Pkcs12Handler.php @@ -14,6 +14,7 @@ use OCA\Libresign\Handler\CertificateEngine\OrderCertificatesTrait; use OCA\Libresign\Handler\DocMdpHandler; use OCA\Libresign\Handler\FooterHandler; +use OCA\Libresign\Handler\SignEngine\JSignPdf\JSignPdfHandler; use OCA\Libresign\Service\CaIdentifierService; use OCA\Libresign\Service\Crl\CrlService; use OCA\Libresign\Service\FolderService; @@ -30,6 +31,11 @@ class Pkcs12Handler extends SignEngineHandler { use OrderCertificatesTrait; protected string $certificate = ''; + /** @var array> */ + private const ENGINE_HANDLERS = [ + 'jSignPdfHandler' => JSignPdfHandler::class, + 'phpNativeHandler' => PhpNativeHandler::class, + ]; private ?JSignPdfHandler $jSignPdfHandler = null; private ?PhpNativeHandler $phpNativeHandler = null; private string $rootCertificatePem = ''; @@ -358,11 +364,13 @@ private function enrichLeafWithNativeData( private function getHandler(): SignEngineHandler { $sign_engine = $this->appConfig->getValueString(Application::APP_ID, 'signature_engine', 'JSignPdf'); $property = lcfirst($sign_engine) . 'Handler'; - if (!property_exists($this, $property)) { + // Resolved through a class map instead of a name built at runtime, so + // moving a handler to another namespace cannot break this silently. + if (!isset(self::ENGINE_HANDLERS[$property])) { // TRANSLATORS API/config error when LibreSign's signature_engine setting names a backend that is not available (for example a mistyped JSignPdf/native engine). throw new LibresignException($this->l10n->t('Invalid Sign engine.'), 400); } - $classHandler = 'OCA\\Libresign\\Handler\\SignEngine\\' . ucfirst($property); + $classHandler = self::ENGINE_HANDLERS[$property]; if (!$this->$property instanceof $classHandler) { $this->$property = \OCP\Server::get($classHandler); } diff --git a/lib/SetupCheck/JSignPdfSetupCheck.php b/lib/SetupCheck/JSignPdfSetupCheck.php index baeef16287..5037e63a06 100644 --- a/lib/SetupCheck/JSignPdfSetupCheck.php +++ b/lib/SetupCheck/JSignPdfSetupCheck.php @@ -9,7 +9,7 @@ namespace OCA\Libresign\SetupCheck; use OCA\Libresign\AppInfo\Application; -use OCA\Libresign\Handler\SignEngine\JSignPdfHandler; +use OCA\Libresign\Handler\SignEngine\JSignPdf\JSignPdfHandler; use OCA\Libresign\Helper\JavaHelper; use OCA\Libresign\Service\Install\InstallService; use OCA\Libresign\Service\Install\SignSetupService; diff --git a/tests/php/Unit/Handler/SignEngine/HashAlgorithmResolverTest.php b/tests/php/Unit/Handler/SignEngine/JSignPdf/HashAlgorithmResolverTest.php similarity index 96% rename from tests/php/Unit/Handler/SignEngine/HashAlgorithmResolverTest.php rename to tests/php/Unit/Handler/SignEngine/JSignPdf/HashAlgorithmResolverTest.php index e3cb6f9ebe..754eaf5247 100644 --- a/tests/php/Unit/Handler/SignEngine/HashAlgorithmResolverTest.php +++ b/tests/php/Unit/Handler/SignEngine/JSignPdf/HashAlgorithmResolverTest.php @@ -6,9 +6,9 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Libresign\Tests\Unit\Handler\SignEngine; +namespace OCA\Libresign\Tests\Unit\Handler\SignEngine\JSignPdf; -use OCA\Libresign\Handler\SignEngine\HashAlgorithmResolver; +use OCA\Libresign\Handler\SignEngine\JSignPdf\HashAlgorithmResolver; use OCA\Libresign\Service\Policy\Model\ResolvedPolicy; use OCA\Libresign\Service\Policy\PolicyService; use OCA\Libresign\Service\Policy\Provider\SignatureHashAlgorithm\SignatureHashAlgorithmPolicy; diff --git a/tests/php/Unit/Handler/SignEngine/JSignPdfHandlerTest.php b/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php similarity index 97% rename from tests/php/Unit/Handler/SignEngine/JSignPdfHandlerTest.php rename to tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php index ad031d0441..b76f31055b 100644 --- a/tests/php/Unit/Handler/SignEngine/JSignPdfHandlerTest.php +++ b/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php @@ -6,7 +6,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Libresign\Tests\Unit\Handler\SignEngine; +namespace OCA\Libresign\Tests\Unit\Handler\SignEngine\JSignPdf; use OCA\Libresign\AppInfo\Application; use OCA\Libresign\DataObjects\VisibleElementAssoc; @@ -14,8 +14,8 @@ use OCA\Libresign\Enum\DocMdpLevel; use OCA\Libresign\Exception\LibresignException; use OCA\Libresign\Handler\CertificateEngine\CertificateEngineFactory; -use OCA\Libresign\Handler\SignEngine\HashAlgorithmResolver; -use OCA\Libresign\Handler\SignEngine\JSignPdfHandler; +use OCA\Libresign\Handler\SignEngine\JSignPdf\HashAlgorithmResolver; +use OCA\Libresign\Handler\SignEngine\JSignPdf\JSignPdfHandler; use OCA\Libresign\Helper\JavaHelper; use OCA\Libresign\Service\DocMdp\ConfigService as DocMdpConfigService; use OCA\Libresign\Service\SignatureBackgroundService; @@ -278,7 +278,7 @@ public function testSignAffectedParams( ); $this->signatureBackgroundService->method('getImagePath')->willReturn( - realpath(__DIR__ . '/../../../../../img/LibreSign.png') + realpath(__DIR__ . '/../../../../../../img/LibreSign.png') ); $this->appConfig->setValueFloat('libresign', 'template_font_size', $templateFontSize); @@ -345,7 +345,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 0, 'urx' => 0, 'ury' => 0, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 100, 'signatureHeight' => 100, 'template' => '', @@ -363,7 +363,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 20, 'signatureHeight' => 20, 'template' => '', @@ -381,7 +381,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 20, 'signatureHeight' => 20, 'template' => 'aaaaa', @@ -399,7 +399,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 20, 'signatureHeight' => 20, 'template' => 'aaaaa', @@ -417,7 +417,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 20, 'signatureHeight' => 20, 'template' => 'aaaaa', @@ -435,7 +435,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 20, 'signatureHeight' => 20, 'template' => 'a"b $c \'d e', @@ -453,7 +453,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 20, 'signatureHeight' => 20, 'template' => '', @@ -471,7 +471,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 20, 'signatureHeight' => 20, 'template' => 'aaaaa', @@ -489,7 +489,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 100, 'urx' => 351, 'ury' => 200, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 350, 'signatureHeight' => 100, 'template' => 'aaaaa', @@ -507,7 +507,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 20, 'signatureHeight' => 20, 'template' => 'aaaaa', @@ -564,7 +564,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 20, 'signatureHeight' => 20, 'template' => '', @@ -582,7 +582,7 @@ public static function providerSignAffectedParams(): array { 'lly' => 20, 'urx' => 30, 'ury' => 40, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png'))], + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png'))], 'signatureWidth' => 0, 'signatureHeight' => 0, 'template' => '', @@ -606,7 +606,7 @@ public function testDocMdpAppliedOnlyOnFirstVisibleElement(): void { $this->signatureBackgroundService->method('getSignatureBackgroundType')->willReturn('deleted'); $this->signatureBackgroundService->method('getImagePath')->willReturn( - realpath(__DIR__ . '/../../../../../img/LibreSign.png') + realpath(__DIR__ . '/../../../../../../img/LibreSign.png') ); $this->appConfig->setValueFloat('libresign', 'template_font_size', 10); @@ -641,14 +641,14 @@ public function testDocMdpAppliedOnlyOnFirstVisibleElement(): void { 'lly' => 10, 'urx' => 110, 'ury' => 60, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png')), + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png')), self::getElement([ 'page' => 1, 'llx' => 120, 'lly' => 10, 'urx' => 220, 'ury' => 60, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png')), + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png')), ]); $jSignPdfHandler->setJSignPdf($mock); $jSignPdfHandler->setInputFile($inputFile); @@ -673,7 +673,7 @@ public function testDocMdpSkippedWhenSignatureExists(): void { $this->signatureBackgroundService->method('getSignatureBackgroundType')->willReturn('deleted'); $this->signatureBackgroundService->method('getImagePath')->willReturn( - realpath(__DIR__ . '/../../../../../img/LibreSign.png') + realpath(__DIR__ . '/../../../../../../img/LibreSign.png') ); $this->appConfig->setValueFloat('libresign', 'template_font_size', 10); @@ -708,7 +708,7 @@ public function testDocMdpSkippedWhenSignatureExists(): void { 'lly' => 10, 'urx' => 110, 'ury' => 60, - ], realpath(__DIR__ . '/../../../../../img/app-dark.png')), + ], realpath(__DIR__ . '/../../../../../../img/app-dark.png')), ]); $jSignPdfHandler->setJSignPdf($mock); $jSignPdfHandler->setInputFile($inputFile); diff --git a/tests/php/Unit/SetupCheck/JSignPdfSetupCheckTest.php b/tests/php/Unit/SetupCheck/JSignPdfSetupCheckTest.php index 9e56a4fdf3..efbdf37c6b 100644 --- a/tests/php/Unit/SetupCheck/JSignPdfSetupCheckTest.php +++ b/tests/php/Unit/SetupCheck/JSignPdfSetupCheckTest.php @@ -22,7 +22,7 @@ function is_dir(string $filename): bool { namespace OCA\Libresign\Tests\Unit\SetupCheck; -use OCA\Libresign\Handler\SignEngine\JSignPdfHandler; +use OCA\Libresign\Handler\SignEngine\JSignPdf\JSignPdfHandler; use OCA\Libresign\Helper\JavaHelper; use OCA\Libresign\Service\Install\InstallService; use OCA\Libresign\Service\Install\JSignPdfRelease; From 954f9fa4c16ab5bc5be6510745bddafa6d101899 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:15:46 -0300 Subject: [PATCH 3/9] fix(stable34): adapt hash resolver config source Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php b/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php index c9b1d231cf..60597b177d 100644 --- a/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php +++ b/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php @@ -8,8 +8,8 @@ namespace OCA\Libresign\Handler\SignEngine\JSignPdf; -use OCA\Libresign\Service\Policy\PolicyService; -use OCA\Libresign\Service\Policy\Provider\SignatureHashAlgorithm\SignatureHashAlgorithmPolicy; +use OCA\Libresign\AppInfo\Application; +use OCP\IAppConfig; /** * Resolves which hash algorithm JSignPdf has to use. @@ -26,7 +26,7 @@ class HashAlgorithmResolver { private const array SUPPORTED_ALGORITHMS = ['SHA1', 'SHA256', 'SHA384', 'SHA512', 'RIPEMD160']; public function __construct( - private PolicyService $policyService, + private IAppConfig $appConfig, ) { } @@ -81,6 +81,6 @@ private function validate(string $algorithm): string { } private function getConfiguredAlgorithm(): string { - return (string)$this->policyService->resolve(SignatureHashAlgorithmPolicy::KEY)->getEffectiveValue(); + return $this->appConfig->getValueString(Application::APP_ID, 'signature_hash_algorithm', self::DEFAULT_ALGORITHM); } } From 2a85d936e81b7cf1bf408b9967887507cabccff9 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:15:46 -0300 Subject: [PATCH 4/9] fix(stable34): remove duplicated hash resolution Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- .../SignEngine/JSignPdf/JSignPdfHandler.php | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php b/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php index e414b77046..908aaa7d10 100644 --- a/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php +++ b/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php @@ -29,9 +29,7 @@ class JSignPdfHandler extends Pkcs12Handler { private const MIN_PDF_VERSION = 1.2; private const TARGET_OLD_PDF_VERSION = '1.3'; - private const MIN_PDF_VERSION_SHA256 = 1.6; private const TARGET_PDF_VERSION_SHA256 = '1.6'; - private const MIN_PDF_VERSION_SHA1_REJECT = 1.7; private const SIGNATURE_DEFAULT_FONT_SIZE = 10.0; private const PAGE_FIRST = 1; private const SCALE_FACTOR_MIN = 5; @@ -148,20 +146,6 @@ private function createEmptyFile(string $path): void { fclose($file); } - private function getHashAlgorithm(string $pdfContent): string { - $configuredAlgorithm = $this->appConfig->getValueString(Application::APP_ID, 'signature_hash_algorithm', 'SHA256'); - /** - * Need to respect the follow code: - * https://github.com/intoolswetrust/jsignpdf/blob/JSignPdf_2_2_2/jsignpdf/src/main/java/net/sf/jsignpdf/types/HashAlgorithm.java#L46-L47 - */ - $pdfVersion = $this->extractPdfVersion($pdfContent); - - if ($pdfVersion === null) { - return $this->validateHashAlgorithm($configuredAlgorithm); - } - - return $this->getHashAlgorithmForPdfVersion($pdfVersion, $configuredAlgorithm); - } private function extractPdfVersion(string $content): ?float { if (!preg_match('/^%PDF-(?\d+(\.\d+)?)/', $content, $match)) { @@ -170,23 +154,7 @@ private function extractPdfVersion(string $content): ?float { return (float)$match['version']; } - private function getHashAlgorithmForPdfVersion(float $pdfVersion, string $configuredAlgorithm): string { - if ($pdfVersion < 1.6) { - return 'SHA1'; - } - if ($pdfVersion < self::MIN_PDF_VERSION_SHA1_REJECT) { - return 'SHA256'; - } - if ($pdfVersion >= self::MIN_PDF_VERSION_SHA1_REJECT && $configuredAlgorithm === 'SHA1') { - return 'SHA256'; - } - return $this->validateHashAlgorithm($configuredAlgorithm); - } - private function validateHashAlgorithm(string $algorithm): string { - $supportedAlgorithms = ['SHA1', 'SHA256', 'SHA384', 'SHA512', 'RIPEMD160']; - return in_array($algorithm, $supportedAlgorithms) ? $algorithm : 'SHA256'; - } /** * Normalizes very old PDFs (1.0/1.1) to 1.3. @@ -218,13 +186,6 @@ private function isVeryOldPdfVersion(float $version): bool { return $version > 0 && $version < self::MIN_PDF_VERSION; } - private function requiresPdfVersionUpgradeForSha256(float $version): bool { - if ($version >= self::MIN_PDF_VERSION_SHA256) { - return false; - } - $hashAlgorithm = $this->appConfig->getValueString(Application::APP_ID, 'signature_hash_algorithm', 'SHA256'); - return $hashAlgorithm === 'SHA256'; - } private function replacePdfVersion(string $content, string $newVersion): string { return (string)preg_replace('/^%PDF-\d+(\.\d+)?/', '%PDF-' . $newVersion, $content, 1); From 415039d4a0f58fdb368a786b89c1a9d4b84156fa Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:15:46 -0300 Subject: [PATCH 5/9] test(stable34): adapt hash resolver tests Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- .../JSignPdf/HashAlgorithmResolverTest.php | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/tests/php/Unit/Handler/SignEngine/JSignPdf/HashAlgorithmResolverTest.php b/tests/php/Unit/Handler/SignEngine/JSignPdf/HashAlgorithmResolverTest.php index 754eaf5247..1dbe7683bd 100644 --- a/tests/php/Unit/Handler/SignEngine/JSignPdf/HashAlgorithmResolverTest.php +++ b/tests/php/Unit/Handler/SignEngine/JSignPdf/HashAlgorithmResolverTest.php @@ -8,37 +8,32 @@ namespace OCA\Libresign\Tests\Unit\Handler\SignEngine\JSignPdf; +use OCA\Libresign\AppInfo\Application; use OCA\Libresign\Handler\SignEngine\JSignPdf\HashAlgorithmResolver; -use OCA\Libresign\Service\Policy\Model\ResolvedPolicy; -use OCA\Libresign\Service\Policy\PolicyService; -use OCA\Libresign\Service\Policy\Provider\SignatureHashAlgorithm\SignatureHashAlgorithmPolicy; +use OCP\IAppConfig; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; class HashAlgorithmResolverTest extends TestCase { - private PolicyService&MockObject $policyService; + private IAppConfig&MockObject $appConfig; #[\Override] protected function setUp(): void { - $this->policyService = $this->createMock(PolicyService::class); + $this->appConfig = $this->createMock(IAppConfig::class); } - private function getInstance(mixed $configuredAlgorithm): HashAlgorithmResolver { - $this->policyService - ->method('resolve') - ->with(SignatureHashAlgorithmPolicy::KEY) - ->willReturn( - (new ResolvedPolicy()) - ->setPolicyKey(SignatureHashAlgorithmPolicy::KEY) - ->setEffectiveValue($configuredAlgorithm) - ); + private function getInstance(string $configuredAlgorithm): HashAlgorithmResolver { + $this->appConfig + ->method('getValueString') + ->with(Application::APP_ID, 'signature_hash_algorithm', 'SHA256') + ->willReturn($configuredAlgorithm); - return new HashAlgorithmResolver($this->policyService); + return new HashAlgorithmResolver($this->appConfig); } #[DataProvider('providerSignatureHashAlgorithm')] - public function testForSignature(mixed $configuredAlgorithm, ?float $pdfVersion, string $expected): void { + public function testForSignature(string $configuredAlgorithm, ?float $pdfVersion, string $expected): void { $resolver = $this->getInstance($configuredAlgorithm); $this->assertSame($expected, $resolver->forSignature($pdfVersion)); @@ -51,7 +46,6 @@ public static function providerSignatureHashAlgorithm(): array { 'unknown version keeps RIPEMD160' => ['RIPEMD160', null, 'RIPEMD160'], 'unknown version falls back on an empty algorithm' => ['', null, 'SHA256'], 'unknown version falls back on an unsupported algorithm' => ['XYZ', null, 'SHA256'], - 'unknown version falls back on an unset policy' => [null, null, 'SHA256'], // JSignPdf only accepts SHA1 in PDFs older than 1.6. 'PDF 1.0 is signed with SHA1' => ['SHA256', 1.0, 'SHA1'], 'PDF 1.5 is signed with SHA1' => ['SHA512', 1.5, 'SHA1'], @@ -70,7 +64,7 @@ public static function providerSignatureHashAlgorithm(): array { } #[DataProvider('providerPdfVersionUpgrade')] - public function testRequiresPdfVersionUpgradeForSha256(mixed $configuredAlgorithm, float $pdfVersion, bool $expected): void { + public function testRequiresPdfVersionUpgradeForSha256(string $configuredAlgorithm, float $pdfVersion, bool $expected): void { $resolver = $this->getInstance($configuredAlgorithm); $this->assertSame($expected, $resolver->requiresPdfVersionUpgradeForSha256($pdfVersion)); @@ -84,7 +78,6 @@ public static function providerPdfVersionUpgrade(): array { 'SHA256 in a PDF 1.7 does not need the upgrade' => ['SHA256', 1.7, false], 'SHA1 in a PDF 1.5 does not need the upgrade' => ['SHA1', 1.5, false], 'SHA512 in a PDF 1.5 does not need the upgrade' => ['SHA512', 1.5, false], - 'an unset policy in a PDF 1.5 does not need the upgrade' => [null, 1.5, false], ]; } } From 8297456f4f0643526cb0a519cf0e2c90ce06900d Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:15:46 -0300 Subject: [PATCH 6/9] test(stable34): adapt JSignPdf handler tests Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- .../JSignPdf/JSignPdfHandlerTest.php | 35 +------------------ 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php b/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php index b76f31055b..e4a16b06b4 100644 --- a/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php +++ b/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php @@ -94,7 +94,7 @@ private function getInstance(array $methods = []): JSignPdfHandler|MockObject { // Create mock factory if initialization failed in setUpBeforeClass $certificateEngineFactory = self::$certificateEngineFactory ?? $this->createMock(CertificateEngineFactory::class); - $hashAlgorithmResolver = new HashAlgorithmResolver($policyService); + $hashAlgorithmResolver = new HashAlgorithmResolver($this->appConfig); if (empty($methods)) { return new JSignPdfHandler( @@ -131,39 +131,6 @@ private function setDocMdpConfigService(JSignPdfHandler $handler, DocMdpConfigSe $reflection->setValue($handler, $docMdpConfigService); } - #[DataProvider('providerGetHashAlgorithm')] - public function testGetHashAlgorithm(string $setting, string $content, string $expected): void { - if (self::$certificateEngineFactory === null || empty(self::$certificateContent)) { - $this->markTestSkipped('Certificate initialization failed'); - } - - $this->appConfig->setValueString('libresign', 'signature_hash_algorithm', $setting); - $instance = $this->getInstance(['getInputFile']); - $file = $this->createMock(\OCP\Files\File::class); - $file->method('getContent')->willReturn($content); - $instance->method('getInputFile')->willReturn($file); - $actual = self::invokePrivate($instance, 'getHashAlgorithm', [$content]); - $this->assertEquals($expected, $actual); - } - - public static function providerGetHashAlgorithm(): array { - return [ - 'empty setting, PDF 1.6' => ['', '%PDF-1.6', 'SHA256'], - 'invalid PDF header' => ['', 'random data', 'SHA256'], - 'invalid setting, fallback to SHA256 on PDF 1.7' => ['XYZ', '%PDF-1.7', 'SHA256'], - 'null-like setting, PDF 1.5' => ['0', '%PDF-1.5', 'SHA1'], - 'default with PDF 1.0' => ['', '%PDF-1', 'SHA1'], - 'SHA1 with PDF 1.5' => ['', '%PDF-1.5', 'SHA1'], - 'SHA1 with PDF 1.6' => ['', '%PDF-1.6', 'SHA256'], - 'SHA1 with PDF 1.7' => ['', '%PDF-1.7', 'SHA256'], - 'SHA1 with PDF 2.0' => ['', '%PDF-2.0', 'SHA256'], - 'SHA384, PDF 1.6 (fallback)' => ['SHA384', '%PDF-1.6', 'SHA256'], - 'SHA384, PDF 1.7' => ['SHA384', '%PDF-1.7', 'SHA384'], - 'SHA512, PDF 1.6' => ['SHA512', '%PDF-1.6', 'SHA256'], - 'RIPEMD160, PDF 1.6 (unsupported)' => ['RIPEMD160', '%PDF-1.6', 'SHA256'], - 'RIPEMD160, PDF 1.7 (supported)' => ['RIPEMD160', '%PDF-1.7', 'RIPEMD160'], - ]; - } #[DataProvider('providerExtractPdfVersion')] public function testExtractPdfVersion(string $content, ?float $expected): void { From b6bb8137f9378567d2a062c89e5b695a98134d5e Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:18:59 -0300 Subject: [PATCH 7/9] fix(stable34): support PHP 8.2 in hash resolver Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php b/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php index 60597b177d..f6c60bdfa6 100644 --- a/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php +++ b/lib/Handler/SignEngine/JSignPdf/HashAlgorithmResolver.php @@ -19,11 +19,11 @@ * own method here. */ class HashAlgorithmResolver { - private const float MIN_PDF_VERSION_SHA256 = 1.6; - private const float MIN_PDF_VERSION_SHA1_REJECT = 1.7; - private const string DEFAULT_ALGORITHM = 'SHA256'; + private const MIN_PDF_VERSION_SHA256 = 1.6; + private const MIN_PDF_VERSION_SHA1_REJECT = 1.7; + private const DEFAULT_ALGORITHM = 'SHA256'; /** @var string[] */ - private const array SUPPORTED_ALGORITHMS = ['SHA1', 'SHA256', 'SHA384', 'SHA512', 'RIPEMD160']; + private const SUPPORTED_ALGORITHMS = ['SHA1', 'SHA256', 'SHA384', 'SHA512', 'RIPEMD160']; public function __construct( private IAppConfig $appConfig, From 40105c37a011b003c8a6a8711c004fd0214e78c1 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:22:01 -0300 Subject: [PATCH 8/9] style(stable34): fix JSignPdf handler formatting Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php b/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php index 908aaa7d10..41479ca293 100644 --- a/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php +++ b/lib/Handler/SignEngine/JSignPdf/JSignPdfHandler.php @@ -146,7 +146,6 @@ private function createEmptyFile(string $path): void { fclose($file); } - private function extractPdfVersion(string $content): ?float { if (!preg_match('/^%PDF-(?\d+(\.\d+)?)/', $content, $match)) { return null; @@ -154,8 +153,6 @@ private function extractPdfVersion(string $content): ?float { return (float)$match['version']; } - - /** * Normalizes very old PDFs (1.0/1.1) to 1.3. * Rationale: JSignPDF enum PdfVersion only defines 1.2+; for 1.0/1.1, @@ -186,7 +183,6 @@ private function isVeryOldPdfVersion(float $version): bool { return $version > 0 && $version < self::MIN_PDF_VERSION; } - private function replacePdfVersion(string $content, string $newVersion): string { return (string)preg_replace('/^%PDF-\d+(\.\d+)?/', '%PDF-' . $newVersion, $content, 1); } From e16900d8d31d0cbe895ac18a0b9c36bb288d94d4 Mon Sep 17 00:00:00 2001 From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:22:15 -0300 Subject: [PATCH 9/9] style(stable34): fix JSignPdf handler test formatting Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> --- .../php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php b/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php index e4a16b06b4..f6f1643b30 100644 --- a/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php +++ b/tests/php/Unit/Handler/SignEngine/JSignPdf/JSignPdfHandlerTest.php @@ -131,7 +131,6 @@ private function setDocMdpConfigService(JSignPdfHandler $handler, DocMdpConfigSe $reflection->setValue($handler, $docMdpConfigService); } - #[DataProvider('providerExtractPdfVersion')] public function testExtractPdfVersion(string $content, ?float $expected): void { if (self::$certificateEngineFactory === null || empty(self::$certificateContent)) {