<div class="stickycol"></div> </div> </body> </html> <?php } else { if ($_REQUEST["bb_action"] == "bb_main_edit_mainviewinfo") { BB_RunPluginAction("pre_bb_main_edit_mainviewinfo"); // Extensions check. BB_LoadExtensionsCache(); BB_UpdateExtensionsCache(); if (count($bb_extensions_info["vulnerabilities"])) { echo "<div id=\"mainviewinfo_vulnerabilities\">" . BB_HTMLPurify(implode("<br /><br />", $bb_extensions_info["vulnerabilities"])) . "</div>"; } if (count($bb_extensions_info["updates"])) { echo "<div id=\"mainviewinfo_updates\">" . BB_HTMLPurify(implode("<br /><br />", $bb_extensions_info["updates"])) . "</div>"; } echo $bb_revision_writeable ? "" : BB_Translate("<b>[Read Only]</b> "); echo htmlspecialchars(BB_Translate(BB_GetIANADesc($bb_pref_lang))); echo $bb_pref_lang == $bb_page["defaultlang"] ? BB_Translate(" [default]") : ""; echo $bb_profile != "" ? htmlspecialchars(BB_Translate(", " . $bb_profiles[$bb_profile])) : ""; if ($bb_revision_num < 0) { echo ", <a href=\"" . htmlspecialchars(BB_GetFullRequestURLBase("http") . "?lang=" . urlencode($bb_pref_lang)) . "\">" . BB_Translate("Live Page") . "</a>"; } else { echo BB_Translate(", Revision #%d, %s, Reason: %s | %s", $bb_revision_num, $bb_revision[0] == "" ? BB_Translate("<i>[Root]</i>") : htmlspecialchars($bb_revision[0]), htmlspecialchars($bb_revision[4]), "<a href=\"" . htmlspecialchars(BB_GetFullRequestURLBase("http") . "?lang=" . urlencode($bb_pref_lang)) . "\">" . BB_Translate("Live Page") . "</a>"); } if (isset($_REQUEST["notify"])) { require_once "translate.php"; if (isset($bb_translate_notify[(int) $_REQUEST["notify"]])) { $entry = $bb_translate_notify[(int) $_REQUEST["notify"]]; echo BB_Translate("<br />%s, %s, %s => %s, %s", htmlspecialchars($entry[0]), BB_FormatTimestamp($entry[1]), htmlspecialchars(BB_Translate(BB_GetIANADesc($entry[4], true, true))), htmlspecialchars(BB_Translate(BB_GetIANADesc($entry[5], true, true))), htmlspecialchars($entry[6]));
function BB_HTMLPurifyForWYMEditor($data, $options) { if (isset($options["shortcodes"]) && (!$options["shortcodes"] || !isset($options["shortcode_placeholder"]) || !isset($options["shortcode_ids"]))) { unset($options["shortcodes"]); } if (isset($options["validate_img"]) && !$options["validate_img"]) { unset($options["validate_img"]); } // Let HTML Purifier do the heavy-lifting (removes XSS, etc). // If the 'p' tag ever accepts more than 'class', the 'class' extraction code while generating pretty HTML will need rewriting. $config = array("Attr.EnableID" => isset($options["shortcodes"]), "HTML.Allowed" => "p[class],strong,em,sup,sub,a[title|href],ul[class],ol[class],li[class],h1[class],h2[class],h3[class],h4[class],h5[class],h6[class],pre[class],blockquote[class],img[" . (isset($options["shortcodes"]) ? "id|class|" : "") . "src|alt]"); if (isset($options["allowed_classes"]) && is_array($options["allowed_classes"])) { $config["Attr.AllowedClasses"] = $options["allowed_classes"]; } $data = BB_HTMLPurify($data, $config); // Replace newlines outside of 'pre' tags with spaces. $data2 = ""; $lastpos = 0; $pos = strpos($data, "<pre"); $pos2 = strpos($data, "</pre>"); $pos3 = strpos($data, ">", $pos); while ($pos !== false && $pos2 !== false && $pos3 !== false && $pos3 < $pos2) { $data2 .= Str::ReplaceNewlines(" ", substr($data, $lastpos, $pos3 + 1 - $lastpos)); $data2 .= Str::ReplaceNewlines("\n", substr($data, $pos3 + 1, $pos2 - $pos3 - 1)); $data2 .= "</pre>"; $lastpos = $pos2 + 6; $pos = strpos($data, "<pre", $lastpos); $pos2 = strpos($data, "</pre>", $lastpos); $pos3 = strpos($data, ">", $pos); } $data = $data2 . Str::ReplaceNewlines(" ", substr($data, $lastpos)); // Process the DOM to create consistent input and output. require_once ROOT_PATH . "/" . SUPPORT_PATH . "/simple_html_dom.php"; $html = new simple_html_dom(); $html2 = new simple_html_dom(); // Make sure all elements and text are inside a top-level tag. $html->load("<body>" . $data . "</body>"); $bodytags = array("p" => true, "ul" => true, "ol" => true, "h1" => true, "h2" => true, "h3" => true, "h4" => true, "h5" => true, "h6" => true, "pre" => true, "blockquote" => true); $rows = $html->find("body text"); foreach ($rows as $row) { $row2 = $row; while ($row2->parent()->tag != "body") { $row2 = $row2->parent(); } if (!isset($bodytags[$row2->tag])) { $row2->outertext = "<p>" . $row2->outertext . "</p>"; } } $html->load($html->save()); $body = $html->find("body", 0); $rows = $body->children(); foreach ($rows as $row) { if (!isset($bodytags[$row->tag])) { $row->outertext = "<p>" . $row->outertext . "</p>"; } } $html->load($html->save()); $rows = $html->find("blockquote text"); foreach ($rows as $row) { $row2 = $row; while ($row2->parent()->tag != "blockquote") { $row2 = $row2->parent(); } if (!isset($bodytags[$row2->tag])) { $row2->outertext = "<p>" . $row2->outertext . "</p>"; } } $html->load($html->save()); // Clean up 'li' elements. WYMEditor only allows a limited number of tags (a good thing). $rows = $html->find("li"); foreach ($rows as $row) { $row->innertext = strip_tags($row->innertext, "<strong><em><sup><sub><a><img><ul><ol><li>"); } // Replace with spaces. $data = $html->save(); $data = str_replace(array(" ", " ", "Â "), array(" ", " ", " "), $data); $html->load($data); // Process shortcodes or images. if (isset($options["shortcodes"])) { // Remove invalid 'img' tags. $rows = $html->find("img"); foreach ($rows as $row) { if (!isset($row->class) || $row->class != $options["shortcode_placeholder"] || !isset($row->id) || !isset($options["shortcode_ids"][$row->id])) { $row->outertext = ""; } else { $row->src = $options["shortcode_ids"][$row->id]; } } $html->load($html->save()); // Move text inside the special 'p.wrap-shortcode' class to separate 'p' tags. $rows = $html->find("p.wrap-shortcode img"); foreach ($rows as $row) { $str = $row->parent()->innertext; $pos = strpos($str, "<img "); $pos2 = strpos($str, "/>", $pos); $str2 = substr($str, 0, $pos); $str3 = substr($str, $pos2 + 2); $str = substr($str, $pos, $pos2 + 2 - $pos); if ($str2 != "" || $str3 != "") { $row->parent()->outertext = ($str2 == "" ? "" : "<p>" . $str2 . "</p>") . "<p class=\"" . $row->parent()->class . "\">" . $str . "</p>" . ($str3 == "" ? "" : "<p>" . $str3 . "</p>"); } } $html->load($html->save()); } else { if (isset($options["validate_img"])) { // Download each 'img' 'src' and check them for valid web output (only allow JPEG, PNG, and GIF). $imgopts = array("protocol" => isset($options["validate_img_protocol"]) ? $options["validate_img_protocol"] : "", "allow_gif" => isset($options["validate_img_allow_gif"]) ? $options["validate_img_allow_gif"] : true, "allow_jpg" => isset($options["validate_img_allow_jpg"]) ? $options["validate_img_allow_jpg"] : true, "allow_png" => isset($options["validate_img_allow_png"]) ? $options["validate_img_allow_png"] : true); $rows = $html->find("img"); foreach ($rows as $row) { if (!isset($row->src)) { $row->outertext = ""; } else { $imginfo = BB_IsValidHTMLImage($row->src, $imgopts); if (!$imginfo["success"]) { $row->outertext = ""; } } } $html->load($html->save()); } } // Remove special classes that are improperly used. $specials = array("wrap-start" => "p", "wrap-end" => "p", "table-row" => "p", "table-cell" => "p", "table-end" => "p"); if (isset($options["shortcodes"])) { $specials["wrap-shortcode"] = array("p", "img"); } if (isset($options["additional_specials"])) { $specials = array_merge($specials, $options["additional_specials"]); } foreach ($specials as $class => $tags) { $rows = $html->find("." . $class); foreach ($rows as $row) { if (is_string($tags)) { $valid = true; } else { $html2->load($row->innertext); $row2 = $html2->find($tags[1], 0); $valid = $row2 ? true : false; } $valid = $valid && (is_string($tags) && $row->tag == $tags || is_array($tags) && $row->tag == $tags[0]); if (!$valid) { $row->class = BB_HTMLRemoveClass($row->class, $class); } if ($row->class == "") { unset($row->class); } } $html->load($html->save()); } // Remove empty elements without a class attribute. do { $found = false; $stack = array(); $body = $html->find("body", 0); $stack[] = array("rows" => $body->children(), "pos" => 0); while (count($stack)) { $pos = count($stack) - 1; if ($stack[$pos]["pos"] >= count($stack[$pos]["rows"])) { $stack = array_slice($stack, 0, -1); if (count($stack)) { $pos = count($stack) - 1; $row = $stack[$pos]["rows"][$stack[$pos]["pos"]]; if (!$found && trim($row->innertext) !== $row->innertext) { $row->innertext = trim($row->innertext); $found = true; } $stack[$pos]["pos"]++; } } else { $row = $stack[$pos]["rows"][$stack[$pos]["pos"]]; $rows = $row->children(); if (count($rows)) { $stack[] = array("rows" => $rows, "pos" => 0); } else { if (!isset($row->class) && trim($row->innertext) == "") { $row->outertext = ""; $found = true; } else { if (trim($row->innertext) !== $row->innertext) { $row->innertext = trim($row->innertext); $found = true; } } $stack[$pos]["pos"]++; } } } $html->load($html->save()); } while ($found); $body = $html->find("body", 0); $data = $body->innertext; // Finalize 'li' tag cleanup. $data = preg_replace('/<\\/li>\\s+/', "</li>", $data); return $data; }