changeset 828:6cc8f27447ee

plugin links: improve printing Trim title and remove predefined XML entities. closes #937 closes #946
author David Demelier <markand@malikania.fr>
date Tue, 05 Feb 2019 20:24:00 +0100
parents 2ecff01d4277
children 963feffc07fe
files plugins/links/requester.cpp
diffstat 1 files changed, 55 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/links/requester.cpp	Tue Jan 15 20:13:44 2019 +0100
+++ b/plugins/links/requester.cpp	Tue Feb 05 20:24:00 2019 +0100
@@ -17,6 +17,10 @@
  */
 
 #include <regex>
+#include <string_view>
+#include <unordered_map>
+
+#include <boost/algorithm/string/trim_all.hpp>
 
 #include <irccd/daemon/server.hpp>
 
@@ -67,6 +71,50 @@
 
 namespace irccd {
 
+namespace {
+
+auto unentities(const std::string& input) -> std::string
+{
+	static const std::unordered_map<std::string_view, char> predef{
+		{ "quot",       '"'     },
+		{ "amp",        '&'     },
+		{ "apos",       '\''    },
+		{ "lt",         '<'     },
+		{ "gt",         '>'     }
+	};
+
+	std::string output;
+	std::string entity;
+
+	output.reserve(input.size());
+	entity.reserve(6);
+
+	for (auto it = input.begin(); it != input.end(); ) {
+		if (*it != '&') {
+			output.push_back(*it++);
+			continue;
+		}
+
+		entity.clear();
+
+		for (++it; it != input.end() && *it != ';'; ++it)
+			entity.push_back(*it);
+		if (const auto e = predef.find(entity); e != predef.end())
+			output.push_back(e->second);
+		if (it != input.end())
+			++it;
+	}
+
+	return output;
+}
+
+auto trim(std::string input) -> std::string
+{
+	return boost::algorithm::trim_all_copy(input);
+}
+
+} // !namespace
+
 void requester::notify(const string& title)
 {
 	subst subst;
@@ -91,8 +139,13 @@
 	string data(res_.body().data());
 	smatch match;
 
-	if (regex_search(data, match, regex))
-		notify(match[1]);
+	// Remove XML predefined entities.
+	if (regex_search(data, match, regex)) {
+		const auto title = trim(unentities(match[1]));
+
+		if (title.size() > 0)
+			notify(title);
+	}
 }
 
 void requester::handle_read(const error_code& code)