protected function parseWikitext($title, $newRevId) { $apiParams = array('action' => 'parse', 'page' => $title->getPrefixedDBkey(), 'oldid' => $newRevId, 'prop' => 'text|revid|categorieshtml|displaytitle|modules|jsconfigvars'); $api = new ApiMain(new DerivativeRequest($this->getRequest(), $apiParams, false), true); $api->execute(); if (defined('ApiResult::META_CONTENT')) { $result = $api->getResult()->getResultData(null, array('BC' => array(), 'Types' => array(), 'Strip' => 'all')); } else { $result = $api->getResultData(); } $content = isset($result['parse']['text']['*']) ? $result['parse']['text']['*'] : false; $categorieshtml = isset($result['parse']['categorieshtml']['*']) ? $result['parse']['categorieshtml']['*'] : false; $links = isset($result['parse']['links']) ? $result['parse']['links'] : array(); $revision = Revision::newFromId($result['parse']['revid']); $timestamp = $revision ? $revision->getTimestamp() : wfTimestampNow(); $displaytitle = isset($result['parse']['displaytitle']) ? $result['parse']['displaytitle'] : false; $modules = isset($result['parse']['modules']) ? $result['parse']['modules'] : array(); $jsconfigvars = isset($result['parse']['jsconfigvars']) ? $result['parse']['jsconfigvars'] : array(); if ($content === false || strlen($content) && $revision === null) { return false; } if ($displaytitle !== false) { // Escape entities as in OutputPage::setPageTitle() $displaytitle = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($displaytitle)); } return array('content' => $content, 'categorieshtml' => $categorieshtml, 'basetimestamp' => $timestamp, 'starttimestamp' => wfTimestampNow(), 'displayTitleHtml' => $displaytitle, 'modules' => $modules, 'jsconfigvars' => $jsconfigvars); }
/** * "Page title" means the contents of \<h1\>. It is stored as a valid HTML fragment. * This function allows good tags like \<sup\> in the \<h1\> tag, but not bad tags like \<script\>. * This function automatically sets \<title\> to the same content as \<h1\> but with all tags removed. * Bad tags that were escaped in \<h1\> will still be escaped in \<title\>, and good tags like \<i\> will be dropped entirely. * * @param $name string */ public function setPageTitle($name) { # change "<script>foo&bar</script>" to "<script>foo&bar</script>" # but leave "<i>foobar</i>" alone $nameWithTags = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($name)); $this->mPagetitle = $nameWithTags; # change "<i>foo&bar</i>" to "foo&bar" $this->setHTMLTitle(wfMsg('pagetitle', Sanitizer::stripAllTags($nameWithTags))); }
/** * @see DataValue::setOutputFormat */ public function setOutputFormat($formatstring) { if ($formatstring == $this->m_outformat) { return; } unset($this->trueCaption); unset($this->falseCaption); if ($formatstring === '') { // no format // (unsetting the captions is exactly the right thing here) } elseif (strtolower($formatstring) == '-') { // "plain" format $this->trueCaption = 'true'; $this->falseCaption = 'false'; } elseif (strtolower($formatstring) == 'x') { // X format $this->trueCaption = '<span style="font-family: sans-serif; ">X</span>'; $this->falseCaption = ' '; } else { // format "truelabel, falselabel" (hopefully) $captions = explode(',', $formatstring, 2); if (count($captions) == 2) { // note: escaping needed to be safe; MW-sanitising would be an alternative $this->trueCaption = \Sanitizer::removeHTMLtags(trim($captions[0])); $this->falseCaption = \Sanitizer::removeHTMLtags(trim($captions[1])); } // else: no format that is recognised, ignore } // Localized version if (strpos($formatstring, 'LOCL') !== false) { $this->setLocalizedCaptions($formatstring); } $this->m_caption = $this->getStandardCaption(true); $this->m_outformat = $formatstring; }
/** * Override the title of the page when viewed, provided we've been given a * title which will normalise to the canonical title * * @param $parser Parser: parent parser * @param string $text desired title text * @return String */ static function displaytitle($parser, $text = '') { global $wgRestrictDisplayTitle; #parse a limited subset of wiki markup (just the single quote items) $text = $parser->doQuotes($text); #remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever $text = preg_replace('/' . preg_quote($parser->uniqPrefix(), '/') . '.*?' . preg_quote(Parser::MARKER_SUFFIX, '/') . '/', '', $text); #list of disallowed tags for DISPLAYTITLE #these will be escaped even though they are allowed in normal wiki text $bad = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr', 'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rp', 'br'); #only requested titles that normalize to the actual title are allowed through #if $wgRestrictDisplayTitle is true (it is by default) #mimic the escaping process that occurs in OutputPage::setPageTitle $text = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($text, null, array(), array(), $bad)); $title = Title::newFromText(Sanitizer::stripAllTags($text)); if (!$wgRestrictDisplayTitle) { $parser->mOutput->setDisplayTitle($text); } elseif ($title instanceof Title && $title->getFragment() == '' && $title->equals($parser->mTitle)) { $parser->mOutput->setDisplayTitle($text); } return ''; }
} // link icon if ($image['link'] != '') { $linkMsg = htmlspecialchars($image['link']); } else { $linkMsg = wfMsg('wikiaPhotoGallery-preview-add-link'); } // image caption if ($image['caption'] != '') { $caption = Sanitizer::removeHTMLtags($image['caption']); } else { $caption = wfMsg('wikiaPhotoGallery-preview-add-caption'); } // image description if ($image['linktext'] != '') { $linktext = Sanitizer::removeHTMLtags($image['linktext']); } else { $linktext = wfMsg('wikiaPhotoGallery-preview-add-description'); } ?> <span class="WikiaPhotoGalleryPreviewSliderCaptionWrapper"> <p class="WikiaPhotoGalleryPreviewSliderCaption WikiaPhotoGalleryPreviewItemCaption SliderTitle"><?php echo $caption; ?> </p> <p class="WikiaPhotoGalleryPreviewSliderCaption WikiaPhotoGalleryPreviewItemCaption SliderDescription"><?php echo $linktext; ?> </p> <p class="WikiaPhotoGalleryPreviewSliderCaption WikiaPhotoGalleryPreviewItemCaption SliderLink"><?php echo $linkMsg;
function testSelfClosingTag() { $GLOBALS['wgUseTidy'] = false; $this->assertEquals('<div>Hello world</div>', Sanitizer::removeHTMLtags('<div>Hello world</div />'), 'Self-closing closing div'); }
/** * strip/replaceVariables/unstrip for preprocessor regression testing */ function srvus($text) { $text = $this->strip($text, $this->mStripState); $text = Sanitizer::removeHTMLtags($text); $text = $this->replaceVariables($text); $text = preg_replace('/<!--MWTEMPLATESECTION.*?-->/', '', $text); $text = $this->mStripState->unstripBoth($text); return $text; }
/** * Override the title of the page when viewed, provided we've been given a * title which will normalise to the canonical title * * @param Parser $parser Parent parser * @param string $text Desired title text * @param string $uarg * @return string */ public static function displaytitle($parser, $text = '', $uarg = '') { global $wgRestrictDisplayTitle; static $magicWords = null; if (is_null($magicWords)) { $magicWords = new MagicWordArray(['displaytitle_noerror', 'displaytitle_noreplace']); } $arg = $magicWords->matchStartToEnd($uarg); // parse a limited subset of wiki markup (just the single quote items) $text = $parser->doQuotes($text); // remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever $text = $parser->killMarkers($text); // list of disallowed tags for DISPLAYTITLE // these will be escaped even though they are allowed in normal wiki text $bad = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr', 'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rtc', 'rp', 'br']; // disallow some styles that could be used to bypass $wgRestrictDisplayTitle if ($wgRestrictDisplayTitle) { $htmlTagsCallback = function (&$params) { $decoded = Sanitizer::decodeTagAttributes($params); if (isset($decoded['style'])) { // this is called later anyway, but we need it right now for the regexes below to be safe // calling it twice doesn't hurt $decoded['style'] = Sanitizer::checkCss($decoded['style']); if (preg_match('/(display|user-select|visibility)\\s*:/i', $decoded['style'])) { $decoded['style'] = '/* attempt to bypass $wgRestrictDisplayTitle */'; } } $params = Sanitizer::safeEncodeTagAttributes($decoded); }; } else { $htmlTagsCallback = null; } // only requested titles that normalize to the actual title are allowed through // if $wgRestrictDisplayTitle is true (it is by default) // mimic the escaping process that occurs in OutputPage::setPageTitle $text = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($text, $htmlTagsCallback, [], [], $bad)); $title = Title::newFromText(Sanitizer::stripAllTags($text)); if (!$wgRestrictDisplayTitle || $title instanceof Title && !$title->hasFragment() && $title->equals($parser->mTitle)) { $old = $parser->mOutput->getProperty('displaytitle'); if ($old === false || $arg !== 'displaytitle_noreplace') { $parser->mOutput->setDisplayTitle($text); } if ($old !== false && $old !== $text && !$arg) { $converter = $parser->getConverterLanguage()->getConverter(); return '<span class="error">' . wfMessage('duplicate-displaytitle', $converter->markNoConversion(wfEscapeWikiText($old)), $converter->markNoConversion(wfEscapeWikiText($text)))->inContentLanguage()->text() . '</span>'; } else { return ''; } } else { $parser->addTrackingCategory('restricted-displaytitle-ignored'); $converter = $parser->getConverterLanguage()->getConverter(); return '<span class="error">' . wfMessage('restricted-displaytitle', $converter->markNoConversion(wfEscapeWikiText($text)))->inContentLanguage()->text() . '</span>'; } }
static function onInternalParseBeforeLinks(Parser &$parser, &$text) { $varStore = self::get($parser); // only do this if '#var_final' was used if ($varStore->mFinalizedVarsStripState === null) { return true; } /* * all vars are final now, check whether requested vars can be inserted for '#final_var' or * if the default has to be inserted. In any case, adjust the strip item value */ foreach ($varStore->mFinalizedVars as $stripStateId => $varName) { $varVal = $varStore->getVarValue($varName, ''); if ($varVal !== '') { // replace strip item value with final variables value or registered default: //$varStore->mFinalizedVarsStripState->general->setPair( $stripStateId, $varVal ); $varStore->stripStatePair($stripStateId, $varVal); } } /** * Unstrip all '#var_final' strip-markers with their final '#var' or default values. * This HAS to be done here and can't be done thru the normal unstrip process of MW. * This because the default value as well as the variables value stil have to be rendered properly since they * may contain links or even category links. On the other hand, they can't be parsed with Parser::recursiveTagParse() * since this would parse wiki templates and functions which are intended as normal text, kind of similar to * returning a parser functions value with 'noparse' => true. * Also, there is no way to expand the '#var_final' default value here, just if needed, since the output could be an * entirely different, e.g. if variables are used. * This method also takes care of recursive '#var_final' calls (within the default value) quite well. */ $text = $varStore->mFinalizedVarsStripState->unstripGeneral($text); /* * Sanitize the whole thing, otherwise HTML and JS code injection would be possible. * Basically the same is happening in Parser::internalParse() right before 'InternalParseBeforeLinks' hook is called. */ $text = Sanitizer::removeHTMLtags($text, array(&$parser, 'attributeStripCallback'), false, array_keys($parser->mTransparentTagHooks)); return true; }
/** * Override the title of the page when viewed, provided we've been given a * title which will normalise to the canonical title * * @param $parser Parser: parent parser * @param string $text desired title text * @return String */ static function displaytitle($parser, $text = '') { global $wgRestrictDisplayTitle; // parse a limited subset of wiki markup (just the single quote items) $text = $parser->doQuotes($text); // remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever $text = preg_replace('/' . preg_quote($parser->uniqPrefix(), '/') . '.*?' . preg_quote(Parser::MARKER_SUFFIX, '/') . '/', '', $text); // list of disallowed tags for DISPLAYTITLE // these will be escaped even though they are allowed in normal wiki text $bad = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr', 'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rp', 'br'); // disallow some styles that could be used to bypass $wgRestrictDisplayTitle if ($wgRestrictDisplayTitle) { $htmlTagsCallback = function (&$params) { $decoded = Sanitizer::decodeTagAttributes($params); if (isset($decoded['style'])) { // this is called later anyway, but we need it right now for the regexes below to be safe // calling it twice doesn't hurt $decoded['style'] = Sanitizer::checkCss($decoded['style']); if (preg_match('/(display|user-select|visibility)\\s*:/i', $decoded['style'])) { $decoded['style'] = '/* attempt to bypass $wgRestrictDisplayTitle */'; } } $params = Sanitizer::safeEncodeTagAttributes($decoded); }; } else { $htmlTagsCallback = null; } // only requested titles that normalize to the actual title are allowed through // if $wgRestrictDisplayTitle is true (it is by default) // mimic the escaping process that occurs in OutputPage::setPageTitle $text = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($text, $htmlTagsCallback, array(), array(), $bad)); $title = Title::newFromText(Sanitizer::stripAllTags($text)); if (!$wgRestrictDisplayTitle) { $parser->mOutput->setDisplayTitle($text); } elseif ($title instanceof Title && !$title->hasFragment() && $title->equals($parser->mTitle)) { $parser->mOutput->setDisplayTitle($text); } return ''; }
/** * @dataProvider dataRemoveHTMLtags * @covers Sanitizer::removeHTMLtags */ public function testRemoveHTMLtags($input, $output, $msg = null) { MWTidy::setInstance(false); $this->assertEquals($output, Sanitizer::removeHTMLtags($input), $msg); }
/** * Return the text of a template, after recursively * replacing any variables or templates within the template. * * @param array $piece The parts of the template * $piece['text']: matched text * $piece['title']: the title, i.e. the part before the | * $piece['parts']: the parameter array * @return string the text of the template * @private */ function braceSubstitution($piece) { global $wgContLang, $wgLang, $wgAllowDisplayTitle, $action; $fname = __METHOD__; wfProfileIn($fname); wfProfileIn(__METHOD__ . '-setup'); # Flags $found = false; # $text has been filled $nowiki = false; # wiki markup in $text should be escaped $noparse = false; # Unsafe HTML tags should not be stripped, etc. $noargs = false; # Don't replace triple-brace arguments in $text $replaceHeadings = false; # Make the edit section links go to the template not the article $isHTML = false; # $text is HTML, armour it against wikitext transformation $forceRawInterwiki = false; # Force interwiki transclusion to be done in raw mode not rendered # Title object, where $text came from $title = NULL; $linestart = ''; # $part1 is the bit before the first |, and must contain only title characters # $args is a list of arguments, starting from index 0, not including $part1 $titleText = $part1 = $piece['title']; # If the third subpattern matched anything, it will start with | if (null == $piece['parts']) { $replaceWith = $this->variableSubstitution(array($piece['text'], $piece['title'])); if ($replaceWith != $piece['text']) { $text = $replaceWith; $found = true; $noparse = true; $noargs = true; } } $args = null == $piece['parts'] ? array() : $piece['parts']; $argc = count($args); wfProfileOut(__METHOD__ . '-setup'); # SUBST wfProfileIn(__METHOD__ . '-modifiers'); if (!$found) { $mwSubst =& MagicWord::get('subst'); if ($mwSubst->matchStartAndRemove($part1) xor $this->ot['wiki']) { # One of two possibilities is true: # 1) Found SUBST but not in the PST phase # 2) Didn't find SUBST and in the PST phase # In either case, return without further processing $text = $piece['text']; $found = true; $noparse = true; $noargs = true; } } # MSG, MSGNW and RAW if (!$found) { # Check for MSGNW: $mwMsgnw =& MagicWord::get('msgnw'); if ($mwMsgnw->matchStartAndRemove($part1)) { $nowiki = true; } else { # Remove obsolete MSG: $mwMsg =& MagicWord::get('msg'); $mwMsg->matchStartAndRemove($part1); } # Check for RAW: $mwRaw =& MagicWord::get('raw'); if ($mwRaw->matchStartAndRemove($part1)) { $forceRawInterwiki = true; } } wfProfileOut(__METHOD__ . '-modifiers'); # Parser functions if (!$found) { wfProfileIn(__METHOD__ . '-pfunc'); $colonPos = strpos($part1, ':'); if ($colonPos !== false) { # Case sensitive functions $function = substr($part1, 0, $colonPos); if (isset($this->mFunctionSynonyms[1][$function])) { $function = $this->mFunctionSynonyms[1][$function]; } else { # Case insensitive functions $function = strtolower($function); if (isset($this->mFunctionSynonyms[0][$function])) { $function = $this->mFunctionSynonyms[0][$function]; } else { $function = false; } } if ($function) { $funcArgs = array_map('trim', $args); $funcArgs = array_merge(array(&$this, trim(substr($part1, $colonPos + 1))), $funcArgs); $result = call_user_func_array($this->mFunctionHooks[$function], $funcArgs); $found = true; // The text is usually already parsed, doesn't need triple-brace tags expanded, etc. //$noargs = true; //$noparse = true; if (is_array($result)) { if (isset($result[0])) { $text = $linestart . $result[0]; unset($result[0]); } // Extract flags into the local scope // This allows callers to set flags such as nowiki, noparse, found, etc. extract($result); } else { $text = $linestart . $result; } } } wfProfileOut(__METHOD__ . '-pfunc'); } # Template table test # Did we encounter this template already? If yes, it is in the cache # and we need to check for loops. if (!$found && isset($this->mTemplates[$piece['title']])) { $found = true; # Infinite loop test if (isset($this->mTemplatePath[$part1])) { $noparse = true; $noargs = true; $found = true; $text = $linestart . "[[{$part1}]]<!-- WARNING: template loop detected -->"; wfDebug(__METHOD__ . ": template loop broken at '{$part1}'\n"); } else { # set $text to cached message. $text = $linestart . $this->mTemplates[$piece['title']]; } } # Load from database $lastPathLevel = $this->mTemplatePath; if (!$found) { wfProfileIn(__METHOD__ . '-loadtpl'); $ns = NS_TEMPLATE; # declaring $subpage directly in the function call # does not work correctly with references and breaks # {{/subpage}}-style inclusions $subpage = ''; $part1 = $this->maybeDoSubpageLink($part1, $subpage); if ($subpage !== '') { $ns = $this->mTitle->getNamespace(); } $title = Title::newFromText($part1, $ns); if (!is_null($title)) { $titleText = $title->getPrefixedText(); $checkVariantLink = sizeof($wgContLang->getVariants()) > 1; # Check for language variants if the template is not found if ($checkVariantLink && $title->getArticleID() == 0) { $wgContLang->findVariantLink($part1, $title); } if (!$title->isExternal()) { if ($title->getNamespace() == NS_SPECIAL && $this->mOptions->getAllowSpecialInclusion() && $this->ot['html']) { $text = SpecialPage::capturePath($title); if (is_string($text)) { $found = true; $noparse = true; $noargs = true; $isHTML = true; $this->disableCache(); } } else { $articleContent = $this->fetchTemplate($title); if ($articleContent !== false) { $found = true; $text = $articleContent; $replaceHeadings = true; } } # If the title is valid but undisplayable, make a link to it if (!$found && ($this->ot['html'] || $this->ot['pre'])) { $text = "[[:{$titleText}]]"; $found = true; } } elseif ($title->isTrans()) { // Interwiki transclusion if ($this->ot['html'] && !$forceRawInterwiki) { $text = $this->interwikiTransclude($title, 'render'); $isHTML = true; $noparse = true; } else { $text = $this->interwikiTransclude($title, 'raw'); $replaceHeadings = true; } $found = true; } # Template cache array insertion # Use the original $piece['title'] not the mangled $part1, so that # modifiers such as RAW: produce separate cache entries if ($found) { if ($isHTML) { // A special page; don't store it in the template cache. } else { $this->mTemplates[$piece['title']] = $text; } $text = $linestart . $text; } } wfProfileOut(__METHOD__ . '-loadtpl'); } if ($found && !$this->incrementIncludeSize('pre-expand', strlen($text))) { # Error, oversize inclusion $text = $linestart . "[[{$titleText}]]<!-- WARNING: template omitted, pre-expand include size too large -->"; $noparse = true; $noargs = true; } # Recursive parsing, escaping and link table handling # Only for HTML output if ($nowiki && $found && ($this->ot['html'] || $this->ot['pre'])) { $text = wfEscapeWikiText($text); } elseif (!$this->ot['msg'] && $found) { if ($noargs) { $assocArgs = array(); } else { # Clean up argument array $assocArgs = array(); $index = 1; foreach ($args as $arg) { $eqpos = strpos($arg, '='); if ($eqpos === false) { $assocArgs[$index++] = $arg; } else { $name = trim(substr($arg, 0, $eqpos)); $value = trim(substr($arg, $eqpos + 1)); if ($value === false) { $value = ''; } if ($name !== false) { $assocArgs[$name] = $value; } } } # Add a new element to the templace recursion path $this->mTemplatePath[$part1] = 1; } if (!$noparse) { # If there are any <onlyinclude> tags, only include them if (in_string('<onlyinclude>', $text) && in_string('</onlyinclude>', $text)) { preg_match_all('/<onlyinclude>(.*?)\\n?<\\/onlyinclude>/s', $text, $m); $text = ''; foreach ($m[1] as $piece) { $text .= $piece; } } # Remove <noinclude> sections and <includeonly> tags $text = preg_replace('/<noinclude>.*?<\\/noinclude>/s', '', $text); $text = strtr($text, array('<includeonly>' => '', '</includeonly>' => '')); if ($this->ot['html'] || $this->ot['pre']) { # Strip <nowiki>, <pre>, etc. $text = $this->strip($text, $this->mStripState); if ($this->ot['html']) { $text = Sanitizer::removeHTMLtags($text, array(&$this, 'replaceVariables'), $assocArgs); } elseif ($this->ot['pre'] && $this->mOptions->getRemoveComments()) { $text = Sanitizer::removeHTMLcomments($text); } } $text = $this->replaceVariables($text, $assocArgs); # If the template begins with a table or block-level # element, it should be treated as beginning a new line. if (!$piece['lineStart'] && preg_match('/^({\\||:|;|#|\\*)/', $text)) { $text = "\n" . $text; } } elseif (!$noargs) { # $noparse and !$noargs # Just replace the arguments, not any double-brace items # This is used for rendered interwiki transclusion $text = $this->replaceVariables($text, $assocArgs, true); } } # Prune lower levels off the recursion check path $this->mTemplatePath = $lastPathLevel; if ($found && !$this->incrementIncludeSize('post-expand', strlen($text))) { # Error, oversize inclusion $text = $linestart . "[[{$titleText}]]<!-- WARNING: template omitted, post-expand include size too large -->"; $noparse = true; $noargs = true; } if (!$found) { wfProfileOut($fname); return $piece['text']; } else { wfProfileIn(__METHOD__ . '-placeholders'); if ($isHTML) { # Replace raw HTML by a placeholder # Add a blank line preceding, to prevent it from mucking up # immediately preceding headings $text = "\n\n" . $this->insertStripItem($text, $this->mStripState); } else { # replace ==section headers== # XXX this needs to go away once we have a better parser. if (!$this->ot['wiki'] && !$this->ot['pre'] && $replaceHeadings) { if (!is_null($title)) { $encodedname = base64_encode($title->getPrefixedDBkey()); } else { $encodedname = base64_encode(""); } $m = preg_split('/(^={1,6}.*?={1,6}\\s*?$)/m', $text, -1, PREG_SPLIT_DELIM_CAPTURE); $text = ''; $nsec = 0; for ($i = 0; $i < count($m); $i += 2) { $text .= $m[$i]; if (!isset($m[$i + 1]) || $m[$i + 1] == "") { continue; } $hl = $m[$i + 1]; if (strstr($hl, "<!--MWTEMPLATESECTION")) { $text .= $hl; continue; } preg_match('/^(={1,6})(.*?)(={1,6})\\s*?$/m', $hl, $m2); $text .= $m2[1] . $m2[2] . "<!--MWTEMPLATESECTION=" . $encodedname . "&" . base64_encode("{$nsec}") . "-->" . $m2[3]; $nsec++; } } } wfProfileOut(__METHOD__ . '-placeholders'); } # Prune lower levels off the recursion check path $this->mTemplatePath = $lastPathLevel; if (!$found) { wfProfileOut($fname); return $piece['text']; } else { wfProfileOut($fname); return $text; } }
/** * Display the "long" value in HTML. This behaves largely like * getLongWikiText() but does not embed images. * * @param $linker mixed if a Linker is given, the result will be linked * @return string */ public function getLongHTMLText($linker = null) { if ($this->m_fragment !== '') { $this->linkAttributes['class'] = 'smw-subobject-entity'; } // init the Title object, may reveal hitherto unnoticed errors: if (!is_null($linker) && $this->m_outformat != '-') { $this->getTitle(); } if (!$this->isValid()) { return $this->getErrorText(); } if ($linker === null || $linker === false || $this->m_outformat == '-') { return \Sanitizer::removeHTMLtags($this->getWikiValue()); } elseif ($this->getNamespace() == NS_MEDIA) { // this extra case is really needed return $linker->makeMediaLinkObj($this->getTitle(), \Sanitizer::removeHTMLtags($this->getLongCaptionText())); } // all others use default linking, no embedding of images here return $linker->link($this->getTitle(), \Sanitizer::removeHTMLtags($this->getLongCaptionText()), $this->linkAttributes); }
/** * strip/replaceVariables/unstrip for preprocessor regression testing */ function testSrvus($text, $title, $options, $outputType = self::OT_HTML) { $this->clearState(); if (!$title instanceof Title) { $title = Title::newFromText($title); } $this->mTitle = $title; $this->mOptions = $options; $this->setOutputType($outputType); $text = $this->replaceVariables($text); $text = $this->mStripState->unstripBoth($text); $text = Sanitizer::removeHTMLtags($text); return $text; }
/** * Return a HTML representation of the image slider * * @author Jakub Kurcek */ private function renderSlider() { wfProfileIn(__METHOD__); // do not render empty sliders if (empty($this->mFiles)) { wfProfileOut(__METHOD__); return ''; } $orientation = $this->getParam('orientation'); // setup image serving for main images and navigation thumbnails if ($orientation == 'mosaic') { $imagesDimensions = array('w' => WikiaPhotoGalleryHelper::WIKIA_GRID_SLIDER_MOSAIC_MIN_IMG_WIDTH, 'h' => WikiaPhotoGalleryHelper::SLIDER_MOSAIC_MIN_IMG_HEIGHT); $sliderClass = 'mosaic'; $thumbDimensions = array("w" => WikiaPhotoGalleryHelper::WIKIA_GRID_THUMBNAIL_MAX_WIDTH, "h" => 100); } else { $imagesDimensions = array('w' => WikiaPhotoGalleryHelper::SLIDER_MIN_IMG_WIDTH, 'h' => WikiaPhotoGalleryHelper::SLIDER_MIN_IMG_HEIGHT); if ($orientation == 'right') { $sliderClass = 'vertical'; $thumbDimensions = array("w" => 110, "h" => 50); } else { $sliderClass = 'horizontal'; $thumbDimensions = array("w" => 90, "h" => 70); } } $out = array(); $sliderImageLimit = $orientation == 'mosaic' ? 5 : 4; foreach ($this->mFiles as $p => $pair) { /** * @var $nt Title * @var $text String * @var $link String */ $nt = $pair[0]; $text = $pair[1]; $link = $pair[2]; $linkText = $this->mData['images'][$p]['linktext']; $shortText = $this->mData['images'][$p]['shorttext']; $time = $descQuery = false; // parse link (RT #142515) $linkAttribs = $this->parseLink($nt->getLocalUrl(), $nt->getText(), $link); wfRunHooks('BeforeGalleryFindFile', array(&$this, &$nt, &$time, &$descQuery)); $file = wfFindFile($nt, $time); if (is_object($file) && $nt->getNamespace() == NS_FILE) { list($adjWidth, $adjHeight) = $this->fitWithin($file, $imagesDimensions); if (F::app()->checkSkin('wikiamobile')) { $imageUrl = wfReplaceImageServer($file->getUrl(), $file->getTimestamp()); } else { $imageUrl = $this->resizeURL($file, $imagesDimensions); } // generate navigation thumbnails $thumbUrl = $this->cropURL($file, $thumbDimensions); // Handle videos $videoHtml = false; $videoPlayButton = false; $navClass = ''; if (WikiaFileHelper::isFileTypeVideo($file)) { // Get HTML for main video image $htmlParams = array('file-link' => true, 'linkAttribs' => array('class' => 'wikiaPhotoGallery-slider force-lightbox')); $videoHtml = $file->transform(array('width' => $imagesDimensions['w']))->toHtml($htmlParams); // Get play button overlay for little video thumb $videoPlayButton = $this->videoPlayButton; $navClass = 'xxsmall video-thumbnail'; } $data = array('imageUrl' => $imageUrl, 'imageTitle' => Sanitizer::removeHTMLtags($text), 'imageName' => $file->getTitle()->getText(), 'imageKey' => $file->getTitle()->getDBKey(), 'imageShortTitle' => Sanitizer::removeHTMLtags($shortText), 'imageLink' => !empty($link) ? $linkAttribs['href'] : '', 'imageDescription' => Sanitizer::removeHTMLtags($linkText), 'imageThumbnail' => $thumbUrl, 'adjWidth' => $adjWidth, 'adjHeight' => $adjHeight, 'centerTop' => $imagesDimensions['h'] > $adjHeight ? intval(($imagesDimensions['h'] - $adjHeight) / 2) : 0, 'centerLeft' => $imagesDimensions['w'] > $adjWidth ? intval(($imagesDimensions['w'] - $adjWidth) / 2) : 0, 'videoHtml' => $videoHtml, 'videoPlayButton' => $videoPlayButton, 'navClass' => $navClass); if (F::app()->checkSkin('wikiamobile')) { $origWidth = $file->getWidth(); $origHeight = $file->getHeight(); $size = WikiaMobileMediaService::calculateMediaSize($origWidth, $origHeight); $thumb = $file->transform($size); $imageAttribs = array('src' => wfReplaceImageServer($thumb->getUrl(), $file->getTimestamp()), 'width' => $size['width'], 'height' => $size['height']); $imageParams = array('full' => $imageUrl); if ($this->mParser) { $this->mParser->replaceLinkHolders($text); } $data['mediaInfo'] = array('attributes' => $imageAttribs, 'parameters' => $imageParams, 'caption' => $text, 'noscript' => Xml::element('img', $imageAttribs, '', true)); } $out[] = $data; } if (count($out) >= $sliderImageLimit) { break; } } $html = ''; //check if we have something to show (images might not match required sizes) if (count($out)) { $template = new EasyTemplate(dirname(__FILE__) . '/templates'); $template->set_vars(array('sliderClass' => $sliderClass, 'files' => $out, 'thumbDimensions' => $thumbDimensions, 'sliderId' => $this->mData['id'], 'imagesDimensions' => $imagesDimensions)); if (F::app()->checkSkin('wikiamobile')) { $html = $template->render('renderWikiaMobileSlider'); } else { if ($orientation == 'mosaic') { $html = $template->render('renderMosaicSlider'); } else { $html = $template->render('renderSlider'); } } if ($orientation == 'mosaic') { $sliderResources = array('wikia_photo_gallery_mosaic_js', 'wikia_photo_gallery_mosaic_scss'); $javascriptInitializationFunction = 'WikiaMosaicSliderMasterControl.init'; } else { $sliderResources = array('wikia_photo_gallery_slider_js', 'wikia_photo_gallery_slider_scss'); $javascriptInitializationFunction = 'WikiaPhotoGallerySlider.init'; } $html .= JSSnippets::addToStack($sliderResources, array(), $javascriptInitializationFunction, array($this->mData['id'])); //load WikiaMobile resources if needed using JSSnippets filtering mechanism $html .= JSSnippets::addToStack(array('wikiaphotogallery_slider_scss_wikiamobile', 'wikiaphotogallery_slider_js_wikiamobile')); } wfProfileOut(__METHOD__); return $html; }
/** * strip/replaceVariables/unstrip for preprocessor regression testing * * @param $text string * @param $title Title * @param $options ParserOptions * @param $outputType int * * @return string */ function testSrvus($text, Title $title, ParserOptions $options, $outputType = self::OT_HTML) { $this->startParse($title, $options, $outputType, true); $text = $this->replaceVariables($text); $text = $this->mStripState->unstripBoth($text); $text = Sanitizer::removeHTMLtags($text); return $text; }
/** * @dataProvider dataRemoveHTMLtags */ function testRemoveHTMLtags($input, $output, $msg = null) { $GLOBALS['wgUseTidy'] = false; $this->assertEquals($output, Sanitizer::removeHTMLtags($input), $msg); }
/** * "Page title" means the contents of \<h1\>. It is stored as a valid HTML * fragment. This function allows good tags like \<sup\> in the \<h1\> tag, * but not bad tags like \<script\>. This function automatically sets * \<title\> to the same content as \<h1\> but with all tags removed. Bad * tags that were escaped in \<h1\> will still be escaped in \<title\>, and * good tags like \<i\> will be dropped entirely. * * @param string|Message $name */ public function setPageTitle($name) { if ($name instanceof Message) { $name = $name->setContext($this->getContext())->text(); } # change "<script>foo&bar</script>" to "<script>foo&bar</script>" # but leave "<i>foobar</i>" alone $nameWithTags = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($name)); $this->mPagetitle = $nameWithTags; # change "<i>foo&bar</i>" to "foo&bar" $this->setHTMLTitle($this->msg('pagetitle')->rawParams(Sanitizer::stripAllTags($nameWithTags))->inContentLanguage()); }
protected function parseWikitext($title) { $apiParams = array('action' => 'parse', 'page' => $title->getPrefixedDBkey(), 'prop' => 'text|revid|categorieshtml|displaytitle'); $api = new ApiMain(new DerivativeRequest($this->getRequest(), $apiParams, false), true); $api->execute(); $result = $api->getResultData(); $content = isset($result['parse']['text']['*']) ? $result['parse']['text']['*'] : false; $categorieshtml = isset($result['parse']['categorieshtml']['*']) ? $result['parse']['categorieshtml']['*'] : false; $links = isset($result['parse']['links']) ? $result['parse']['links'] : array(); $revision = Revision::newFromId($result['parse']['revid']); $timestamp = $revision ? $revision->getTimestamp() : wfTimestampNow(); $displaytitle = isset($result['parse']['displaytitle']) ? $result['parse']['displaytitle'] : false; if ($content === false || strlen($content) && $revision === null) { return false; } if ($displaytitle !== false) { // Escape entities as in OutputPage::setPageTitle() $displaytitle = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($displaytitle)); } return array('content' => $content, 'categorieshtml' => $categorieshtml, 'basetimestamp' => $timestamp, 'starttimestamp' => wfTimestampNow(), 'displayTitleHtml' => $displaytitle); }