aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_partial_uploads.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-01 11:47:39 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-01 11:47:39 +0200
commit760ac421b1944cd69a80e3a92127a1a966f15938 (patch)
treec894b655d4f21698ebb91c0865ddf3e04985586d /packages/meshbay-node/tests/test_partial_uploads.py
parent752b160c7c5e671e0db8f402a52fac27bb85ab06 (diff)
downloadmeshbay-760ac421b1944cd69a80e3a92127a1a966f15938.tar.gz
fix: downloads are marked and keep their extension; Explorer files are refused
The desktop app writes the Mark-of-the-Web on each file it saves on Windows, as a browser does. Bidirectional controls are reserved characters in a saved name (portable-name.js and paths.sanitize_for_download, and again in the main process), so a name cannot display one extension and carry another. The node refuses uploads of files Windows Explorer acts on by itself: desktop.ini, .lnk, .url, .scf, .library-ms, .searchConnector-ms (F-19). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/tests/test_partial_uploads.py')
-rw-r--r--packages/meshbay-node/tests/test_partial_uploads.py21
1 files changed, 21 insertions, 0 deletions
diff --git a/packages/meshbay-node/tests/test_partial_uploads.py b/packages/meshbay-node/tests/test_partial_uploads.py
index 138ee3b..556b26a 100644
--- a/packages/meshbay-node/tests/test_partial_uploads.py
+++ b/packages/meshbay-node/tests/test_partial_uploads.py
@@ -22,6 +22,7 @@ import time
import types
from pathlib import Path
+import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.crypto import generate_gek
from meshbay_common.protocol import (
@@ -552,3 +553,23 @@ def test_without_hard_links_a_file_is_still_not_replaced(tmp_path, monkeypatch):
assert (tmp_path / "a.txt").read_bytes() == b"there first"
assert (tmp_path / "a (2).txt").read_bytes() == b"uploaded"
assert not part.exists()
+
+
+# ── files Explorer acts on by itself ─────────────────────────────────────────
+
+
+@pytest.mark.parametrize("name", ["desktop.ini", "Desktop.INI", "photos.lnk", "site.url",
+ "x.scf", "Docs.library-ms", "s.searchConnector-ms"])
+async def test_a_file_explorer_acts_on_is_refused(tmp_path, name):
+ ctx = _group_ctx(tmp_path)
+ peer = _peer(ctx)
+ await peer._do_file_upload(sealed_upload(peer, filename=name, data=b"[x]"))
+ assert [m.get("code") for m in _errors(peer)] == ["file_type_refused"]
+ assert not any(ctx["roots"].roots[0].path.iterdir())
+
+
+async def test_an_ordinary_file_with_a_near_name_is_accepted(tmp_path):
+ ctx = _group_ctx(tmp_path)
+ peer = _peer(ctx)
+ await peer._do_file_upload(sealed_upload(peer, filename="url-notes.txt", data=b"x"))
+ assert _errors(peer) == []