From aa6fe820ccc703843c3ab9412a2326d5e9c6578c Mon Sep 17 00:00:00 2001
From: timcooijmans <t.cooijmans@simplendi.com>
Date: Fri, 27 Jul 2012 22:07:26 +0200
Subject: [PATCH] Issue #1673444 by timcooijmans: Added setting to disable the
 filtering by the xml parser.

---
 closedquestion.module |   29 ++++++++++
 lib/XmlLib.inc.php    |  144 +++++++++++++++++++++++++++++--------------------
 2 files changed, 115 insertions(+), 58 deletions(-)

diff --git a/closedquestion.module b/closedquestion.module
index fe4aa14..b1e36d4 100644
--- a/closedquestion.module
+++ b/closedquestion.module
@@ -19,6 +19,10 @@ define('CLOSEDQUESTION_RIGHT_EDITOWN', 'edit own closedquestion');
  * User-right for editing other users' closed questions
  */
 define('CLOSEDQUESTION_RIGHT_EDITALL', 'edit all closedquestions');
+/**
+ * User-right for editing module settings
+ */
+define('CLOSEDQUESTION_RIGHT_SETTINGS', 'edit closedquestion settings');
 
 /**
  * Implements hook_help()
@@ -42,6 +46,7 @@ function closedquestion_perm() {
     CLOSEDQUESTION_RIGHT_CREATE,
     CLOSEDQUESTION_RIGHT_EDITOWN,
     CLOSEDQUESTION_RIGHT_EDITALL,
+    CLOSEDQUESTION_RIGHT_SETTINGS,
   );
   return $retval;
 }
@@ -195,6 +200,14 @@ function closedquestion_menu() {
     'access arguments' => array(CLOSEDQUESTION_RIGHT_CREATE),
     'type' => MENU_CALLBACK,
   );
+  $items['admin/settings/closedquestion'] = array(
+    'title' => 'Closed Question module settings',
+    'description' => 'Edit the Closed Question module settings',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('closedquestion_admin'),
+    'access arguments' => array('CLOSEDQUESTION_RIGHT_SETTINGS'),
+    'type' => MENU_NORMAL_ITEM,
+   );
   return $items;
 }
 
@@ -451,6 +464,22 @@ function closedquestion_view($node, $teaser = FALSE, $page = FALSE) {
 }
 
 /**
+ * Implements the administration page
+ */
+function closedquestion_admin() {
+  $form = array();
+  
+  $form['closedquestion_usebuiltinfilter'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Use the built-in XML filter to filter HTML'),
+    '#default_value' => variable_get('closedquestion_usebuiltinfilter', 1),
+    '#description' => t('Using the built-in XML filter prevents the use of Javascript and other tags, disabling this option allows the use of input formats to define allowed tags and per user allowed tags <b>but can cause a security issue!</b>')
+  );
+  
+  return system_settings_form($form);
+}
+
+/**
  * Form builder wrapper. Fetches the question-form for the passed node.
  *
  * @param object $node
diff --git a/lib/XmlLib.inc.php b/lib/XmlLib.inc.php
index 30146a0..a88a6a9 100644
--- a/lib/XmlLib.inc.php
+++ b/lib/XmlLib.inc.php
@@ -50,66 +50,94 @@ function cq_copy_attributes($node) {
 function cq_get_text_content($parent, $context, $full_filter = TRUE, $delay = FALSE) {
   $retval = '';
   $nodes = $parent->childNodes;
-  foreach ($nodes as $node) {
-    switch ($node->nodeName) {
-      case '#comment':
-        break;
-
-      case '#text':
-      case '#cdata-section':
-        $retval .= $node->nodeValue;
-        break;
-
-      case 'formblock':
-        $retval .= '<formblock/>';
-        break;
-
-      case 'img':
-      case 'br':
-        $retval .= '<' . $node->nodeName . ' ' . cq_copy_attributes($node) . '/>';
-        break;
-
-      case 'h1':
-      case 'h2':
-      case 'h3':
-      case 'h4':
-      case 'h5':
-      case 'h6':
-      case 'sub':
-      case 'sup':
-      case 'p':
-      case 'pre':
-      case 'b':
-      case 'i':
-      case 'u':
-      case 'strong':
-      case 'em':
-      case 'table':
-      case 'a':
-      case 'tr':
-      case 'td':
-      case 'th':
-      case 'span':
-      case 'div':
-      case 'ul':
-      case 'ol':
-      case 'dl':
-      case 'dt':
-      case 'dd':
-      case 'li':
-      case 'applet':
-      case 'param':
-        $retval .= '<' . $node->nodeName . ' ' . cq_copy_attributes($node) . '>' . cq_get_text_content($node, $context, FALSE, $delay) . '</' . $node->nodeName . '>';
-        break;
-
-      default:
-        $retval .= $node->nodeValue;
-        break;
+  
+  if(variable_get('closedquestion_usebuiltinfilter', 1) == 1) {
+    foreach ($nodes as $node) {
+      switch ($node->nodeName) {
+        case '#comment':
+          break;
+  
+        case '#text':
+        case '#cdata-section':
+          $retval .= $node->nodeValue;
+          break;
+  
+        case 'formblock':
+          $retval .= '<formblock/>';
+          break;
+  
+        case 'img':
+        case 'br':
+          $retval .= '<' . $node->nodeName . ' ' . cq_copy_attributes($node) . '/>';
+          break;
+  
+        case 'h1':
+        case 'h2':
+        case 'h3':
+        case 'h4':
+        case 'h5':
+        case 'h6':
+        case 'sub':
+        case 'sup':
+        case 'p':
+        case 'pre':
+        case 'b':
+        case 'i':
+        case 'u':
+        case 'strong':
+        case 'em':
+        case 'table':
+        case 'a':
+        case 'tr':
+        case 'td':
+        case 'th':
+        case 'span':
+        case 'div':
+        case 'ul':
+        case 'ol':
+        case 'dl':
+        case 'dt':
+        case 'dd':
+        case 'li':
+        case 'applet':
+        case 'param':
+          $retval .= '<' . $node->nodeName . ' ' . cq_copy_attributes($node) . '>' . cq_get_text_content($node, $context, FALSE, $delay) . '</' . $node->nodeName . '>';
+          break;
+  
+        default:
+          $retval .= $node->nodeValue;
+          break;
+      }
+      foreach ($context->getHandledTags() AS $tag) {
+        if (drupal_strtolower($node->nodeName) == drupal_strtolower($tag)) {
+          $retval .= $context->handleNode($node, $delay);
+        }
+      }
     }
-    foreach ($context->getHandledTags() AS $tag) {
-      if (drupal_strtolower($node->nodeName) == drupal_strtolower($tag)) {
-        $retval .= $context->handleNode($node, $delay);
+  } 
+  else {
+    foreach($nodes as $node) {
+      // A boolean is used to indicated wheter the node is already handled
+      $handled = False;
+      foreach ($context->getHandledTags() AS $tag) {
+        if (drupal_strtolower($node->nodeName) == drupal_strtolower($tag)) {
+          $retval .= $context->handleNode($node, $delay);
+          $handled = True;
+        }
       }
+      
+      // If the node is not handled handle it now
+      if ($handled == False) {
+        // If the node has children parse them
+        if ($node->hasChildNodes() && $node->nodeName != '#cdata-section') {
+          $retval .= '<' . $node->nodeName . ' ' . cq_copy_attributes($node) . '>' . cq_get_text_content($node, $context, FALSE, $delay) . '</' . $node->nodeName . '>';          
+        } 
+        // Otherwise return the string representation of the node
+        else {
+          $retval .= $node->ownerDocument->saveXML($node);
+        }
+      }
+
     }
   }
   if ($full_filter && !$delay) {
-- 
1.7.9.5

