From 641037880c3b892925f9d67fdaebfd68b8966523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B6=B5=E6=9B=A6?= Date: Fri, 19 Jul 2024 08:33:36 +0800 Subject: [PATCH] Fix: Resolve the issue where the directory itself being a symlink does not work. --- starlette/staticfiles.py | 2 +- tests/test_staticfiles.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/starlette/staticfiles.py b/starlette/staticfiles.py index 7498c3011..746e740e0 100644 --- a/starlette/staticfiles.py +++ b/starlette/staticfiles.py @@ -155,7 +155,7 @@ def lookup_path(self, path: str) -> tuple[str, os.stat_result | None]: full_path = os.path.abspath(joined_path) else: full_path = os.path.realpath(joined_path) - directory = os.path.realpath(directory) + directory = os.path.realpath(directory) if os.path.commonpath([full_path, directory]) != directory: # Don't allow misbehaving clients to break out of the static files # directory. diff --git a/tests/test_staticfiles.py b/tests/test_staticfiles.py index 8beb3cd87..8f7423593 100644 --- a/tests/test_staticfiles.py +++ b/tests/test_staticfiles.py @@ -559,3 +559,23 @@ def test_staticfiles_avoids_path_traversal(tmp_path: Path) -> None: assert exc_info.value.status_code == 404 assert exc_info.value.detail == "Not Found" + + +def test_staticfiles_self_symlinks(tmpdir: Path, test_client_factory: TestClientFactory) -> None: + statics_path = os.path.join(tmpdir, "statics") + os.mkdir(statics_path) + + source_file_path = os.path.join(statics_path, "index.html") + with open(source_file_path, "w") as file: + file.write("

Hello

") + + statics_symlink_path = os.path.join(tmpdir, "statics_symlink") + os.symlink(statics_path, statics_symlink_path) + + app = StaticFiles(directory=statics_symlink_path, follow_symlink=True) + client = test_client_factory(app) + + response = client.get("/index.html") + assert response.url == "http://testserver/index.html" + assert response.status_code == 200 + assert response.text == "

Hello

"