fix: Task 3 review round 1 - strip control chars before the sanitizer (S32a), S34 minors
Control characters now go on the raw value in AttrWriter::cleanNode and
VariableRef::setting; after the sanitizer only rejection remains ('<' + VT/FF
no longer turns into a tag). VALUE_KEY anchored with D, exact column-width
fractions, nested rows in columns, specialty columns refused, fullwidth by
catalog category, preset ambiguity in DesignSystem::modulePresetId().
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:
@@ -186,7 +186,7 @@ final class ShortformWriterTest extends TestCase
|
||||
'color: two references' => ['color', $color . $color],
|
||||
// Markers the sanitizer would rebuild (S28).
|
||||
'text: tag-split marker' => ['text', '$variable<x>(' . substr($color, 10)],
|
||||
'text: NUL-split marker' => ['text', '$variable' . chr(0) . '(' . substr($color, 10)],
|
||||
'text: NUL-split marker embedded' => ['text', 'Hallo $variable' . chr(0) . '(' . substr($color, 10)],
|
||||
'text: octet-split marker' => ['text', '$variable%41(' . substr($color, 10)],
|
||||
'url: stripped-characters marker' => ['url', '$variable<"{}>(y)$'],
|
||||
'url: NUL-split marker' => ['url', '$variable' . chr(0) . '(y)$'],
|
||||
@@ -220,17 +220,17 @@ final class ShortformWriterTest extends TestCase
|
||||
self::assertStringContainsString('$variable(', $sanitizer->text($rows[$row][1]));
|
||||
}
|
||||
|
||||
// S32: like sanitize_text_field, the fake text() keeps NUL – so the marker the NUL row
|
||||
// hides is rebuilt only by AttrWriter's control-character stripping (production code).
|
||||
self::assertStringNotContainsString('$variable(', $sanitizer->text($rows['text: NUL-split marker'][1]));
|
||||
self::assertStringContainsString(chr(0), $sanitizer->text($rows['text: NUL-split marker'][1]));
|
||||
// S32/S32a: like sanitize_text_field, the fake text() keeps NUL – the marker the NUL row
|
||||
// hides appears only through AttrWriter's control stripping on the raw value (production code).
|
||||
self::assertStringNotContainsString('$variable(', $sanitizer->text($rows['text: NUL-split marker embedded'][1]));
|
||||
self::assertStringContainsString(chr(0), $sanitizer->text($rows['text: NUL-split marker embedded'][1]));
|
||||
|
||||
foreach (['url: stripped-characters marker', 'url: NUL-split marker', 'url: line-break octet marker'] as $row) {
|
||||
self::assertStringNotContainsString('$variable(', $rows[$row][1]);
|
||||
self::assertStringContainsString('$variable(', $sanitizer->url($rows[$row][1]));
|
||||
}
|
||||
|
||||
self::assertStringContainsString(chr(0), $rows['text: NUL-split marker'][1]);
|
||||
self::assertStringContainsString(chr(0), $rows['text: NUL-split marker embedded'][1]);
|
||||
}
|
||||
|
||||
/** Ruling S33b: an attachment alt carrying a reference (whole or split) is dropped, never canonicalized. */
|
||||
@@ -245,6 +245,21 @@ final class ShortformWriterTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
/** Ruling S32a: a control character after "<" never turns into a tag – in text and in media alt. */
|
||||
public function testControlSplitTagsAreRemoved(): void
|
||||
{
|
||||
$writer = ComposeFixture::shortform();
|
||||
foreach (['<' . chr(11) . 'img src=x onerror=alert(1)>Hallo', '<' . chr(12) . 'script>alert(1)</script>Hallo'] as $value) {
|
||||
$result = $writer->apply('heading', [], ['text' => $value], 'n');
|
||||
self::assertSame([], $result['errors']);
|
||||
self::assertSame('Hallo', $result['attrs']['title']['innerContent']['desktop']['value']);
|
||||
}
|
||||
|
||||
$image = $writer->apply('image', [], ['image_id' => 46], 'n');
|
||||
self::assertSame([], $image['errors']);
|
||||
self::assertSame('Team', $image['attrs']['image']['innerContent']['desktop']['value']['alt']);
|
||||
}
|
||||
|
||||
/** Ruling S21 applies to short-form text too: before/after of a reference are cleaned, not rejected. */
|
||||
public function testReferenceSettingsInTextAreCleaned(): void
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user