From: Aarni Koskela Date: Fri, 10 Jan 2025 06:17:02 +0000 (+0200) Subject: Strip extra leading slashes in `/etc/localtime` (#1165) X-Git-Tag: v2.17.0~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c2b397ee6de7532a36c723478ed6eb38edfdf70c;p=thirdparty%2Fbabel.git Strip extra leading slashes in `/etc/localtime` (#1165) * Strip extra leading slashes in `/etc/localtime` Fixes #990 Co-authored-by: Tomas R. --- diff --git a/babel/localtime/_unix.py b/babel/localtime/_unix.py index eb81beb6..782a7d24 100644 --- a/babel/localtime/_unix.py +++ b/babel/localtime/_unix.py @@ -45,7 +45,13 @@ def _get_localzone(_root: str = '/') -> datetime.tzinfo: else: pos = link_dst.find('/zoneinfo/') if pos >= 0: - zone_name = link_dst[pos + 10:] + # On occasion, the `/etc/localtime` symlink has a double slash, e.g. + # "/usr/share/zoneinfo//UTC", which would make `zoneinfo.ZoneInfo` + # complain (no absolute paths allowed), and we'd end up returning + # `None` (as a fix for #1092). + # Instead, let's just "fix" the double slash symlink by stripping + # leading slashes before passing the assumed zone name forward. + zone_name = link_dst[pos + 10:].lstrip("/") tzinfo = _get_tzinfo(zone_name) if tzinfo is not None: return tzinfo diff --git a/tests/test_localtime.py b/tests/test_localtime.py index 723ffa0b..a7eaba8f 100644 --- a/tests/test_localtime.py +++ b/tests/test_localtime.py @@ -1,4 +1,6 @@ +import os import sys +from unittest.mock import Mock import pytest @@ -27,3 +29,16 @@ def test_issue_1092_with_pytz(monkeypatch): monkeypatch.setenv("TZ", "/UTC") # Malformed timezone name. with pytest.raises(LookupError): get_localzone() + + +@pytest.mark.skipif( + sys.platform == "win32", + reason="Issue 990 is not applicable on Windows", +) +def test_issue_990(monkeypatch): + monkeypatch.setenv("TZ", "") + fake_readlink = Mock(return_value="/usr/share/zoneinfo////UTC") # Double slash, oops! + monkeypatch.setattr(os, "readlink", fake_readlink) + from babel.localtime._unix import _get_localzone + assert _get_localzone() is not None + fake_readlink.assert_called_with("/etc/localtime")