fix(audit L1): Schleifen in module.advanced.loop brauchen list_users (Benutzer) bzw. read_private_posts (any, attachment, leere subTypes), auch beim Kopieren

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-20 00:00:59 +02:00
co-authored by Claude Sonnet 5.5
parent 9c1d5fad22
commit 4a8a889f93
10 changed files with 299 additions and 9 deletions
@@ -61,16 +61,43 @@ final class StoredNodeGuard
/** @return list<string> German problems; [] when $root may move to the target post. */
public function problems(Block $root): array
{
$problems = [];
$this->loops($root, $problems);
if ($this->sanitizer->allowsUnfilteredHtml()) {
return [];
return array_values(array_unique($problems));
}
$problems = [];
$this->walk($root, $problems);
return array_values(array_unique($problems));
}
/**
* Audit L1: loop settings need list_users / read_private_posts also for accounts with unfiltered_html.
*
* @param list<string> $problems
*/
private function loops(Block $block, array &$problems): void
{
$attrs = $block->isDivi() ? $this->attributesOf($block) : null;
$loop = is_array($attrs) ? AttrMap::get($attrs, 'module.advanced.loop') : null;
$desktop = is_array($loop) && is_array($loop['desktop'] ?? null) ? $loop['desktop']['value'] ?? null : null;
if ($desktop instanceof stdClass) {
$desktop = get_object_vars($desktop);
}
try {
$this->cleaner->guardLoop('module.advanced.loop', $desktop);
} catch (InvalidArgumentException $e) {
$problems[] = $e->getMessage();
}
foreach ($block->parts() as $part) {
if ($part instanceof Block) {
$this->loops($part, $problems);
}
}
}
/** @param list<string> $problems */
private function walk(Block $block, array &$problems): void
{