if ( $showEditLink ) {
$editLinkAsToken = $this->mOptions->getEditSectionTokens();
if ( $editLinkAsToken ) {
- $this->mOutput->setEditSectionTokens( "{$this->mUniqPrefix}-editsection-", self::MARKER_SUFFIX );
+ $this->mOutput->setEditSectionTokens( true );
}
}
} else {
$editlinkArgs = array( $this->mTitle->getPrefixedText(), $sectionIndex, $headlineHint );
}
- // We use nearly the same structure as uniqPrefix and the marker stuffix (besides there being nothing random)
- // However the this is output into the parser output itself not replaced early, so we hardcode this in case
- // the constants change in a different version of MediaWiki, which would break this code.
- $editlink = "{$this->mUniqPrefix}-editsection-" . implode('|', array_map('urlencode', $editlinkArgs)) . self::MARKER_SUFFIX;
+ // We use a bit of pesudo-xml for editsection markers. The language converter is run later on
+ // Using a UNIQ style marker leads to the converter screwing up the tokens when it converts stuff
+ // And trying to insert strip tags fails too. At this point all real inputted tags have already been escaped
+ // so we don't have to worry about a user trying to input one of these markers directly.
+ // We use a page and section attribute to stop the language converter from converting these important bits
+ // of data, but put the headline hint inside a content block because the language converter is supposed to
+ // be able to convert that piece of data.
+ $editlink = '<editsection page="' . htmlspecialchars($editlinkArgs[0]);
+ $editlink .= '" section="' . htmlspecialchars($editlinkArgs[1]) .'"';
+ if ( isset($editlinkArgs[2]) ) {
+ $editlink .= '>' . $editlinkArgs[2] . '</editsection>';
+ } else {
+ $editlink .= '/>';
+ }
} else {
// Output edit section links directly as markup like we used to
if ( $isTemplate ) {
function getText() {
if ( $this->mEditSectionTokens ) {
- $editSectionTokens = $this->mEditSectionTokens;
- return preg_replace_callback( "#{$editSectionTokens[0]}(.*?){$editSectionTokens[1]}#", array( &$this, 'replaceEditSectionLinksCallback' ), $this->mText );
+ return preg_replace_callback( '#<editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)(</editsection>))#', array( &$this, 'replaceEditSectionLinksCallback' ), $this->mText );
}
return $this->mText;
}
*/
function replaceEditSectionLinksCallback( $m ) {
global $wgUser, $wgLang;
- $args = array_map('urldecode', explode('|', $m[1], 3));
+ $args = array(
+ htmlspecialchars_decode($m[1]),
+ htmlspecialchars_decode($m[2]),
+ $m[4] ? $m[3] : null,
+ );
$args[0] = Title::newFromText( $args[0] );
if ( !is_object($args[0]) ) {
throw new MWException("Bad parser output text.");
function setTitleText( $t ) { return wfSetVar( $this->mTitleText, $t ); }
function setSections( $toc ) { return wfSetVar( $this->mSections, $toc ); }
- function setEditSectionTokens( $p, $s ) { return wfSetVar( $this->mEditSectionTokens, array( $p, $s ) ); }
+ function setEditSectionTokens( $t ) { return wfSetVar( $this->mEditSectionTokens, $t ); }
function setIndexPolicy( $policy ) { return wfSetVar( $this->mIndexPolicy, $policy ); }
function setTOCHTML( $tochtml ) { return wfSetVar( $this->mTOCHTML, $tochtml ); }