Skip to content

Commit ccd7683

Browse files
committed
fix: corrected regex
1 parent caa3a76 commit ccd7683

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

phpmyfaq/src/phpMyFAQ/Filter.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,16 @@ public static function removeAttributes(string $html = ''): string
158158
// remove broken stuff
159159
$html = str_replace(search: '
', replace: '', subject: $html);
160160

161-
preg_match_all(pattern: '/[a-z]+=".+"/iU', subject: $html, matches: $attributes);
161+
// Match attributes with double quotes, single quotes, or no quotes
162+
preg_match_all(
163+
pattern: '/[a-z]+\s*=\s*(?:"[^"]*"|\'[^\']*\'|[^\s>]+)/iU',
164+
subject: $html,
165+
matches: $attributes,
166+
);
162167

163168
foreach ($attributes[0] as $attribute) {
164169
$attributeName = stristr($attribute, needle: '=', before_needle: true);
170+
$attributeName = trim($attributeName);
165171
if (!self::isAttribute($attributeName)) {
166172
continue;
167173
}

tests/phpMyFAQ/FilterTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,40 @@ public function testComplexHtmlFiltering(): void
250250
$this->assertStringNotContainsString('onmouseover', $result);
251251
}
252252

253+
public function testRemoveAttributesWithUnquotedValues(): void
254+
{
255+
$html = '<img src=x onerror=alert(1)>';
256+
$result = Filter::removeAttributes($html);
257+
258+
$this->assertStringNotContainsString('onerror', $result);
259+
}
260+
261+
public function testRemoveAttributesWithSingleQuotedValues(): void
262+
{
263+
$html = "<img src='x' onerror='alert(1)'>";
264+
$result = Filter::removeAttributes($html);
265+
266+
$this->assertStringNotContainsString('onerror', $result);
267+
}
268+
269+
public function testRemoveAttributesWithSvgOnload(): void
270+
{
271+
$html = '<svg onload=alert(1)>';
272+
$result = Filter::removeAttributes($html);
273+
274+
$this->assertStringNotContainsString('onload', $result);
275+
}
276+
277+
public function testRemoveAttributesWithMixedQuoteStyles(): void
278+
{
279+
$html = '<div class="safe" onclick=alert(1) style=\'color:red\' onmouseover="steal()">';
280+
$result = Filter::removeAttributes($html);
281+
282+
$this->assertStringContainsString('class="safe"', $result);
283+
$this->assertStringNotContainsString('onclick', $result);
284+
$this->assertStringNotContainsString('onmouseover', $result);
285+
}
286+
253287
protected function tearDown(): void
254288
{
255289
unset($_GET['test_var'], $_GET['special_test'], $_POST['name'], $_POST['email']);

0 commit comments

Comments
 (0)