From 6557681a6c2d010d48ad63987327b1ce08fc3d28 Mon Sep 17 00:00:00 2001 From: mailchuck Date: Tue, 15 Dec 2015 01:24:10 +0100 Subject: [PATCH] Message has safe link opening Links in message body (if in HTML mode) now open, but it asks for a confirmation in a dialog box. Fixes #27 --- src/bitmessageqt/messageview.py | 21 +++++++++++++++++---- src/bitmessageqt/safehtmlparser.py | 8 ++++++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index 94e73ff1..049a2706 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -2,16 +2,21 @@ from PyQt4 import QtCore, QtGui from safehtmlparser import * -class MessageView(QtGui.QTextEdit): +class MessageView(QtGui.QTextBrowser): MODE_PLAIN = 0 MODE_HTML = 1 TEXT_PLAIN = "HTML detected, click here to display" TEXT_HTML = "Click here to disable HTML" + CONFIRM_TITLE = "Follow external link" + CONFIRM_TEXT = "The link \"%1\" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure?" def __init__(self, parent = 0): super(MessageView, self).__init__(parent) self.mode = MessageView.MODE_PLAIN self.html = None + self.setOpenExternalLinks(False) + self.setOpenLinks(False) + self.anchorClicked.connect(self.confirmURL) def mousePressEvent(self, event): #text = textCursor.block().text() @@ -22,18 +27,26 @@ class MessageView(QtGui.QTextEdit): self.showPlain() else: super(MessageView, self).mousePressEvent(event) + + def confirmURL(self, link): + reply = QtGui.QMessageBox.question(self, + QtGui.QApplication.translate(type(self).__name__, MessageView.CONFIRM_TITLE), + QtGui.QApplication.translate(type(self).__name__, MessageView.CONFIRM_TEXT).arg(str(link.toString())), + QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) + if reply == QtGui.QMessageBox.Yes: + QtGui.QDesktopServices.openUrl(link) def showPlain(self): self.mode = MessageView.MODE_PLAIN out = self.html.raw if self.html.has_html: - out = "
" + QtGui.QApplication.translate("MessageView", MessageView.TEXT_PLAIN) + "

" + out - self.setHtml(QtCore.QString(out)) + out = "
" + QtGui.QApplication.translate(type(self).__name__, MessageView.TEXT_PLAIN) + "

" + out + self.setHtml(QtCore.QString(out)) def showHTML(self): self.mode = MessageView.MODE_HTML out = self.html.sanitised - out = "
" + QtGui.QApplication.translate("MessageView", MessageView.TEXT_HTML) + "

" + out + out = "
" + QtGui.QApplication.translate(type(self).__name__, MessageView.TEXT_HTML) + "

" + out self.setHtml(QtCore.QString(out)) def setContent(self, data): diff --git a/src/bitmessageqt/safehtmlparser.py b/src/bitmessageqt/safehtmlparser.py index e22a776f..c058dd6f 100644 --- a/src/bitmessageqt/safehtmlparser.py +++ b/src/bitmessageqt/safehtmlparser.py @@ -39,7 +39,9 @@ class SafeHTMLParser(HTMLParser): for attr in attrs: if tag == "img" and attr[0] == "src" and not self.allow_picture: attr[1] = "" - self.sanitised += " " + quote_plus(attr[0]) + "=\"" + attr[1] + "\"" + self.sanitised += " " + quote_plus(attr[0]) + if attr[1] is not None: + self.sanitised += "=\"" + attr[1] + "\"" if inspect.stack()[1][3] == "handle_startendtag": self.sanitised += "/" self.sanitised += ">" @@ -53,7 +55,9 @@ class SafeHTMLParser(HTMLParser): for attr in attrs: if tag == "img" and attr[0] == "src" and not self.allow_picture: attr[1] = "" - self.raw += " " + attr[0] + "="" + attr[1] + """ + self.raw += " " + attr[0] + if attr[1] is not None: + self.raw + "="" + attr[1] + """ if inspect.stack()[1][3] == "handle_startendtag": self.raw += "/" self.raw += ">"