SECURITY: Always normalize link url before adding to ParserOutput
[lhc/web/wiklou.git] / includes / parser / ParserOutput.php
index b0768b6..7de3b30 100644 (file)
@@ -193,6 +193,9 @@ class ParserOutput extends CacheTime {
         */
        private $mLimitReportData = [];
 
+       /** @var array Parser limit report data for JSON */
+       private $mLimitReportJSData = [];
+
        /**
         * @var array $mParseStartTime Timestamps for getTimeSinceStart().
         */
@@ -215,7 +218,7 @@ class ParserOutput extends CacheTime {
        private $mMaxAdaptiveExpiry = INF;
 
        const EDITSECTION_REGEX =
-               '#<(?:mw:)?editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)(</(?:mw:)?editsection>))#';
+               '#<(?:mw:)?editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)(</(?:mw:)?editsection>))#s';
 
        // finalizeAdaptiveCacheExpiry() uses TTL = MAX( m * PARSE_TIME + b, MIN_AR_TTL)
        // Current values imply that m=3933.333333 and b=-333.333333
@@ -411,6 +414,10 @@ class ParserOutput extends CacheTime {
                return $this->mLimitReportData;
        }
 
+       public function getLimitReportJSData() {
+               return $this->mLimitReportJSData;
+       }
+
        public function getTOCEnabled() {
                return $this->mTOCEnabled;
        }
@@ -528,6 +535,10 @@ class ParserOutput extends CacheTime {
                # We don't register links pointing to our own server, unless... :-)
                global $wgServer, $wgRegisterInternalExternals;
 
+               # Replace unnecessary URL escape codes with the referenced character
+               # This prevents spammers from hiding links from the filters
+               $url = parser::normalizeLinkUrl( $url );
+
                $registerExternalLink = true;
                if ( !$wgRegisterInternalExternals ) {
                        $registerExternalLink = !self::isLinkInternal( $wgServer, $url );
@@ -689,6 +700,8 @@ class ParserOutput extends CacheTime {
         * to SpecialTrackingCategories::$coreTrackingCategories, and extensions
         * should add to "TrackingCategories" in their extension.json.
         *
+        * @todo Migrate some code to TrackingCategories
+        *
         * @param string $msg Message key
         * @param Title $title title of the page which is being tracked
         * @return bool Whether the addition was successful
@@ -700,7 +713,7 @@ class ParserOutput extends CacheTime {
                        return false;
                }
 
-               // Important to parse with correct title (bug 31469)
+               // Important to parse with correct title (T33469)
                $cat = wfMessage( $msg )
                        ->title( $title )
                        ->inContentLanguage()
@@ -1010,6 +1023,26 @@ class ParserOutput extends CacheTime {
         */
        public function setLimitReportData( $key, $value ) {
                $this->mLimitReportData[$key] = $value;
+
+               if ( is_array( $value ) ) {
+                       if ( array_keys( $value ) === [ 0, 1 ]
+                               && is_numeric( $value[0] )
+                               && is_numeric( $value[1] )
+                       ) {
+                               $data = [ 'value' => $value[0], 'limit' => $value[1] ];
+                       } else {
+                               $data = $value;
+                       }
+               } else {
+                       $data = $value;
+               }
+
+               if ( strpos( $key, '-' ) ) {
+                       list( $ns, $name ) = explode( '-', $key, 2 );
+                       $this->mLimitReportJSData[$ns][$name] = $data;
+               } else {
+                       $this->mLimitReportJSData[$key] = $data;
+               }
        }
 
        /**