Handle an invalid $XDG_RUNTIME_DIR gracefully

This is probably against the XDG basedir spec, but some people have a
Linux without anything setting $XDG_RUNTIME_DIR correctly.

Fixes #971.
This commit is contained in:
Florian Bruhin 2016-11-24 10:14:02 +01:00
parent 98dc92fe16
commit 64b47fc3a2
3 changed files with 36 additions and 3 deletions

View File

@ -187,6 +187,8 @@ Fixed
- `:tab-detach` now fails correctly when there's only one tab open.
- Various small issues with the command completion
- Fixed hang when using multiple spaces in a row with the URL completion
- qutebrowser now still starts with an incorrectly configured
`$XDG_RUNTIME_DIR`.
v0.8.3
------

View File

@ -33,6 +33,11 @@ from qutebrowser.utils import log, qtutils, debug
_args = None
class EmptyValueError(Exception):
"""Error raised when QStandardPaths returns an empty value."""
def config():
"""Get a location for configs."""
typ = QStandardPaths.ConfigLocation
@ -104,9 +109,18 @@ def runtime():
else: # pragma: no cover
# RuntimeLocation is a weird path on OS X and Windows.
typ = QStandardPaths.TempLocation
overridden, path = _from_args(typ, _args)
if not overridden:
path = _writable_location(typ)
try:
path = _writable_location(typ)
except EmptyValueError:
# Fall back to TempLocation when RuntimeLocation is misconfigured
if typ == QStandardPaths.TempLocation:
raise
path = _writable_location(QStandardPaths.TempLocation)
# This is generic, but per-user.
#
# For TempLocation:
@ -128,7 +142,7 @@ def _writable_location(typ):
typ_str = debug.qenum_key(QStandardPaths, typ)
log.misc.debug("writable location for {}: {}".format(typ_str, path))
if not path:
raise ValueError("QStandardPaths returned an empty value!")
raise EmptyValueError("QStandardPaths returned an empty value!")
# Qt seems to use '/' as path separator even on Windows...
path = path.replace('/', os.sep)
return path

View File

@ -90,7 +90,7 @@ class TestWritableLocation:
monkeypatch.setattr(
'qutebrowser.utils.standarddir.QStandardPaths.writableLocation',
lambda typ: '')
with pytest.raises(ValueError):
with pytest.raises(standarddir.EmptyValueError):
standarddir._writable_location(QStandardPaths.DataLocation)
def test_sep(self, monkeypatch):
@ -137,6 +137,23 @@ class TestStandardDir:
monkeypatch.delenv('XDG_{}_HOME'.format(var), raising=False)
assert func() == str(tmpdir.join(*subdirs))
@pytest.mark.linux
@pytest.mark.qt_log_ignore(r'^QStandardPaths: XDG_RUNTIME_DIR points to '
r'non-existing path')
def test_linux_invalid_runtimedir(self, monkeypatch, tmpdir):
"""With invalid XDG_RUNTIME_DIR, fall back to TempLocation."""
monkeypatch.setenv('XDG_RUNTIME_DIR', str(tmpdir / 'does-not-exist'))
monkeypatch.setenv('TMPDIR', str(tmpdir / 'temp'))
assert standarddir.runtime() == str(tmpdir / 'temp' / 'qute_test')
def test_runtimedir_empty_tempdir(self, monkeypatch, tmpdir):
"""With an empty tempdir on non-Linux, we should raise."""
monkeypatch.setattr(standarddir.sys, 'platform', 'nt')
monkeypatch.setattr(standarddir.QStandardPaths, 'writableLocation',
lambda typ: '')
with pytest.raises(standarddir.EmptyValueError):
standarddir.runtime()
@pytest.mark.parametrize('func, elems, expected', [
(standarddir.data, 2, ['qute_test', 'data']),
(standarddir.config, 1, ['qute_test']),