--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: life...@packages.debian.org
Control: affects -1 + src:liferea
Please unblock package liferea
[ Reason ]
A CVE was discovered in liferea and upstream quickly released a new
version including the fix. The new version also fixes a crash on
double free. Unfortunately it also included one more less important
improvement and an updated translation. Considering my options, I
decided it was best to upload the new version instead of only fixing
the CVE.
https://security-tracker.debian.org/tracker/CVE-2023-1350
[ Impact ]
The CVE is about a Remote Code Excecution of RSS feed information when
the user has opted-in to "Extract full content from HTML5 and Google
AMP". I believe that's pretty bad, but luckily it's not the default.
[ Tests ]
liferea doesn't have autopkgtests (yet), but I do activate the
upstream tests during build. Unfortunately, that currently fails
(because liferea isn't installed during build and if that's worked
around something fails due to being root; sorry, haven't fixed that
yet), but I ran the tests locally and then all regular tests pass. The
memtest fails in the same way as before. I also eat my own dogfood as
I'm a user of liferea and have the binaries installed since I built
them.
[ Risks ]
In the end, the changes are a bit more than trivial, but the delta in
this release is targetted to specific issues. I have a good relation
with upstream and he even supported me in the discussion with the
security team. Unfortunately, liferea isn't a leaf package as the
bfh-desktop (new in bookworm) and progress-linux-desktop (already in
bullseye) depend on it.
[ Checklist ]
[x] all changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in testing
[ Other info ]
I recommend viewing the debdiff with the following filter to ignore
upstream workflow items, the translation update and additional test
cases added for the purpose of testing the fix:
filterdiff -x '*/.gitignore' -x '*/.github/workflows/cb.yml' -x '*/po/fr.po' -x
'*/src/tests' liferea_1.14.1-1.debdiff
unblock liferea/1.14.1-1
Paul
diff -Nru liferea-1.14.0/ChangeLog liferea-1.14.1/ChangeLog
--- liferea-1.14.0/ChangeLog 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/ChangeLog 2023-03-12 21:00:51.000000000 +0100
@@ -1,3 +1,17 @@
+2023-03-12 Lars Windolf <lars.wind...@gmx.de>
+
+ Version 1.14.1
+
+ * Fixes CVE-2023-1350: RCE vulnerability on feed enrichment
+ (patch by Alexander Erwin Ittner)
+
+ * Fixes #1200: Crash on double free
+ (mozbugbox)
+
+ * Improve #1192 be reordering widget creation order
+ (Lars Windolf)
+
+
2023-01-10 Lars Windolf <lars.wind...@gmx.de>
Version 1.14.0
diff -Nru liferea-1.14.0/configure.ac liferea-1.14.1/configure.ac
--- liferea-1.14.0/configure.ac 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/configure.ac 2023-03-12 21:00:51.000000000 +0100
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT([liferea],[1.14.0],[liferea-de...@lists.sourceforge.net])
+AC_INIT([liferea],[1.14.1],[liferea-de...@lists.sourceforge.net])
AC_CANONICAL_HOST
AC_CONFIG_SRCDIR([src/feedlist.c])
diff -Nru liferea-1.14.0/debian/changelog liferea-1.14.1/debian/changelog
--- liferea-1.14.0/debian/changelog 2023-01-15 21:14:44.000000000 +0100
+++ liferea-1.14.1/debian/changelog 2023-03-12 21:32:33.000000000 +0100
@@ -1,3 +1,12 @@
+liferea (1.14.1-1) unstable; urgency=medium
+
+ * New upstream version 1.14.1
+ Contains fix for CVE-2023-1350 which is a RCE when the option "Extract
+ full content from HTML5 and Google AMP" is enable on a feed (Closes:
+ #1032822)
+
+ -- Paul Gevers <elb...@debian.org> Sun, 12 Mar 2023 21:32:33 +0100
+
liferea (1.14.0-1) unstable; urgency=medium
* New upstream version 1.14.0
diff -Nru liferea-1.14.0/.github/workflows/cb.yml
liferea-1.14.1/.github/workflows/cb.yml
--- liferea-1.14.0/.github/workflows/cb.yml 2023-01-10 21:12:42.000000000
+0100
+++ liferea-1.14.1/.github/workflows/cb.yml 2023-03-12 21:00:51.000000000
+0100
@@ -24,7 +24,7 @@
- run: |
sudo apt-get update -qq
- sudo apt-get install -y -qq libxml2-dev libxslt1-dev libsqlite3-dev
libwebkit2gtk-4.0-dev libjson-glib-dev libgirepository1.0-dev libpeas-dev
gsettings-desktop-schemas-dev python3 libtool intltool valgrind libfribidi-dev
gla11y
+ sudo apt-get install -y -qq libxml2-dev libxslt1-dev libsqlite3-dev
libwebkit2gtk-4.0-dev libjson-glib-dev libgirepository1.0-dev libpeas-dev
gsettings-desktop-schemas-dev python3 libtool intltool valgrind libfribidi-dev
gla11y appstream-util desktop-file-utils
mkdir inst
- run: |
@@ -35,6 +35,8 @@
- run: make && make install
- run: sudo cp net.sf.liferea.gschema.xml /usr/share/glib-2.0/schemas
- run: sudo /usr/bin/glib-compile-schemas /usr/share/glib-2.0/schemas/
- - run: ls -l /usr/share/glib-2.0/schemas
+ - run: ls -l /usr/share/glib-2.0/schemas
- run: cd src/tests && make test
- run: cd src/tests && ./memcheck.sh parse_xml parse_date
+ - run: desktop-file-validate net.sourceforge.liferea.desktop
+ - run: appstream-util validate net.sourceforge.liferea.appdata.xml
diff -Nru liferea-1.14.0/.gitignore liferea-1.14.1/.gitignore
--- liferea-1.14.0/.gitignore 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/.gitignore 2023-03-12 21:00:51.000000000 +0100
@@ -50,8 +50,9 @@
src/Liferea-3.0.typelib
src/tests/favicon
src/tests/html_auto
-src/tests/parse_html
src/tests/parse_date
+src/tests/parse_html
+src/tests/parse_rss
src/tests/parse_xml
src/tests/social
xslt/*.xml
diff -Nru liferea-1.14.0/net.sourceforge.liferea.appdata.xml.in
liferea-1.14.1/net.sourceforge.liferea.appdata.xml.in
--- liferea-1.14.0/net.sourceforge.liferea.appdata.xml.in 2023-01-10
21:12:42.000000000 +0100
+++ liferea-1.14.1/net.sourceforge.liferea.appdata.xml.in 2023-03-12
21:00:51.000000000 +0100
@@ -201,8 +201,6 @@
Now Liferea will never allow the panes to be smaller than 5% in
height or width
regarding to there orientation. If a pane is smaller than 5%
height/width it will be
set to 30% width or 50% height on startup.
-
- The intention here is that panes are never invisible after startup.
</li>
<li>
Wait for network to be fully available before updating: sometimes
when real internet
diff -Nru liferea-1.14.0/po/fr.po liferea-1.14.1/po/fr.po
--- liferea-1.14.0/po/fr.po 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/po/fr.po 2023-03-12 21:00:51.000000000 +0100
@@ -13,15 +13,15 @@
"Project-Id-Version: Liferea 1.8\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-26 01:24+0200\n"
-"PO-Revision-Date: 2022-09-16 10:26+0200\n"
-"Last-Translator: Guillaume Bernard <associati...@guillaume-bernard.fr>\n"
+"PO-Revision-Date: 2023-01-13 12:16+0100\n"
+"Last-Translator: Irénée Thirion <irenee.thirion@e.email>\n"
"Language-Team: français <>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 3.1.1\n"
+"X-Generator: Poedit 3.2.2\n"
#: ../net.sourceforge.liferea.desktop.in.h:1 ../src/liferea_application.c:349
#: ../glade/mainwindow.ui.h:1
@@ -439,18 +439,17 @@
msgstr "La connexion a échoué !"
#: ../src/fl_sources/google_source.c:404
-#, fuzzy
msgid "Google Reader API"
-msgstr "Google Reader"
+msgstr "API Google Reader"
#: ../src/fl_sources/google_source_feed.c:159
-#, fuzzy
msgid "Could not parse JSON returned by Google Reader API!"
-msgstr "Impossible d’analyser le JSON envoyé par l’API Reedah !"
+msgstr ""
+"Impossible d’analyser le fichier JSON retourné par l’API Google Reader !"
#: ../src/fl_sources/node_source.c:117
msgid "Miniflux"
-msgstr ""
+msgstr "Miniflux"
#: ../src/fl_sources/node_source.c:332
msgid "No feed list source types found!"
@@ -717,30 +716,28 @@
#. http 5xx server errors
#: ../src/net.c:493
-#, fuzzy
msgid "Internal Server Error"
-msgstr "Erreur du serveur"
+msgstr "Erreur interne du serveur"
#: ../src/net.c:494
msgid "Not Implemented"
-msgstr ""
+msgstr "Non implémenté"
#: ../src/net.c:495
msgid "Bad Gateway"
-msgstr ""
+msgstr "Mauvaise passerelle"
#: ../src/net.c:496
-#, fuzzy
msgid "Service Unavailable"
-msgstr "« %s » n’est pas disponible"
+msgstr "Service indisponible"
#: ../src/net.c:497
msgid "Gateway Timeout"
-msgstr ""
+msgstr "Délai d’attente de la passerelle écoulé"
#: ../src/net.c:498
msgid "HTTP Version Not Supported"
-msgstr ""
+msgstr "Version HTTP non prise en charge"
#: ../src/net.c:503
msgid "There was an internal error in the update process"
@@ -819,9 +816,8 @@
msgstr "Le corps de l’élément"
#: ../src/rule.c:277
-#, fuzzy
msgid "Item author"
-msgstr "Le corps de l’élément"
+msgstr "L’auteur de l’élément"
#: ../src/rule.c:278
msgid "Read status"
@@ -1091,14 +1087,14 @@
msgstr "Aucun élément n’a été sélectionné"
#: ../src/ui/liferea_browser.c:482
-#, fuzzy
msgid "Content download failed! Try disabling reader mode."
-msgstr "Impossible de télécharger le contenu."
+msgstr ""
+"Impossible de télécharger le contenu. Essayez de désactiver le mode lecture."
#: ../src/ui/liferea_browser.c:495
-#, fuzzy
msgid "Content extraction failed! Try disabling reader mode."
-msgstr "Impossible d’extraire le contenu."
+msgstr ""
+"Impossible d’extraire le contenu. Essayez de désactiver le mode lecture."
#: ../src/ui/liferea_shell.c:409
#, c-format
@@ -1325,9 +1321,8 @@
msgstr "Programme"
#: ../src/ui/rule_editor.c:257
-#, fuzzy
msgid "Remove"
-msgstr "_Supprimer"
+msgstr "Supprimer"
#: ../src/ui/search_dialog.c:106
msgid "Saved Search"
@@ -1504,15 +1499,16 @@
"de maintenant."
#: ../glade/google_source.ui.h:1
-#, fuzzy
msgid "Add Google Reader API Account"
-msgstr "Ajouter un compte Google Reader"
+msgstr "Ajouter un compte API Google Reader"
#: ../glade/google_source.ui.h:2
msgid ""
"Please enter the details of the new Google Reader API compatible "
"subscription."
msgstr ""
+"Veuillez saisir les détails du nouvel abonnement compatible avec l’API "
+"Google Reader."
#: ../glade/google_source.ui.h:3 ../glade/reedah_source.ui.h:3
#: ../glade/theoldreader_source.ui.h:3 ../glade/ttrss_source.ui.h:4
@@ -1525,14 +1521,12 @@
msgstr "Nom d’_utilisateur (e-mail)"
#: ../glade/google_source.ui.h:5
-#, fuzzy
msgid "_Server"
-msgstr "URL du _serveur"
+msgstr "_Serveur"
#: ../glade/google_source.ui.h:6
-#, fuzzy
msgid "_Name"
-msgstr "_Nom du flux"
+msgstr "_Nom"
#: ../glade/liferea_menu.ui.h:1
msgid "_Subscriptions"
@@ -1886,9 +1880,8 @@
"recherche."
#: ../glade/prefs.ui.h:22
-#, fuzzy
msgid "Ask for confirmation when marking all items as read."
-msgstr "Demander confirmation pour marquer tous les éléments comme lus"
+msgstr "Demander confirmation pour marquer tous les éléments comme lus."
#: ../glade/prefs.ui.h:23
msgid "Web Integration"
diff -Nru liferea-1.14.0/src/common.c liferea-1.14.1/src/common.c
--- liferea-1.14.0/src/common.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/common.c 2023-03-12 21:00:51.000000000 +0100
@@ -138,7 +138,9 @@
g_assert (NULL != url);
/* xmlURIEscape returns NULL if spaces are in the URL,
- so we need to replace them first (see SF #2965158) */
+ so we need to replace them first (see SF #2965158).
+ TODO: perhaps replace xmlURIEscape with g_uri_escape_string ?
+ */
tmp = (xmlChar *)common_strreplace (g_strdup ((gchar *)url), " ",
"%20");
result = xmlURIEscape (tmp);
g_free (tmp);
diff -Nru liferea-1.14.0/src/feed.c liferea-1.14.1/src/feed.c
--- liferea-1.14.0/src/feed.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/feed.c 2023-03-12 21:00:51.000000000 +0100
@@ -460,7 +460,7 @@
NODE_CAPABILITY_EXPORT |
NODE_CAPABILITY_EXPORT_ITEMS,
"feed", /* not used, feed format ids are used instead */
- NULL,
+ ICON_DEFAULT,
feed_import,
feed_export,
feed_load,
@@ -472,7 +472,6 @@
feed_properties,
feed_free
};
- nti.icon = icon_get (ICON_DEFAULT);
return &nti;
}
diff -Nru liferea-1.14.0/src/feed_parser.h liferea-1.14.1/src/feed_parser.h
--- liferea-1.14.0/src/feed_parser.h 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/feed_parser.h 2023-03-12 21:00:51.000000000 +0100
@@ -1,7 +1,7 @@
/**
* @file feed_parser.h parsing of different feed formats
*
- * Copyright (C) 2008-2021 Lars Windolf <lars.wind...@gmx.de>
+ * Copyright (C) 2008-2023 Lars Windolf <lars.wind...@gmx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
subscriptionPtr subscription; /**< the subscription the feed
belongs to (optional) */
feedPtr feed; /**< the feed structure to fill
*/
GList *items; /**< the list of new items */
- struct item *item; /**< the item currently parsed
(or NULL) */
+ itemPtr item; /**< the item currently parsed
(or NULL) */
GHashTable *tmpdata; /**< tmp data hash used during
stateful parsing */
diff -Nru liferea-1.14.0/src/fl_sources/node_source.c
liferea-1.14.1/src/fl_sources/node_source.c
--- liferea-1.14.0/src/fl_sources/node_source.c 2023-01-10 21:12:42.000000000
+0100
+++ liferea-1.14.1/src/fl_sources/node_source.c 2023-03-12 21:00:51.000000000
+0100
@@ -1,7 +1,7 @@
/*
* @file node_source.c generic node source provider implementation
*
- * Copyright (C) 2005-2022 Lars Windolf <lars.wind...@gmx.de>
+ * Copyright (C) 2005-2023 Lars Windolf <lars.wind...@gmx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -622,7 +622,7 @@
/* derive the node source node type from the folder node type */
nodeType = (nodeTypePtr) g_new0 (struct nodeType, 1);
nodeType->id = "source";
- nodeType->icon = icon_get (ICON_DEFAULT);
+ nodeType->icon = ICON_DEFAULT;
nodeType->capabilities =
NODE_CAPABILITY_SHOW_UNREAD_COUNT |
NODE_CAPABILITY_SHOW_ITEM_FAVICONS |
NODE_CAPABILITY_UPDATE_CHILDS
|
diff -Nru liferea-1.14.0/src/folder.c liferea-1.14.1/src/folder.c
--- liferea-1.14.0/src/folder.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/folder.c 2023-03-12 21:00:51.000000000 +0100
@@ -119,7 +119,7 @@
NODE_CAPABILITY_UPDATE_CHILDS |
NODE_CAPABILITY_EXPORT,
"folder",
- NULL,
+ ICON_FOLDER,
folder_import,
folder_export,
folder_load,
@@ -131,7 +131,6 @@
feed_list_view_rename_node,
NULL
};
- fnti.icon = icon_get (ICON_FOLDER);
return &fnti;
}
@@ -150,7 +149,7 @@
NODE_CAPABILITY_UPDATE_CHILDS |
NODE_CAPABILITY_EXPORT,
"root",
- NULL, /* and no need for an icon */
+ 0, /* and no need for an icon */
folder_import,
folder_export,
folder_load,
diff -Nru liferea-1.14.0/src/html.c liferea-1.14.1/src/html.c
--- liferea-1.14.0/src/html.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/html.c 2023-03-12 21:00:51.000000000 +0100
@@ -221,7 +221,7 @@
GSList *
html_auto_discover_feed (const gchar* data, const gchar *defaultBaseUri)
{
- GSList *iter, *links = NULL;
+ GSList *iter, *links = NULL, *valid_links = NULL;
gchar *baseUri = NULL;
xmlDocPtr doc;
xmlNodePtr node, root;
@@ -253,17 +253,25 @@
/* Turn relative URIs into absolute URIs */
iter = links;
while (iter) {
- gchar *tmp = iter->data;
- iter->data = common_build_url (tmp, baseUri);
- g_free (tmp);
- debug1 (DEBUG_UPDATE, "search result: %s", (gchar *)iter->data);
+ gchar *tmp = (gchar *)common_build_url (iter->data, baseUri);
+
+ /* We expect only relative URIs starting with '/' or absolute
URIs starting with 'http://' or 'https://' */
+ if ('h' == tmp[0] || '/' == tmp[0]) {
+ debug1 (DEBUG_UPDATE, "search result: %s", (gchar
*)iter->data);
+ valid_links = g_slist_append (valid_links, tmp);
+ } else {
+ debug1 (DEBUG_UPDATE, "html_auto_discover_feed:
discarding invalid URL %s", tmp ? tmp : "NULL");
+ g_free (tmp);
+ }
+
iter = g_slist_next (iter);
}
+ g_slist_free_full (links, g_free);
g_free (baseUri);
xmlFreeDoc (doc);
- return links;
+ return valid_links;
}
GSList *
diff -Nru liferea-1.14.0/src/item.c liferea-1.14.1/src/item.c
--- liferea-1.14.0/src/item.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/item.c 2023-03-12 21:00:51.000000000 +0100
@@ -1,7 +1,7 @@
/**
* @file item.c item handling
*
- * Copyright (C) 2003-2021 Lars Windolf <lars.wind...@gmx.de>
+ * Copyright (C) 2003-2023 Lars Windolf <lars.wind...@gmx.de>
* Copyright (C) 2004-2006 Nathan J. Conrad <t98...@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
@@ -34,27 +34,55 @@
#include "render.h"
#include "xml.h"
-itemPtr
-item_new (void)
+G_DEFINE_TYPE (LifereaItem, liferea_item, G_TYPE_OBJECT);
+
+static void
+liferea_item_finalize (GObject *object)
{
- itemPtr item;
+ LifereaItem *item = LIFEREA_ITEM (object);
+
+ g_free (item->title);
+ g_free (item->source);
+ g_free (item->sourceId);
+ g_free (item->description);
+ g_free (item->commentFeedId);
+ g_free (item->nodeId);
+ g_free (item->parentNodeId);
- item = g_new0 (struct item, 1);
+ g_assert (NULL == item->tmpdata); /* should be free after
rendering */
+ metadata_list_free (item->metadata);
+}
+
+static void
+liferea_item_class_init (LifereaItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = liferea_item_finalize;
+}
+
+static void
+liferea_item_init (LifereaItem *item)
+{
item->popupStatus = TRUE;
+}
- return item;
+LifereaItem *
+item_new (void)
+{
+ return LIFEREA_ITEM (g_object_new (LIFEREA_ITEM_TYPE, NULL));
}
-itemPtr
+LifereaItem *
item_load (gulong id)
{
return db_item_load (id);
}
-itemPtr
-item_copy (itemPtr item)
+LifereaItem *
+item_copy (LifereaItem *item)
{
- itemPtr copy = item_new ();
+ LifereaItem *copy = item_new ();
item_set_title (copy, item->title);
item_set_source (copy, item->source);
@@ -84,7 +112,7 @@
}
void
-item_set_title (itemPtr item, const gchar * title)
+item_set_title (LifereaItem *item, const gchar * title)
{
g_free (item->title);
@@ -95,7 +123,7 @@
}
void
-item_set_description (itemPtr item, const gchar *description)
+item_set_description (LifereaItem *item, const gchar *description)
{
if (!description)
return;
@@ -109,39 +137,41 @@
}
void
-item_set_source (itemPtr item, const gchar * source)
+item_set_source (LifereaItem *item, const gchar * source)
{
g_free (item->source);
- if (source)
+
+ /* We expect only relative URIs starting with '/' or absolute URIs
starting with 'http://' or 'https://' */
+ if (source && ('/' == source[0] || 'h' == source[0]))
item->source = g_strstrip (g_strdup (source));
else
item->source = NULL;
}
void
-item_set_id (itemPtr item, const gchar * id)
+item_set_id (LifereaItem *item, const gchar * id)
{
g_free (item->sourceId);
item->sourceId = g_strdup (id);
}
void
-item_set_time (itemPtr item, gint64 time)
+item_set_time (LifereaItem *item, gint64 time)
{
item->time = time;
if (item->time > 0)
item->validTime = TRUE;
}
-const gchar * item_get_id(itemPtr item) { return item->sourceId; }
-const gchar * item_get_title(itemPtr item) {return item->title; }
-const gchar * item_get_description(itemPtr item) { return item->description; }
-const gchar * item_get_source(itemPtr item) { return item->source; }
+const gchar * item_get_id(LifereaItem *item) { return item->sourceId; }
+const gchar * item_get_title(LifereaItem *item) {return item->title; }
+const gchar * item_get_description(LifereaItem *item) { return
item->description; }
+const gchar * item_get_source(LifereaItem *item) { return item->source; }
static GRegex *whitespace_strip_re = NULL;
gchar *
-item_get_teaser (itemPtr item)
+item_get_teaser (LifereaItem *item)
{
gchar *input, *tmpDesc;
gchar *teaser = NULL;
@@ -176,7 +206,7 @@
}
gchar *
-item_make_link (itemPtr item)
+item_make_link (LifereaItem *item)
{
const gchar *src;
gchar *link;
@@ -202,7 +232,7 @@
}
const gchar *
-item_get_author(itemPtr item)
+item_get_author(LifereaItem *item)
{
gchar *author;
@@ -210,25 +240,8 @@
return author;
}
-void
-item_unload (itemPtr item)
-{
- g_free (item->title);
- g_free (item->source);
- g_free (item->sourceId);
- g_free (item->description);
- g_free (item->commentFeedId);
- g_free (item->nodeId);
- g_free (item->parentNodeId);
-
- g_assert (NULL == item->tmpdata); /* should be free after
rendering */
- metadata_list_free (item->metadata);
-
- g_free (item);
-}
-
const gchar *
-item_get_base_url (itemPtr item)
+item_get_base_url (LifereaItem *item)
{
/* item->node is always the source node for the item
never a search folder or folder */
@@ -236,7 +249,7 @@
}
void
-item_to_xml (itemPtr item, gpointer xmlNode)
+item_to_xml (LifereaItem *item, gpointer xmlNode)
{
xmlNodePtr parentNode = (xmlNodePtr)xmlNode;
xmlNodePtr duplicatesNode;
@@ -293,7 +306,7 @@
duplicates = iter = db_item_get_duplicates(item->sourceId);
while (iter) {
gulong id = GPOINTER_TO_UINT (iter->data);
- itemPtr duplicate = item_load (id);
+ LifereaItem * duplicate = item_load (id);
if (duplicate) {
nodePtr duplicateNode = node_from_id
(duplicate->nodeId);
if (duplicateNode && (item->id !=
duplicate->id))
@@ -328,7 +341,7 @@
}
static const gchar *
-item_get_text_direction (itemPtr item)
+item_get_text_direction (LifereaItem *item)
{
if (item_get_title (item))
return (common_get_text_direction (item_get_title (item)));
@@ -340,7 +353,7 @@
}
gchar *
-item_render (itemPtr item, guint viewMode)
+item_render (LifereaItem *item, guint viewMode)
{
renderParamPtr params;
gchar *output = NULL, *baseUrl = NULL;
diff -Nru liferea-1.14.0/src/item.h liferea-1.14.1/src/item.h
--- liferea-1.14.0/src/item.h 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/item.h 2023-03-12 21:00:51.000000000 +0100
@@ -1,7 +1,7 @@
/*
* @file item.h item handling
*
- * Copyright (C) 2003-2022 Lars Windolf <lars.wind...@gmx.de>
+ * Copyright (C) 2003-2023 Lars Windolf <lars.wind...@gmx.de>
* Copyright (C) 2004-2006 Nathan J. Conrad <t98...@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
@@ -23,24 +23,27 @@
#define _ITEM_H
#include <glib.h>
+#include <glib-object.h>
-/* Currently Liferea knows only a single type of items used
- for the itemset types feed, folder and search folder. So each
- feed list type provider must provide it's data using the
- item interface. */
-
-/* ------------------------------------------------------------ */
-/* item interface */
-/* ------------------------------------------------------------ */
+/* Each feed/subscription type provider must provide it's data using `Item` */
+
+G_BEGIN_DECLS
+
+#define LIFEREA_ITEM_TYPE (liferea_item_get_type ())
+G_DECLARE_FINAL_TYPE (LifereaItem, liferea_item, LIFEREA, ITEM, GObject)
/*
* An item stores a particular entry in a feed or a search.
+ *
* Each item belongs to an item set. An itemset is a collection
* of items. There are different item set types (e.g. feed,
- * folder,vfolder or plugin). Each item has a source node.
+ * folder, search folder or plugin). Each item has a source node.
* The item set node and the item source node is different
- * for folders and vfolders. */
-typedef struct item {
+ * for folders and search folders.
+ */
+struct _LifereaItem {
+ GObject parent_instance;
+
gulong id; /*<< internally unique item id
*/
/* those fields should not be accessed directly. Accessors are
provided. */
@@ -75,7 +78,9 @@
/* remote states used during sync of remote accounts */
gboolean remoteReadStatus; /*<< TRUE if the remote copy of
the item has been read */
gboolean remoteFlagStatus; /*<< TRUE if the remote copy of
the item has been flagged */
-} *itemPtr;
+};
+
+typedef struct _LifereaItem *itemPtr;
/**
* item_new: (skip)
@@ -83,7 +88,7 @@
*
* Returns: (transfer full): the new structure
*/
-itemPtr item_new(void);
+LifereaItem * item_new(void);
/**
* item_load: (skip)
@@ -95,7 +100,10 @@
*
* Returns: (transfer full) (nullable): item structure
*/
-itemPtr item_load(gulong id);
+LifereaItem * item_load(gulong id);
+
+// For legacy code let's keep item_unload()
+#define item_unload(a) g_object_unref(a)
/**
* item_copy: (skip)
@@ -107,7 +115,7 @@
*
* Returns: (transfer full): copy of the item.
*/
-itemPtr item_copy(itemPtr item);
+LifereaItem * item_copy(LifereaItem * item);
/**
* item_get_base_url: (skip)
@@ -117,27 +125,17 @@
*
* Returns: base URL
*/
-const gchar * item_get_base_url(itemPtr item);
-
-/**
- * item_unload: (skip)
- * @item: the item to unload
- *
- * Free the memory used by an itempointer. The item needs to be
- * removed from the itemlist before calling this function.
- *
- */
-void item_unload(itemPtr item);
+const gchar * item_get_base_url(LifereaItem *item);
/* methods to access properties */
/* Returns the id of item. */
-const gchar * item_get_id(itemPtr item);
+const gchar * item_get_id(LifereaItem *item);
/* Returns the title of item. */
-const gchar * item_get_title(itemPtr item);
+const gchar * item_get_title(LifereaItem *item);
/* Returns the description of item. */
-const gchar * item_get_description(itemPtr item);
+const gchar * item_get_description(LifereaItem *item);
/* Returns the source of item. */
-const gchar * item_get_source(itemPtr item);
+const gchar * item_get_source(LifereaItem *item);
/**
* item_get_teaser: (skip)
@@ -147,7 +145,7 @@
*
* Returns: (transfer full): newly allocated string to be free'd using
g_free() (or NULL)
*/
-gchar * item_get_teaser(itemPtr item);
+gchar * item_get_teaser(LifereaItem *item);
/**
* item_make_link: (skip)
@@ -157,7 +155,7 @@
*
* Returns: (transfer full): newly allocated URI to be free'd using g_free()
*/
-gchar * item_make_link(itemPtr item);
+gchar * item_make_link(LifereaItem *item);
/**
* item_get_author: (skip)
@@ -167,7 +165,7 @@
*
* Returns: pointer to string in GSList meta data
*/
-const gchar * item_get_author (itemPtr item);
+const gchar * item_get_author(LifereaItem *item);
/**
* item_set_title: (skip)
@@ -176,7 +174,7 @@
*
* Sets the item title
*/
-void item_set_title(itemPtr item, const gchar * title);
+void item_set_title(LifereaItem *item, const gchar * title);
/**
* item_set_description: (skip)
@@ -187,7 +185,7 @@
* will merge the new description against the old one deciding
* on the best to keep.
*/
-void item_set_description (itemPtr item, const gchar *description);
+void item_set_description (LifereaItem *item, const gchar *description);
/**
* item_set_source: (skip)
@@ -196,7 +194,7 @@
*
* Sets the item source
*/
-void item_set_source(itemPtr item, const gchar * source);
+void item_set_source(LifereaItem *item, const gchar * source);
/**
* item_set_id: (skip)
@@ -205,7 +203,7 @@
*
* Sets the item id
*/
-void item_set_id (itemPtr item, const gchar * id);
+void item_set_id (LifereaItem *item, const gchar * id);
/**
* item_set_time: (skip)
@@ -215,7 +213,7 @@
* Sets the item time. Always use this when a valid date was
* supplied for the item!
*/
-void item_set_time (itemPtr item, gint64 time);
+void item_set_time (LifereaItem *item, gint64 time);
/**
* item_to_xml: (skip)
@@ -225,7 +223,7 @@
* Adds an XML node to the given item.
*
*/
-void item_to_xml (itemPtr item, gpointer parentNode);
+void item_to_xml (LifereaItem *item, gpointer parentNode);
/**
* item_render: (skip)
@@ -236,6 +234,8 @@
*
* Returns XML string (to be free'd using g_free())
*/
-gchar * item_render (itemPtr item, guint viewMode);
+gchar * item_render (LifereaItem *item, guint viewMode);
+
+G_END_DECLS
-#endif
+#endif
\ No newline at end of file
diff -Nru liferea-1.14.0/src/itemlist.c liferea-1.14.1/src/itemlist.c
--- liferea-1.14.0/src/itemlist.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/itemlist.c 2023-03-12 21:00:51.000000000 +0100
@@ -237,9 +237,9 @@
if (itemlist->priv->deferredRemove) {
itemlist->priv->deferredRemove = FALSE;
itemlist_remove_item (item);
+ } else {
+ item_unload (item);
}
-
- item_unload (item);
}
static void
@@ -499,16 +499,8 @@
while (iter) {
itemPtr item = (itemPtr) iter->data;
-
- if (itemlist->priv->selectedId != item->id) {
- /* don't call itemlist_remove_item() here, because it's
to slow */
- itemview_remove_item (item);
- db_item_remove (item->id);
- } else {
- /* go the normal and selection-safe way to avoid
disturbing the user */
- itemlist_request_remove_item (item);
- }
- item_unload (item);
+ itemlist_request_remove_item (item);
+ db_item_remove (item->id);
iter = g_list_next (iter);
}
@@ -590,7 +582,7 @@
}
if (item)
- item_unload (item);
+ g_object_unref (item);
debug_end_measurement (DEBUG_GUI, "itemlist selection");
debug_exit ("itemlist_selection_changed");
diff -Nru liferea-1.14.0/src/itemset.c liferea-1.14.1/src/itemset.c
--- liferea-1.14.0/src/itemset.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/itemset.c 2023-03-12 21:00:51.000000000 +0100
@@ -44,7 +44,7 @@
itemPtr item = item_load (GPOINTER_TO_UINT (iter->data));
if (item) {
(*callback) (item, userdata);
- item_unload (item);
+ g_object_unref (item);
}
iter = g_list_next (iter);
}
diff -Nru liferea-1.14.0/src/newsbin.c liferea-1.14.1/src/newsbin.c
--- liferea-1.14.0/src/newsbin.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/newsbin.c 2023-03-12 21:00:51.000000000 +0100
@@ -217,7 +217,7 @@
NODE_CAPABILITY_SHOW_ITEM_COUNT |
NODE_CAPABILITY_EXPORT_ITEMS;
nodeType->id = "newsbin";
- nodeType->icon = icon_get (ICON_NEWSBIN);
+ nodeType->icon = ICON_NEWSBIN;
nodeType->load = feed_get_node_type()->load;
nodeType->import = newsbin_import;
nodeType->export = newsbin_export;
diff -Nru liferea-1.14.0/src/node.c liferea-1.14.1/src/node.c
--- liferea-1.14.0/src/node.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/node.c 2023-03-12 21:00:51.000000000 +0100
@@ -43,6 +43,7 @@
#include "date.h"
#include "fl_sources/node_source.h"
#include "ui/feed_list_view.h"
+#include "ui/icons.h"
#include "ui/liferea_shell.h"
static GHashTable *nodes = NULL; /*<< node id -> node lookup table */
@@ -431,7 +432,7 @@
node_get_icon (nodePtr node)
{
if (!node->icon)
- return (gpointer) NODE_TYPE(node)->icon;
+ return (gpointer) icon_get (NODE_TYPE(node)->icon);
return node->icon;
}
diff -Nru liferea-1.14.0/src/node_type.h liferea-1.14.1/src/node_type.h
--- liferea-1.14.0/src/node_type.h 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/node_type.h 2023-03-12 21:00:51.000000000 +0100
@@ -54,7 +54,7 @@
typedef struct nodeType {
gulong capabilities; /**< bitmask of node type capabilities
*/
const gchar *id; /**< type id (used for type attribute
in OPML export) */
- const GIcon *icon; /**< default icon for nodes of this
type (if no favicon available) */
+ guint icon; /**< default icon for nodes of this
type (if no favicon available) */
/* For method documentation see the wrappers defined below!
All methods are mandatory for each node type. */
diff -Nru liferea-1.14.0/src/subscription.c liferea-1.14.1/src/subscription.c
--- liferea-1.14.0/src/subscription.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/subscription.c 2023-03-12 21:00:51.000000000 +0100
@@ -282,6 +282,7 @@
subscription->updateState,
subscription->updateOptions
);
+ update_request_allow_commands (request, TRUE);
if (subscription_get_filter (subscription))
request->filtercmd = g_strdup (subscription_get_filter
(subscription));
diff -Nru liferea-1.14.0/src/tests/Makefile.am
liferea-1.14.1/src/tests/Makefile.am
--- liferea-1.14.0/src/tests/Makefile.am 2023-01-10 21:12:42.000000000
+0100
+++ liferea-1.14.1/src/tests/Makefile.am 2023-03-12 21:00:51.000000000
+0100
@@ -2,7 +2,7 @@
noinst_PROGRAMS = $(TEST_PROGS)
-TEST_PROGS = parse_html favicon parse_date parse_xml social
+TEST_PROGS = parse_html favicon parse_date parse_rss parse_xml social
test: $(TEST_PROGS)
echo $(TEST_PROGS) |\
@@ -93,6 +93,9 @@
parse_date_CFLAGS = $(AM_CPPFLAGS)
parse_date_LDADD = $(favicon_LDADD)
+parse_rss_CFLAGS = $(AM_CPPFLAGS)
+parse_rss_LDADD = $(favicon_LDADD)
+
parse_xml_CFLAGS = $(AM_CPPFLAGS)
parse_xml_LDADD = $(favicon_LDADD)
diff -Nru liferea-1.14.0/src/tests/parse_html.c
liferea-1.14.1/src/tests/parse_html.c
--- liferea-1.14.0/src/tests/parse_html.c 2023-01-10 21:12:42.000000000
+0100
+++ liferea-1.14.1/src/tests/parse_html.c 2023-03-12 21:00:51.000000000
+0100
@@ -1,7 +1,7 @@
/**
- * @file html.c Test cases for feed link auto discovery
+ * @file parse_html.c Test cases for feed link auto discovery
*
- * Copyright (C) 2014-2019 Lars Windolf <lars.wind...@gmx.de>
+ * Copyright (C) 2014-2023 Lars Windolf <lars.wind...@gmx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#include <glib.h>
+#include "debug.h"
#include "html.h"
/* We need two groups of autodiscovery test cases, one for the tag soup fuzzy
@@ -115,6 +116,13 @@
NULL
};
+// Injection via "|"" command must not result in command subscription
+gchar *tc_xml_rce[] = {
+ "<html><head><link rel=\"alternate\" type=\"application/rss+xml\"
href=\"|date >/tmp/bad-feed-discovery.txt\"></html>",
+ NULL,
+ NULL
+};
+
/* HTML5 extraction test cases */
gchar *tc_article[] = {
@@ -214,6 +222,9 @@
{
g_test_init (&argc, &argv, NULL);
+ if (argv[1] && g_str_equal (argv[1], "--debug"))
+ set_debug_level (DEBUG_UPDATE | DEBUG_HTML | DEBUG_PARSING);
+
g_test_add_data_func ("/html/auto_discover_link_xml", &tc_xml,
&tc_auto_discover_link);
g_test_add_data_func ("/html/auto_discover_link_xml_base_url",
&tc_xml_base_url, &tc_auto_discover_link);
g_test_add_data_func ("/html/auto_discover_link_rss", &tc_rss,
&tc_auto_discover_link);
@@ -225,6 +236,7 @@
g_test_add_data_func ("/html/auto_discover_link_xml_atom",
&tc_xml_atom, &tc_auto_discover_link);
g_test_add_data_func ("/html/auto_discover_link_xml_atom2",
&tc_xml_atom2, &tc_auto_discover_link);
g_test_add_data_func ("/html/auto_discover_link_xml_atom3",
&tc_xml_atom3, &tc_auto_discover_link);
+ g_test_add_data_func ("/html/auto_discover_link_xml_rce", &tc_xml_rce,
&tc_auto_discover_link);
g_test_add_data_func ("/html/html5_extract_article", &tc_article,
&tc_get_article);
g_test_add_data_func ("/html/html5_extract_article_main",
&tc_article_main, &tc_get_article);
diff -Nru liferea-1.14.0/src/tests/parse_rss.c
liferea-1.14.1/src/tests/parse_rss.c
--- liferea-1.14.0/src/tests/parse_rss.c 1970-01-01 01:00:00.000000000
+0100
+++ liferea-1.14.1/src/tests/parse_rss.c 2023-03-12 21:00:51.000000000
+0100
@@ -0,0 +1,128 @@
+/**
+ * @file parse_rss.c Test cases for RSS parsing
+ *
+ * Copyright (C) 2023 Lars Windolf <lars.wind...@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include "debug.h"
+#include "feed.h"
+#include "feed_parser.h"
+#include "item.h"
+#include "subscription.h"
+#include "xml.h"
+
+/* Format of test cases:
+
+ 1. feed XML string
+ 2. "true" for successfully parsed feed, "false" for unparseable
+ 3. number of items
+ 4..n string of XML serialized items
+ */
+
+gchar *tc_rss_feed1[] = {
+ "<rss
version=\"2.0\"><channel><title>T</title><link>http://localhost</link><item><title>i1</title><link>http://localhost/item1.html</link><description>D</description></item><item><title>i2</title><link>https://localhost/item2.html</link></item></channel></rss>",
+ "true",
+ "2",
+ "<item><title>i1</title><description><div
xmlns=\"http://www.w3.org/1999/xhtml\"><p>D</p></div></description><source>http://localhost/item1.html</source><nr>0</nr><readStatus>0</readStatus><updateStatus>0</updateStatus><mark>0</mark><time>1678397817</time><sourceId/><sourceNr>0</sourceNr><attributes/></item>",
+
"<item><title>i2</title><source>https://localhost/item2.html</source><nr>0</nr><readStatus>0</readStatus><updateStatus>0</updateStatus><mark>0</mark><time>1678397817</time><sourceId/><sourceNr>0</sourceNr><attributes/></item>",
+ NULL
+};
+
+/* Test case to prevent | command injection in item link which could trigger
+ a HTML5 extraction */
+gchar *tc_rss_feed2_rce[] = {
+ "<rss
version=\"2.0\"><channel><title>T</title><item><title>i1</title><link>|date
>/tmp/bad-item-link.txt</link></item></channel></rss>",
+ "true",
+ "1",
+
"<item><title>i1</title><nr>0</nr><readStatus>0</readStatus><updateStatus>0</updateStatus><mark>0</mark><time>1678397817</time><sourceId/><sourceNr>0</sourceNr><attributes/></item>",
+ NULL
+};
+
+static void
+tc_parse_feed (gconstpointer user_data)
+{
+ gchar **tc = (gchar **)user_data;
+ nodePtr node;
+ feedParserCtxtPtr ctxt;
+ int i;
+ GList *iter;
+
+ node = node_new (feed_get_node_type ());
+ node_set_data (node, feed_new ());
+ node_set_subscription (node, subscription_new (NULL, NULL, NULL));
+ ctxt = feed_parser_ctxt_new (node->subscription, tc[0], strlen(tc[0]));
+
+ g_assert_cmpstr (feed_parse (ctxt)?"true":"false", ==, tc[1]);
+ g_assert (g_list_length (ctxt->items) == atoi(tc[2]));
+
+ i = 2;
+ iter = ctxt->items;
+ while (tc[++i]) {
+ gchar *buffer, *tmp, *tmp2;
+ gint buffersize;
+ xmlDocPtr doc = xmlNewDoc (BAD_CAST"1.0");
+ xmlNodePtr rootNode = xmlNewDocNode (doc, NULL,
BAD_CAST"result", NULL);
+
+ xmlDocSetRootElement (doc, rootNode);
+
+ // Force time and delete <timestr> to make result compareable
+ itemPtr item = (itemPtr)iter->data;
+ item->time = 1678397817;
+ item_to_xml (item, rootNode);
+
+ xmlNode *timestr = xpath_find (rootNode, "//timestr");
+ if (timestr) {
+ xmlUnlinkNode (timestr);
+ xmlFreeNode (timestr);
+ }
+ xmlDocDumpMemory(doc, (xmlChar **)&buffer, &buffersize);
+
+ /* strip boilerplate */
+ tmp = buffer;
+ if ((tmp = strstr (tmp, "<result>")))
+ tmp += 8;
+ if ((tmp2 = strstr (tmp, "</result>")))
+ *tmp2 = 0;
+
+ g_assert_cmpstr (tc[i], ==, tmp);
+
+ xmlFreeDoc (doc);
+ xmlFree (buffer);
+
+ iter = g_list_next (iter);
+ }
+
+ feed_parser_ctxt_free (ctxt);
+ node_free (node);
+}
+
+int
+main (int argc, char *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+
+ if (argv[1] && g_str_equal (argv[1], "--debug"))
+ set_debug_level (DEBUG_UPDATE | DEBUG_HTML | DEBUG_PARSING);
+
+ g_test_add_data_func ("/rss/feed1", &tc_rss_feed1,
&tc_parse_feed);
+ g_test_add_data_func ("/rss/feed2_rce", &tc_rss_feed2_rce,
&tc_parse_feed);
+
+ return g_test_run();
+}
diff -Nru liferea-1.14.0/src/ui/liferea_shell.c
liferea-1.14.1/src/ui/liferea_shell.c
--- liferea-1.14.0/src/ui/liferea_shell.c 2023-01-10 21:12:42.000000000
+0100
+++ liferea-1.14.1/src/ui/liferea_shell.c 2023-03-12 21:00:51.000000000
+0100
@@ -1387,7 +1387,6 @@
liferea_shell_update_toolbar ();
liferea_shell_update_history_actions ();
liferea_shell_setup_URL_receiver ();
- liferea_shell_restore_state (overrideWindowState);
gtk_widget_set_sensitive (GTK_WIDGET (shell->feedlistViewWidget), TRUE);
@@ -1407,6 +1406,7 @@
G_CALLBACK (liferea_shell_update_node_actions), NULL);
/* 11.) Restore latest layout and selection */
+ liferea_shell_restore_state (overrideWindowState);
conf_get_int_value (DEFAULT_VIEW_MODE, &mode);
itemview_set_layout (mode);
diff -Nru liferea-1.14.0/src/update.c liferea-1.14.1/src/update.c
--- liferea-1.14.0/src/update.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/update.c 2023-03-12 21:00:51.000000000 +0100
@@ -234,6 +234,13 @@
request->authValue = g_strdup (authValue);
}
+void
+update_request_allow_commands (UpdateRequest *request, gboolean allowCommands)
+{
+ request->allowCommands = allowCommands;
+}
+
+
/* update result object */
updateResultPtr
@@ -672,8 +679,14 @@
/* everything starting with '|' is a local command */
if (*(job->request->source) == '|') {
- debug1 (DEBUG_UPDATE, "Recognized local command: %s",
job->request->source);
- update_exec_cmd (job);
+ if (job->request->allowCommands) {
+ debug1 (DEBUG_UPDATE, "Recognized local command: %s",
job->request->source);
+ update_exec_cmd (job);
+ } else {
+ debug1 (DEBUG_UPDATE, "Refusing to run local command
from unexpected source: %s", job->request->source);
+ job->result->httpstatus = 403; /* Forbidden. */
+ update_process_finished_job (job);
+ }
return;
}
diff -Nru liferea-1.14.0/src/update.h liferea-1.14.1/src/update.h
--- liferea-1.14.0/src/update.h 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/update.h 2023-03-12 21:00:51.000000000 +0100
@@ -103,6 +103,7 @@
updateOptionsPtr options; /**< Update options for the request */
gchar *filtercmd; /**< Command will filter output of URL
*/
updateStatePtr updateState; /**< Update state of the requested
object (etags, last modified...) */
+ gboolean allowCommands; /**< Allow this requests to run
commands */
};
/** structure to store results of the processing of an update request */
@@ -229,6 +230,21 @@
void update_request_set_auth_value (UpdateRequest *request, const gchar*
authValue);
/**
+ * Allows *this* request to run local commands.
+ *
+ * At first it may look this flag should be in updateOptions, but we can
+ * take a safer path: feed commands are restricted to a few use cases while
+ * options are propagated to downstream requests (feed enrichment, comments,
+ * etc.), so it is a good idea to prevent these from running commands in the
+ * local system via tricky URLs without needing to validate these options
+ * everywhere (which is error-prone).
+ *
+ * @param request the update request
+ * @param can_run TRUE if the request can run commands, FALSE otherwise.
+ */
+void update_request_allow_commands (UpdateRequest *request, gboolean
allowCommands);
+
+/**
* Creates a new update result for the given update request.
*
* @returns update result (to be free'd using update_result_free())
diff -Nru liferea-1.14.0/src/vfolder.c liferea-1.14.1/src/vfolder.c
--- liferea-1.14.0/src/vfolder.c 2023-01-10 21:12:42.000000000 +0100
+++ liferea-1.14.1/src/vfolder.c 2023-03-12 21:00:51.000000000 +0100
@@ -308,7 +308,7 @@
NODE_CAPABILITY_SHOW_UNREAD_COUNT |
NODE_CAPABILITY_EXPORT_ITEMS,
"vfolder",
- NULL,
+ ICON_VFOLDER,
vfolder_import,
vfolder_export,
vfolder_load,
@@ -320,7 +320,6 @@
vfolder_properties,
vfolder_free
};
- nti.icon = icon_get (ICON_VFOLDER);
return &nti;
}
--- End Message ---