MDL-78343 core_table: Improved HTML tag detection in format_text

This commit is contained in:
David Woloszyn
2026-02-06 13:37:47 +11:00
parent e99b368c60
commit 2d9bddeebf
2 changed files with 23 additions and 6 deletions
@@ -80,7 +80,11 @@ class base_export_format {
* @param null|int $courseid
*/
public function format_text($text, $format = FORMAT_MOODLE, $options = null, $courseid = null) {
return html_entity_decode(strip_tags($text), ENT_COMPAT);
// Decode all HTML entities first (e.g. & -> &).
$text = html_entity_decode($text, ENT_COMPAT);
// Detect and remove HTML tags. Unlike strip_tags, this will allow things like '2 > 1' through.
$text = preg_replace('/<\/?[A-Za-z][^>\r\n]*>/', '', $text);
return $text;
}
/**
+18 -5
View File
@@ -687,24 +687,37 @@ final class tablelib_test extends \advanced_testcase {
}
/**
* Test export in CSV format
* Test export in CSV format.
*
* By default, CSV strips HTML tags. Ensure inputs are exported as expected.
*/
public function test_table_export(): void {
$table = new flexible_table('tablelib_test_export');
$table->define_baseurl('/invalid.php');
$table->define_columns(['c1', 'c2', 'c3']);
$table->define_headers(['Col1', 'Col2', 'Col3']);
$table->define_columns(['c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8']);
$table->define_headers(['Col1', 'Col2', 'Col3', 'Col4', 'Col5', 'Col6', 'Col7', 'Col8']);
ob_start();
$table->is_downloadable(true);
$table->is_downloading('csv');
$table->setup();
$table->add_data(['column0' => 'a', 'column1' => 'b', 'column2' => 'c']);
$table->add_data([
'Hello', // Simple string.
'<h1>My</h1><div>Contents</div>', // Tags should be removed, leaving the contents.
'2>1', // Mathematical statements should not be misinterpreted as tags.
'3 < 4', // Mathematical statements should not be misinterpreted as tags (with spaces).
'<img src="pic.gif"/>Tag was here', // Self-closing tag should be removed.
'&lt;span&gt;htmlentities&lt;/span&gt;', // HTML entities should be detected too.
"1 <lessthan\ngreaterthan> 2", // Multiline pseudo-mathematical should not be removed.
"<taglikes>removed", // Tag-likes will also be removed.
]);
$output = ob_get_contents();
ob_end_clean();
$this->assertEquals("Col1,Col2,Col3\na,b,c\n", substr($output, 3));
$expected = "Col1,Col2,Col3,Col4,Col5,Col6,Col7,Col8\n";
$expected .= "Hello,MyContents,2>1,\"3 < 4\",\"Tag was here\",htmlentities,\"1 <lessthan\ngreaterthan> 2\",removed\n";
$this->assertEquals($expected, substr($output, 3));
}
/**