diff --git a/src/calibre/ebooks/__init__.py b/src/calibre/ebooks/__init__.py index 8053c9ba5a..785d964ed9 100644 --- a/src/calibre/ebooks/__init__.py +++ b/src/calibre/ebooks/__init__.py @@ -165,20 +165,15 @@ def render_html_data(path_to_html, width, height): def render_html(path_to_html, width=590, height=750, as_xhtml=True): from PyQt5.QtWebKitWidgets import QWebPage - from PyQt5.QtWebKit import QWebSettings from PyQt5.Qt import QEventLoop, QPalette, Qt, QUrl, QSize - from calibre.gui2 import is_ok_to_use_qt + from calibre.gui2 import is_ok_to_use_qt, secure_web_page if not is_ok_to_use_qt(): return None path_to_html = os.path.abspath(path_to_html) with CurrentDir(os.path.dirname(path_to_html)): page = QWebPage() settings = page.settings() - settings.setAttribute(QWebSettings.JavaEnabled, False) - settings.setAttribute(QWebSettings.PluginsEnabled, False) - settings.setAttribute(QWebSettings.JavascriptCanOpenWindows, False) - settings.setAttribute(QWebSettings.JavascriptCanAccessClipboard, False) - settings.setAttribute(QWebSettings.LocalContentCanAccessFileUrls, False) # ensure javascript cannot read from local files + secure_web_page(settings) pal = page.palette() pal.setBrush(QPalette.Background, Qt.white) page.setPalette(pal) diff --git a/src/calibre/ebooks/lrf/html/table_as_image.py b/src/calibre/ebooks/lrf/html/table_as_image.py index 7a22743e91..d8dcd40fee 100644 --- a/src/calibre/ebooks/lrf/html/table_as_image.py +++ b/src/calibre/ebooks/lrf/html/table_as_image.py @@ -19,6 +19,7 @@ class HTMLTableRenderer(QObject): `width, height`: page width and height in pixels `base_dir`: The directory in which the HTML file that contains the table resides ''' + from calibre.gui2 import secure_web_page QObject.__init__(self) self.app = None @@ -28,6 +29,7 @@ class HTMLTableRenderer(QObject): self.tdir = tempfile.mkdtemp(prefix='calibre_render_table') self.loop = QEventLoop() self.page = QWebPage() + secure_web_page(self.page.settings()) self.page.loadFinished.connect(self.render_html) self.page.mainFrame().setTextSizeMultiplier(factor) self.page.mainFrame().setHtml(html, diff --git a/src/calibre/ebooks/pdf/render/from_html.py b/src/calibre/ebooks/pdf/render/from_html.py index d54ca1f4df..8bda12395d 100644 --- a/src/calibre/ebooks/pdf/render/from_html.py +++ b/src/calibre/ebooks/pdf/render/from_html.py @@ -65,6 +65,7 @@ def get_page_size(opts, for_comic=False): # {{{ class Page(QWebPage): # {{{ def __init__(self, opts, log): + from calibre.gui2 import secure_web_page self.log = log QWebPage.__init__(self) settings = self.settings() @@ -74,11 +75,7 @@ class Page(QWebPage): # {{{ opts.pdf_mono_font_size) settings.setFontSize(QWebSettings.MinimumLogicalFontSize, 8) settings.setFontSize(QWebSettings.MinimumFontSize, 8) - settings.setAttribute(QWebSettings.JavaEnabled, False) - settings.setAttribute(QWebSettings.PluginsEnabled, False) - settings.setAttribute(QWebSettings.JavascriptCanOpenWindows, False) - settings.setAttribute(QWebSettings.JavascriptCanAccessClipboard, False) - settings.setAttribute(QWebSettings.LocalContentCanAccessFileUrls, False) # ensure javascript cannot read from local files + secure_web_page(settings) std = {'serif':opts.pdf_serif_family, 'sans':opts.pdf_sans_family, 'mono':opts.pdf_mono_family}.get(opts.pdf_standard_font, diff --git a/src/calibre/ebooks/pdf/writer.py b/src/calibre/ebooks/pdf/writer.py index 07d158989b..7e3ffe614c 100644 --- a/src/calibre/ebooks/pdf/writer.py +++ b/src/calibre/ebooks/pdf/writer.py @@ -106,9 +106,11 @@ def draw_image_page(printer, painter, p, preserve_aspect_ratio=True): class Page(QWebPage): # {{{ def __init__(self, opts, log): + from calibre.gui2 import secure_web_page self.log = log QWebPage.__init__(self) settings = self.settings() + secure_web_page(settings) settings.setFontSize(QWebSettings.DefaultFontSize, opts.pdf_default_font_size) settings.setFontSize(QWebSettings.DefaultFixedFontSize, @@ -396,5 +398,3 @@ class ImagePDFWriter(object): # {{{ painter.end() # }}} - - diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 549390e374..867c93e243 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -1401,3 +1401,16 @@ def event_type_name(ev_or_etype): if num == etype: return name return 'UnknownEventType' + + +def secure_web_page(qwebpage_or_qwebsettings): + from PyQt5.QtWebKit import QWebSettings + settings = qwebpage_or_qwebsettings if isinstance(qwebpage_or_qwebsettings, QWebSettings) else qwebpage_or_qwebsettings.settings() + settings.setAttribute(QWebSettings.JavaEnabled, False) + settings.setAttribute(QWebSettings.PluginsEnabled, False) + settings.setAttribute(QWebSettings.JavascriptCanOpenWindows, False) + settings.setAttribute(QWebSettings.JavascriptCanAccessClipboard, False) + settings.setAttribute(QWebSettings.LocalContentCanAccessFileUrls, False) # ensure javascript cannot read from local files + settings.setAttribute(QWebSettings.NotificationsEnabled, False) + settings.setThirdPartyCookiePolicy(QWebSettings.AlwaysBlockThirdPartyCookies) + return settings diff --git a/src/calibre/gui2/comments_editor.py b/src/calibre/gui2/comments_editor.py index 5182e6d842..e6ec5d939f 100644 --- a/src/calibre/gui2/comments_editor.py +++ b/src/calibre/gui2/comments_editor.py @@ -19,7 +19,7 @@ from PyQt5.QtWebKitWidgets import QWebView, QWebPage from calibre.ebooks.chardet import xml_to_unicode from calibre import xml_replace_entities, prepare_string_for_xml -from calibre.gui2 import open_url, error_dialog, choose_files, gprefs, NO_URL_FORMATTING +from calibre.gui2 import open_url, error_dialog, choose_files, gprefs, NO_URL_FORMATTING, secure_web_page from calibre.utils.soupparser import fromstring from calibre.utils.config import tweaks from calibre.utils.imghdr import what @@ -171,6 +171,7 @@ class EditorWidget(QWebView): # {{{ self.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) self.page().linkClicked.connect(self.link_clicked) + secure_web_page(self.page().settings()) self.setHtml('') self.set_readonly(False) @@ -412,6 +413,8 @@ class EditorWidget(QWebView): # {{{ # }}} # Highlighter {{{ + + State_Text = -1 State_DocType = 0 State_Comment = 1 @@ -791,6 +794,7 @@ class Editor(QWidget): # {{{ # }}} + if __name__ == '__main__': app = QApplication([]) w = Editor() diff --git a/src/calibre/gui2/toc/location.py b/src/calibre/gui2/toc/location.py index 763f6f3558..b850259b35 100644 --- a/src/calibre/gui2/toc/location.py +++ b/src/calibre/gui2/toc/location.py @@ -17,7 +17,7 @@ from PyQt5.QtWebKitWidgets import QWebView, QWebPage from PyQt5.QtWebKit import QWebElement from calibre.ebooks.oeb.display.webview import load_html -from calibre.gui2 import error_dialog, question_dialog, gprefs +from calibre.gui2 import error_dialog, question_dialog, gprefs, secure_web_page from calibre.utils.logging import default_log @@ -28,6 +28,7 @@ class Page(QWebPage): # {{{ def __init__(self): self.log = default_log QWebPage.__init__(self) + secure_web_page(self.settings()) self.js = None self.evaljs = self.mainFrame().evaluateJavaScript self.bridge_value = None diff --git a/src/calibre/gui2/tweak_book/preview.py b/src/calibre/gui2/tweak_book/preview.py index c023ae991a..f607ffe58a 100644 --- a/src/calibre/gui2/tweak_book/preview.py +++ b/src/calibre/gui2/tweak_book/preview.py @@ -25,7 +25,7 @@ from calibre import prints from calibre.constants import FAKE_PROTOCOL, FAKE_HOST from calibre.ebooks.oeb.polish.parsing import parse from calibre.ebooks.oeb.base import serialize, OEB_DOCS -from calibre.gui2 import error_dialog, open_url, NO_URL_FORMATTING +from calibre.gui2 import error_dialog, open_url, NO_URL_FORMATTING, secure_web_page from calibre.gui2.tweak_book import current_container, editors, tprefs, actions, TOP from calibre.gui2.viewer.documentview import apply_settings from calibre.gui2.viewer.config import config @@ -262,12 +262,8 @@ class WebPage(QWebPage): settings = self.settings() apply_settings(settings, config().parse()) settings.setMaximumPagesInCache(0) - settings.setAttribute(settings.JavaEnabled, False) - settings.setAttribute(settings.PluginsEnabled, False) + secure_web_page(settings) settings.setAttribute(settings.PrivateBrowsingEnabled, True) - settings.setAttribute(settings.JavascriptCanOpenWindows, False) - settings.setAttribute(settings.JavascriptCanAccessClipboard, False) - settings.setAttribute(settings.LocalContentCanAccessFileUrls, False) # ensure javascript cannot read from local files settings.setAttribute(settings.LinksIncludedInFocusChain, False) settings.setAttribute(settings.DeveloperExtrasEnabled, True) settings.setDefaultTextEncoding('utf-8') diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index a45ff8962b..ac41b05776 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -18,7 +18,7 @@ from PyQt5.QtWebKit import QWebSettings, QWebElement from calibre.gui2.viewer.flip import SlideFlip from calibre.gui2.shortcuts import Shortcuts -from calibre.gui2 import open_url +from calibre.gui2 import open_url, secure_web_page from calibre import prints from calibre.customize.ui import all_viewer_plugins from calibre.gui2.viewer.keys import SHORTCUTS @@ -48,16 +48,9 @@ def apply_settings(settings, opts): def apply_basic_settings(settings): - # Security - settings.setAttribute(QWebSettings.JavaEnabled, False) - settings.setAttribute(QWebSettings.PluginsEnabled, False) - settings.setAttribute(QWebSettings.JavascriptCanOpenWindows, False) - settings.setAttribute(QWebSettings.JavascriptCanAccessClipboard, False) - settings.setAttribute(QWebSettings.LocalContentCanAccessFileUrls, False) # ensure javascript cannot read from local files + secure_web_page(settings) # PrivateBrowsing disables console messages # settings.setAttribute(QWebSettings.PrivateBrowsingEnabled, True) - settings.setAttribute(QWebSettings.NotificationsEnabled, False) - settings.setThirdPartyCookiePolicy(QWebSettings.AlwaysBlockThirdPartyCookies) # Miscellaneous settings.setAttribute(QWebSettings.LinksIncludedInFocusChain, True)