diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py
index 4525e58c2..d4e8a3514 100644
--- a/qutebrowser/config/configtypes.py
+++ b/qutebrowser/config/configtypes.py
@@ -37,7 +37,7 @@ from PyQt5.QtWidgets import QTabWidget, QTabBar
from qutebrowser.commands import cmdutils
from qutebrowser.config import configexc
-from qutebrowser.utils import standarddir, utils
+from qutebrowser.utils import standarddir, utils, urlutils
SYSTEM_PROXY = object() # Return value for Proxy type
@@ -1177,8 +1177,7 @@ class UserStyleSheet(File):
if path is not None and os.path.exists(path):
return QUrl.fromLocalFile(path)
else:
- data = base64.b64encode(value.encode('utf-8')).decode('ascii')
- return QUrl("data:text/css;charset=utf-8;base64,{}".format(data))
+ return urlutils.data_url('text/css', value.encode('utf-8'))
def validate(self, value):
self._basic_validation(value)
diff --git a/qutebrowser/utils/jinja.py b/qutebrowser/utils/jinja.py
index a8d746b58..0487f5ddb 100644
--- a/qutebrowser/utils/jinja.py
+++ b/qutebrowser/utils/jinja.py
@@ -82,8 +82,7 @@ def data_url(path):
filename = utils.resource_filename(path)
mimetype = mimetypes.guess_type(filename)
assert mimetype is not None, path
- b64 = base64.b64encode(data).decode('ascii')
- return 'data:{};charset=utf-8;base64,{}'.format(mimetype[0], b64)
+ return urlutils.data_url(mimetype[0], data).toString()
def render(template, **kwargs):
diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py
index 5417d9a7a..6a24ceb82 100644
--- a/qutebrowser/utils/urlutils.py
+++ b/qutebrowser/utils/urlutils.py
@@ -20,6 +20,7 @@
"""Utils regarding URL handling."""
import re
+import base64
import os.path
import ipaddress
import posixpath
@@ -580,3 +581,11 @@ def file_url(path):
path: The absolute path to the local file
"""
return QUrl.fromLocalFile(path).toString(QUrl.FullyEncoded)
+
+
+def data_url(mimetype, data):
+ """Get a data: QUrl for the given data."""
+ b64 = base64.b64encode(data).decode('ascii')
+ url = QUrl('data:{};base64,{}'.format(mimetype, b64))
+ qtutils.ensure_valid(url)
+ return url
diff --git a/tests/unit/browser/webkit/test_history.py b/tests/unit/browser/webkit/test_history.py
index 7b2b6f53a..94169e40e 100644
--- a/tests/unit/browser/webkit/test_history.py
+++ b/tests/unit/browser/webkit/test_history.py
@@ -19,7 +19,6 @@
"""Tests for the global page history."""
-import base64
import logging
import pytest
@@ -28,7 +27,7 @@ from hypothesis import strategies
from PyQt5.QtCore import QUrl
from qutebrowser.browser import history
-from qutebrowser.utils import objreg
+from qutebrowser.utils import objreg, urlutils
class FakeWebHistory:
@@ -375,9 +374,8 @@ def hist_interface():
def test_history_interface(qtbot, webview, hist_interface):
- html = "foo"
- data = base64.b64encode(html.encode('utf-8')).decode('ascii')
- url = QUrl("data:text/html;charset=utf-8;base64,{}".format(data))
+ html = b"foo"
+ url = urlutils.data_url('text/html', html)
with qtbot.waitSignal(webview.loadFinished):
webview.load(url)
diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py
index f9d86f0ce..2f0c3ce7a 100644
--- a/tests/unit/config/test_configtypes.py
+++ b/tests/unit/config/test_configtypes.py
@@ -1350,7 +1350,7 @@ class TestFileAndUserStyleSheet:
def test_transform_userstylesheet_base64(self, monkeypatch):
"""Test transform with a data string."""
b64 = base64.b64encode(b"test").decode('ascii')
- url = QUrl("data:text/css;charset=utf-8;base64,{}".format(b64))
+ url = QUrl("data:text/css;base64,{}".format(b64))
assert configtypes.UserStyleSheet().transform("test") == url
diff --git a/tests/unit/utils/test_jinja.py b/tests/unit/utils/test_jinja.py
index eb7a621fc..e951e3994 100644
--- a/tests/unit/utils/test_jinja.py
+++ b/tests/unit/utils/test_jinja.py
@@ -102,7 +102,7 @@ def test_data_url():
print(data)
url = QUrl(data)
assert url.isValid()
- assert data == 'data:text/plain;charset=utf-8;base64,Zm9v' # 'foo'
+ assert data == 'data:text/plain;base64,Zm9v' # 'foo'
def test_not_found():
diff --git a/tests/unit/utils/test_urlutils.py b/tests/unit/utils/test_urlutils.py
index f98ba65d6..984971b3c 100644
--- a/tests/unit/utils/test_urlutils.py
+++ b/tests/unit/utils/test_urlutils.py
@@ -731,3 +731,8 @@ class TestIncDecNumber:
def test_file_url():
assert urlutils.file_url('/foo/bar') == 'file:///foo/bar'
+
+
+def test_data_url():
+ url = urlutils.data_url('text/plain', b'foo')
+ assert url == QUrl('data:text/plain;base64,Zm9v')