Skip to content

Commit 569725a

Browse files
authored
Merge pull request #476 from driskell/fix-entity-query-type-cache
fix: Fix unpredictable false positive/negative of missing entity access check in function scope due to cache key conflict
2 parents 2d2f7b4 + 728c1f0 commit 569725a

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

src/Type/EntityQuery/EntityQueryType.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,20 @@ public function hasAccessCheck(): bool
1717

1818
public function withAccessCheck(): self
1919
{
20-
$type = clone $this;
20+
// The constructor of ObjectType is under backward compatibility promise.
21+
// @see https://phpstan.org/developing-extensions/backward-compatibility-promise
22+
// @phpstan-ignore-next-line
23+
$type = new static(
24+
$this->getClassName(),
25+
$this->getSubtractedType(),
26+
$this->getClassReflection()
27+
);
2128
$type->hasAccessCheck = true;
22-
2329
return $type;
2430
}
31+
32+
protected function describeAdditionalCacheKey(): string
33+
{
34+
return $this->hasAccessCheck ? 'with-access-check' : 'without-access-check';
35+
}
2536
}

tests/src/Rules/EntityQueryHasAccessCheckRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,15 @@ public function cases(): \Generator
8686
[__DIR__ . '/data/bug-437.php'],
8787
[]
8888
];*/
89+
90+
yield 'bug-475.php' => [
91+
[__DIR__.'/data/bug-475.php'],
92+
[]
93+
];
94+
95+
yield 'bug-475b.php' => [
96+
[__DIR__.'/data/bug-475b.php'],
97+
[]
98+
];
8999
}
90100
}

tests/src/Rules/data/bug-475.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/**
4+
* Cache key differs outside of class so this is separate reproduction
5+
*
6+
* @return void
7+
*/
8+
function bug475Caching(): void
9+
{
10+
// Here condition() return type will be cached as one that has no access check
11+
\Drupal::entityQuery('node')
12+
->condition('field_test', 'foo', '=')
13+
->accessCheck(FALSE)
14+
->execute();
15+
16+
// Cache return on condition() will also be no access check, even though caller did, unless caller type changes cache key
17+
\Drupal::entityQuery('node')
18+
->accessCheck(FALSE)
19+
->condition('field_test', 'foo', '=')
20+
->execute();
21+
}

tests/src/Rules/data/bug-475b.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Bug475CacheKeyExample;
4+
5+
/**
6+
* Cache key differs if in class so this tests that too
7+
*
8+
* @return void
9+
*/
10+
class TestClass
11+
{
12+
public function bug475Caching(): void
13+
{
14+
// Here condition() return type will be cached as one that has no access check
15+
\Drupal::entityQuery('node')
16+
->condition('field_test', 'foo', '=')
17+
->accessCheck(FALSE)
18+
->execute();
19+
20+
// Cache return on condition() will also be no access check, even though caller did, unless caller type changes cache key
21+
\Drupal::entityQuery('node')
22+
->accessCheck(FALSE)
23+
->condition('field_test', 'foo', '=')
24+
->execute();
25+
}
26+
}

0 commit comments

Comments
 (0)