fix: anchored input patterns end at the last character (/D)

Without /D, "$" also matches before a trailing "\n", so "custom_meta_telefon\n",
a color setting "5\n" (stored as sent) or a whole reference followed by "\n"
passed VariableRef. Added /D to every ^...$ pattern that validates client or
admin input:
- VariableRef META_KEY, NUMBER, WHOLE (canonical/typeOf; Placeholders::field
  shares META_KEY)
- Cursor::decode, GuideRepository topic names (MCP input and filter keys)
- ExposurePolicy::sanitize ability keys and group ids, LogTab list filters

Not changed: Placeholders::PATTERN (runs on trim()), Warnings hex checks (hints
only), NodeSummary/AttrPathIndex/LogListTable (stored or Divi data, no client
input). Each fixed pattern has a test with a trailing "\n" that is rejected.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
2026-09-26 18:02:51 +02:00
co-authored by Claude Opus 5.5
parent 60290c85a5
commit e420145cbe
10 changed files with 81 additions and 9 deletions
@@ -47,7 +47,7 @@ final class VariableRef
public const MARKER = '$variable(';
/** custom_meta_<key>: no leading "_" – Divi renders protected meta publicly (ruling S12). */
public const META_KEY = '/^[A-Za-z0-9-][A-Za-z0-9_-]*$/';
public const META_KEY = '/^[A-Za-z0-9-][A-Za-z0-9_-]*$/D';
/** @var array<string, array<string, string>> Placeholders::POST values and their settings. */
public const DEFAULT_DYNAMIC_CONTENT = [
@@ -79,7 +79,7 @@ final class VariableRef
private const COLOR_SETTINGS = ['hue', 'saturation', 'lightness', 'opacity'];
private const WHOLE = '/^\$variable\((.*)\)\$$/s';
private const WHOLE = '/^\$variable\((.*)\)\$$/sD';
private const META_PREFIX = 'custom_meta_';
@@ -95,7 +95,7 @@ final class VariableRef
'loop_term_meta_key_',
];
private const NUMBER = '/^-?\d+(\.\d+)?$/';
private const NUMBER = '/^-?\d+(\.\d+)?$/D';
/** @var array<string, array<string, string>> */
private array $dynamicContent;