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:
@@ -138,6 +138,33 @@ final class VariableRefTest extends TestCase
|
||||
self::ref()->canonical($input, ComposeFixture::sanitizer());
|
||||
}
|
||||
|
||||
/**
|
||||
* "$" without /D also matches before a trailing newline: the whole-reference pattern, a meta
|
||||
* key name and a color setting number must each end with their last character.
|
||||
*/
|
||||
public function testATrailingNewlineIsNeverAnAnchorMatch(): void
|
||||
{
|
||||
$color = VariableRef::serialize('color', 'gcid-a1b2', []);
|
||||
$rejects = [
|
||||
'whole reference' => [$color . "\n", 'Verweise nur allein im Wert'],
|
||||
'meta key name' => [
|
||||
VariableRef::serialize('content', "custom_meta_telefon\n", ['before' => '', 'after' => '']),
|
||||
'Unbekannter Name',
|
||||
],
|
||||
'color number' => [VariableRef::serialize('color', 'gcid-a1b2', ['hue' => "5\n"]), 'nur Zahlen'],
|
||||
];
|
||||
foreach ($rejects as $label => [$input, $message]) {
|
||||
try {
|
||||
self::ref()->canonical($input, ComposeFixture::sanitizer());
|
||||
self::fail($label . ': accepted');
|
||||
} catch (InvalidArgumentException $e) {
|
||||
self::assertStringContainsString($message, $e->getMessage(), $label);
|
||||
}
|
||||
}
|
||||
|
||||
self::assertNull(VariableRef::typeOf($color . "\n"));
|
||||
}
|
||||
|
||||
/** I-1: the escape really is in the input, and nothing with ")$" inside comes out. */
|
||||
public function testEscapedEndMarkerIsBytesNotTheCharacter(): void
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user