aboutsummaryrefslogtreecommitdiff
path: root/app/Models/Feed.php
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2022-11-22 08:15:22 +0100
committerGravatar GitHub <noreply@github.com> 2022-11-22 08:15:22 +0100
commit4bf678f8e4311da467aec09e4d67fe0c5f57d512 (patch)
tree5bbcc6385c334bbcd96cd42ce1f5f56b86562d7c /app/Models/Feed.php
parent9b674e7e9390d19c1a9686710d78164a41ad31d1 (diff)
HTML+XPath allow content as HTML (#4878)
* HTML+XPath allow content as HTML #fix https://github.com/FreshRSS/FreshRSS/issues/4869 * Wrong variable reuse * Allow both HTML and expressions
Diffstat (limited to 'app/Models/Feed.php')
-rw-r--r--app/Models/Feed.php29
1 files changed, 26 insertions, 3 deletions
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index f24ec1884..538814370 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -653,7 +653,23 @@ class FreshRSS_Feed extends Minz_Model {
foreach ($nodes as $node) {
$item = [];
$item['title'] = $xPathItemTitle == '' ? '' : @$xpath->evaluate('normalize-space(' . $xPathItemTitle . ')', $node);
- $item['content'] = $xPathItemContent == '' ? '' : @$xpath->evaluate('normalize-space(' . $xPathItemContent . ')', $node);
+
+ $item['content'] = '';
+ if ($xPathItemContent != '') {
+ $result = @$xpath->evaluate($xPathItemContent, $node);
+ if ($result instanceof DOMNodeList) {
+ // List of nodes, save as HTML
+ $content = '';
+ foreach ($result as $child) {
+ $content .= $doc->saveHTML($child) . "\n";
+ }
+ $item['content'] = $content;
+ } else {
+ // Typed expression, save as-is
+ $item['content'] = strval($result);
+ }
+ }
+
$item['link'] = $xPathItemUri == '' ? '' : @$xpath->evaluate('normalize-space(' . $xPathItemUri . ')', $node);
$item['author'] = $xPathItemAuthor == '' ? '' : @$xpath->evaluate('normalize-space(' . $xPathItemAuthor . ')', $node);
$item['timestamp'] = $xPathItemTimestamp == '' ? '' : @$xpath->evaluate('normalize-space(' . $xPathItemTimestamp . ')', $node);
@@ -679,8 +695,15 @@ class FreshRSS_Feed extends Minz_Model {
$item['guid'] = 'urn:sha1:' . sha1($item['title'] . $item['content'] . $item['link']);
}
- if ($item['title'] . $item['content'] . $item['link'] != '') {
- $item = Minz_Helper::htmlspecialchars_utf8($item);
+ if ($item['title'] != '' || $item['content'] != '' || $item['link'] != '') {
+ // HTML-encoding/escaping of the relevant fields (all except 'content')
+ foreach (['author', 'categories', 'guid', 'link', 'thumbnail', 'timestamp', 'title'] as $key) {
+ if (!empty($item[$key])) {
+ $item[$key] = Minz_Helper::htmlspecialchars_utf8($item[$key]);
+ }
+ }
+ // CDATA protection
+ $item['content'] = str_replace(']]>', ']]&gt;', $item['content']);
$view->entries[] = FreshRSS_Entry::fromArray($item);
}
}