From f9327731b85cb80d3f7d370b67f11db29d456b27 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 12 Sep 2018 23:54:32 +0200 Subject: [PATCH] Handle UTF-8 byte order marks in Greasemonkey scripts See e.g. https://github.com/jerone/UserScripts/issues/135 --- doc/changelog.asciidoc | 1 + qutebrowser/browser/greasemonkey.py | 2 +- tests/unit/javascript/test_greasemonkey.py | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 57c95c8f3..0ec1d8003 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -59,6 +59,7 @@ Fixed ~~~~~ - Error when passing a substring with spaces to `:tab-take`. +- Greasemonkey scripts which start with an UTF-8 BOM are now handled correctly. Removed ~~~~~~~ diff --git a/qutebrowser/browser/greasemonkey.py b/qutebrowser/browser/greasemonkey.py index 7e5ff7f5b..d48e6db1f 100644 --- a/qutebrowser/browser/greasemonkey.py +++ b/qutebrowser/browser/greasemonkey.py @@ -234,7 +234,7 @@ class GreasemonkeyManager(QObject): if not os.path.isfile(script_filename): continue script_path = os.path.join(scripts_dir, script_filename) - with open(script_path, encoding='utf-8') as script_file: + with open(script_path, encoding='utf-8-sig') as script_file: script = GreasemonkeyScript.parse(script_file.read()) if not script.name: script.name = script_filename diff --git a/tests/unit/javascript/test_greasemonkey.py b/tests/unit/javascript/test_greasemonkey.py index 15fa4321e..79983a5c9 100644 --- a/tests/unit/javascript/test_greasemonkey.py +++ b/tests/unit/javascript/test_greasemonkey.py @@ -130,6 +130,26 @@ def test_load_emits_signal(qtbot): gm_manager.load_scripts() +def test_utf8_bom(): + """Make sure UTF-8 BOMs are stripped from scripts. + + If we don't strip them, we'll have a BOM in the middle of the file, causing + QtWebEngine to not catch the "// ==UserScript==" line. + """ + script = textwrap.dedent(""" + \N{BYTE ORDER MARK}// ==UserScript== + // @name qutebrowser test userscript + // ==/UserScript== + """.lstrip('\n')) + _save_script(script, 'bom.user.js') + gm_manager = greasemonkey.GreasemonkeyManager() + + scripts = gm_manager.all_scripts() + assert len(scripts) == 1 + script = scripts[0] + assert '// ==UserScript==' in script.code().splitlines() + + def test_required_scripts_are_included(download_stub, tmpdir): test_require_script = textwrap.dedent(""" // ==UserScript==