Index: trunk/extensions/RSS/RSSHooks.php |
— | — | @@ -21,19 +21,24 @@ |
22 | 22 | * @param $frame PPFrame parser context |
23 | 23 | */ |
24 | 24 | static function renderRss( $input, $args, $parser, $frame ) { |
25 | | - global $wgRSSCacheAge, $wgRSSCacheCompare, $wgRSSNamespaces, $wgRSSUrlWhitelist; |
| 25 | + global $wgRSSCacheAge, $wgRSSCacheCompare, $wgRSSNamespaces, |
| 26 | + $wgRSSUrlWhitelist,$wgRSSAllowedFeeds; |
26 | 27 | |
27 | 28 | if ( is_array( $wgRSSNamespaces ) && count( $wgRSSNamespaces ) ) { |
28 | 29 | $ns = $parser->getTitle()->getNamespace(); |
29 | 30 | $checkNS = array_flip( $wgRSSNamespaces ); |
30 | 31 | |
31 | 32 | if( !isset( $checkNS[$ns] ) ) { |
32 | | - return wfMsg( 'rss-ns-permission' ); |
| 33 | + return RSSUtils::RSSError( 'rss-ns-permission' ); |
33 | 34 | } |
34 | 35 | } |
35 | 36 | |
36 | 37 | switch ( true ) { |
37 | 38 | |
| 39 | + case ( isset( $wgRSSAllowedFeeds ) ): |
| 40 | + return RSSUtils::RSSError( 'rss-deprecated-wgrssallowedfeeds-found' ); |
| 41 | + break; |
| 42 | + |
38 | 43 | # disallow because there is no whitelist or empty whitelist |
39 | 44 | case ( !isset( $wgRSSUrlWhitelist ) |
40 | 45 | || !is_array( $wgRSSUrlWhitelist ) |
— | — | @@ -59,7 +64,7 @@ |
60 | 65 | } |
61 | 66 | |
62 | 67 | if ( !Http::isValidURI( $input ) ) { |
63 | | - return wfMsg( 'rss-invalid-url', htmlspecialchars( $input ) ); |
| 68 | + return RSSutils::RSSError( 'rss-invalid-url', htmlspecialchars( $input ) ); |
64 | 69 | } |
65 | 70 | if ( $wgRSSCacheCompare ) { |
66 | 71 | $timeout = $wgRSSCacheCompare; |
— | — | @@ -79,7 +84,7 @@ |
80 | 85 | } |
81 | 86 | |
82 | 87 | if ( !is_object( $rss->rss ) || !is_array( $rss->rss->items ) ) { |
83 | | - return wfMsg( 'rss-empty', htmlspecialchars( $input ) ); |
| 88 | + return RSSUtils::RSSError( 'rss-empty', htmlspecialchars( $input ) ); |
84 | 89 | } |
85 | 90 | |
86 | 91 | return $rss->renderFeed( $parser, $frame ); |
Index: trunk/extensions/RSS/RELEASE-NOTES |
— | — | @@ -10,13 +10,20 @@ |
11 | 11 | coming in. Then you could abort cleanly once it's gotten too much |
12 | 12 | (otherwise using the defaults - PHP will abort the entire program when your |
13 | 13 | memory usage gets too high) |
14 | | -* bug 30028 "Error parsing XML for RSS" - improve and harden Extension:RSS when |
15 | | - parsing differently flavoured RSS feeds and ATOM feeds |
16 | 14 | |
| 15 | +=== Version 2.10 2012-02-27 === |
| 16 | +* final solution of bug 30028 "Error parsing XML for RSS" - improve and harden |
| 17 | + Extension:RSS when parsing differently flavoured RSS feeds and ATOM feeds |
| 18 | +* new parameter $wgRSSUrlNumberOfAllowedRedirects (default = 0) |
| 19 | + Some feed urls redirect. The new RSS version can deal with redirects, |
| 20 | + but it must be expressly enabled. For example, you can set |
| 21 | + $wgRSSUrlNumberOfAllowedRedirects = 1; |
| 22 | + |
17 | 23 | === Version 2.01 2012-02-24 === |
18 | 24 | * "summary" element of ATOM feed items are shown |
19 | 25 | which is handled like "description" element of RSS |
20 | 26 | * handling of basic HTML layout tags <p> <br> <b> <i> <u> <s> in item description |
| 27 | + |
21 | 28 | === Version 2.00 2012-02-24 === |
22 | 29 | * first version which can parse RSS and at least some ATOM feeds |
23 | 30 | partial solution of bug 30028 "Error parsing XML for RSS" - improve and harden |
Index: trunk/extensions/RSS/RSSData.php |
— | — | @@ -16,26 +16,13 @@ |
17 | 17 | } |
18 | 18 | $xpath = new DOMXPath( $xml ); |
19 | 19 | |
20 | | - // register namespace as below, and apply a regex to the expression |
21 | | - // http://de3.php.net/manual/en/domxpath.query.php#103461 |
22 | | - $namespaceURI = $xml->lookupnamespaceURI( NULL ); |
| 20 | + // namespace-safe method to find all elements |
| 21 | + $items = $xpath->query( "//*[local-name() = 'item']" ); |
23 | 22 | |
24 | | - if ( ( null !== $namespaceURI ) ) { |
25 | | - $defaultNS = "defaultNS"; |
26 | | - $xpath->registerNamespace( $defaultNS, $namespaceURI ); |
27 | | - $defaultNS = "defaultNS:"; |
28 | | - } else { |
29 | | - $defaultNS = ""; |
| 23 | + if ( $items->length == 0 ) { |
| 24 | + $items = $xpath->query( "//*[local-name() = 'entry']" ); |
30 | 25 | } |
31 | 26 | |
32 | | - // is it an RSS feed ? |
33 | | - $items = $xpath->query( $this->namespacePrefixedQuery( "/rss/channel/item", $defaultNS ) ); |
34 | | - |
35 | | - if ( $items->length === 0 ) { |
36 | | - // or is it an ATOM feed ? |
37 | | - $items = $xpath->query( $this->namespacePrefixedQuery( "/feed/entry", $defaultNS ) ); |
38 | | - } |
39 | | - |
40 | 27 | if( $items->length !== 0 ) { |
41 | 28 | foreach ( $items as $item ) { |
42 | 29 | $bit = array(); |
— | — | @@ -61,14 +48,6 @@ |
62 | 49 | } |
63 | 50 | } |
64 | 51 | |
65 | | - protected function namespacePrefixedQuery( $query, $namespace = "" ) { |
66 | | - if ( $namespace !== "" ) { |
67 | | - $ret = preg_replace( '#(::|/\s*|\A)(?![/@].+?|[a-z\-]+::)#', '$1' . $namespace . '$2', $query ); |
68 | | - } else { |
69 | | - $ret = $query; |
70 | | - } |
71 | | - return $ret; |
72 | | - } |
73 | 52 | /** |
74 | 53 | * Return a string that will be used to map RSS elements that |
75 | 54 | * contain similar data (e.g. dc:date, date, and pubDate) to the |
Index: trunk/extensions/RSS/RSSParser.php |
— | — | @@ -218,7 +218,8 @@ |
219 | 219 | * @return Status object |
220 | 220 | */ |
221 | 221 | protected function fetchRemote( $key, array $headers = array()) { |
222 | | - global $wgRSSFetchTimeout, $wgRSSUserAgent, $wgRSSProxy; |
| 222 | + global $wgRSSFetchTimeout, $wgRSSUserAgent, $wgRSSProxy, |
| 223 | + $wgRSSUrlNumberOfAllowedRedirects; |
223 | 224 | |
224 | 225 | if ( $this->etag ) { |
225 | 226 | wfDebugLog( 'RSS', 'Used etag: ' . $this->etag ); |
— | — | @@ -244,16 +245,54 @@ |
245 | 246 | */ |
246 | 247 | |
247 | 248 | $url = $this->url; |
248 | | - $noProxy = false; |
| 249 | + $noProxy = !isset( $wgRSSProxy ); |
249 | 250 | |
250 | 251 | // Example for disabling proxy use for certain urls |
251 | 252 | // $noProxy = preg_match( '!\.internal\.example\.com$!i', parse_url( $url, PHP_URL_HOST ) ); |
252 | | - |
| 253 | + |
| 254 | + /** |
| 255 | + * Copied from HttpFunctions.php |
| 256 | + * Perform an HTTP request |
| 257 | + * |
| 258 | + * @param $method String: HTTP method. Usually GET/POST |
| 259 | + * @param $url String: full URL to act on. If protocol-relative, will be expanded to an http:// URL |
| 260 | + * @param $options Array: options to pass to MWHttpRequest object. |
| 261 | + * Possible keys for the array: |
| 262 | + * - timeout Timeout length in seconds |
| 263 | + * - postData An array of key-value pairs or a url-encoded form data |
| 264 | + * - proxy The proxy to use. |
| 265 | + * Otherwise it will use $wgHTTPProxy (if set) |
| 266 | + * Otherwise it will use the environment variable "http_proxy" (if set) |
| 267 | + * - noProxy Don't use any proxy at all. Takes precedence over proxy value(s). |
| 268 | + * - sslVerifyHost (curl only) Verify hostname against certificate |
| 269 | + * - sslVerifyCert (curl only) Verify SSL certificate |
| 270 | + * - caInfo (curl only) Provide CA information |
| 271 | + * - maxRedirects Maximum number of redirects to follow (defaults to 5) |
| 272 | + * - followRedirects Whether to follow redirects (defaults to false). |
| 273 | + * Note: this should only be used when the target URL is trusted, |
| 274 | + * to avoid attacks on intranet services accessible by HTTP. |
| 275 | + * - userAgent A user agent, if you want to override the default |
| 276 | + * MediaWiki/$wgVersion |
| 277 | + * @return Mixed: (bool)false on failure or a string on success |
| 278 | + */ |
| 279 | + |
| 280 | + if ( isset( $wgRSSUrlNumberOfAllowedRedirects ) |
| 281 | + && is_numeric( $wgRSSUrlNumberOfAllowedRedirects ) ) { |
| 282 | + $maxRedirects = $wgRSSUrlNumberOfAllowedRedirects; |
| 283 | + } else { |
| 284 | + $maxRedirects = 0; |
| 285 | + } |
| 286 | + |
| 287 | + // we set followRedirects intentionally to true to see error messages |
| 288 | + // in cases where the maximum number of redirects is reached |
253 | 289 | $client = HttpRequest::factory( $url, |
254 | 290 | array( |
255 | | - 'timeout' => $wgRSSFetchTimeout, |
256 | | - 'proxy' => $wgRSSProxy, |
257 | | - 'noProxy' => $noProxy, |
| 291 | + 'timeout' => $wgRSSFetchTimeout, |
| 292 | + 'followRedirects' => true, |
| 293 | + 'maxRedirects' => $maxRedirects, |
| 294 | + 'proxy' => $wgRSSProxy, |
| 295 | + 'noProxy' => $noProxy, |
| 296 | + 'userAgent' => $wgRSSUserAgent, |
258 | 297 | ) |
259 | 298 | ); |
260 | 299 | |
— | — | @@ -506,8 +545,8 @@ |
507 | 546 | * |
508 | 547 | * @param $text String: the text to examine |
509 | 548 | * @param $filterType String: "filterOut" to check for matches in the |
510 | | - * filterOut member list. |
511 | | - * Otherwise, uses the filter member list. |
| 549 | + * filterOut member list. |
| 550 | + * Otherwise, uses the filter member list. |
512 | 551 | * @return Boolean: decision to filter or not. |
513 | 552 | */ |
514 | 553 | protected function filter( $text, $filterType ) { |
— | — | @@ -591,7 +630,7 @@ |
592 | 631 | * @param String|Array $param Error parameter (or parameters) |
593 | 632 | * @return String Html that is the error. |
594 | 633 | */ |
595 | | - public static function RSSError( $errorMessageName, $param ) { |
| 634 | + public static function RSSError( $errorMessageName, $param = false ) { |
596 | 635 | |
597 | 636 | // Anything from a parser tag should use Content lang for message, |
598 | 637 | // since the cache doesn't vary by user language: do not use wfMsgForContent but wfMsgForContent |
Index: trunk/extensions/RSS/RSS.i18n.php |
— | — | @@ -22,6 +22,7 @@ |
23 | 23 | 'rss-ns-permission' => 'RSS is not allowed in this namespace', |
24 | 24 | 'rss-url-is-not-whitelisted' => '"$1" is not in the whitelist of allowed feeds. {{PLURAL:$3|$2 is the only allowed feed|The allowed feeds are as follows: $2}}.', |
25 | 25 | 'rss-empty-whitelist' => '"$1" is not in the whitelist of allowed feeds. There are no allowed feed URLs in the whitelist.', |
| 26 | + 'rss-deprecated-wgrssallowedfeeds-found' => 'The deprecated variable $wgRSSAllowedFeeds has been detected. Since RSS version 2.0 this variable has to be replaced by $wgRSSUrlWhitelist as described in the manual page Extension:RSS.', |
26 | 27 | 'rss-item' => '{{$1 | title = {{{title}}} | link = {{{link}}} | date = {{{date}}} | author = {{{author}}} | description = {{{description}}} }}', |
27 | 28 | 'rss-feed' => "<!-- the following are two alternative templates. The first is the basic default template for feeds -->; '''<span class='plainlinks'>[{{{link}}} {{{title}}}]</span>''' |
28 | 29 | : {{{description}}} |
Index: trunk/extensions/RSS/RSS.php |
— | — | @@ -4,7 +4,7 @@ |
5 | 5 | * |
6 | 6 | * @file |
7 | 7 | * @ingroup Extensions |
8 | | - * @version 2.01 |
| 8 | + * @version 2.10 |
9 | 9 | * @author mutante, Daniel Kinzler, Rdb, Mafs, Thomas Gries, Alxndr, Chris Reigrut, K001 |
10 | 10 | * @author Kellan Elliott-McCrea <kellan@protest.net> -- author of MagpieRSS |
11 | 11 | * @author Jeroen De Dauw |
— | — | @@ -14,7 +14,7 @@ |
15 | 15 | * @link http://www.mediawiki.org/wiki/Extension:RSS Documentation |
16 | 16 | */ |
17 | 17 | |
18 | | -define( "EXTENSION_RSS_VERSION", "2.01 20120224" ); |
| 18 | +define( "EXTENSION_RSS_VERSION", "2.10 20120227" ); |
19 | 19 | |
20 | 20 | if ( !defined( 'MEDIAWIKI' ) ) { |
21 | 21 | die( "This is not a valid entry point.\n" ); |
— | — | @@ -52,7 +52,7 @@ |
53 | 53 | // for debugging set $wgRSSCacheCompare = 1; |
54 | 54 | $wgRSSCacheCompare = false; |
55 | 55 | |
56 | | -// 5 second timeout |
| 56 | +// 15 second timeout |
57 | 57 | $wgRSSFetchTimeout = 15; |
58 | 58 | |
59 | 59 | // Ignore the RSS tag in all but the namespaces listed here. |
— | — | @@ -77,6 +77,11 @@ |
78 | 78 | // include "*" if you expressly want to allow all urls (you should not do this) |
79 | 79 | // $wgRSSUrlWhitelist = array( "*" ); |
80 | 80 | |
| 81 | +// Maximum number of redirects to follow (defaults to 0) |
| 82 | +// Note: this should only be used when the target URLs are trusted, |
| 83 | +// to avoid attacks on intranet services accessible by HTTP. |
| 84 | +$wgRSSUrlNumberOfAllowedRedirects = 0; |
| 85 | + |
81 | 86 | // Agent to use for fetching feeds |
82 | 87 | $wgRSSUserAgent = "MediaWikiRSS/" . strtok( EXTENSION_RSS_VERSION, " " ) . " (+http://www.mediawiki.org/wiki/Extension:RSS) / MediaWiki RSS extension"; |
83 | 88 | |
— | — | @@ -89,4 +94,4 @@ |
90 | 95 | // limit the number of characters in the item description |
91 | 96 | // or set to false for unlimited length. |
92 | 97 | // $wgRSSItemMaxLength = false; |
93 | | -// $wgRSSItemMaxLength = 100; |
| 98 | +$wgRSSItemMaxLength = 200; |