Skip to content

Commit 3844f32

Browse files
committed
fix: fixed State contamination in marking stores due to class-based getter cache
1 parent 5f9310b commit 3844f32

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function getMarking(object $subject): Marking
5151
{
5252
$marking = null;
5353
try {
54-
$marking = ($this->getters[$subject::class] ??= $this->getGetter($subject))();
54+
$marking = ($this->getters[self::getSubjectIdentity($subject)] ??= $this->getGetter($subject))();
5555
} catch (\Error $e) {
5656
$unInitializedPropertyMessage = \sprintf('Typed property %s::$%s must not be accessed before initialization', get_debug_type($subject), $this->property);
5757
if ($e->getMessage() !== $unInitializedPropertyMessage) {
@@ -84,7 +84,7 @@ public function setMarking(object $subject, Marking $marking, array $context = [
8484
$marking = key($marking);
8585
}
8686

87-
($this->setters[$subject::class] ??= $this->getSetter($subject))($marking, $context);
87+
($this->setters[self::getSubjectIdentity($subject)] ??= $this->getSetter($subject))($marking, $context);
8888
}
8989

9090
private function getGetter(object $subject): callable
@@ -109,6 +109,11 @@ private function getSetter(object $subject): callable
109109
};
110110
}
111111

112+
private static function getSubjectIdentity(object $subject): string
113+
{
114+
return sprintf('%s_%s', $subject::class, spl_object_id($subject));
115+
}
116+
112117
private static function getType(object $subject, string $property, string $method, ?string &$type = null): MarkingStoreMethod
113118
{
114119
try {

src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,23 @@ public function testGetMarkingWithUninitializedProperty2()
125125
$markingStore->getMarking($subject);
126126
}
127127

128+
public function testGetMarkingWithSameSubjectMultipleTimes(): void
129+
{
130+
$subject1 = new Subject('first_place');
131+
$subject2 = new Subject('second_place');
132+
$subject3 = new Subject('third_place');
133+
134+
$markingStore = new MethodMarkingStore(true);
135+
136+
$marking1 = $markingStore->getMarking($subject1);
137+
$marking2 = $markingStore->getMarking($subject2);
138+
$marking3 = $markingStore->getMarking($subject3);
139+
140+
$this->assertSame(['first_place' => 1], $marking1->getPlaces());
141+
$this->assertSame(['second_place' => 1], $marking2->getPlaces());
142+
$this->assertSame(['third_place' => 1], $marking3->getPlaces());
143+
}
144+
128145
private function createValueObject(string $markingValue): object
129146
{
130147
return new class($markingValue) {

0 commit comments

Comments
 (0)