Skip to content

fix(signature): apply the payload encoding to the clone, not the receiver - #695

Merged
Spomky merged 1 commit into
4.2.xfrom
fix/jws-builder-clone-mutation
Aug 28, 2026
Merged

fix(signature): apply the payload encoding to the clone, not the receiver#695
Spomky merged 1 commit into
4.2.xfrom
fix/jws-builder-clone-mutation

Conversation

@Spomky

@Spomky Spomky commented Aug 28, 2026

Copy link
Copy Markdown
Member

Fixes #679.

JWSBuilder::addSignature() is documented as immutable ("This method will return a new JWSBuilder object") but it wrote isPayloadEncoded on $this before cloning:

if ($this->isPayloadEncoded === null) {
    $this->isPayloadEncoded = $isPayloadEncoded;   // mutates the receiver
} elseif ($this->isPayloadEncoded !== $isPayloadEncoded) {
    throw new InvalidArgumentException('Foreign payload encoding detected.');
}

The bundle registers the builder as a shared service, so a single addSignature() call on the injected instance permanently pinned the b64 mode of that service: every later, unrelated build failed with Foreign payload encoding detected..

The clone is now created before the state transition and the transition applied to it, exactly as JWEBuilder::addRecipient() already does with checkAndSetContentEncryptionAlgorithm(). The check order is unchanged, so the exceptions raised on invalid input are the same as before.

The regression test reuses one builder instance across two independent builds; it fails with Foreign payload encoding detected. on 4.2.x and passes with the fix.

The wider redesign — making the builders genuinely immutable so the create() reset becomes unnecessary — stays tracked for 4.3.0.

Checks

  • phpunit -c .ci-tools/phpunit.xml.dist: 869 tests, 2541 assertions, OK (the 2 incomplete tests are pre-existing)
  • ECS, PHPStan and Rector: clean

…iver

`JWSBuilder::addSignature()` is documented as immutable but it wrote
`isPayloadEncoded` on `$this` before cloning. The bundle registers the
builder as a shared service, so the first call pinned the "b64" mode of
that service for the rest of the process and any later, unrelated build
failed with "Foreign payload encoding detected.".

Clone first, then perform the state transition on the clone, as
`JWEBuilder::addRecipient()` already does.

Fixes #679
@Spomky Spomky added this to the 4.2.1 milestone Aug 28, 2026
@Spomky Spomky self-assigned this Aug 28, 2026
@Spomky Spomky added the bug label Aug 28, 2026
@Spomky
Spomky merged commit 116e372 into 4.2.x Aug 28, 2026
17 checks passed
@Spomky
Spomky deleted the fix/jws-builder-clone-mutation branch August 28, 2026 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JWSBuilder::addSignature() mutates the builder instance instead of the clone

1 participant