From a44fdbe63e106c6a3aa1c12cdf1361a997f8fccb Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 6 Oct 2013 18:10:19 -0700 Subject: Show html messages as html, using an external filter to strip dangerous tags. --- lurker/common/ConfigFile.cpp | 9 ++++++ lurker/common/ConfigFile.h | 1 + lurker/lurker.conf.in | 7 ++++ lurker/render/message.cpp | 77 +++++++++++++++++++++++++++++++++----------- lurker/ui/default.css | 3 +- lurker/ui/message.xsl | 3 ++ 6 files changed, 80 insertions(+), 20 deletions(-) diff --git a/lurker/common/ConfigFile.cpp b/lurker/common/ConfigFile.cpp index b781cc7..874ed73 100644 --- a/lurker/common/ConfigFile.cpp +++ b/lurker/common/ConfigFile.cpp @@ -925,6 +925,15 @@ int Config::process_command(const string& file, int c, const string& keys, const } xslt = val; } + else if (key == "html_filter") + { + if (lc != "") + { + ERROR << "html_filter command cannot be localized" << endl; + return -1; + } + html_filter = val; + } else if (key == "delete_message") { if (lc != "") diff --git a/lurker/common/ConfigFile.h b/lurker/common/ConfigFile.h index 81c3bea..353eb92 100644 --- a/lurker/common/ConfigFile.h +++ b/lurker/common/ConfigFile.h @@ -161,6 +161,7 @@ class Config string dbdir; int db_umask; string xslt; + string html_filter; string delete_message; string pgpv_mime; string pgpv_inline; diff --git a/lurker/lurker.conf.in b/lurker/lurker.conf.in index 3071c4f..c1ee408 100644 --- a/lurker/lurker.conf.in +++ b/lurker/lurker.conf.in @@ -45,6 +45,13 @@ admin_address = nill@bitbucket.org xslt = xsltproc --nonet - +# The command invoked to clean html of unwanted tags +# +# The deafult is to do nothing! All HTML from HTML bodies is embedded +# into the archive. +# +# htmlfilt = + # The command invoked to delete a message. # # Lurker will feed a password from the UI into this command via stdin. diff --git a/lurker/render/message.cpp b/lurker/render/message.cpp index 481d89c..12fff34 100644 --- a/lurker/render/message.cpp +++ b/lurker/render/message.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -385,6 +386,39 @@ bool handle_signed_mime(ostream& o, DwEntity& e) return true; } +string shell_filter(const string &shell_cmd, const string &html) +{ + char tempname[] = "/tmp/lurkerXXXXXX"; + int fd_tmp = mkstemp(tempname); + + if (fd_tmp == -1) + error(_("Unable to create temporary file: "), strerror(errno), + _("This was needed to do some HTML filtering. Bummer!")); + + char fd_txt[10]; + sprintf(fd_txt, " >&%d", fd_tmp); + string cmd = shell_cmd + fd_txt; + + FILE *filt = popen(cmd.c_str(), "w"); + + if (filt == 0) + error(_("Unable to open command pipe: "), cmd + " (" + strerror(errno) + ")", + _("Oops!")); + + + if (fputs(html.c_str(), filt) == EOF) + error(_("Error writing HTML data to command pipe: "), cmd + " (" + strerror(errno) + ")", + _("Oops!")); + + pclose(filt); + close(fd_tmp); + + std::ifstream readtmp(tempname); + string new_html((std::istreambuf_iterator(readtmp)), std::istreambuf_iterator()); + remove(tempname); + return new_html; +} + void process_text(ostream& o, bool html, const string& charset, const DwString& out, const Config& cfg) { CharsetEscape decode(charset.c_str()); @@ -398,21 +432,28 @@ void process_text(ostream& o, bool html, const string& charset, const DwString& if (html) { - string::size_type start, end; - - start = 0; - while ((end = utf8.find('<', start)) != string::npos) - { - my_service_process(o, utf8.c_str()+start, end-start, cfg); - start = utf8.find('>', end); + if (cfg.html_filter != "") { + utf8 = shell_filter(cfg.html_filter, utf8); + o << ""; + } else { + string::size_type start, end; - if (start == string::npos) break; - ++start; + start = 0; + while ((end = utf8.find('<', start)) != string::npos) + { + my_service_process(o, utf8.c_str()+start, end-start, cfg); + start = utf8.find('>', end); + + if (start == string::npos) break; + ++start; + } + + // deal with half-open tag at end of input + if (start != string::npos) + my_service_process(o, utf8.c_str()+start, utf8.length()-start, cfg); } - - // deal with half-open tag at end of input - if (start != string::npos) - my_service_process(o, utf8.c_str()+start, utf8.length()-start, cfg); } else { @@ -578,18 +619,18 @@ void message_build(ostream& o, DwEntity& e, for (DwBodyPart* p = e.Body().FirstBodyPart(); p != 0; p = p->Next()) { - bool plain = false; + bool html = false; if (p->Headers().HasContentType()) { DwMediaType& mt = p->Headers().ContentType(); - plain = mt.Type() == DwMime::kTypeText && - mt.Subtype() == DwMime::kSubtypePlain; + html = mt.Type() == DwMime::kTypeText && + mt.Subtype() == DwMime::kSubtypeHtml; } if (t.Subtype() != DwMime::kSubtypeAlternative || - p->Next() == 0 || plain) - { // display all parts, or plain, or last + p->Next() == 0 || html) + { // display all parts, or html, or last message_build(o, *p, charset, dump, x, cfg); // if we printed something, we are done diff --git a/lurker/ui/default.css b/lurker/ui/default.css index 0f54507..c2a2989 100644 --- a/lurker/ui/default.css +++ b/lurker/ui/default.css @@ -135,8 +135,7 @@ div.messageBody i.quote { } div.messageBody pre { - font-family: monospace; - font-size: 100%; + white-space: pre-wrap; } /* opsbar = row of them */ diff --git a/lurker/ui/message.xsl b/lurker/ui/message.xsl index d3abec7..b3a20ff 100644 --- a/lurker/ui/message.xsl +++ b/lurker/ui/message.xsl @@ -128,6 +128,9 @@
+ + +      -- cgit v1.2.3