Merge branch 'qutebrowser:master' into master

This commit is contained in:
mkonig 2022-03-09 09:19:41 +01:00 committed by GitHub
commit 75a714e7f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 387 additions and 140 deletions

View File

@ -47,6 +47,9 @@ Changed
than `rofi` to ask for a password.
- The `content.headers.custom` setting now accepts empty strings as values,
resulting in an empty header being sent.
- Renamed settings:
* `qt.low_end_device_mode` -> `qt.chromium.low_end_device_mode`
* `qt.process_model` -> `qt.chromium.process_model`
Added
~~~~~
@ -55,6 +58,9 @@ Added
more emacs-like bindings.
- New `{relative_index}` field for `tabs.title.format` (and `.pinned_format`)
which shows relative tab numbers.
- New `input.mode_override` option which allows overriding the current mode
based on the new URL when navigating or switching tabs.
- New `qt.chromium.sandboxing` setting which allows to disable Chromium's sandboxing (mainly intended for development and testing)
Fixed
~~~~~

View File

@ -407,7 +407,7 @@ Pre-built colorschemes
- A collection of https://github.com/chriskempson/base16[base16] color-schemes can be found in https://github.com/theova/base16-qutebrowser[base16-qutebrowser] and used with https://github.com/AuditeMarlow/base16-manager[base16-manager].
- Another collection: https://github.com/leosolid/qutebrowser-themes[qutebrowser-themes]
- https://gitlab.com/jjzmajic/qutewal[Pywal integration]
- Pywal integration: https://gitlab.com/jjzmajic/qutewal[qutewal], https://github.com/makman12/pywalQute[pywalQute]
- https://github.com/arcticicestudio/nord[Nord]: https://github.com/Linuus/nord-qutebrowser[Linuus], https://github.com/KnownAsDon/QuteBrowser-Nord-Theme[KnownAsDon]
- https://github.com/dracula/qutebrowser-dracula-theme[Dracula]
- https://gitlab.com/lovetocode999/selenized-qutebrowser[Selenized]

View File

@ -271,6 +271,7 @@
|<<input.links_included_in_focus_chain,input.links_included_in_focus_chain>>|Include hyperlinks in the keyboard focus chain when tabbing.
|<<input.match_counts,input.match_counts>>|Interpret number prefixes as counts for bindings.
|<<input.media_keys,input.media_keys>>|Whether the underlying Chromium should handle media keys.
|<<input.mode_override,input.mode_override>>|Mode to change to when focusing on a tab/URL changes.
|<<input.mouse.back_forward_buttons,input.mouse.back_forward_buttons>>|Enable back and forward buttons on the mouse.
|<<input.mouse.rocker_gestures,input.mouse.rocker_gestures>>|Enable Opera-like mouse rocker gestures.
|<<input.partial_timeout,input.partial_timeout>>|Timeout (in milliseconds) for partially typed key bindings.
@ -286,13 +287,14 @@
|<<prompt.filebrowser,prompt.filebrowser>>|Show a filebrowser in download prompts.
|<<prompt.radius,prompt.radius>>|Rounding radius (in pixels) for the edges of prompts.
|<<qt.args,qt.args>>|Additional arguments to pass to Qt, without leading `--`.
|<<qt.chromium.low_end_device_mode,qt.chromium.low_end_device_mode>>|When to use Chromium's low-end device mode.
|<<qt.chromium.process_model,qt.chromium.process_model>>|Which Chromium process model to use.
|<<qt.chromium.sandboxing,qt.chromium.sandboxing>>|What sandboxing mechanisms in Chromium to use.
|<<qt.environ,qt.environ>>|Additional environment variables to set.
|<<qt.force_platform,qt.force_platform>>|Force a Qt platform to use.
|<<qt.force_platformtheme,qt.force_platformtheme>>|Force a Qt platformtheme to use.
|<<qt.force_software_rendering,qt.force_software_rendering>>|Force software rendering for QtWebEngine.
|<<qt.highdpi,qt.highdpi>>|Turn on Qt HighDPI scaling.
|<<qt.low_end_device_mode,qt.low_end_device_mode>>|When to use Chromium's low-end device mode.
|<<qt.process_model,qt.process_model>>|Which Chromium process model to use.
|<<qt.workarounds.locale,qt.workarounds.locale>>|Work around locale parsing issues in QtWebEngine 5.15.3.
|<<qt.workarounds.remove_service_workers,qt.workarounds.remove_service_workers>>|Delete the QtWebEngine Service Worker directory on every start.
|<<scrolling.bar,scrolling.bar>>|When/how to show the scrollbar.
@ -3587,6 +3589,22 @@ Type: <<types,Bool>>
Default: +pass:[true]+
[[input.mode_override]]
=== input.mode_override
Mode to change to when focusing on a tab/URL changes.
This setting supports link:configuring{outfilesuffix}#patterns[URL patterns].
Type: <<types,String>>
Valid values:
* +normal+
* +insert+
* +passthrough+
Default: empty
[[input.mouse.back_forward_buttons]]
=== input.mouse.back_forward_buttons
Enable back and forward buttons on the mouse.
@ -3755,6 +3773,73 @@ Type: <<types,List of String>>
Default: empty
[[qt.chromium.low_end_device_mode]]
=== qt.chromium.low_end_device_mode
When to use Chromium's low-end device mode.
This improves the RAM usage of renderer processes, at the expense of performance.
This setting requires a restart.
This setting is only available with the QtWebEngine backend.
Type: <<types,String>>
Valid values:
* +always+: Always use low-end device mode.
* +auto+: Decide automatically (uses low-end mode with < 1 GB available RAM).
* +never+: Never use low-end device mode.
Default: +pass:[auto]+
[[qt.chromium.process_model]]
=== qt.chromium.process_model
Which Chromium process model to use.
Alternative process models use less resources, but decrease security and robustness.
See the following pages for more details:
- https://www.chromium.org/developers/design-documents/process-models
- https://doc.qt.io/qt-5/qtwebengine-features.html#process-models
This setting requires a restart.
This setting is only available with the QtWebEngine backend.
Type: <<types,String>>
Valid values:
* +process-per-site-instance+: Pages from separate sites are put into separate processes and separate visits to the same site are also isolated.
* +process-per-site+: Pages from separate sites are put into separate processes. Unlike Process per Site Instance, all visits to the same site will share an OS process. The benefit of this model is reduced memory consumption, because more web pages will share processes. The drawbacks include reduced security, robustness, and responsiveness.
* +single-process+: Run all tabs in a single process. This should be used for debugging purposes only, and it disables `:open --private`.
Default: +pass:[process-per-site-instance]+
[[qt.chromium.sandboxing]]
=== qt.chromium.sandboxing
What sandboxing mechanisms in Chromium to use.
Chromium has various sandboxing layers, which should be enabled for normal browser usage. Mainly for testing and development, it's possible to disable individual sandboxing layers via this setting.
Open `chrome://sandbox` to see the current sandbox status.
Changing this setting is only recommended if you know what you're doing, as it **disables one of Chromium's security layers**. To avoid sandboxing being accidentally disabled persistently, this setting can only be set via `config.py`, not via `:set`.
See the Chromium documentation for more details:
- https://chromium.googlesource.com/chromium/src/\+/HEAD/docs/linux/sandboxing.md[Linux] - https://chromium.googlesource.com/chromium/src/\+/HEAD/docs/design/sandbox.md[Windows] - https://chromium.googlesource.com/chromium/src/\+/HEAD/docs/design/sandbox_faq.md[FAQ (Windows-centric)]
This setting requires a restart.
This setting can only be set in config.py.
This setting is only available with the QtWebEngine backend.
Type: <<types,String>>
Valid values:
* +enable-all+: Enable all available sandboxing mechanisms.
* +disable-seccomp-bpf+: Disable the Seccomp BPF filter sandbox (Linux only).
* +disable-all+: Disable all sandboxing (**not recommended!**).
Default: +pass:[enable-all]+
[[qt.environ]]
=== qt.environ
Additional environment variables to set.
@ -3820,48 +3905,6 @@ Type: <<types,Bool>>
Default: +pass:[false]+
[[qt.low_end_device_mode]]
=== qt.low_end_device_mode
When to use Chromium's low-end device mode.
This improves the RAM usage of renderer processes, at the expense of performance.
This setting requires a restart.
This setting is only available with the QtWebEngine backend.
Type: <<types,String>>
Valid values:
* +always+: Always use low-end device mode.
* +auto+: Decide automatically (uses low-end mode with < 1 GB available RAM).
* +never+: Never use low-end device mode.
Default: +pass:[auto]+
[[qt.process_model]]
=== qt.process_model
Which Chromium process model to use.
Alternative process models use less resources, but decrease security and robustness.
See the following pages for more details:
- https://www.chromium.org/developers/design-documents/process-models
- https://doc.qt.io/qt-5/qtwebengine-features.html#process-models
This setting requires a restart.
This setting is only available with the QtWebEngine backend.
Type: <<types,String>>
Valid values:
* +process-per-site-instance+: Pages from separate sites are put into separate processes and separate visits to the same site are also isolated.
* +process-per-site+: Pages from separate sites are put into separate processes. Unlike Process per Site Instance, all visits to the same site will share an OS process. The benefit of this model is reduced memory consumption, because more web pages will share processes. The drawbacks include reduced security, robustness, and responsiveness.
* +single-process+: Run all tabs in a single process. This should be used for debugging purposes only, and it disables `:open --private`.
Default: +pass:[process-per-site-instance]+
[[qt.workarounds.locale]]
=== qt.workarounds.locale
Work around locale parsing issues in QtWebEngine 5.15.3.

View File

@ -34,7 +34,7 @@ show it.
*'URL'*::
URLs to open on startup (empty as a window separator).
=== optional arguments
=== options
*-h*, *--help*::
show this help message and exit

View File

@ -6,4 +6,4 @@ packaging==21.3
pep517==0.12.0
pyparsing==3.0.7
toml==0.10.2
tomli==2.0.0
tomli==2.0.1

View File

@ -5,17 +5,15 @@ build==0.7.0
bump2version==1.0.1
certifi==2021.10.8
cffi==1.15.0
charset-normalizer==2.0.11
charset-normalizer==2.0.12
colorama==0.4.4
cryptography==36.0.1
Deprecated==1.2.13
docutils==0.18.1
github3.py==3.0.0
github3.py==3.2.0
hunter==3.4.3
idna==3.3
importlib-metadata==4.10.1
importlib-metadata==4.11.2
jeepney==0.7.1
jwcrypto==1.0
keyring==23.5.0
manhole==1.8.0
packaging==21.3
@ -23,11 +21,12 @@ pep517==0.12.0
pkginfo==1.8.2
pycparser==2.21
Pygments==2.11.2
PyJWT==2.3.0
Pympler==1.0.1
pyparsing==3.0.7
PyQt-builder==1.12.2
python-dateutil==2.8.2
readme-renderer==32.0
readme-renderer==33.0
requests==2.27.1
requests-toolbelt==0.9.1
rfc3986==2.0.0
@ -35,11 +34,10 @@ SecretStorage==3.3.1
sip==6.5.1
six==1.16.0
toml==0.10.2
tomli==2.0.0
tqdm==4.62.3
tomli==2.0.1
tqdm==4.63.0
twine==3.8.0
uritemplate==4.1.1
# urllib3==1.26.8
webencodings==0.5.1
wrapt==1.13.3
zipp==3.7.0

View File

@ -2,18 +2,18 @@
chardet==4.0.0
diff-cover==6.4.4
importlib-metadata==4.10.1
importlib-metadata==4.11.2
importlib-resources==5.4.0
Jinja2==3.0.3
lxml==4.7.1
MarkupSafe==2.0.1
lxml==4.8.0
MarkupSafe==2.1.0
mypy==0.931
mypy-extensions==0.4.3
pluggy==1.0.0
Pygments==2.11.2
PyQt5-stubs==5.15.2.0
tomli==2.0.0
tomli==2.0.1
types-dataclasses==0.6.4
types-PyYAML==6.0.4
typing_extensions==4.0.1
typing_extensions==4.1.1
zipp==3.7.0

View File

@ -1,5 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
altgraph==0.17.2
pyinstaller==4.9
pyinstaller-hooks-contrib==2022.0
pyinstaller==4.10
pyinstaller-hooks-contrib==2022.2

View File

@ -3,19 +3,18 @@
astroid==2.9.3
certifi==2021.10.8
cffi==1.15.0
charset-normalizer==2.0.11
charset-normalizer==2.0.12
cryptography==36.0.1
Deprecated==1.2.13
future==0.18.2
github3.py==3.0.0
github3.py==3.2.0
idna==3.3
isort==5.10.1
jwcrypto==1.0
lazy-object-proxy==1.7.1
mccabe==0.6.1
pefile==2021.9.3
platformdirs==2.4.1 ; python_version>="3.7"
platformdirs==2.5.1 ; python_version>="3.7"
pycparser==2.21
PyJWT==2.3.0
pylint==2.12.2
python-dateutil==2.8.2
./scripts/dev/pylint_checkers
@ -23,7 +22,7 @@ requests==2.27.1
six==1.16.0
toml==0.10.2
typed-ast==1.5.2 ; python_version<"3.8"
typing_extensions==4.0.1
typing_extensions==4.1.1
uritemplate==4.1.1
# urllib3==1.26.8
wrapt==1.13.3

View File

@ -1,7 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
certifi==2021.10.8
charset-normalizer==2.0.11
charset-normalizer==2.0.12
docutils==0.18.1
idna==3.3
Pygments==2.11.2

View File

@ -23,3 +23,5 @@ typing_extensions # from importlib-metadata
#@ add: importlib-metadata<4.9 ; python_version=="3.6.*"
#@ markers: zipp python_version>="3.7"
#@ add: zipp<3.7 ; python_version=="3.6.*"
#@ markers: MarkupSafe python_version>="3.7"
#@ add: MarkupSafe<2.1.0 ; python_version=="3.6.*"

View File

@ -3,13 +3,13 @@
alabaster==0.7.12
Babel==2.9.1
certifi==2021.10.8
charset-normalizer==2.0.11
charset-normalizer==2.0.12
docutils==0.17.1
idna==3.3
imagesize==1.3.0
importlib-metadata==4.10.1
importlib-metadata==4.11.2
Jinja2==3.0.3
MarkupSafe==2.0.1
MarkupSafe==2.1.0
packaging==21.3
Pygments==2.11.2
pyparsing==3.0.7

View File

@ -3,26 +3,25 @@
attrs==21.4.0
beautifulsoup4==4.10.0
certifi==2021.10.8
charset-normalizer==2.0.11
charset-normalizer==2.0.12
cheroot==8.6.0
click==8.0.3
coverage==6.3.1 ; python_version>="3.7"
EasyProcess==1.1
click==8.0.4
coverage==6.3.2 ; python_version>="3.7"
execnet==1.9.0
filelock==3.4.2 ; python_version>="3.7"
Flask==2.0.2
filelock==3.6.0 ; python_version>="3.7"
Flask==2.0.3
glob2==0.7
hunter==3.4.3
hypothesis==6.36.1 ; python_version>="3.7"
hypothesis==6.39.1 ; python_version>="3.7"
icdiff==2.0.4
idna==3.3
iniconfig==1.1.1
itsdangerous==2.0.1
itsdangerous==2.1.0 ; python_version>="3.7"
jaraco.functools==3.5.0 ; python_version>="3.7"
# Jinja2==3.0.3
Mako==1.1.6
manhole==1.8.0
# MarkupSafe==2.0.1
# MarkupSafe==2.1.0
more-itertools==8.12.0
packaging==21.3
parse==1.19.0
@ -33,7 +32,7 @@ py==1.11.0
py-cpuinfo==8.0.0
Pygments==2.11.2
pyparsing==3.0.7
pytest==7.0.0
pytest==7.0.1
pytest-bdd==4.1.0
pytest-benchmark==3.4.1
pytest-cov==3.0.0
@ -46,21 +45,23 @@ pytest-repeat==0.9.1
pytest-rerunfailures==10.2
pytest-xdist==2.5.0
pytest-xvfb==2.0.0
PyVirtualDisplay==2.2
PyVirtualDisplay==3.0
requests==2.27.1
requests-file==1.5.1
six==1.16.0
sortedcontainers==2.4.0
soupsieve==2.3.1
tldextract==3.1.2
tldextract==3.2.0 ; python_version>="3.7"
toml==0.10.2
tomli==2.0.0 ; python_version>="3.7"
tomli==2.0.1 ; python_version>="3.7"
urllib3==1.26.8
vulture==2.3
Werkzeug==2.0.2
Werkzeug==2.0.3
jaraco.functools<3.5 ; python_version=="3.6.*"
tomli<2 ; python_version=="3.6.*"
filelock==3.4.1 ; python_version=="3.6.*"
hypothesis<6.32 ; python_version=="3.6.*"
coverage<6.3 ; python_version=="3.6.*"
pytest-mock<3.7 ; python_version=="3.6.*"
itsdangerous<2.1.0 ; python_version=="3.6.*"
tldextract<3.2.0 ; python_version=="3.6.*"

View File

@ -49,3 +49,7 @@ tldextract
#@ add: coverage<6.3 ; python_version=="3.6.*"
#@ markers: pytest-mock python_version>="3.7"
#@ add: pytest-mock<3.7 ; python_version=="3.6.*"
#@ markers: itsdangerous python_version>="3.7"
#@ add: itsdangerous<2.1.0 ; python_version=="3.6.*"
#@ markers: tldextract python_version>="3.7"
#@ add: tldextract<3.2.0 ; python_version=="3.6.*"

View File

@ -1,18 +1,18 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
distlib==0.3.4
filelock==3.4.2 ; python_version>="3.7"
filelock==3.6.0 ; python_version>="3.7"
packaging==21.3
pip==22.0.3 ; python_version>="3.7"
platformdirs==2.4.1 ; python_version>="3.7"
platformdirs==2.5.1 ; python_version>="3.7"
pluggy==1.0.0
py==1.11.0
pyparsing==3.0.7
setuptools==60.8.1 ; python_version>="3.7"
setuptools==60.9.3 ; python_version>="3.7"
six==1.16.0
toml==0.10.2
tox==3.24.5
virtualenv==20.13.1
virtualenv==20.13.2
wheel==0.37.1
setuptools<60 ; python_version=="3.6.*"
filelock==3.4.1 ; python_version=="3.6.*"

View File

@ -6,7 +6,7 @@
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published bjy
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#

View File

@ -6,7 +6,7 @@
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published bjy
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#

View File

@ -239,6 +239,9 @@ qt.force_platformtheme:
based on the desktop environment.
qt.process_model:
renamed: qt.chromium.process_model
qt.chromium.process_model:
type:
name: String
valid_values:
@ -268,6 +271,9 @@ qt.process_model:
- https://doc.qt.io/qt-5/qtwebengine-features.html#process-models
qt.low_end_device_mode:
renamed: qt.chromium.low_end_device_mode
qt.chromium.low_end_device_mode:
type:
name: String
valid_values:
@ -284,6 +290,39 @@ qt.low_end_device_mode:
This improves the RAM usage of renderer processes, at the expense of
performance.
qt.chromium.sandboxing:
type:
name: String
valid_values:
- enable-all: Enable all available sandboxing mechanisms.
- disable-seccomp-bpf: Disable the Seccomp BPF filter sandbox (Linux only).
- disable-all: Disable all sandboxing (**not recommended!**).
default: enable-all
backend: QtWebEngine
restart: true
no_autoconfig: true # due to it being dangerous
# yamllint disable rule:line-length
desc: >-
What sandboxing mechanisms in Chromium to use.
Chromium has various sandboxing layers, which should be enabled for normal
browser usage. Mainly for testing and development, it's possible to disable
individual sandboxing layers via this setting.
Open `chrome://sandbox` to see the current sandbox status.
Changing this setting is only recommended if you know what you're doing, as
it **disables one of Chromium's security layers**. To avoid sandboxing being
accidentally disabled persistently, this setting can only be set via
`config.py`, not via `:set`.
See the Chromium documentation for more details:
- https://chromium.googlesource.com/chromium/src/\+/HEAD/docs/linux/sandboxing.md[Linux]
- https://chromium.googlesource.com/chromium/src/\+/HEAD/docs/design/sandbox.md[Windows]
- https://chromium.googlesource.com/chromium/src/\+/HEAD/docs/design/sandbox_faq.md[FAQ (Windows-centric)]
# yamllint enable rule:line-length
qt.highdpi:
type: Bool
default: false
@ -1811,6 +1850,18 @@ input.match_counts:
Disabling it allows for emacs-like bindings where number keys are passed
through (according to `input.forward_unbound_keys`) instead.
input.mode_override:
default: null
type:
name: String
none_ok: true
valid_values:
- normal
- insert
- passthrough
supports_pattern: true
desc: Mode to change to when focusing on a tab/URL changes.
## keyhint
keyhint.blacklist:

View File

@ -321,12 +321,12 @@ def _qtwebengine_settings_args(versions: version.WebEngineVersions) -> Iterator[
'--force-webrtc-ip-handling-policy='
'disable_non_proxied_udp',
},
'qt.process_model': {
'qt.chromium.process_model': {
'process-per-site-instance': None,
'process-per-site': '--process-per-site',
'single-process': '--single-process',
},
'qt.low_end_device_mode': {
'qt.chromium.low_end_device_mode': {
'auto': None,
'always': '--enable-low-end-device-mode',
'never': '--disable-low-end-device-mode',
@ -338,6 +338,11 @@ def _qtwebengine_settings_args(versions: version.WebEngineVersions) -> Iterator[
True: '--force-prefers-reduced-motion',
False: None,
},
'qt.chromium.sandboxing': {
'enable-all': None,
'disable-seccomp-bpf': '--disable-seccomp-filter-sandbox',
'disable-all': '--no-sandbox',
}
}
qt_514_ver = utils.VersionNumber(5, 14)

View File

@ -41,8 +41,8 @@ hopefully help.</p>
notification support was added for Qt 5.13.0.</p>
<p><b>Resource usage</b>: qutebrowser v1.5.0 added the <span
class="mono">qt.process_model</span> and <span
class="mono">qt.low_end_device_mode</span> settings which can be used to
class="mono">qt.chromium.process_model</span> and <span
class="mono">qt.chromium.low_end_device_mode</span> settings which can be used to
decrease the resource usage of QtWebEngine (but come with other drawbacks).</p>
<p><b>Not trusting Google</b>: Various people have checked the connections made
@ -78,7 +78,7 @@ security fixes took months to arrive there). You might be better off choosing an
method</a>.</p>
<p><b>White flashing between loads with a custom stylesheet</b>: This doesn't
seem to happen with <span class="mono">qt.process_model = single-process</span>
seem to happen with <span class="mono">qt.chromium.process_model = single-process</span>
set. However, note that that setting comes with decreased security and
stability, but QtWebKit doesn't have any process isolation at all.</p>
{% endblock %}

View File

@ -223,6 +223,10 @@ class TabbedBrowser(QWidget):
# https://bugreports.qt.io/browse/QTBUG-65223
self.cur_load_finished.connect(self._leave_modes_on_load)
# handle mode_override
self.current_tab_changed.connect(lambda tab: self._mode_override(tab.url()))
self.cur_url_changed.connect(self._mode_override)
# This init is never used, it is immediately thrown away in the next
# line.
self.undo_stack: UndoStackType = collections.deque()
@ -777,6 +781,23 @@ class TabbedBrowser(QWidget):
if not self.widget.page_title(idx):
self.widget.set_page_title(idx, url.toDisplayString())
def _mode_override(self, url: QUrl) -> None:
"""Override mode if url matches pattern.
Args:
url: The QUrl to match for
"""
if not url.isValid():
return
mode = config.instance.get('input.mode_override', url=url)
if mode:
log.modes.debug(f"Mode change to {mode} triggered for url {url}")
modeman.enter(
self._win_id,
usertypes.KeyMode[mode],
reason='mode_override',
)
@pyqtSlot(browsertab.AbstractTab)
def _on_icon_changed(self, tab):
"""Set the icon of a tab.

View File

@ -724,7 +724,7 @@ class WebEngineVersions:
)
def qtwebengine_versions(avoid_init: bool = False) -> WebEngineVersions:
def qtwebengine_versions(*, avoid_init: bool = False) -> WebEngineVersions:
"""Get the QtWebEngine and Chromium version numbers.
If we have a parsed user agent, we use it here. If not, we avoid initializing

View File

@ -1,15 +1,16 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
adblock==0.5.1
adblock==0.5.2
colorama==0.4.4
dataclasses==0.6 ; python_version<"3.7"
importlib-metadata==4.10.1 ; python_version=="3.7.*"
importlib-metadata==4.11.2 ; python_version=="3.7.*"
importlib-resources==5.4.0 ; python_version<"3.9"
Jinja2==3.0.3
MarkupSafe==2.0.1
MarkupSafe==2.1.0 ; python_version>="3.7"
Pygments==2.11.2
PyYAML==6.0
typing_extensions==4.0.1 ; python_version<"3.8"
typing_extensions==4.1.1 ; python_version<"3.8"
zipp==3.7.0 ; python_version>="3.7"
importlib-metadata<4.9 ; python_version=="3.6.*"
zipp<3.7 ; python_version=="3.6.*"
MarkupSafe<2.1.0 ; python_version=="3.6.*"

View File

@ -8,7 +8,6 @@
"pytest-xdist": "https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst",
"pytest-forked": "https://github.com/pytest-dev/pytest-forked/blob/master/CHANGELOG.rst",
"pytest-xvfb": "https://github.com/The-Compiler/pytest-xvfb/blob/master/CHANGELOG.rst",
"EasyProcess": "https://github.com/ponty/EasyProcess/commits/master",
"PyVirtualDisplay": "https://github.com/ponty/PyVirtualDisplay/commits/master",
"execnet": "https://execnet.readthedocs.io/en/latest/changelog.html",
"pytest-rerunfailures": "https://github.com/pytest-dev/pytest-rerunfailures/blob/master/CHANGES.rst",
@ -95,7 +94,6 @@
"altgraph": "https://github.com/ronaldoussoren/altgraph/blob/master/doc/changelog.rst",
"urllib3": "https://github.com/urllib3/urllib3/blob/master/CHANGES.rst",
"lxml": "https://github.com/lxml/lxml/blob/master/CHANGES.txt",
"jwcrypto": "https://github.com/latchset/jwcrypto/commits/master",
"wrapt": "https://github.com/GrahamDumpleton/wrapt/blob/develop/docs/changes.rst",
"pep517": "https://github.com/pypa/pep517/blob/master/doc/changelog.rst",
"cryptography": "https://cryptography.io/en/latest/changelog.html",
@ -129,7 +127,7 @@
"yamllint": "https://github.com/adrienverge/yamllint/blob/master/CHANGELOG.rst",
"pathspec": "https://github.com/cpburnz/python-path-specification/blob/master/CHANGES.rst",
"filelock": "https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst",
"github3.py": "https://github3py.readthedocs.io/en/master/release-notes/index.html",
"github3.py": "https://github3.readthedocs.io/en/latest/release-notes/index.html",
"manhole": "https://github.com/ionelmc/python-manhole/blob/master/CHANGELOG.rst",
"pycparser": "https://github.com/eliben/pycparser/blob/master/CHANGES",
"python-dateutil": "https://dateutil.readthedocs.io/en/stable/changelog.html",
@ -147,7 +145,6 @@
"setuptools": "https://setuptools.readthedocs.io/en/latest/history.html",
"future": "https://python-future.org/whatsnew.html",
"pefile": "https://github.com/erocarrera/pefile/commits/master",
"Deprecated": "https://github.com/tantale/deprecated/blob/master/CHANGELOG.rst",
"SecretStorage": "https://github.com/mitya57/secretstorage/blob/master/changelog",
"bleach": "https://github.com/mozilla/bleach/blob/main/CHANGES",
"jeepney": "https://gitlab.com/takluyver/jeepney/-/blob/master/docs/release-notes.rst",
@ -158,5 +155,6 @@
"rfc3986": "https://rfc3986.readthedocs.io/en/latest/release-notes/index.html",
"tqdm": "https://tqdm.github.io/releases/",
"twine": "https://twine.readthedocs.io/en/stable/changelog.html",
"webencodings": "https://github.com/gsnedders/python-webencodings/commits/master"
"webencodings": "https://github.com/gsnedders/python-webencodings/commits/master",
"PyJWT": "https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst"
}

View File

@ -536,7 +536,9 @@ def regenerate_manpage(filename):
# pylint: disable=protected-access
for group in parser._action_groups:
groupdata = []
groupdata.append('=== {}'.format(group.title))
# https://bugs.python.org/issue9694 backport
title = "options" if group.title == "optional arguments" else group.title
groupdata.append('=== {}'.format(title))
if group.description is not None:
groupdata.append(group.description)
for action in group._group_actions:

View File

@ -194,9 +194,8 @@ def pytest_ignore_collect(path):
@pytest.fixture(scope='session')
def qapp_args():
"""Make QtWebEngine unit tests run on older Qt versions + newer kernels."""
seccomp_args = testutils.seccomp_args(qt_flag=False)
if seccomp_args:
return [sys.argv[0]] + seccomp_args
if testutils.disable_seccomp_bpf_sandbox():
return [sys.argv[0], testutils.DISABLE_SECCOMP_BPF_FLAG]
return []

View File

@ -1741,3 +1741,22 @@ Feature: Tab management
And I run :undo
And I run :message-info "Still alive!"
Then the message "Still alive!" should be shown
Scenario: Passthrough mode override
When I run :set -u localhost:*/data/numbers/1.txt input.mode_override 'passthrough'
And I open data/numbers/1.txt
Then "Entering mode KeyMode.passthrough (reason: mode_override)" should be logged
Scenario: Insert mode override
When I run :set -u localhost:*/data/numbers/1.txt input.mode_override 'insert'
And I open data/numbers/1.txt
Then "Entering mode KeyMode.insert (reason: mode_override)" should be logged
Scenario: Mode override on tab switch
When I run :set -u localhost:*/data/numbers/1.txt input.mode_override 'insert'
And I open data/numbers/1.txt
And I wait for "Entering mode KeyMode.insert (reason: mode_override)" in the log
And I run :fake-key -g <esc>
And I open data/numbers/2.txt in a new tab
And I run :tab-prev
Then "Entering mode KeyMode.insert (reason: mode_override)" should be logged

View File

@ -549,8 +549,8 @@ class QuteProc(testprocess.Process):
'--debug-flag', 'werror', '--debug-flag',
'test-notification-service']
if self.request.config.webengine:
args += testutils.seccomp_args(qt_flag=True)
if self.request.config.webengine and testutils.disable_seccomp_bpf_sandbox():
args += testutils.DISABLE_SECCOMP_BPF_ARGS
args.append('about:blank')
return args

View File

@ -56,8 +56,8 @@ def _base_args(config):
else:
args += ['--backend', 'webkit']
if config.webengine:
args += testutils.seccomp_args(qt_flag=True)
if config.webengine and testutils.disable_seccomp_bpf_sandbox():
args += testutils.DISABLE_SECCOMP_BPF_ARGS
args.append('about:blank')
return args
@ -826,3 +826,81 @@ def test_json_logging_without_debug(request, quteproc_new, runtime_tmpdir):
quteproc_new.exit_expected = True
quteproc_new.start(args, env={'XDG_RUNTIME_DIR': str(runtime_tmpdir)})
assert not quteproc_new.is_running()
@pytest.mark.qtwebkit_skip
@pytest.mark.parametrize(
'sandboxing, has_namespaces, has_seccomp, has_yama, expected_result', [
('enable-all', True, True, True, "You are adequately sandboxed."),
('disable-seccomp-bpf', True, False, True, "You are NOT adequately sandboxed."),
('disable-all', False, False, False, "You are NOT adequately sandboxed."),
]
)
def test_sandboxing(
request, quteproc_new, sandboxing,
has_namespaces, has_seccomp, has_yama, expected_result,
):
if not request.config.webengine:
pytest.skip("Skipped with QtWebKit")
elif sandboxing == "enable-all" and testutils.disable_seccomp_bpf_sandbox():
pytest.skip("Full sandboxing not supported")
args = _base_args(request.config) + [
'--temp-basedir',
'-s', 'qt.chromium.sandboxing', sandboxing,
]
quteproc_new.start(args)
quteproc_new.open_url('chrome://sandbox')
text = quteproc_new.get_content()
print(text)
not_found_msg = ("The webpage at chrome://sandbox/ might be temporarily down or "
"it may have moved permanently to a new web address.")
if not_found_msg in text.split("\n"):
line = quteproc_new.wait_for(message='Load error: ERR_INVALID_URL')
line.expected = True
pytest.skip("chrome://sandbox/ not supported")
bpf_text = "Seccomp-BPF sandbox"
yama_text = "Ptrace Protection with Yama LSM"
if "\n\n\n" in text:
# Qt 5.12
header, rest = text.split("\n", maxsplit=1)
rest, result = rest.rsplit("\n\n", maxsplit=1)
lines = rest.replace("\t\n", "\t").split("\n\n\n")
expected_status = {
"Namespace Sandbox": "Yes" if has_namespaces else "No",
"Network namespaces": "Yes" if has_namespaces else "No",
"PID namespaces": "Yes" if has_namespaces else "No",
"SUID Sandbox": "No",
bpf_text: "Yes" if has_seccomp else "No",
f"{bpf_text} supports TSYNC": "Yes" if has_seccomp else "No",
"Yama LSM Enforcing": "Yes" if has_yama else "No",
}
else:
header, *lines, empty, result = text.split("\n")
assert not empty
expected_status = {
"Layer 1 Sandbox": "Namespace" if has_namespaces else "None",
"PID namespaces": "Yes" if has_namespaces else "No",
"Network namespaces": "Yes" if has_namespaces else "No",
bpf_text: "Yes" if has_seccomp else "No",
f"{bpf_text} supports TSYNC": "Yes" if has_seccomp else "No",
f"{yama_text} (Broker)": "Yes" if has_yama else "No",
f"{yama_text} (Non-broker)": "No",
}
assert header == "Sandbox Status"
assert result == expected_result
status = dict(line.split("\t") for line in lines)
assert status == expected_status

View File

@ -31,14 +31,9 @@ import importlib.machinery
import pytest
from PyQt5.QtCore import qVersion
from PyQt5.QtGui import QColor
try:
from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION_STR
except ImportError:
PYQT_WEBENGINE_VERSION_STR = None
from qutebrowser.utils import qtutils, log, utils
from qutebrowser.utils import qtutils, log, utils, version
ON_CI = 'CI' in os.environ
@ -267,35 +262,38 @@ def easyprivacy_txt():
return _decompress_gzip_datafile("easyprivacy.txt.gz")
def seccomp_args(qt_flag):
"""Get necessary flags to disable the seccomp BPF sandbox.
DISABLE_SECCOMP_BPF_FLAG = "--disable-seccomp-filter-sandbox"
DISABLE_SECCOMP_BPF_ARGS = ["-s", "qt.chromium.sandboxing", "disable-seccomp-bpf"]
def disable_seccomp_bpf_sandbox():
"""Check whether we need to disable the seccomp BPF sandbox.
This is needed for some QtWebEngine setups, with older Qt versions but
newer kernels.
Args:
qt_flag: Add a '--qt-flag' argument.
"""
try:
from PyQt5 import QtWebEngine # pylint: disable=unused-import
except ImportError:
# no QtWebEngine available
return False
affected_versions = set()
for base, patch_range in [
# 5.12.0 to 5.12.7 (inclusive)
('5.12', range(0, 8)),
# 5.12.0 to 5.12.10 (inclusive)
('5.12', range(0, 11)),
# 5.13.0 to 5.13.2 (inclusive)
('5.13', range(0, 3)),
# 5.14.0
('5.14', [0]),
# 5.15.0 to 5.15.2 (inclusive)
('5.15', range(0, 3)),
]:
for patch in patch_range:
affected_versions.add('{}.{}'.format(base, patch))
affected_versions.add(utils.VersionNumber.parse(f'{base}.{patch}'))
version = (PYQT_WEBENGINE_VERSION_STR
if PYQT_WEBENGINE_VERSION_STR is not None
else qVersion())
if version in affected_versions:
disable_arg = 'disable-seccomp-filter-sandbox'
return ['--qt-flag', disable_arg] if qt_flag else ['--' + disable_arg]
return []
versions = version.qtwebengine_versions(avoid_init=True)
return versions.webengine in affected_versions
def import_userscript(name):

View File

@ -249,7 +249,7 @@ class TestWebEngineArgs:
('single-process', True),
])
def test_process_model(self, config_stub, parser, process_model, added):
config_stub.val.qt.process_model = process_model
config_stub.val.qt.chromium.process_model = process_model
parsed = parser.parse_args([])
args = qtargs.qt_args(parsed)
@ -267,7 +267,7 @@ class TestWebEngineArgs:
('never', '--disable-low-end-device-mode'),
])
def test_low_end_device_mode(self, config_stub, parser, low_end_device_mode, arg):
config_stub.val.qt.low_end_device_mode = low_end_device_mode
config_stub.val.qt.chromium.low_end_device_mode = low_end_device_mode
parsed = parser.parse_args([])
args = qtargs.qt_args(parsed)
@ -277,6 +277,28 @@ class TestWebEngineArgs:
else:
assert arg in args
@pytest.mark.parametrize('sandboxing, arg', [
('enable-all', None),
('disable-seccomp-bpf', '--disable-seccomp-filter-sandbox'),
('disable-all', '--no-sandbox'),
])
def test_sandboxing(self, config_stub, parser, sandboxing, arg):
config_stub.val.qt.chromium.sandboxing = sandboxing
parsed = parser.parse_args([])
args = qtargs.qt_args(parsed)
remaining_flags = {
'--no-sandbox',
'--disable-seccomp-filter-sandbox',
}
if arg is not None:
remaining_flags.remove(arg)
if arg is not None:
assert arg in args
assert not set(args) & remaining_flags
@pytest.mark.parametrize('qt_version, referer, arg', [
# 'always' -> no arguments
('5.15.0', 'always', None),