rsync 3.4.1 drop-in parity (#285-#297) + parity completion (protocol 2.26.0) #298

Merged
TapTap merged 77 commits from feat/rsync-parity into dev 2026-09-17 20:33:17 +02:00
Showing only changes of commit c41bfb2cdb - Show all commits
+19 -13
View File
@@ -2325,11 +2325,11 @@ class TestRemoteOptionTransport:
class TestTrustSenderServerPath: class TestTrustSenderServerPath:
"""--trust-sender is a receiver-local policy: only the receiving SERVER's """--trust-sender is a receiver-local file-list validation policy. Symlink
own flag matters. For a push, a client --trust-sender is never sent to the targets are stored verbatim like rsync (an absolute/`..` target is copied as
peer, so it must not relax a server that did not opt in; a server started a symlink by default); the sender-side --safe-links is what suppresses
with --trust-sender must copy an escaping symlink target verbatim (its unsafe links. A client --trust-sender is never sent to the peer, so it
normal mode skips it while still confining the link itself).""" cannot change how the receiving server stores links."""
def _make_source(self, name): def _make_source(self, name):
source = os.path.join(TEST_DATA_DIR, name) source = os.path.join(TEST_DATA_DIR, name)
@@ -2353,18 +2353,24 @@ class TestTrustSenderServerPath:
server.stop() server.stop()
@pytest.mark.ci @pytest.mark.ci
def test_client_flag_does_not_relax_server(self): def test_escaping_symlink_stored_verbatim_by_default(self):
result, link = self._run_with_server([], ["--trust-sender"], "client") result, link = self._run_with_server([], [], "default")
assert result.returncode == 0, result.stderr[:200] assert result.returncode == 0, result.stderr[:200]
assert not os.path.lexists(link), \ assert os.path.islink(link), "rsync parity: -l stores the link verbatim"
"a client --trust-sender must not relax a server that did not opt in" assert os.readlink(link) == "/etc/passwd"
@pytest.mark.ci @pytest.mark.ci
def test_server_flag_materializes_escaping_symlink(self): def test_client_trust_sender_does_not_change_server_storage(self):
result, link = self._run_with_server(["--trust-sender"], [], "server") result, link = self._run_with_server([], ["--trust-sender"], "client")
assert result.returncode == 0, result.stderr[:200] assert result.returncode == 0, result.stderr[:200]
assert os.path.islink(link), "server --trust-sender should materialize the symlink" assert os.path.islink(link) and os.readlink(link) == "/etc/passwd", \
assert os.readlink(link) == "/etc/passwd" "a client --trust-sender must not change how the server stores links"
@pytest.mark.ci
def test_safe_links_skips_escaping_symlink(self):
result, link = self._run_with_server([], ["--safe-links"], "safe")
assert result.returncode == 0, result.stderr[:200]
assert not os.path.lexists(link), "--safe-links must skip an unsafe target"
def _source_files(): def _source_files():