From: Jeremy Epstein Date: Sat, 1 Jun 2024 13:07:03 +0000 (+1000) Subject: Send 404 instead of 500 when filename requested is too long on `StaticFiles` (#2583) X-Git-Tag: 0.38.0~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4f16aedc0f51e10fb466ece0fc6460ceec2034c8;p=thirdparty%2Fstarlette.git Send 404 instead of 500 when filename requested is too long on `StaticFiles` (#2583) * Make "Filename too long" return 404 not 500 * Simplify code source * Correct comment --------- Co-authored-by: Jeremy Epstein Co-authored-by: Marcelo Trylesinski --- diff --git a/starlette/staticfiles.py b/starlette/staticfiles.py index 5d0856cc..afb09b56 100644 --- a/starlette/staticfiles.py +++ b/starlette/staticfiles.py @@ -1,5 +1,6 @@ from __future__ import annotations +import errno import importlib.util import os import stat @@ -124,8 +125,12 @@ class StaticFiles: ) except PermissionError: raise HTTPException(status_code=401) - except OSError: - raise + except OSError as exc: + # Filename is too long, so it can't be a valid static file. + if exc.errno == errno.ENAMETOOLONG: + raise HTTPException(status_code=404) + + raise exc if stat_result and stat.S_ISREG(stat_result.st_mode): # We have a static file to serve. diff --git a/tests/test_staticfiles.py b/tests/test_staticfiles.py index d20bb7ef..08530130 100644 --- a/tests/test_staticfiles.py +++ b/tests/test_staticfiles.py @@ -469,6 +469,19 @@ def test_staticfiles_access_file_as_dir_returns_404( assert response.text == "Not Found" +def test_staticfiles_filename_too_long( + tmpdir: Path, test_client_factory: TestClientFactory +) -> None: + routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")] + app = Starlette(routes=routes) + client = test_client_factory(app) + + path_max_size = os.pathconf("/", "PC_PATH_MAX") + response = client.get(f"/{'a' * path_max_size}.txt") + assert response.status_code == 404 + assert response.text == "Not Found" + + def test_staticfiles_unhandled_os_error_returns_500( tmpdir: Path, test_client_factory: TestClientFactory,