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:
+62
-2
@@ -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);
|
||||
|
||||
@@ -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/');
|
||||
|
||||
Reference in New Issue
Block a user