t('Filter administration functionality'),
'description' => t('Thoroughly test the administrative interface of the filter module.'),
'group' => t('Filter'),
);
}
/**
* Test filter administration functionality.
*/
function testFilterAdmin() {
// URL filter.
$first_filter = 2;
// Line filter.
$second_filter = 1;
// Create users.
$admin_user = $this->drupalCreateUser(array('administer filters'));
$web_user = $this->drupalCreateUser(array('create page content'));
$this->drupalLogin($admin_user);
list($filtered, $full) = $this->checkFilterFormats();
// Change default filter.
$edit = array();
$edit['default'] = $full;
$this->drupalPost('admin/settings/formats', $edit, t('Save changes'));
$this->assertText(t('Default format updated.'), t('Default filter updated successfully.'));
$this->assertNoRaw('admin/settings/formats/delete/' . $full, t('Delete link not found.'));
// Add an additional tag.
$edit = array();
$edit['allowed_html_1'] = ' aaa ccc
';
$this->drupalPost('admin/settings/formats/' . $filtered . '/configure', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Allowed HTML tag added.'));
$this->assertRaw(htmlentities($edit['allowed_html_1']), t('Tag displayed.'));
$result = db_query('SELECT * FROM {cache_filter}')->fetchObject();
$this->assertFalse($result, t('Cache cleared.'));
// Reorder filters.
$edit = array();
$edit['weights[filter/' . $second_filter . ']'] = 1;
$edit['weights[filter/' . $first_filter . ']'] = 2;
$this->drupalPost('admin/settings/formats/' . $filtered . '/order', $edit, t('Save configuration'));
$this->assertText(t('The filter ordering has been saved.'), t('Order saved successfully.'));
$result = db_query('SELECT * FROM {filter} WHERE format = :format ORDER BY weight ASC', array(':format' => $filtered));
$filters = array();
foreach ($result as $filter) {
if ($filter->delta == $second_filter || $filter->delta == $first_filter) {
$filters[] = $filter;
}
}
$this->assertTrue(($filters[0]->delta == $second_filter && $filters[1]->delta == $first_filter), t('Order confirmed.'));
// Add filter.
$edit = array();
$edit['name'] = $this->randomName();
$edit['roles[2]'] = TRUE;
$edit['filters[filter/' . $second_filter . ']'] = TRUE;
$edit['filters[filter/' . $first_filter . ']'] = TRUE;
$this->drupalPost('admin/settings/formats/add', $edit, t('Save configuration'));
$this->assertRaw(t('Added text format %format.', array('%format' => $edit['name'])), t('New filter created.'));
$format = $this->getFilter($edit['name']);
$this->assertNotNull($format, t('Format found in database.'));
if ($format !== NULL) {
$this->assertFieldByName('roles[2]', '', t('Role found.'));
$this->assertFieldByName('filters[filter/' . $second_filter . ']', '', t('Line break filter found.'));
$this->assertFieldByName('filters[filter/' . $first_filter . ']', '', t('Url filter found.'));
// Delete new filter.
$this->drupalPost('admin/settings/formats/delete/' . $format->format, array(), t('Delete'));
$this->assertRaw(t('Deleted text format %format.', array('%format' => $edit['name'])), t('Format successfully deleted.'));
}
// Change default filter back.
$edit = array();
$edit['default'] = $filtered;
$this->drupalPost('admin/settings/formats', $edit, t('Save changes'));
$this->assertText(t('Default format updated.'), t('Default filter updated successfully.'));
$this->assertNoRaw('admin/settings/formats/delete/' . $filtered, t('Delete link not found.'));
// Allow authenticated users on full HTML.
$edit = array();
$edit['roles[2]'] = TRUE;
$this->drupalPost('admin/settings/formats/' . $full, $edit, t('Save configuration'));
$this->assertText(t('The text format settings have been updated.'), t('Full HTML format successfully updated.'));
// Switch user.
$this->drupalLogout();
$this->drupalLogin($web_user);
$this->drupalGet('node/add/page');
$this->assertRaw('', t('Full HTML filter accessible.'));
// Use filtered HTML and see if it removes tags that are not allowed.
$body = $this->randomName();
$extra_text = 'text';
$edit = array();
$edit['title'] = $this->randomName();
$edit['body[0][value]'] = $body . '
tags, while paragraphs
// separated with double line breaks should be enclosed with tags.
$f = _filter_autop("aaa\nbbb\n\nccc");
$this->assertEqual(str_replace("\n", '', $f), "
bbb
'), substr_count($f, '
'), t('Make sure line breaking produces matching paragraph tags.')); $f = _filter_autop('
'), substr_count($f, '
'), t('Make sure line breaking produces matching paragraph tags.')); $f = _filter_autop(''); $this->assertEqual(substr_count($f, 'aaa
'), substr_count($f, '
'), t('Make sure line breaking produces matching paragraph tags.')); $limit = max(ini_get('pcre.backtrack_limit'), ini_get('pcre.recursion_limit')); $f = _filter_autop($this->randomName($limit)); $this->assertNotEqual($f, '', t('Make sure line breaking can process long strings.')); } /** * Test limiting allowed tags, XSS prevention and adding 'nofollow' to links. * * XSS tests assume that script is dissallowed on default and src is allowed * on default, but on* and style are dissallowed. * * Script injection vectors mostly adopted from http://ha.ckers.org/xss.html. * * Relevant CVEs: * - CVE-2002-1806, ~CVE-2005-0682, ~CVE-2005-2106, CVE-2005-3973, * CVE-2006-1226 (= rev. 1.112?), CVE-2008-0273, CVE-2008-3740. */ function testHtmlFilter() { // Tag stripping, different ways to work around removal of HTML tags. $f = filter_xss(''); $this->assertNoNormalized($f, 'script', t('HTML tag stripping -- simple script without special characters.')); $f = filter_xss(''); $this->assertNoNormalized($f, 'script', t('HTML tag stripping -- empty script with source.')); $f = filter_xss(''); $this->assertNoNormalized($f, 'script', t('HTML tag stripping evasion -- non whitespace character after tag name.')); $f = filter_xss(''); $this->assertNoNormalized($f, 'script', t('HTML tag stripping evasion -- no space between tag and attribute.')); // Null between < and tag name works at least with IE6. $f = filter_xss("<\0scr\0ipt>alert(0)"); $this->assertNoNormalized($f, 'ipt', t('HTML tag stripping evasion -- breaking HTML with nulls.')); $f = filter_xss("', array('p')); $this->assertNoNormalized($f, 'onmouseover', t('HTML filter attributes removal -- events, no evasion.')); $f = filter_xss('