MDL-22959 PARA_TEXT multilang whitelisting cleanup; the text is no longer being processed by kses or htmlpurifier - this should fix some recent regressions, any xhtml strict tweaking should be done in format_string() if necessary; unit tests included

This commit is contained in:
Petr Skoda
2010-09-02 17:30:00 +00:00
parent dc3e95c0d8
commit b6059edcac
2 changed files with 83 additions and 2 deletions
+62 -2
View File
@@ -208,7 +208,7 @@ define('PARAM_TAG', 'tag');
define('PARAM_TAGLIST', 'taglist');
/**
* PARAM_TEXT - general plain text compatible with multilang filter, no other html tags.
* PARAM_TEXT - general plain text compatible with multilang filter, no other html tags. Please note '<', or '>' are allowed here.
*/
define('PARAM_TEXT', 'text');
@@ -582,7 +582,67 @@ function clean_param($param, $type) {
return strip_tags($param);
case PARAM_TEXT: // leave only tags needed for multilang
return clean_param(strip_tags($param, '<lang><span>'), PARAM_CLEAN);
// if the multilang syntax is not correct we strip all tags
// because it would break xhtml strict which is required for accessibility standards
// please note this cleaning does not strip unbalanced '>' for BC compatibility reasons
do {
if (strpos($param, '</lang>') !== false) {
// old and future mutilang syntax
$param = strip_tags($param, '<lang>');
if (!preg_match_all('/<.*>/suU', $param, $matches)) {
break;
}
$open = false;
foreach ($matches[0] as $match) {
if ($match === '</lang>') {
if ($open) {
$open = false;
continue;
} else {
break 2;
}
}
if (!preg_match('/^<lang lang="[a-zA-Z0-9_-]+"\s*>$/u', $match)) {
break 2;
} else {
$open = true;
}
}
if ($open) {
break;
}
return $param;
} else if (strpos($param, '</span>') !== false) {
// current problematic multilang syntax
$param = strip_tags($param, '<span>');
if (!preg_match_all('/<.*>/suU', $param, $matches)) {
break;
}
$open = false;
foreach ($matches[0] as $match) {
if ($match === '</span>') {
if ($open) {
$open = false;
continue;
} else {
break 2;
}
}
if (!preg_match('/^<span(\s+lang="[a-zA-Z0-9_-]+"|\s+class="multilang"){2}\s*>$/u', $match)) {
break 2;
} else {
$open = true;
}
}
if ($open) {
break;
}
return $param;
}
} while (false);
// easy, just strip all tags, if we ever want to fix orphaned '&' we have to do that in format_string()
return strip_tags($param);
case PARAM_SAFEDIR: // Remove everything not a-zA-Z0-9_-
return preg_replace('/[^a-zA-Z0-9_-]/i', '', $param);
+21
View File
@@ -270,6 +270,27 @@ class moodlelib_test extends UnitTestCase {
',9789,42897');
}
function test_clean_param_text() {
$this->assertEqual(PARAM_TEXT, PARAM_MULTILANG);
//standard
$this->assertEqual(clean_param('xx<lang lang="en">aa</lang><lang lang="yy">pp</lang>', PARAM_TEXT), 'xx<lang lang="en">aa</lang><lang lang="yy">pp</lang>');
$this->assertEqual(clean_param('<span lang="en" class="multilang">aa</span><span lang="xy" class="multilang">bb</span>', PARAM_TEXT), '<span lang="en" class="multilang">aa</span><span lang="xy" class="multilang">bb</span>');
$this->assertEqual(clean_param('xx<lang lang="en">aa'."\n".'</lang><lang lang="yy">pp</lang>', PARAM_TEXT), 'xx<lang lang="en">aa'."\n".'</lang><lang lang="yy">pp</lang>');
//malformed
$this->assertEqual(clean_param('<span lang="en" class="multilang">aa</span>', PARAM_TEXT), '<span lang="en" class="multilang">aa</span>');
$this->assertEqual(clean_param('<span lang="en" class="nothing" class="multilang">aa</span>', PARAM_TEXT), 'aa');
$this->assertEqual(clean_param('<lang lang="en" class="multilang">aa</lang>', PARAM_TEXT), 'aa');
$this->assertEqual(clean_param('<lang lang="en!!">aa</lang>', PARAM_TEXT), 'aa');
$this->assertEqual(clean_param('<span lang="en==" class="multilang">aa</span>', PARAM_TEXT), 'aa');
$this->assertEqual(clean_param('a<em>b</em>c', PARAM_TEXT), 'abc');
$this->assertEqual(clean_param('a><xx >c>', PARAM_TEXT), 'a>c>'); // standard strip_tags() behaviour
$this->assertEqual(clean_param('a<b', PARAM_TEXT), 'a');
$this->assertEqual(clean_param('a>b', PARAM_TEXT), 'a>b');
$this->assertEqual(clean_param('<lang lang="en">a>a</lang>', PARAM_TEXT), '<lang lang="en">a>a</lang>'); // standard strip_tags() behaviour
$this->assertEqual(clean_param('<lang lang="en">a<a</lang>', PARAM_TEXT), 'a');
$this->assertEqual(clean_param('<lang lang="en">a<br>a</lang>', PARAM_TEXT), '<lang lang="en">aa</lang>');
}
function test_clean_param_url() {
// Test PARAM_URL and PARAM_LOCALURL a bit
$this->assertEqual(clean_param('http://google.com/', PARAM_URL), 'http://google.com/');