From f4d2193e8d0cd864e6ee5850f4ef9985e786c41c Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 29 Aug 2026 21:08:32 +0000 Subject: [PATCH 1/8] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[MEDIUM?= =?UTF-8?q?]=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20Form=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=EC=97=90=20=EA=B8=B8=EC=9D=B4=20=EC=A0=9C=ED=95=9C=EC=9D=84=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=ED=95=98=EC=97=AC=20DoS=20=EA=B3=B5=EA=B2=A9?= =?UTF-8?q?=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .jules/sentinel.md | 4 ++++ src/newsdom_api/main.py | 6 ++++-- src/newsdom_api/schemas.py | 4 +++- tests/test_auth.py | 27 ++++++++++++++---------- tests/test_auth_deployment_contract.py | 2 +- tests/test_auth_fail_closed_contract.py | 28 +++++++------------------ tests/test_auth_protocol_edges.py | 4 +--- tests/test_parse_endpoint.py | 25 ++++++++++++++++++++++ tests/test_project_metadata.py | 6 ++---- tests/test_pypdf_security_floor.py | 4 +--- 10 files changed, 65 insertions(+), 45 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 2b5d819c..361227f5 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -90,3 +90,7 @@ **Vulnerability:** The `_safe_upload_filename` function used `filename.replace`, `PurePosixPath`, and `re.sub` on unbounded client input, making it vulnerable to ReDoS or CPU/memory exhaustion (DoS) when fed extremely long strings. **Learning:** Even fast standard library functions like `PurePosixPath` and string replacements can cause significant lag when chained on strings in the megabytes. String processing operations should always bound their inputs first if the input is untrusted and can be arbitrarily large. **Prevention:** Cap the length of client-provided filename strings early by slicing them (e.g. `filename = filename[-512:]`) before doing more complex string parsing or regex replacements, especially when only the basename suffix is relevant. +## 2026-08-29 - [DoS Risk Mitigation] Form Field Max Length +**Vulnerability:** FastAPIs using `Form()` without a `max_length` can be exploited to cause memory exhaustion by uploading arbitrarily large fields, as `python-multipart` loads them fully into memory. +**Learning:** Even auxiliary configuration fields (like `language` and `mode`) can present critical resource exhaustion vectors if their length is unbounded. +**Prevention:** Always define a tight `max_length` (e.g. `max_length=50`) on string `Form()` parameters. diff --git a/src/newsdom_api/main.py b/src/newsdom_api/main.py index f61aafc2..eaaf24ef 100644 --- a/src/newsdom_api/main.py +++ b/src/newsdom_api/main.py @@ -205,19 +205,21 @@ async def parse( language: Annotated[ str, Form( + max_length=50, description=( "MinerU language family or compatibility alias (e.g. `ch`, " "`en`, `japan`, `korean`, `arabic`, `devanagari`)." - ) + ), ), ] = DEFAULT_LANGUAGE, mode: Annotated[ str, Form( + max_length=50, description=( "MinerU parsing mode: `auto` (born-digital text PDFs skip forced " "OCR), `ocr` (force OCR), or `txt` (embedded text layer only)." - ) + ), ), ] = DEFAULT_MODE, ) -> ParseResponse: diff --git a/src/newsdom_api/schemas.py b/src/newsdom_api/schemas.py index d4295412..f6695a31 100644 --- a/src/newsdom_api/schemas.py +++ b/src/newsdom_api/schemas.py @@ -97,7 +97,9 @@ class ArticleNode(BaseModel): body_blocks: List[str] = Field( default_factory=list, description="Ordered text blocks that make up the article body.", - json_schema_extra={"example": ["First paragraph of the article.", "Second paragraph."]}, + json_schema_extra={ + "example": ["First paragraph of the article.", "Second paragraph."] + }, ) images: List[ImageNode] = Field( default_factory=list, diff --git a/tests/test_auth.py b/tests/test_auth.py index 3dc8311b..b9731c98 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -28,9 +28,7 @@ security_boundary_middleware, ) -_PDF_FILES = { - "file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf") -} +_PDF_FILES = {"file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf")} def _settings( @@ -147,9 +145,12 @@ def test_development_disabled_mode_allows_parse_and_warns_once( assert client.post("/parse", files=_PDF_FILES).status_code == 200 assert parser_spy["count"] == 2 messages = [record.getMessage() for record in caplog.records] - assert messages.count( - "Parser authentication is disabled for the explicit development profile" - ) == 1 + assert ( + messages.count( + "Parser authentication is disabled for the explicit development profile" + ) + == 1 + ) def test_direct_runtime_settings_reject_invalid_security_invariants() -> None: @@ -350,11 +351,15 @@ def test_concurrent_requests_cannot_switch_authentication_state( ) def request(token: str) -> int: - return TestClient(application).post( - "/parse", - files=_PDF_FILES, - headers={"Authorization": f"Bearer {token}"}, - ).status_code + return ( + TestClient(application) + .post( + "/parse", + files=_PDF_FILES, + headers={"Authorization": f"Bearer {token}"}, + ) + .status_code + ) tokens = ["fixed" if index % 2 == 0 else "changed" for index in range(20)] with ThreadPoolExecutor(max_workers=8) as executor: diff --git a/tests/test_auth_deployment_contract.py b/tests/test_auth_deployment_contract.py index 33d862b9..2053091d 100644 --- a/tests/test_auth_deployment_contract.py +++ b/tests/test_auth_deployment_contract.py @@ -27,7 +27,7 @@ def _project_version(pyproject_text: str) -> str: ) match = ( re.search( - r'''^version\s*=\s*(["'])([^"']+)\1\s*(?:#.*)?$''', + r"""^version\s*=\s*(["'])([^"']+)\1\s*(?:#.*)?$""", project_table.group("body"), re.MULTILINE, ) diff --git a/tests/test_auth_fail_closed_contract.py b/tests/test_auth_fail_closed_contract.py index 3c565cb7..6bafc4d2 100644 --- a/tests/test_auth_fail_closed_contract.py +++ b/tests/test_auth_fail_closed_contract.py @@ -11,9 +11,7 @@ ) from newsdom_api.main import create_app -_PDF_FILES = { - "file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf") -} +_PDF_FILES = {"file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf")} def test_default_configuration_without_token_blocks_parser_before_work( @@ -36,12 +34,10 @@ def fake_parse_pdf(*_args, **_kwargs): monkeypatch.setattr("newsdom_api.main._validate_pdf_structure", lambda _: None) monkeypatch.setattr("newsdom_api.main.parse_pdf", fake_parse_pdf) - application = create_app( - settings, runtime_readiness_probe=lambda: True + application = create_app(settings, runtime_readiness_probe=lambda: True) + response = TestClient(application, raise_server_exceptions=False).post( + "/parse", files=_PDF_FILES ) - response = TestClient( - application, raise_server_exceptions=False - ).post("/parse", files=_PDF_FILES) assert response.status_code == 503 assert response.json() == {"detail": "Service Unavailable"} @@ -58,13 +54,9 @@ def test_ready_fails_closed_when_required_authentication_is_unconfigured( runtime_profile=RuntimeProfile.PRODUCTION, api_token=None, ) - application = create_app( - settings, runtime_readiness_probe=lambda: True - ) + application = create_app(settings, runtime_readiness_probe=lambda: True) - response = TestClient( - application, raise_server_exceptions=False - ).get("/ready") + response = TestClient(application, raise_server_exceptions=False).get("/ready") assert response.status_code == 503 assert response.json() == {"detail": "Service Unavailable"} @@ -82,13 +74,9 @@ def test_health_remains_liveness_only_when_authentication_is_unconfigured( runtime_profile=RuntimeProfile.PRODUCTION, api_token=None, ) - application = create_app( - settings, runtime_readiness_probe=lambda: False - ) + application = create_app(settings, runtime_readiness_probe=lambda: False) - response = TestClient( - application, raise_server_exceptions=False - ).get("/health") + response = TestClient(application, raise_server_exceptions=False).get("/health") assert response.status_code == 200 assert response.json() == {"status": "ok"} diff --git a/tests/test_auth_protocol_edges.py b/tests/test_auth_protocol_edges.py index dbd733be..6021a9a8 100644 --- a/tests/test_auth_protocol_edges.py +++ b/tests/test_auth_protocol_edges.py @@ -12,9 +12,7 @@ ) from newsdom_api.main import create_app -_PDF_FILES = { - "file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf") -} +_PDF_FILES = {"file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf")} _BEARER_PREFIX = "Bearer " diff --git a/tests/test_parse_endpoint.py b/tests/test_parse_endpoint.py index 1491ada0..d8ed7e4a 100644 --- a/tests/test_parse_endpoint.py +++ b/tests/test_parse_endpoint.py @@ -555,3 +555,28 @@ def spy_unlink(self, missing_ok=False): # We should have unlinked exactly one file, which should be in the temp directory assert len(unlinked_paths) == 1 assert "tmp" in unlinked_paths[0].lower() or "temp" in unlinked_paths[0].lower() + + +def test_parse_endpoint_rejects_excessively_long_form_fields(monkeypatch): + from fastapi.testclient import TestClient + from newsdom_api.main import app + + monkeypatch.setenv("NEWSDOM_AUTH_MODE", "disabled") + monkeypatch.setenv("NEWSDOM_RUNTIME_PROFILE", "development") + client = TestClient(app) + + long_string = "a" * 100 + + response_lang = client.post( + "/parse", + files={"file": ("test.pdf", b"%PDF-1.4\n...", "application/pdf")}, + data={"language": long_string, "mode": "auto"}, + ) + assert response_lang.status_code == 422 + + response_mode = client.post( + "/parse", + files={"file": ("test.pdf", b"%PDF-1.4\n...", "application/pdf")}, + data={"language": "ch", "mode": long_string}, + ) + assert response_mode.status_code == 422 diff --git a/tests/test_project_metadata.py b/tests/test_project_metadata.py index 324cb086..114c1fb6 100644 --- a/tests/test_project_metadata.py +++ b/tests/test_project_metadata.py @@ -172,12 +172,10 @@ def test_project_declares_python_compatible_locked_fuzz_extra(): assert "fuzz = [" in text assert ( - '"atheris==3.0.0 ; platform_system == \'Linux\' and ' - 'python_version == \'3.11\'"' + "\"atheris==3.0.0 ; platform_system == 'Linux' and python_version == '3.11'\"" ) in text assert ( - '"atheris==3.1.0 ; platform_system == \'Linux\' and ' - 'python_version >= \'3.12\'"' + "\"atheris==3.1.0 ; platform_system == 'Linux' and python_version >= '3.12'\"" ) in text assert _locked_package_versions("atheris") == {(3, 0, 0), (3, 1, 0)} assert '"pyinstaller==6.21.0"' in text diff --git a/tests/test_pypdf_security_floor.py b/tests/test_pypdf_security_floor.py index 6a641e83..56b741c8 100644 --- a/tests/test_pypdf_security_floor.py +++ b/tests/test_pypdf_security_floor.py @@ -71,9 +71,7 @@ def test_trivy_registry_exception_is_scoped_to_the_example_manifest() -> None: ignore_document = yaml.safe_load( Path(".trivyignore.yaml").read_text(encoding="utf-8") ) - exceptions = { - entry["id"]: entry for entry in ignore_document["misconfigurations"] - } + exceptions = {entry["id"]: entry for entry in ignore_document["misconfigurations"]} assert trivy_config["ignorefile"] == ".trivyignore.yaml" assert exceptions["KSV-0125"]["paths"] == [ From df46e7483711e9faa40763368aa82ef842a88636 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 29 Aug 2026 21:21:23 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=ED=8F=AC=EB=A7=B7=ED=8C=85=20=EB=B3=80=EA=B2=BD=EC=82=AC?= =?UTF-8?q?=ED=95=AD=EC=9D=84=20=EB=A1=A4=EB=B0=B1=ED=95=98=EC=97=AC=20PR?= =?UTF-8?q?=20=ED=81=AC=EA=B8=B0=20=EC=B4=88=EA=B3=BC=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?(413)=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/newsdom_api/schemas.py | 4 +--- tests/test_auth.py | 27 ++++++++++-------------- tests/test_auth_deployment_contract.py | 2 +- tests/test_auth_fail_closed_contract.py | 28 ++++++++++++++++++------- tests/test_auth_protocol_edges.py | 4 +++- tests/test_project_metadata.py | 6 ++++-- tests/test_pypdf_security_floor.py | 4 +++- 7 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/newsdom_api/schemas.py b/src/newsdom_api/schemas.py index f6695a31..d4295412 100644 --- a/src/newsdom_api/schemas.py +++ b/src/newsdom_api/schemas.py @@ -97,9 +97,7 @@ class ArticleNode(BaseModel): body_blocks: List[str] = Field( default_factory=list, description="Ordered text blocks that make up the article body.", - json_schema_extra={ - "example": ["First paragraph of the article.", "Second paragraph."] - }, + json_schema_extra={"example": ["First paragraph of the article.", "Second paragraph."]}, ) images: List[ImageNode] = Field( default_factory=list, diff --git a/tests/test_auth.py b/tests/test_auth.py index b9731c98..3dc8311b 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -28,7 +28,9 @@ security_boundary_middleware, ) -_PDF_FILES = {"file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf")} +_PDF_FILES = { + "file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf") +} def _settings( @@ -145,12 +147,9 @@ def test_development_disabled_mode_allows_parse_and_warns_once( assert client.post("/parse", files=_PDF_FILES).status_code == 200 assert parser_spy["count"] == 2 messages = [record.getMessage() for record in caplog.records] - assert ( - messages.count( - "Parser authentication is disabled for the explicit development profile" - ) - == 1 - ) + assert messages.count( + "Parser authentication is disabled for the explicit development profile" + ) == 1 def test_direct_runtime_settings_reject_invalid_security_invariants() -> None: @@ -351,15 +350,11 @@ def test_concurrent_requests_cannot_switch_authentication_state( ) def request(token: str) -> int: - return ( - TestClient(application) - .post( - "/parse", - files=_PDF_FILES, - headers={"Authorization": f"Bearer {token}"}, - ) - .status_code - ) + return TestClient(application).post( + "/parse", + files=_PDF_FILES, + headers={"Authorization": f"Bearer {token}"}, + ).status_code tokens = ["fixed" if index % 2 == 0 else "changed" for index in range(20)] with ThreadPoolExecutor(max_workers=8) as executor: diff --git a/tests/test_auth_deployment_contract.py b/tests/test_auth_deployment_contract.py index 2053091d..33d862b9 100644 --- a/tests/test_auth_deployment_contract.py +++ b/tests/test_auth_deployment_contract.py @@ -27,7 +27,7 @@ def _project_version(pyproject_text: str) -> str: ) match = ( re.search( - r"""^version\s*=\s*(["'])([^"']+)\1\s*(?:#.*)?$""", + r'''^version\s*=\s*(["'])([^"']+)\1\s*(?:#.*)?$''', project_table.group("body"), re.MULTILINE, ) diff --git a/tests/test_auth_fail_closed_contract.py b/tests/test_auth_fail_closed_contract.py index 6bafc4d2..3c565cb7 100644 --- a/tests/test_auth_fail_closed_contract.py +++ b/tests/test_auth_fail_closed_contract.py @@ -11,7 +11,9 @@ ) from newsdom_api.main import create_app -_PDF_FILES = {"file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf")} +_PDF_FILES = { + "file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf") +} def test_default_configuration_without_token_blocks_parser_before_work( @@ -34,10 +36,12 @@ def fake_parse_pdf(*_args, **_kwargs): monkeypatch.setattr("newsdom_api.main._validate_pdf_structure", lambda _: None) monkeypatch.setattr("newsdom_api.main.parse_pdf", fake_parse_pdf) - application = create_app(settings, runtime_readiness_probe=lambda: True) - response = TestClient(application, raise_server_exceptions=False).post( - "/parse", files=_PDF_FILES + application = create_app( + settings, runtime_readiness_probe=lambda: True ) + response = TestClient( + application, raise_server_exceptions=False + ).post("/parse", files=_PDF_FILES) assert response.status_code == 503 assert response.json() == {"detail": "Service Unavailable"} @@ -54,9 +58,13 @@ def test_ready_fails_closed_when_required_authentication_is_unconfigured( runtime_profile=RuntimeProfile.PRODUCTION, api_token=None, ) - application = create_app(settings, runtime_readiness_probe=lambda: True) + application = create_app( + settings, runtime_readiness_probe=lambda: True + ) - response = TestClient(application, raise_server_exceptions=False).get("/ready") + response = TestClient( + application, raise_server_exceptions=False + ).get("/ready") assert response.status_code == 503 assert response.json() == {"detail": "Service Unavailable"} @@ -74,9 +82,13 @@ def test_health_remains_liveness_only_when_authentication_is_unconfigured( runtime_profile=RuntimeProfile.PRODUCTION, api_token=None, ) - application = create_app(settings, runtime_readiness_probe=lambda: False) + application = create_app( + settings, runtime_readiness_probe=lambda: False + ) - response = TestClient(application, raise_server_exceptions=False).get("/health") + response = TestClient( + application, raise_server_exceptions=False + ).get("/health") assert response.status_code == 200 assert response.json() == {"status": "ok"} diff --git a/tests/test_auth_protocol_edges.py b/tests/test_auth_protocol_edges.py index 6021a9a8..dbd733be 100644 --- a/tests/test_auth_protocol_edges.py +++ b/tests/test_auth_protocol_edges.py @@ -12,7 +12,9 @@ ) from newsdom_api.main import create_app -_PDF_FILES = {"file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf")} +_PDF_FILES = { + "file": ("fixture.pdf", b"%PDF-1.4\n%synthetic\n", "application/pdf") +} _BEARER_PREFIX = "Bearer " diff --git a/tests/test_project_metadata.py b/tests/test_project_metadata.py index 114c1fb6..324cb086 100644 --- a/tests/test_project_metadata.py +++ b/tests/test_project_metadata.py @@ -172,10 +172,12 @@ def test_project_declares_python_compatible_locked_fuzz_extra(): assert "fuzz = [" in text assert ( - "\"atheris==3.0.0 ; platform_system == 'Linux' and python_version == '3.11'\"" + '"atheris==3.0.0 ; platform_system == \'Linux\' and ' + 'python_version == \'3.11\'"' ) in text assert ( - "\"atheris==3.1.0 ; platform_system == 'Linux' and python_version >= '3.12'\"" + '"atheris==3.1.0 ; platform_system == \'Linux\' and ' + 'python_version >= \'3.12\'"' ) in text assert _locked_package_versions("atheris") == {(3, 0, 0), (3, 1, 0)} assert '"pyinstaller==6.21.0"' in text diff --git a/tests/test_pypdf_security_floor.py b/tests/test_pypdf_security_floor.py index 56b741c8..6a641e83 100644 --- a/tests/test_pypdf_security_floor.py +++ b/tests/test_pypdf_security_floor.py @@ -71,7 +71,9 @@ def test_trivy_registry_exception_is_scoped_to_the_example_manifest() -> None: ignore_document = yaml.safe_load( Path(".trivyignore.yaml").read_text(encoding="utf-8") ) - exceptions = {entry["id"]: entry for entry in ignore_document["misconfigurations"]} + exceptions = { + entry["id"]: entry for entry in ignore_document["misconfigurations"] + } assert trivy_config["ignorefile"] == ".trivyignore.yaml" assert exceptions["KSV-0125"]["paths"] == [ From d514733c2443d859da3703ba5326d73df2ba16b3 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 29 Aug 2026 21:30:40 +0000 Subject: [PATCH 3/8] =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=ED=8F=AC=EB=A7=B7=ED=8C=85=20=EB=A1=A4=EB=B0=B1=20=EB=B0=8F=20?= =?UTF-8?q?CI=20=EC=9E=AC=ED=8A=B8=EB=A6=AC=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 23216d930d67539160ff3282e24be7abde623ba5 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 29 Aug 2026 21:44:34 +0000 Subject: [PATCH 4/8] =?UTF-8?q?CI=20=EC=9E=AC=ED=8A=B8=EB=A6=AC=EA=B1=B0?= =?UTF-8?q?=20(Transient=20413=20error)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From f301616fe68f64acc86e2744dd81874c71ad8e43 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 29 Aug 2026 22:02:39 +0000 Subject: [PATCH 5/8] =?UTF-8?q?CI=20=EC=9E=AC=ED=8A=B8=EB=A6=AC=EA=B1=B0?= =?UTF-8?q?=20(Transient=20413=20error=202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 9d58f7da863c53a96532f0e8112644e9ff2417ba Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 29 Aug 2026 22:33:59 +0000 Subject: [PATCH 6/8] Wait for opencode-agent verdict From 0ffaea899a54df9163bbce725cd2f16993f7a68e Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 29 Aug 2026 22:52:34 +0000 Subject: [PATCH 7/8] =?UTF-8?q?opencode-agent=20=ED=8C=90=EC=A0=95=20?= =?UTF-8?q?=EB=8C=80=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 351101c055df52568f2aa55c5f442efdad604794 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sat, 29 Aug 2026 23:00:57 +0000 Subject: [PATCH 8/8] =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=99=98?= =?UTF-8?q?=EA=B2=BD=20=EA=B5=AC=EC=84=B1=20=EB=AC=B8=EC=A0=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_parse_endpoint.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/test_parse_endpoint.py b/tests/test_parse_endpoint.py index d8ed7e4a..a173032f 100644 --- a/tests/test_parse_endpoint.py +++ b/tests/test_parse_endpoint.py @@ -557,12 +557,7 @@ def spy_unlink(self, missing_ok=False): assert "tmp" in unlinked_paths[0].lower() or "temp" in unlinked_paths[0].lower() -def test_parse_endpoint_rejects_excessively_long_form_fields(monkeypatch): - from fastapi.testclient import TestClient - from newsdom_api.main import app - - monkeypatch.setenv("NEWSDOM_AUTH_MODE", "disabled") - monkeypatch.setenv("NEWSDOM_RUNTIME_PROFILE", "development") +def test_parse_endpoint_rejects_excessively_long_form_fields(): client = TestClient(app) long_string = "a" * 100