/** * Replace plugins with guid keys and store them in an array * * @param $data string data to be cleaned of plugins * @param $noparsed array output array */ function plugins_remove(&$data, &$noparsed) { $matches = WikiParser_PluginMatcher::match($data); // find the plugins foreach ($matches as $match) { // each plugin $plugin = (string) $match; $key = '§' . md5(TikiLib::genPass()) . '§'; // by replace whole plugin with a guid $noparsed['key'][] = $key; $noparsed['data'][] = $plugin; } $data = str_replace($noparsed['data'], $noparsed['key'], $data); }
public function convertData($data) { //we store the original matches because we are about to change and update them, we need to get their fingerprint $oldMatches = WikiParser_PluginMatcher::match($data); // HTML-decode pages $data = htmlspecialchars_decode($data); // find the plugins $matches = WikiParser_PluginMatcher::match($data); $replaced = array(); $fingerPrintsOld = array(); foreach ($oldMatches as $match) { $name = $match->getName(); $meta = $this->parserlib->plugin_info($name); // only check fingerprints of plugins requiring validation if (!empty($meta['validate'])) { $args = $this->argumentParser->parse($match->getArguments()); //RobertPlummer - pre 9, latest findings from v8 is that the < and > chars are THE ONLY ones converted to < and > everything else seems to be decoded $body = $match->getBody(); // jonnyb - pre 9.0, Tiki 6 (?) fingerprints are calculated with the undecoded body $fingerPrint = $this->parserlib->plugin_fingerprint($name, $meta, $body, $args); // so check the db for previously recorded plugins if (!$this->parserlib->getOne('SELECT COUNT(*) FROM tiki_plugin_security WHERE fingerprint = ?', array($fingerPrint))) { // jb but v 7 & 8 fingerprints may be calculated differently, so check both fully decoded and partially $body = htmlspecialchars_decode($body); $fingerPrint = $this->parserlib->plugin_fingerprint($name, $meta, $body, $args); if (!$this->parserlib->getOne('SELECT COUNT(*) FROM tiki_plugin_security WHERE fingerprint = ?', array($fingerPrint))) { $body = str_replace(array('<', '>'), array('<', '>'), $body); $fingerPrint = $this->parserlib->plugin_fingerprint($name, $meta, $body, $args); if (!$this->parserlib->getOne('SELECT COUNT(*) FROM tiki_plugin_security WHERE fingerprint = ?', array($fingerPrint))) { // old fingerprint not found - what to do? Might be worth trying " chars too... $fingerPrint = ''; } } } $fingerPrintsOld[] = $fingerPrint; } } $fingerPrintsNew = array(); // each plugin foreach ($matches as $match) { $name = $match->getName(); $meta = $this->parserlib->plugin_info($name); $argsRaw = $match->getArguments(); //Here we detect if a plugin was double encoded and this is the second decode //try to detect double encoding if (preg_match("/&&/i", $argsRaw) || preg_match("/"/i", $argsRaw) || preg_match("/>/i", $argsRaw)) { $argsRaw = htmlspecialchars_decode($argsRaw); // decode entities in the plugin args (usually ") } $args = $this->argumentParser->parse($argsRaw); $plugin = (string) $match; $key = '§' . md5(TikiLib::genPass()) . '§'; // by replace whole plugin with a guid $data = str_replace($plugin, $key, $data); $body = $match->getBody(); // leave the bodies alone $key2 = '§' . md5(TikiLib::genPass()) . '§'; // by replacing it with a guid $plugin = str_replace($body, $key2, $plugin); //Here we detect if a plugin was double encoded and this is the second decode //try to detect double encoding if (preg_match("/&&/i", $plugin) || preg_match("/"/i", $plugin) || preg_match("/>/i", $plugin)) { $plugin = htmlspecialchars_decode($plugin); // decode entities in the plugin args (usually ") } $plugin = str_replace($key2, $body, $plugin); // finally put the body back $replaced['key'][] = $key; $replaced['data'][] = $plugin; // store the decoded-args plugin for replacement later // only check fingerprints of plugins requiring validation if (!empty($meta['validate'])) { $fingerPrintsNew[] = $this->parserlib->plugin_fingerprint($name, $meta, $body, $args); } } $this->parserlib->plugins_replace($data, $replaced); // put the plugins back into the page return array("data" => $data, "fingerPrintsOld" => $fingerPrintsOld, "fingerPrintsNew" => $fingerPrintsNew); }