Index: lib/parser/parserlib.php
===================================================================
--- lib/parser/parserlib.php	(revision 62506)
+++ lib/parser/parserlib.php	(working copy)
@@ -1612,7 +1612,13 @@
 			$parse_color = 1;
 			$temp = $data;
 			while ($parse_color) { // handle nested colors, parse innermost first
-				$temp = preg_replace("/~~([^~:,]+)(,([^~:]+))?:([^~]*)(?!~~[^~:,]+(?:,[^~:]+)?:[^~]*~~)~~/Ums", "<span style=\"color:$1; background-color:$3\">$4</span>", $temp, -1, $parse_color);
+				$temp = preg_replace_callback(
+					"/~~([^~:,]+)(,([^~:]+))?:([^~]*)(?!~~[^~:,]+(?:,[^~:]+)?:[^~]*~~)~~/Ums",
+					'self::colorAttrEscape',
+					$temp,
+					-1,
+					$parse_color
+				);
 
 				if (! empty($temp)) {
 					$data = $temp;
@@ -1622,7 +1628,11 @@
 			// On large pages, the above preg rule can hit a BACKTRACE LIMIT
 			// In case it does, use the simpler color replacement pattern.
 			if (empty($temp)) {
-				$data = preg_replace("/\~\~([^\:\,]+)(,([^\:]+))?:([^~]*)\~\~/Ums", "<span style=\"color:$1; background:$3\">$4</span>", $data);
+				$data = preg_replace_callback(
+					"/\~\~([^\:\,]+)(,([^\:]+))?:([^~]*)\~\~/Ums",
+					'self::colorAttrEscape',
+					$data
+				);
 			}
 		}
 
@@ -1720,6 +1730,23 @@
 		return $data;
 	}
 
+	/**
+	 * Used as preg_replace_callback methods within in the parse_data() method to escape color style attributes when
+	 * generating HTML for the wiki color syntax - e.g. ~~#909:text~~
+	 *
+	 * @param $matches
+	 * @return string
+	 */
+	private function colorAttrEscape($matches)
+	{
+		$esc = new Zend\Escaper\Escaper();
+		$color = !empty($matches[1]) ? 'color:' . $esc->escapeHtmlAttr($matches[1]): '';
+		$background = !empty($matches[3]) ? 'background-color:' . $esc->escapeHtmlAttr($matches[3]) : '';
+		$semi = !empty($color) && !empty($background) ? ';' : '';
+		$text = !empty($matches[4]) ? $matches[4] : '';
+		return '<span style="' . $color . $semi . $background . '">' . $text . '</span>';
+	}
+
 	//*
 	function parse_data_simple( $data )
 	{
@@ -2770,7 +2797,7 @@
 					// Get count of (possible) header signs at start
 					$hdrlevel = $tikilib->how_many_at_start($line, '!');
 					// If 1st char on line is '!' and its count less than 6 (max in HTML)
-					if ($litype == '!' && $hdrlevel > 0 && $hdrlevel <= 6) {
+					if ($litype == '!' && $hdrlevel > 0) { // Modified to allow section levels deeper than 6
 
 						/*
 						 * Handle headings autonumbering syntax (i.e. !#Text, !!#Text, ...)
@@ -2938,10 +2965,15 @@
 
 						$style = $do_center ? ' style="text-align: center;"' : '';
 
+						if ($hdrlevel > 6) {
+							$headerElement = 'h6';
+						} else {
+							$headerElement = 'h' . $hdrlevel;
+						}
 						if ( $prefs['feature_wiki_show_hide_before'] == 'y' ) {
-							$line = $button.'<h'.($hdrlevel).$style.' class="showhide_heading" id="'.$thisid.'">'.$aclose.' '.$title_text.'</h'.($hdrlevel).'>'.$aclose2;
+							$line = $button.'<' . $headerElement . $style.' class="showhide_heading" id="'.$thisid.'">'.$aclose.' '.$title_text.'</' . $headerElement . '>'.$aclose2;
 						} else {
-							$line = $button.'<h'.($hdrlevel).$style.' class="showhide_heading" id="'.$thisid.'">'.$title_text.'</h'.($hdrlevel).'>'.$aclose.$aclose2;
+							$line = $button.'<' . $headerElement . $style.' class="showhide_heading" id="'.$thisid.'">'.$title_text.'</' . $headerElement . '>'.$aclose.$aclose2;
 						}
 					} elseif (!strcmp($line, $prefs['wiki_page_separator'])) {
 						// Close open paragraph, lists, and div's
