fix(state-db): keep non-UTF-8 POSIX paths readable in the read-only URI

state_db_file_uri() quoted the POSIX path as a str; an undecodable filename
byte is carried as a surrogateescape code point, which quote() rejects with
UnicodeEncodeError, and get_cli_sessions() swallowed that as an empty
session list. Quote os.fsencode() bytes instead (what Path.as_uri() did on
master). Regression test: a b'\xff' HERMES_HOME component opens read-only.

Maintainer fold-in during release gating (Codex re-gate finding).

Co-authored-by: ruizanthony <ruizanthony@users.noreply.github.com>
This commit is contained in:
nesquena-hermesandruizanthony committed 2026-09-22 22:56:02 +00:00
1 parent c8b1f87583
commit 8635487d9b
2 files changed
+36 -2

No files matched your search

@@ -207,6 +207,33 @@ def test_empty_authority_uri_opens_on_this_platform(tmp_path):
conn.execute("INSERT INTO t VALUES (1)")
@pytest.mark.skipif(sys.platform == "win32", reason="POSIX filesystem-bytes path")
def test_non_utf8_posix_path_still_opens_readonly(tmp_path):
"""A non-UTF-8 path component must not make every agent session vanish.
Python carries undecodable POSIX filename bytes as ``surrogateescape``
code points; ``quote(str)`` rejects those with UnicodeEncodeError, which
the listing path swallows as "no sessions". ``Path.as_uri()`` (the pre-PR
shape) percent-encoded the fsencode() bytes, so the URI builder must too.
"""
try:
odd_dir = tmp_path / os.fsdecode(b"hermes-\xff-home")
odd_dir.mkdir()
except (OSError, UnicodeError):
pytest.skip("filesystem rejects non-UTF-8 names")
path = odd_dir / "state.db"
with closing(sqlite3.connect(str(path))) as conn:
conn.execute("CREATE TABLE t(x)")
conn.execute("INSERT INTO t VALUES (1)")
conn.commit()
uri = agent_sessions.state_db_readonly_uri(path.resolve())
assert "%FF" in uri
with closing(agent_sessions.open_state_db_readonly(path)) as conn:
assert conn.execute("SELECT COUNT(*) FROM t").fetchone() == (1,)
with pytest.raises(sqlite3.OperationalError):
conn.execute("INSERT INTO t VALUES (2)")
# --------------------------------------------------------------------------
# 3. The index maintenance script imports and runs without fcntl.
# --------------------------------------------------------------------------