diff --git a/library/HTMLPurifier/Generator.php b/library/HTMLPurifier/Generator.php
index b6a9aa24..d717332e 100644
--- a/library/HTMLPurifier/Generator.php
+++ b/library/HTMLPurifier/Generator.php
@@ -21,6 +21,13 @@ HTMLPurifier_ConfigSchema::define(
'This directive was available since 1.1.'
);
+HTMLPurifier_ConfigSchema::define(
+ 'Core', 'CommentScriptContents', true, 'bool',
+ 'Determines whether or not HTML Purifier should attempt to fix up '.
+ 'the contents of script tags for legacy browsers with comments. This '.
+ 'directive was available since 1.7.'
+);
+
// extension constraints could be factored into ConfigSchema
HTMLPurifier_ConfigSchema::define(
'Core', 'TidyFormat', false, 'bool',
@@ -54,6 +61,12 @@ class HTMLPurifier_Generator
*/
var $_xhtml = true;
+ /**
+ * Bool cache of %Core.CommentScriptContents
+ * @private
+ */
+ var $_scriptFix = false;
+
/**
* Generates HTML from an array of tokens.
* @param $tokens Array of HTMLPurifier_Token
@@ -63,11 +76,20 @@ class HTMLPurifier_Generator
function generateFromTokens($tokens, $config, &$context) {
$html = '';
if (!$config) $config = HTMLPurifier_Config::createDefault();
- $this->_clean_utf8 = $config->get('Core', 'CleanUTF8DuringGeneration');
- $this->_xhtml = $config->get('Core', 'XHTML');
+ $this->_clean_utf8 = $config->get('Core', 'CleanUTF8DuringGeneration');
+ $this->_xhtml = $config->get('Core', 'XHTML');
+ $this->_scriptFix = $config->get('Core', 'CommentScriptContents');
if (!$tokens) return '';
- foreach ($tokens as $token) {
- $html .= $this->generateFromToken($token);
+ for ($i = 0, $size = count($tokens); $i < $size; $i++) {
+ if ($this->_scriptFix && $tokens[$i]->name === 'script') {
+ // script special case
+ $html .= $this->generateFromToken($tokens[$i++]);
+ $html .= $this->generateScriptFromToken($tokens[$i++]);
+ while ($tokens[$i]->name != 'script') {
+ $html .= $this->generateScriptFromToken($tokens[$i++]);
+ }
+ }
+ $html .= $this->generateFromToken($tokens[$i]);
}
if ($config->get('Core', 'TidyFormat') && extension_loaded('tidy')) {
@@ -125,6 +147,18 @@ class HTMLPurifier_Generator
}
}
+ /**
+ * Special case processor for the contents of script tags
+ * @warning This runs into problems if there's already a literal
+ * --> somewhere inside the script contents.
+ */
+ function generateScriptFromToken($token) {
+ if (!$token->type == 'text') return $this->generateFromToken($token);
+ return '';
+ // more advanced version:
+ // return '';
+ }
+
/**
* Generates attribute declarations from attribute array.
* @param $assoc_array_of_attributes Attribute array
diff --git a/library/HTMLPurifier/HTMLModuleManager.php b/library/HTMLPurifier/HTMLModuleManager.php
index 8d3ad2d9..6adbeb59 100644
--- a/library/HTMLPurifier/HTMLModuleManager.php
+++ b/library/HTMLPurifier/HTMLModuleManager.php
@@ -41,6 +41,13 @@ HTMLPurifier_ConfigSchema::define(
'like %Core.XHTML or %HTML.Strict.'
);
+HTMLPurifier_ConfigSchema::define(
+ 'HTML', 'Trusted', false, 'bool',
+ 'Indicates whether or not the user input is trusted or not. If the '.
+ 'input is trusted, a more expansive set of allowed tags and attributes '.
+ 'will be used. This directive has been available since 1.7.0.'
+);
+
class HTMLPurifier_HTMLModuleManager
{
@@ -221,6 +228,8 @@ class HTMLPurifier_HTMLModuleManager
*/
function setup($config) {
+ $this->trusted = $config->get('HTML', 'Trusted');
+
// generate
$doctype = $this->doctypes->make($config);
$modules = $doctype->modules;
@@ -325,7 +334,7 @@ class HTMLPurifier_HTMLModuleManager
// element with unknown safety is not to be trusted.
// however, a merge-in definition with undefined safety
// is fine
- if (!$new_def->safe) continue;
+ if (!$trusted && !$new_def->safe) continue;
$def = $new_def;
} elseif ($def) {
$def->mergeIn($new_def);
diff --git a/tests/HTMLPurifier/GeneratorTest.php b/tests/HTMLPurifier/GeneratorTest.php
index f16b95ed..7528f9fa 100644
--- a/tests/HTMLPurifier/GeneratorTest.php
+++ b/tests/HTMLPurifier/GeneratorTest.php
@@ -124,6 +124,31 @@ class HTMLPurifier_GeneratorTest extends HTMLPurifier_Harness
$this->assertIdentical($expect, $result);
}
+ function test_generateFromTokens_Scripting() {
+ $this->config = HTMLPurifier_Config::createDefault();
+
+ $this->assertGeneration(
+ array(
+ new HTMLPurifier_Token_Start('script'),
+ new HTMLPurifier_Token_Text('alert(3 < 5);'),
+ new HTMLPurifier_Token_End('script')
+ ),
+ ""
+ );
+
+ $this->config = HTMLPurifier_Config::createDefault();
+ $this->config->set('Core', 'CommentScriptContents', false);
+
+ $this->assertGeneration(
+ array(
+ new HTMLPurifier_Token_Start('script'),
+ new HTMLPurifier_Token_Text('alert(3 < 5);'),
+ new HTMLPurifier_Token_End('script')
+ ),
+ ""
+ );
+ }
+
function test_generateFromTokens_XHTMLoff() {
$this->config = HTMLPurifier_Config::createDefault();
$this->config->set('Core', 'XHTML', false);
diff --git a/tests/HTMLPurifier/HTMLModule/ScriptingTest.php b/tests/HTMLPurifier/HTMLModule/ScriptingTest.php
new file mode 100644
index 00000000..69b83e0a
--- /dev/null
+++ b/tests/HTMLPurifier/HTMLModule/ScriptingTest.php
@@ -0,0 +1,52 @@
+assertResult(
+ '', 'foo();'
+ );
+
+ // enabled
+ $this->assertResult(
+ '', true,
+ array('HTML.Trusted' => true)
+ );
+
+ // max
+ $this->assertResult(
+ '', true,
+ array('HTML.Trusted' => true, 'Core.CommentScriptContents' => false)
+ );
+
+ // unsupported
+ $this->assertResult(
+ '',
+ '',
+ array('HTML.Trusted' => true, 'Core.CommentScriptContents' => false)
+ );
+
+ // invalid children
+ $this->assertResult(
+ '',
+ '',
+ array('HTML.Trusted' => true, 'Core.CommentScriptContents' => false)
+ );
+
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/tests/test_files.php b/tests/test_files.php
index 602dc47b..81df7851 100644
--- a/tests/test_files.php
+++ b/tests/test_files.php
@@ -68,6 +68,7 @@ $test_files[] = 'HTMLModule/EditTest.php';
$test_files[] = 'HTMLModule/HypertextTest.php';
$test_files[] = 'HTMLModule/ImageTest.php';
$test_files[] = 'HTMLModule/LegacyTest.php';
+$test_files[] = 'HTMLModule/ScriptingTest.php';
$test_files[] = 'IDAccumulatorTest.php';
$test_files[] = 'LanguageFactoryTest.php';
$test_files[] = 'LanguageTest.php';