summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2022-03-07 11:15:00 +0100
committerFlorian Bruhin <me@the-compiler.org>2022-03-07 11:15:00 +0100
commita855831e24c895607848b15ca089f12cb190ad5b (patch)
tree3b1888c28791ffa605debe4c149727f380c8bdc9
parent0924631cdcb1d058e96dac2a1b5ad14b427dd707 (diff)
parent0b412ffb740b4f752afb421a0a5d89d09f1965af (diff)
downloadqutebrowser-a855831e24c895607848b15ca089f12cb190ad5b.tar.gz
qutebrowser-a855831e24c895607848b15ca089f12cb190ad5b.zip
Merge branch 'new-chromium-args'
-rw-r--r--doc/changelog.asciidoc4
-rw-r--r--doc/help/settings.asciidoc114
-rw-r--r--doc/qutebrowser.1.asciidoc2
-rw-r--r--qutebrowser/config/configdata.yml39
-rw-r--r--qutebrowser/config/qtargs.py9
-rw-r--r--qutebrowser/html/warning-webkit.html6
-rw-r--r--qutebrowser/utils/version.py2
-rw-r--r--tests/conftest.py5
-rw-r--r--tests/end2end/fixtures/quteprocess.py4
-rw-r--r--tests/end2end/test_invocations.py80
-rw-r--r--tests/helpers/testutils.py42
-rw-r--r--tests/unit/config/test_qtargs.py26
12 files changed, 251 insertions, 82 deletions
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc
index d46a19709..9df2ce00c 100644
--- a/doc/changelog.asciidoc
+++ b/doc/changelog.asciidoc
@@ -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
~~~~~
@@ -57,6 +60,7 @@ Added
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
~~~~~
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index a51463352..0adc95fdd 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -287,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.
@@ -3772,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.
@@ -3837,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.
diff --git a/doc/qutebrowser.1.asciidoc b/doc/qutebrowser.1.asciidoc
index bc312f108..f22be1ddc 100644
--- a/doc/qutebrowser.1.asciidoc
+++ b/doc/qutebrowser.1.asciidoc
@@ -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
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index 59f16511f..1d41d147d 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -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
diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py
index 2f93b7de5..9e7f2620d 100644
--- a/qutebrowser/config/qtargs.py
+++ b/qutebrowser/config/qtargs.py
@@ -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)
diff --git a/qutebrowser/html/warning-webkit.html b/qutebrowser/html/warning-webkit.html
index 975f98c1b..f5cf9bf01 100644
--- a/qutebrowser/html/warning-webkit.html
+++ b/qutebrowser/html/warning-webkit.html
@@ -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 %}
diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py
index 8da86dd00..33acdce57 100644
--- a/qutebrowser/utils/version.py
+++ b/qutebrowser/utils/version.py
@@ -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
diff --git a/tests/conftest.py b/tests/conftest.py
index ad82b4f24..84cae784b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -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 []
diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py
index 14f34b52c..ab8f28d26 100644
--- a/tests/end2end/fixtures/quteprocess.py
+++ b/tests/end2end/fixtures/quteprocess.py
@@ -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
diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py
index b860feed0..80a3c016b 100644
--- a/tests/end2end/test_invocations.py
+++ b/tests/end2end/test_invocations.py
@@ -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,79 @@ 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"):
+ 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
diff --git a/tests/helpers/testutils.py b/tests/helpers/testutils.py
index 8bb622133..c607718ab 100644
--- a/tests/helpers/testutils.py
+++ b/tests/helpers/testutils.py
@@ -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))
-
- 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]
+ affected_versions.add(utils.VersionNumber.parse(f'{base}.{patch}'))
- return []
+ versions = version.qtwebengine_versions(avoid_init=True)
+ return versions.webengine in affected_versions
def import_userscript(name):
diff --git a/tests/unit/config/test_qtargs.py b/tests/unit/config/test_qtargs.py
index d95382624..076ff6e3c 100644
--- a/tests/unit/config/test_qtargs.py
+++ b/tests/unit/config/test_qtargs.py
@@ -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),