Whitelist config options which support URL patterns

This commit is contained in:
Florian Bruhin 2018-02-20 23:21:24 +01:00
parent 6c5876a494
commit 0d4e20c395
12 changed files with 117 additions and 8 deletions

View File

@ -1447,6 +1447,8 @@ Default:
Enable support for the HTML 5 web application cache feature.
An application cache acts like an HTTP cache in some sense. For documents that use the application cache via JavaScript, the loader engine will first ask the application cache for the contents, before hitting the network.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[true]+
@ -1524,6 +1526,8 @@ This setting is only available with the QtWebKit backend.
=== content.dns_prefetch
Try to pre-fetch DNS entries to speed up browsing.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[true]+
@ -1535,6 +1539,8 @@ This setting is only available with the QtWebKit backend.
Expand each subframe to its contents.
This will flatten all the frames to become one scrollable page.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -1651,6 +1657,8 @@ Default:
=== content.hyperlink_auditing
Enable hyperlink auditing (`<a ping>`).
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -1659,6 +1667,8 @@ Default: +pass:[false]+
=== content.images
Load images automatically in web pages.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[true]+
@ -1676,6 +1686,8 @@ Default: +pass:[true]+
Allow JavaScript to read from or write to the clipboard.
With QtWebEngine, writing the clipboard as response to a user interaction is always allowed.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -1684,6 +1696,8 @@ Default: +pass:[false]+
=== content.javascript.can_close_tabs
Allow JavaScript to close tabs.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -1694,6 +1708,8 @@ This setting is only available with the QtWebKit backend.
=== content.javascript.can_open_tabs_automatically
Allow JavaScript to open new tabs without user interaction.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -1702,6 +1718,8 @@ Default: +pass:[false]+
=== content.javascript.enabled
Enable JavaScript.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[true]+
@ -1741,6 +1759,8 @@ Default: +pass:[true]+
=== content.local_content_can_access_file_urls
Allow locally loaded documents to access other local URLs.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[true]+
@ -1749,6 +1769,8 @@ Default: +pass:[true]+
=== content.local_content_can_access_remote_urls
Allow locally loaded documents to access remote URLs.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -1757,6 +1779,8 @@ Default: +pass:[false]+
=== content.local_storage
Enable support for HTML 5 local storage and Web SQL.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[true]+
@ -1817,6 +1841,8 @@ This setting is only available with the QtWebKit backend.
=== content.plugins
Enable plugins in Web pages.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -1825,6 +1851,8 @@ Default: +pass:[false]+
=== content.print_element_backgrounds
Draw the background color and images also when the page is printed.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[true]+
@ -1889,6 +1917,8 @@ Default: empty
=== content.webgl
Enable WebGL.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[true]+
@ -1906,6 +1936,8 @@ Default: +pass:[false]+
Monitor load requests for cross-site scripting attempts.
Suspicious scripts will be blocked and reported in the inspector's JavaScript console. Enabling this feature might have an impact on performance.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -2379,6 +2411,8 @@ Default: +pass:[false]+
=== input.links_included_in_focus_chain
Include hyperlinks in the keyboard focus chain when tabbing.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[true]+
@ -2406,6 +2440,8 @@ Default: +pass:[false]+
Enable spatial navigation.
Spatial navigation consists in the ability to navigate between focusable elements in a Web page, such as hyperlinks and form controls, by using Left, Right, Up and Down arrow keys. For example, if the user presses the Right key, heuristics determine whether there is an element he might be trying to reach towards the right and which element he probably wants.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -2550,6 +2586,8 @@ Default: +pass:[false]+
Enable smooth scrolling for web pages.
Note smooth scrolling does not work with the `:scroll-px` command.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+
@ -3137,6 +3175,8 @@ Default: +pass:[512]+
=== zoom.text_only
Apply the zoom factor on a frame only to the text or to all content.
This setting supports URL patterns.
Type: <<types,Bool>>
Default: +pass:[false]+

View File

@ -280,6 +280,7 @@ class Config(QObject):
raise configexc.BackendError(opt.name, objects.backend)
opt.typ.to_py(value) # for validation
self._values[opt.name].add(opt.typ.from_obj(value), pattern)
self.changed.emit(opt.name)

View File

@ -48,6 +48,7 @@ class Option:
backends = attr.ib()
raw_backends = attr.ib()
description = attr.ib()
supports_pattern = attr.ib(default=False)
restart = attr.ib(default=False)
@ -197,7 +198,8 @@ def _read_yaml(yaml_data):
migrations = Migrations()
data = utils.yaml_load(yaml_data)
keys = {'type', 'default', 'desc', 'backend', 'restart'}
keys = {'type', 'default', 'desc', 'backend', 'restart',
'supports_pattern'}
for name, option in data.items():
if set(option.keys()) == {'renamed'}:
@ -223,7 +225,9 @@ def _read_yaml(yaml_data):
backends=_parse_yaml_backends(name, backends),
raw_backends=backends if isinstance(backends, dict) else None,
description=option['desc'],
restart=option.get('restart', False))
restart=option.get('restart', False),
supports_pattern=option.get('supports_pattern', False),
)
# Make sure no key shadows another.
for key1 in parsed:

View File

@ -240,6 +240,7 @@ content.cache.appcache:
default: true
type: Bool
backend: QtWebKit
supports_pattern: true
desc: >-
Enable support for the HTML 5 web application cache feature.
@ -298,12 +299,14 @@ content.dns_prefetch:
default: true
type: Bool
backend: QtWebKit
supports_pattern: true
desc: Try to pre-fetch DNS entries to speed up browsing.
content.frame_flattening:
default: false
type: Bool
backend: QtWebKit
supports_pattern: true
desc: >-
Expand each subframe to its contents.
@ -459,12 +462,14 @@ content.host_blocking.whitelist:
content.hyperlink_auditing:
default: false
type: Bool
supports_pattern: true
desc: Enable hyperlink auditing (`<a ping>`).
content.images:
default: true
type: Bool
desc: Load images automatically in web pages.
supports_pattern: true
content.javascript.alert:
default: true
@ -474,6 +479,7 @@ content.javascript.alert:
content.javascript.can_access_clipboard:
default: false
type: Bool
supports_pattern: true
desc: >-
Allow JavaScript to read from or write to the clipboard.
@ -484,16 +490,19 @@ content.javascript.can_close_tabs:
default: false
type: Bool
backend: QtWebKit
supports_pattern: true
desc: Allow JavaScript to close tabs.
content.javascript.can_open_tabs_automatically:
default: false
type: Bool
supports_pattern: true
desc: Allow JavaScript to open new tabs without user interaction.
content.javascript.enabled:
default: true
type: Bool
supports_pattern: true
desc: Enable JavaScript.
content.javascript.log:
@ -536,16 +545,19 @@ content.javascript.prompt:
content.local_content_can_access_remote_urls:
default: false
type: Bool
supports_pattern: true
desc: Allow locally loaded documents to access remote URLs.
content.local_content_can_access_file_urls:
default: true
type: Bool
supports_pattern: true
desc: Allow locally loaded documents to access other local URLs.
content.local_storage:
default: true
type: Bool
supports_pattern: true
desc: Enable support for HTML 5 local storage and Web SQL.
content.media_capture:
@ -583,6 +595,7 @@ content.pdfjs:
content.plugins:
default: false
type: Bool
supports_pattern: true
desc: Enable plugins in Web pages.
content.print_element_backgrounds:
@ -591,6 +604,7 @@ content.print_element_backgrounds:
backend:
QtWebKit: true
QtWebEngine: Qt 5.8
supports_pattern: true
desc: >-
Draw the background color and images also when the page is printed.
@ -631,11 +645,13 @@ content.user_stylesheets:
content.webgl:
default: true
type: Bool
supports_pattern: true
desc: Enable WebGL.
content.xss_auditing:
type: Bool
default: false
supports_pattern: true
desc: >-
Monitor load requests for cross-site scripting attempts.
@ -978,6 +994,7 @@ input.insert_mode.plugins:
input.links_included_in_focus_chain:
default: true
type: Bool
supports_pattern: true
desc: Include hyperlinks in the keyboard focus chain when tabbing.
input.partial_timeout:
@ -1003,6 +1020,7 @@ input.rocker_gestures:
input.spatial_navigation:
default: false
type: Bool
supports_pattern: true
desc: >-
Enable spatial navigation.
@ -1083,6 +1101,7 @@ scrolling.bar:
scrolling.smooth:
type: Bool
default: false
supports_pattern: true
desc: >-
Enable smooth scrolling for web pages.
@ -1557,6 +1576,7 @@ zoom.text_only:
type: Bool
default: false
backend: QtWebKit
supports_pattern: true
desc: Apply the zoom factor on a frame only to the text or to all content.
## colors

View File

@ -40,6 +40,15 @@ class BackendError(Error):
"backend!".format(name, backend.name))
class NoPatternError(Error):
"""Raised when the given setting does not support URL patterns."""
def __init__(self, name):
super().__init__("The {} setting does not support URL patterns!"
.format(name))
class ValidationError(Error):
"""Raised when a value for a config type was invalid.

View File

@ -24,6 +24,7 @@
import attr
from qutebrowser.utils import utils
from qutebrowser.config import configexc
class _UnsetObject:
@ -107,8 +108,14 @@ class Values:
"""Check whether this value is customized."""
return bool(self._values)
def _check_pattern_support(self, arg):
"""Make sure patterns are supported if one was given."""
if arg is not None and not self.opt.supports_pattern:
raise configexc.NoPatternError(self.opt.name)
def add(self, value, pattern=None):
"""Add a value with the given pattern to the list of values."""
self._check_pattern_support(pattern)
self.remove(pattern)
scoped = ScopedValue(value, pattern)
self._values.append(scoped)
@ -119,6 +126,7 @@ class Values:
If a matching pattern was removed, True is returned.
If no matching pattern was found, False is returned.
"""
self._check_pattern_support(pattern)
old_len = len(self._values)
self._values = [v for v in self._values if v.pattern != pattern]
return old_len != len(self._values)
@ -146,6 +154,7 @@ class Values:
With fallback=True, the global/default setting is returned.
With fallback=False, UNSET is returned.
"""
self._check_pattern_support(url)
if url is not None:
for scoped in reversed(self._values):
if scoped.pattern is not None and scoped.pattern.matches(url):
@ -165,6 +174,7 @@ class Values:
With fallback=True, the global/default setting is returned.
With fallback=False, UNSET is returned.
"""
self._check_pattern_support(pattern)
if pattern is not None:
for scoped in reversed(self._values):
if scoped.pattern == pattern:

View File

@ -225,8 +225,9 @@ def update_for_tab(mappings, tab, url):
for values in config.instance:
if values.opt.name not in mappings:
continue
if not values.opt.supports_pattern:
continue
# FIXME:conf handle settings != None with global/static setters
mapping = mappings[values.opt.name]
value = values.get_for_url(url, fallback=False)
@ -237,10 +238,7 @@ def update_for_tab(mappings, tab, url):
settings = tab._widget.settings() # pylint: disable=protected-access
if value is configutils.UNSET:
try:
mapping.unset(settings=settings)
except NotImplementedError:
pass
mapping.unset(settings=settings)
else:
mapping.set(value, settings=settings)

View File

@ -419,6 +419,8 @@ def _generate_setting_option(f, opt):
f.write(opt.description + "\n")
if opt.restart:
f.write("This setting requires a restart.\n")
if opt.supports_pattern:
f.write("\nThis setting supports URL patterns.\n")
f.write("\n")
typ = opt.typ.get_name().replace(',', '&#44;')
f.write('Type: <<types,{typ}>>\n'.format(typ=typ))

View File

@ -581,6 +581,14 @@ class TestConfig:
meth('content.cookies.accept', 'all')
assert not conf._values['content.cookies.accept']
@pytest.mark.parametrize('method', ['set_obj', 'set_str'])
def test_set_no_pattern(self, conf, method, qtbot):
meth = getattr(conf, method)
pattern = urlmatch.UrlPattern('https://www.example.com/')
with pytest.raises(configexc.NoPatternError):
with qtbot.assert_not_emitted(conf.changed):
meth('colors.statusbar.normal.bg', '#abcdef', pattern=pattern)
def test_dump_userconfig(self, conf):
conf.set_obj('content.plugins', True)
conf.set_obj('content.headers.custom', {'X-Foo': 'bar'})

View File

@ -104,6 +104,16 @@ class TestSet:
match='Error while parsing :/: No scheme given'):
commands.set(0, option, 'false', pattern=':/')
def test_set_no_pattern(self, monkeypatch, commands):
"""Run ':set --pattern=*://* colors.statusbar.normal.bg #abcdef.
Should show an error as patterns are unsupported.
"""
with pytest.raises(cmdexc.CommandError,
match='does not support URL patterns'):
commands.set(0, 'colors.statusbar.normal.bg', '#abcdef',
pattern='*://*')
@pytest.mark.parametrize('temp', [True, False])
def test_set_temp_override(self, commands, config_stub, yaml_value, temp):
"""Invoking :set twice.

View File

@ -54,6 +54,12 @@ def test_backend_error():
assert str(e) == expected
def test_no_pattern_error():
e = configexc.NoPatternError('foo')
expected = "The foo setting does not support URL patterns!"
assert str(e) == expected
def test_desc_with_text():
"""Test ConfigErrorDesc.with_text."""
old = configexc.ConfigErrorDesc("Error text", Exception("Exception text"))

View File

@ -38,7 +38,8 @@ def test_unset_object_repr():
def opt():
return configdata.Option(name='example.option', typ=configtypes.String(),
default='default value', backends=None,
raw_backends=None, description=None)
raw_backends=None, description=None,
supports_pattern=True)
@pytest.fixture