• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

blogger


Commit MetaInfo

Révisiona04c9be0ccbcf006494c2567e75959e4cd5eaa86 (tree)
l'heure2017-10-21 05:42:22
Auteurumorigu <umorigu@gmai...>
Commiterumorigu

Message de Log

BugTrack/2176 showrss: Fix character encoding issues etc.

Change Summary

Modification

--- a/plugin/showrss.inc.php
+++ b/plugin/showrss.inc.php
@@ -58,17 +58,24 @@ function plugin_showrss_convert()
5858 if (! is_url($uri))
5959 return '#showrss: Seems not URI: ' . htmlsc($uri) . '<br />' . "\n";
6060
61+ // Remove old caches in 5% rate
62+ if (mt_rand(1, 20) === 1) {
63+ plugin_showrss_cache_expire(24);
64+ }
6165 list($rss, $time) = plugin_showrss_get_rss($uri, $cachehour);
6266 if ($rss === FALSE) return '#showrss: Failed fetching RSS from the server<br />' . "\n";
63-
64- $time = '';
67+ if (! is_array($rss)) {
68+ // Show XML error message
69+ return '#showrss: Error - ' . htmlsc($rss) . '<br />' . "\n";
70+ }
71+ $time_display = '';
6572 if ($timestamp > 0) {
66- $time = '<p style="font-size:10px; font-weight:bold">Last-Modified:' .
73+ $time_display = '<p style="font-size:10px; font-weight:bold">Last-Modified:' .
6774 get_date('Y/m/d H:i:s', $time) . '</p>';
6875 }
6976
7077 $obj = new $class($rss);
71- return $obj->toString($time);
78+ return $obj->toString($time_display);
7279 }
7380
7481 // Create HTML from RSS array()
@@ -157,23 +164,22 @@ function plugin_showrss_get_rss($target, $cachehour)
157164 $buf = '';
158165 $time = NULL;
159166 if ($cachehour) {
167+ $filename = CACHE_DIR . encode($target) . '.tmp';
160168 // Remove expired cache
161- plugin_showrss_cache_expire($cachehour);
162-
169+ plugin_showrss_cache_expire_file($filename, $cachehour);
163170 // Get the cache not expired
164- $filename = CACHE_DIR . encode($target) . '.tmp';
165171 if (is_readable($filename)) {
166172 $buf = join('', file($filename));
167173 $time = filemtime($filename) - LOCALZONE;
168174 }
169175 }
170176
171- if ($time === NULL) {
177+ if (is_null($time)) {
172178 // Newly get RSS
173179 $data = pkwk_http_request($target);
174- if ($data['rc'] !== 200)
180+ if ($data['rc'] !== 200) {
175181 return array(FALSE, 0);
176-
182+ }
177183 $buf = $data['data'];
178184 $time = UTIME;
179185
@@ -184,9 +190,9 @@ function plugin_showrss_get_rss($target, $cachehour)
184190 fclose($fp);
185191 }
186192 }
187-
188193 // Parse
189194 $obj = new ShowRSS_XML();
195+ $obj->modified_date = (is_null($time) ? UTIME : $time);
190196 return array($obj->parse($buf),$time);
191197 }
192198
@@ -204,6 +210,20 @@ function plugin_showrss_cache_expire($cachehour)
204210 $dh->close();
205211 }
206212
213+/**
214+ * Remove single file cache if expired limit exeed
215+ * @param $filename
216+ * @param $cachehour
217+ */
218+function plugin_showrss_cache_expire_file($filename, $cachehour)
219+{
220+ $expire = $cachehour * 60 * 60; // Hour
221+ $last = time() - filemtime($filename);
222+ if ($last > $expire) {
223+ unlink($filename);
224+ }
225+}
226+
207227 // Get RSS and array() them
208228 class ShowRSS_XML
209229 {
@@ -212,6 +232,7 @@ class ShowRSS_XML
212232 var $is_item;
213233 var $tag;
214234 var $encoding;
235+ var $modified_date;
215236
216237 function parse($buf)
217238 {
@@ -219,32 +240,30 @@ class ShowRSS_XML
219240 $this->item = array();
220241 $this->is_item = FALSE;
221242 $this->tag = '';
222-
243+ $utf8 = 'UTF-8';
244+ $this->encoding = $utf8;
223245 // Detect encoding
224246 $matches = array();
225247 if(preg_match('/<\?xml [^>]*\bencoding="([a-z0-9-_]+)"/i', $buf, $matches)) {
226- $this->encoding = $matches[1];
227- } else {
228- $this->encoding = mb_detect_encoding($buf);
229- }
230-
231- // Normalize to UTF-8 / ASCII
232- if (! in_array(strtolower($this->encoding), array('us-ascii', 'iso-8859-1', 'utf-8'))) {
233- $buf = mb_convert_encoding($buf, 'utf-8', $this->encoding);
234- $this->encoding = 'utf-8';
248+ $encoding = $matches[1];
249+ if (strtoupper($encoding) !== $utf8) {
250+ // xml_parse() fails on non UTF-8 encoding attr in XML decLaration
251+ $buf = preg_replace('/<\?xml ([^>]*)\bencoding="[a-z0-9-_]+"/i', '<?xml $1', $buf);
252+ // xml_parse() requires UTF-8 compatible encoding
253+ $buf = mb_convert_encoding($buf, $utf8, $encoding);
254+ }
235255 }
236-
237256 // Parsing
238- $xml_parser = xml_parser_create($this->encoding);
257+ $xml_parser = xml_parser_create($utf8);
239258 xml_set_element_handler($xml_parser, array(& $this, 'start_element'), array(& $this, 'end_element'));
240259 xml_set_character_data_handler($xml_parser, array(& $this, 'character_data'));
241260 if (! xml_parse($xml_parser, $buf, 1)) {
242- return(sprintf('XML error: %s at line %d in %s',
261+ return sprintf('XML error: %s at line %d in %s',
243262 xml_error_string(xml_get_error_code($xml_parser)),
244- xml_get_current_line_number($xml_parser), $buf));
263+ xml_get_current_line_number($xml_parser),
264+ (strlen($buf) < 500 ? $buf : substr($buf, 0, 500) . '...'));
245265 }
246266 xml_parser_free($xml_parser);
247-
248267 return $this->items;
249268 }
250269
@@ -278,10 +297,10 @@ class ShowRSS_XML
278297 $this->item = array();
279298
280299 if (isset($item['DC:DATE'])) {
281- $time = plugin_showrss_get_timestamp($item['DC:DATE']);
300+ $time = plugin_showrss_get_timestamp($item['DC:DATE'], $this->modified_date);
282301
283302 } else if (isset($item['PUBDATE'])) {
284- $time = plugin_showrss_get_timestamp($item['PUBDATE']);
303+ $time = plugin_showrss_get_timestamp($item['PUBDATE'], $this->modified_date);
285304 } else {
286305 $time_from_desc = FALSE;
287306 if (isset($item['DESCRIPTION']) &&
@@ -309,7 +328,7 @@ class ShowRSS_XML
309328 }
310329 }
311330
312-function plugin_showrss_get_timestamp($str)
331+function plugin_showrss_get_timestamp($str, $default_date)
313332 {
314333 $str = trim($str);
315334 if ($str == '') return UTIME;
@@ -318,14 +337,14 @@ function plugin_showrss_get_timestamp($str)
318337 if (preg_match('/(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})(([+-])(\d{2}):(\d{2}))?/', $str, $matches)) {
319338 $time = strtotime($matches[1] . ' ' . $matches[2]);
320339 if ($time === FALSE || $time === -1) {
321- $time = UTIME;
322- } else if ($matches[3]) {
340+ $time = $default_date;
341+ } else if (isset($matches[3])) {
323342 $diff = ($matches[5] * 60 + $matches[6]) * 60;
324343 $time += ($matches[4] == '-' ? $diff : -$diff);
325344 }
326345 return $time;
327346 } else {
328347 $time = strtotime($str);
329- return ($time === FALSE || $time === -1) ? UTIME : $time - LOCALZONE;
348+ return ($time === FALSE || $time === -1) ? $default_date : $time - LOCALZONE;
330349 }
331350 }