fix(lsp): prevent header injection in LSP transport ASCII decoding #10608
@@ -466,6 +466,11 @@ ensuring data is stored with proper parameter values.
|
||||
|
|
||||
|
||||
- **Timeline dashboard updated with 2026-04-18 progress snapshot** (#10288): Added schedule adherence tables and daily milestone snapshot for April 18, covering M3-M10 status including overdue milestones (M3-M7) and in-progress milestones (M8-M10). Risk assessment shows M6 (v3.5.0) highest risk with 1,130 open issues at 18.1% completion.
|
||||
|
||||
- **LSP transport header injection fix** (#10608 / #7112): The `_read_one_message()` method in
|
||||
|
HAL9001
commented
SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up. SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up.
|
||||
`src/cleveragents/lsp/transport.py` now uses `errors="strict"` instead of `errors="replace"` for
|
||||
|
HAL9001
commented
SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up. SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up.
|
||||
ASCII decoding of LSP headers, preventing header injection attacks. Non-ASCII bytes raise
|
||||
|
HAL9001
commented
SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up. SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up.
|
||||
`LspError`. A printable-ASCII guard rejects characters outside 0x20-0x7E range. Epic #824.
|
||||
|
HAL9001
commented
SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up. SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up. SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up.
|
||||
### Fixed
|
||||
|
||||
- **Concurrent ValidationPipeline stdout/stderr restoration** (#7623): Fixed a race
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up. SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up.
HAL9001
commented
SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up. SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up.
|
||||
@@ -13,7 +13,6 @@
|
||||
* Luis Mendes <luis.p.mendes@gmail.com>
|
||||
* Rui Hu <rui.hu@cleverthis.com>
|
||||
* HAL 9000 <hal9000@cleverthis.com> has contributed the parallel subplan execution scheduler (#9555): implemented `ParallelSubplanScheduler` with configurable concurrency control, dependency ordering, fail-fast mode, retry support, and pluggable merge strategies for the v3.3.0 subplan system.
|
||||
* HAL 9000 <hal9000@cleverthis.com> has contributed fix for #10813 — wiring DecisionService into PlanExecutor for strategy decision persistence during strategize.
|
||||
|
||||
* HAL9000 <HAL9000@cleverthis.com> has contributed CLI rendering improvements and TUI overlay visibility handling for `agents project context set` output.
|
||||
|
||||
@@ -50,6 +49,7 @@ Below are some of the specific details of various contributions.
|
||||
* This project was made possible thanks to considerable donation of time, money, and resources by CleverThis, Inc.
|
||||
* HAL 9000 has contributed automated bug fixes, CLI output formatting improvements, and ongoing maintenance as part of the CleverAgents automation system.
|
||||
* HAL 9000 has contributed the pr-review-pool-supervisor tracking prefix documentation fix (#7891): aligned all documentation references from the outdated `AUTO-REV-POOL` prefix to the correct `AUTO-REV-SUP` prefix used in production.
|
||||
* HAL 9000 has contributed the LSP transport header injection security fix (PR #10608): added strict ASCII validation to the ``_read_one_message()`` header parser to enforce US-ASCII-only headers per LSP specification, preventing malicious servers from injecting arbitrary Content-Length values that could cause the transport to read and parse unauthorized data as JSON-RPC messages.
|
||||
* HAL 9000 has contributed the file edit encoding parameter fix (PR #8258 / issue #7559).
|
||||
* HAL 9000 has contributed the architecture-pool-supervisor milestone assignment feature (PR #8188 / issue #7521): added `forgejo_update_pull_request` permission and documented the PR workflow for major spec changes, enabling automatic milestone assignment for specification PRs.
|
||||
* HAL 9000 has contributed the git worktree TOCTOU race condition fix (PR #8178 / issue #7507): replaced the unsafe mkdtemp() + rmdir() pattern with a parent-directory approach to eliminate the race window in concurrent git worktree operations.
|
||||
@@ -80,7 +80,7 @@ Below are some of the specific details of various contributions.
|
||||
* HAL 9000 has contributed the actor compiler `actor_ref` field fix (issue #1429): corrected `_map_node()` and `compile_actor()` in `src/cleveragents/actor/compiler.py` to read `actor_ref` from the top-level `NodeDefinition.actor_ref` field instead of `node.config.get("actor_ref")`, resolving silent failures on all SUBGRAPH nodes where `subgraph_refs` was always empty and `NodeConfig.subgraph` was always `None`.
|
||||
* HAL 9000 has contributed the removal of the unsupported executable resource type (PR #3248 / issue #3077): removed `executable` from `LSP_RESOURCE_TYPES` and `BUILTIN_TYPE_NAMES`, updated `agents resource list` CLI table columns to the spec-required `[Name, ID, Type, Phys/Virt, Children, Projects]`, deleted orphaned `examples/resource-types/executable.yaml`, and updated related BDD test coverage.
|
||||
* HAL 9000 has contributed the alembic fileConfig error handling fix (PR #8288 / issue #7874): wrapped the `fileConfig()` call in `alembic/env.py` with a `try/except` block to catch malformed INI logging configuration and emit clear, actionable error messages to stderr.
|
||||
* HAL 9000 has contributed the Definition-of-Done gating feature for the Apply phase (PR #8299 / issue #7927): `PlanLifecycleService.apply_plan` now evaluates DoD criteria before transitioning to Apply, raising `DoDGatingError` when required criteria fail and storing evaluation results in `plan.validation_summary`.
|
||||
* HAL 9000 has contributed the Definition-of-Done gating feature for the Apply phase (PR #8299 / issue #7927): `PlanLifecycleService.apply_plan` now evaluates DoD criteria before transitioning to the Apply phase, raising `DoDGatingError` when required criteria fail and storing evaluation results in `plan.validation_summary`.
|
||||
* HAL 9000 has contributed the engine cache TOCTOU race condition fix (PR #8265 / issue #7566): added `MEMORY_ENGINES_LOCK` to `engine_cache.py` and wrapped the check-and-set operation in `UnitOfWork.engine` with `with MEMORY_ENGINES_LOCK:` to prevent concurrent threads from creating duplicate in-memory SQLite engine instances; also fixed a cache-hit bug where `self._engine` was never assigned on a cache hit.
|
||||
* HAL 9000 has contributed the plan correct JSON output envelope fix (PR #8662 / issue #8584): restructured `agents plan correct --format json` output to nest correction fields under `data.correction` and pass `command="plan correct"` to `format_output`, producing the spec-required CLI envelope. Added three BDD scenarios validating `data.correction.mode` (revert and append modes) and the `command` field.
|
||||
* HAL 9000 has contributed BDD feature file tag coverage improvements (#9124 / pr #9183): added required `@a2a`, `@session`, and `@cli` Gherkin tags to 30 feature files (8 A2A, 7 session, 15 CLI) to enable selective tag-based test filtering via `behave --tags=a2a,session,cli`.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
@tdd_issue
|
||||
|
HAL9001
commented
BLOCKER — Tags on same line as This is the only feature file in the repository where tags appear inline with the With this format, the parser either discards the tags entirely or raises a parse error. All four scenarios lose the feature-level Required fix — split into separate lines: **BLOCKER — Tags on same line as `Feature:` keyword is invalid Gherkin**
This is the only feature file in the repository where tags appear inline with the `Feature:` keyword. Behave's Gherkin parser requires tags on their own line(s) before the keyword.
With this format, the parser either discards the tags entirely or raises a parse error. All four scenarios lose the feature-level `@tdd_issue` and `@tdd_issue_7112` tags, breaking the TDD tag tracking system.
**Required fix — split into separate lines:**
```gherkin
@tdd_issue
@tdd_issue_7112
Feature: LSP transport header injection vulnerability (issue #7112)
```
HAL9001
commented
BLOCKER — Feature-level tags on same line as Gherkin tags must appear on their own line(s) before the keyword. Placing them inline causes Behave to discard the This is the only feature file in the repo using this inline pattern. Required fix: **BLOCKER — Feature-level tags on same line as `Feature:` keyword (invalid Gherkin)**
Gherkin tags must appear on their own line(s) before the keyword. Placing them inline causes Behave to discard the `@tdd_issue` and `@tdd_issue_7112` feature-level tags from all scenarios.
This is the only feature file in the repo using this inline pattern.
**Required fix:**
```gherkin
@tdd_issue
@tdd_issue_7112
Feature: LSP transport header injection vulnerability (issue #7112)
```
HAL9001
commented
BLOCKER — Tags must be on their own line before Current: Gherkin requires tags on their own line(s) BEFORE the Required fix: Every other **BLOCKER — Tags must be on their own line before `Feature:`, not inline on the same line**
Current:
```
@tdd_issue @tdd_issue_7112 Feature: LSP transport header injection vulnerability (issue #7112)
```
Gherkin requires tags on their own line(s) BEFORE the `Feature:` keyword. Inline tags are discarded or cause a parse error — all scenarios lose the feature-level `@tdd_issue` and `@tdd_issue_7112` tags.
**Required fix:**
```gherkin
@tdd_issue
@tdd_issue_7112
Feature: LSP transport header injection vulnerability (issue #7112)
```
Every other `.feature` file in this repo uses this correct format.
|
||||
@tdd_issue_7112
|
||||
Feature: LSP transport header injection security
|
||||
|
||||
The ``_read_one_message()`` method in the LSP stdio transport must strictly
|
||||
enforce ASCII-only headers. Non-ASCII bytes silently replaced by the
|
||||
old ``errors="replace"`` path could be used to manipulate message
|
||||
boundaries and desynchronise the protocol.
|
||||
|
||||
@tdd_issue_7112
|
||||
Scenario: Non-ASCII byte in Content-Length value raises LspError
|
||||
Given a Transport mock with BytesIO stream containing b"Content-Length: 10\xc0\r\n\r\nhello\x00world"
|
||||
When _read_one_message() is invoked
|
||||
Then it should raise an LspError exception
|
||||
|
HAL9001
commented
BLOCKER — Trailing whitespace on this line This line ends with 2 trailing spaces before the newline ( Required fix: Remove the 2 trailing spaces from the end of this line. **BLOCKER — Trailing whitespace on this line**
This line ends with 2 trailing spaces before the newline (`LspError \n`). Ruff W291 will flag this as a lint error.
**Required fix:** Remove the 2 trailing spaces from the end of this line.
|
||||
And the error message must contain "non-ASCII"
|
||||
|
||||
@tdd_issue_7112
|
||||
Scenario: Non-ASCII byte in a valid Content-Length name raises LspError
|
||||
Given a Transport mock with BytesIO stream containing b"Content-Length\xef\x08: 99\r\n\r\n{\"jsonrpc\":\"2.0\"}"
|
||||
When _read_one_message() is invoked
|
||||
Then it should raise an LspError exception
|
||||
And the error message must contain "non-ASCII"
|
||||
|
||||
@tdd_issue_7112
|
||||
Scenario: Non-ASCII byte in an unrecognized header raises LspError
|
||||
Given a Transport mock with BytesIO stream containing b"Cache-Control\xef\x08: no-cache\r\nContent-Length: 5\r\n\r\n{\"id\":1}"
|
||||
When _read_one_message() is invoked
|
||||
Then it should raise an LspError exception
|
||||
And the error message must contain "non-ASCII"
|
||||
|
||||
@tdd_issue_7112
|
||||
Scenario: Valid ASCII headers are processed correctly
|
||||
Given a Transport mock with BytesIO stream containing b"Content-Length: 43\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"success\"}"
|
||||
When _read_one_message() is invoked
|
||||
Then it should return a parsed JSON dict
|
||||
And the result must contain "jsonrpc" == "2.0"
|
||||
And the result must contain "id" == 1
|
||||
And the result must contain "result" == "success"
|
||||
@@ -0,0 +1,130 @@
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
# pyright: reportRedeclaration=false
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
"""Step definitions for LSP transport header injection security (issue #7112).
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
Mocked ``StdioTransport`` using a ``MagicMock`` subprocess and
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
a ``BytesIO``-based stdout so that non-ASCII header bytes can be
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
injected and the strict-ASCII enforcement guard exercised without
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
requiring a real language server.
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
"""
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
from __future__ import annotations
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
import select
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
from io import BytesIO
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
from typing import Any
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
from behave import given, then, when
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
from cleveragents.lsp.errors import LspError
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
from cleveragents.lsp.transport import StdioTransport
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def patched_select(
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
readable: list[Any],
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
*_args: Any,
|
||||
|
HAL9001
commented
BLOCKER — Custom Behave parse type The Behave raises Simplest fix (Option B — no registration required): Change the step to accept a plain string and The feature file step text ( **BLOCKER — Custom Behave parse type `:r` is not registered anywhere; step collection raises `ParseTypeError`**
The `{raw_headers:r}` format specifier requires a custom type named `r` to be registered with Behave's parse engine. No such registration exists in `features/environment.py`, `features/steps/*.py`, `behave.ini`, or any other project file (confirmed by full-repo search).
Behave raises `ParseTypeError: Unknown type specifier 'r'` during step-collection, before any test runs. All four scenarios fail at discovery.
**Simplest fix (Option B — no registration required):** Change the step to accept a plain string and `eval` it:
```python
@given("a Transport mock with BytesIO stream containing {raw_headers}")
def step_transport_with_streams(context: Any, raw_headers: str) -> None:
data: bytes = eval(raw_headers) # b"..." literal from feature file
context.stream = BytesIO(data)
...
```
The feature file step text (`b"Content-Length: 10\xc0..."`) will be passed as the string `raw_headers` and `eval()` will convert it to bytes. No type registration needed.
HAL9001
commented
BLOCKER — Custom parse type The Simplest fix — remove This is consistent with test patterns used elsewhere in this codebase and requires no type registration. **BLOCKER — Custom parse type `:r` not registered**
The `:r` specifier in `{raw_headers:r}` is not a built-in `parse` type. No `register_type` call for `r` exists anywhere in `features/`. Behave raises `ParseTypeError: Unknown type specifier 'r'` at step-collection time before any scenario can run — all four scenarios fail at discovery.
**Simplest fix — remove `:r` and use plain string + eval:**
```python
@given("a Transport mock with BytesIO stream containing {raw_headers}")
def step_transport_with_streams(context: Any, raw_headers: str) -> None:
data: bytes = eval(raw_headers) # safe in test-only context
context.stream = BytesIO(data)
...
```
This is consistent with test patterns used elsewhere in this codebase and requires no type registration.
HAL9001
commented
BLOCKER — Custom parse type
Recommended fix (Option B — simpler): Drop Alternative (Option A): Register a bytes-literal parse type in **BLOCKER — Custom parse type `:r` is not registered; step discovery fails for all scenarios**
`{raw_headers:r}` uses a custom Behave/parse type specifier `:r` that is not a built-in `parse` type and is not registered anywhere in `features/`. Behave raises `ParseTypeError: Unknown type specifier 'r'` during step-collection — all four scenarios fail before running.
**Recommended fix (Option B — simpler):** Drop `:r` and use `eval()` inside the step:
```python
@given("a Transport mock with BytesIO stream containing {raw_headers}")
def step_transport_with_streams(context: Any, raw_headers: str) -> None:
data: bytes = eval(raw_headers) # raw_headers is e.g. b"Content-Length: 10\\xc0..."
context.stream = BytesIO(data)
...
```
**Alternative (Option A):** Register a bytes-literal parse type in `features/environment.py` using `parse.with_pattern` + `register_type`.
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
**_kwargs: Any,
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
) -> tuple[list[Any], list[Any], list[Any]]:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
"""Patch ``select.select`` to return a ready file descriptor immediately.
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
Returns a proper 3-tuple matching the ``select.select()`` API contract:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
``([readable[0]], [], [])`` rather than just ``[readable[0]]`` which
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
would cause ``ValueError`` during tuple unpacking in ``_read_one_message()``.
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
"""
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
if readable:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
return ([readable[0]], [], [])
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
return ([], [], [])
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
# ── Given steps ──────────────────────────────────────────────────────────
|
||||
|
HAL9001
commented
BLOCKER — Fix by patching The same fix must be applied to all three **BLOCKER** — `context.mock_process.stdout` is set to a `BytesIO` object, but `_read_one_message()` calls `select.select([stdout], [], [], timeout)` which requires a real Unix file descriptor. `BytesIO` has no `fileno()` and raises `io.UnsupportedOperation: fileno` when passed to `select.select()`. This exception is NOT caught by `except LspError as e:`, so it propagates unhandled, failing the scenario before the ASCII decode logic is ever exercised.
Fix by patching `select.select` in the transport module so it returns the mock stdout immediately:
```python
from unittest.mock import patch
with patch("cleveragents.lsp.transport.select") as mock_select:
mock_select.select.return_value = ([context.mock_process.stdout], [], [])
try:
context.transport.read_message(timeout=1.0)
except LspError as e:
context.exception = e
```
The same fix must be applied to all three `@when` step definitions that use `BytesIO` as the stdout mock (lines 39, 53, 67, and the valid-message step at line ~80). This is the root cause of the `CI / unit_tests` failure.
HAL9001
commented
BLOCKER — This and the other three Required fix — wrap the Apply this pattern to all four **BLOCKER** — This and the other three `@when` step implementations still use `BytesIO` as stdout without patching `select.select`. `_read_one_message()` calls `select.select([stdout], [], [], timeout)` (transport.py line 244). `BytesIO` has no file descriptor: `BytesIO.fileno()` raises `io.UnsupportedOperation: fileno` BEFORE the ASCII decode logic runs. This exception is not `LspError`, so the `except LspError` handler does not catch it — Behave sees an ERROR, not a PASS. This is the root cause of `CI / unit_tests` FAILING.
**Required fix** — wrap the `read_message()` call with a `select` patch in all four `@when` steps:
```python
from unittest.mock import patch
with patch("cleveragents.lsp.transport.select") as mock_select:
mock_select.select.return_value = ([context.mock_process.stdout], [], [])
try:
context.transport.read_message(timeout=1.0)
except LspError as e:
context.exception = e
```
Apply this pattern to all four `@when` step functions.
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@given("a Transport mock with BytesIO stream containing {raw_headers}")
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_transport_with_streams(context: Any, raw_headers: str) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
"""Set up a transport whose subprocess.stdout is a BytesIO initialised
|
||||
|
HAL9001
commented
BLOCKER — Incorrect mock:
This means the test never reaches the The same problem affects all four Required fix: Patch Apply this pattern to every Automated by CleverAgents Bot **BLOCKER — Incorrect mock: `BytesIO` is incompatible with `select.select()`**
`StdioTransport._read_one_message()` calls `select.select([stdout], [], [], timeout)` (transport.py line 244). `select.select()` requires a real OS-level file descriptor — `BytesIO` has no `fileno()` and raises `UnsupportedOperation: fileno` immediately.
This means the test never reaches the `line.decode("ascii", errors="strict")` call and the `UnsupportedOperation` exception propagates out of the `try: … except LspError:` block uncaught, causing the Behave step to fail with an unexpected exception.
The same problem affects all four `@when` step functions.
**Required fix:** Patch `select.select` to simulate readiness before calling `read_message()`. For example:
```python
from unittest.mock import patch
with patch("cleveragents.lsp.transport.select") as mock_sel:
mock_sel.select.return_value = ([context.mock_process.stdout], [], [])
try:
context.transport.read_message(timeout=1.0)
except LspError as e:
context.exception = e
```
Apply this pattern to every `@when` step that calls `context.transport.read_message()`.
---
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
with the specified raw header+body bytes."""
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
data: bytes = eval(raw_headers)
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
transport = object.__new__(StdioTransport) # Bypass __init__ validation
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
transport._process = MagicMock()
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
transport._process.poll.return_value = None # Pretend process is alive
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
context.stream = BytesIO(data)
|
||||
|
HAL9001
commented
BLOCKER — Trailing whitespace (ruff This line contains 4 trailing spaces on an otherwise blank line. Ruff Required fix: Delete the 4 trailing spaces so this is a completely empty line (just a newline character). This is the only whitespace violation in the new files and is the root cause of the 1m5s lint CI failure. **BLOCKER — Trailing whitespace (ruff `W291`) — root cause of `CI / lint` failure**
This line contains 4 trailing spaces on an otherwise blank line. Ruff `W291` flags trailing whitespace on non-empty lines.
**Required fix:** Delete the 4 trailing spaces so this is a completely empty line (just a newline character).
This is the only whitespace violation in the new files and is the root cause of the 1m5s lint CI failure.
HAL9001
commented
BLOCKER P0 — Trailing whitespace causes Line 50 contains 4 trailing spaces ( Fix: delete the 4 spaces on this line so it is a plain empty line ( Automated by CleverAgents Bot **BLOCKER P0 — Trailing whitespace causes `CI / lint` failure**
Line 50 contains 4 trailing spaces (` \n` instead of `\n`). With `select = ["E", "F", "W", "B", "UP", "I", "SIM", "RUF"]` in `pyproject.toml`, ruff rule `W291` (trailing whitespace on non-empty line) or `W293` (whitespace before blank line) fires here.
Fix: delete the 4 spaces on this line so it is a plain empty line (`\n`).
---
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
HAL9001
commented
BLOCKER — Trailing whitespace (W291) This line contains 4 trailing spaces: Required fix: Delete the 4 trailing spaces so the line is completely empty ( **BLOCKER — Trailing whitespace (W291)**
This line contains 4 trailing spaces: ` \n` (spaces before the newline). Ruff reports this as `W291 trailing whitespace`. This is the root cause of `CI / lint` failing.
**Required fix:** Delete the 4 trailing spaces so the line is completely empty (`\n` only).
HAL9001
commented
BLOCKER — Trailing whitespace on this blank line (4 spaces) This line contains 4 trailing spaces, causing Required fix: Delete all trailing spaces — this line should be completely empty. **BLOCKER — Trailing whitespace on this blank line (4 spaces)**
This line contains 4 trailing spaces, causing `ruff W291` (trailing whitespace). This is a contributing cause of `CI / lint` FAILING.
**Required fix:** Delete all trailing spaces — this line should be completely empty.
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
transport._process.stdout = context.stream
|
||||
|
HAL9001
commented
BLOCKER —
The real Unpacking Required fix: This also applies to the second **BLOCKER — `_patched_select` returns 1-element list instead of 3-tuple; causes `ValueError: not enough values to unpack` in every test**
`transport.py` line 236 unpacks the result of `select.select` as a 3-tuple:
```python
ready, _, _ = select.select([stdout], [], [], timeout)
```
The real `select.select` always returns `(rlist, wlist, xlist)`. Your patch returns:
```python
return [readable[0]] # only 1 element
```
Unpacking `[stdout_obj]` into `ready, _, _` raises `ValueError: not enough values to unpack (expected 3, got 1)`. This exception propagates to `except Exception as exc` in the step, so `context.raised_error` is a `ValueError`, not an `LspError`. The assertion `isinstance(context.raised_error, (LspError, UnicodeDecodeError))` then fails.
**Required fix:**
```python
def _patched_select(readable, *_args, **_kwargs):
if readable:
return ([readable[0]], [], []) # correct 3-tuple
return ([], [], []) # timeout
```
This also applies to the second `select.select` call inside `_read_one_message` (used for the body read after headers are parsed).
HAL9001
commented
BLOCKER — This function returns a 1-element list This raises Required fix: Note: **BLOCKER — `_patched_select` returns wrong type**
This function returns a 1-element list `[readable[0]]` but `transport.py` unpacks the return as a 3-tuple:
```python
ready, _, _ = select.select([stdout], [], [], timeout)
```
This raises `ValueError: not enough values to unpack (expected 3, got 1)` immediately, before any `LspError` assertion is reached. The bare `except Exception` block catches it and stores it as `context.raised_error`, causing the assertion `isinstance(..., LspError)` to fail.
**Required fix:**
```python
def _patched_select(readable, *_args: Any, **_kwargs: Any) -> tuple[list[Any], list[Any], list[Any]]:
if readable:
return ([readable[0]], [], []) # Correct 3-tuple matching select.select() contract
return ([], [], []) # Timeout path
```
Note: `select.select` is called twice in `_read_one_message` — once per header line in the while loop, and once for the body read. Both calls unpack a 3-tuple and both will hit this error.
HAL9001
commented
BLOCKER —
Required fix: Note: **BLOCKER — `_patched_select` returns 1-element list instead of required 3-tuple**
`_read_one_message()` unpacks `select.select()` as `ready, _, _ = select.select(...)` — a 3-tuple. This function returns `[readable[0]]` (1-element list) or `[]`, causing `ValueError: not enough values to unpack (expected 3, got 1)` on every call. The ValueError is caught by bare `except Exception`, stored as `context.raised_error`, and the `isinstance(context.raised_error, (LspError, UnicodeDecodeError))` assertion fails for all scenarios.
**Required fix:**
```python
def _patched_select(
readable: list[Any],
*_args: Any,
**_kwargs: Any,
) -> tuple[list[Any], list[Any], list[Any]]:
if readable:
return ([readable[0]], [], []) # Correct 3-tuple matching select.select contract
return ([], [], []) # Timeout path
```
Note: `_read_one_message` calls `select.select` TWICE (header loop + body read) — both need correct 3-tuple.
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
context.transport = transport
|
||||
|
HAL9001
commented
BLOCKER P0 —
But This exception IS caught by Required fix: Automated by CleverAgents Bot **BLOCKER P0 — `_patched_select` returns wrong shape; causes `ValueError: not enough values to unpack`**
`transport.py` unpacks the return value of `select.select()` as a 3-tuple:
```python
ready, _, _ = select.select([stdout], [], [], timeout)
```
But `_patched_select` currently returns a 1-item list `[readable[0]]`. Python will raise `ValueError: not enough values to unpack (expected 3, got 1)` before the ASCII-decode code is reached.
This exception IS caught by `except Exception as exc` further down, but `isinstance(ValueError(), (LspError, UnicodeDecodeError))` is `False`, so the `@then "it should raise an LspError exception"` step FAILS. This is the root cause of `CI / unit_tests` FAILING.
**Required fix:**
```python
def _patched_select(readable, *_args, **_kwargs):
if readable:
return ([readable[0]], [], []) # 3-tuple: (ready_read, ready_write, exceptional)
return ([], [], [])
```
---
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
context.mock_process = transport._process
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
# ── When steps ───────────────────────────────────────────────────────────
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@when("_read_one_message() is invoked")
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_invoke_read_message(context: Any) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
"""Call ``_read_one_message`` on the mocked transport.
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
Because :meth:`select.select` does not work natively on ``BytesIO``, we
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
patch it so that a ready file descriptor is returned immediately,
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
unblocking ``stdout.readline()`` and driving the header-reading loop with
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
HAL9001
commented
Suggestion: Consider narrowing the bare Suggestion: Consider narrowing the bare `except Exception` (line 65) to catch only the specific exceptions you want to capture. While this is test-only code and catching all exceptions here is acceptable for comprehensive coverage, narrowing to `except (LspError, UnicodeDecodeError)` would make the captured error scope more explicit and document which exception types are considered valid outcomes.
|
||||
the data already sitting in the ``BytesIO`` buffer.
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
"""
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
with patch.object(select, "select", side_effect=patched_select):
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
context.raised_error = None
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
try:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
context.read_result = context.transport._read_one_message(timeout=1.0)
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
except Exception as exc:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
context.raised_error = exc
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
# ── Then steps ───────────────────────────────────────────────────────────
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@then("it should raise an LspError exception")
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_raises_lsp_error(context: Any) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert context.raised_error is not None, "Expected an error to be raised"
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert isinstance(context.raised_error, (LspError, UnicodeDecodeError)), (
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
f"Expected LspError or UnicodeDecodeError, got {type(context.raised_error).__name__}"
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
)
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@then("it should return a parsed JSON dict")
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_returns_parsed_json_dict(context: Any) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert context.raised_error is None
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert isinstance(context.read_result, dict), (
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
f"Expected parsed dict, got {type(context.read_result).__name__}"
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
)
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@then('the error message must contain "non-ASCII"')
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_error_contains_non_ascii(context: Any) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert context.raised_error is not None
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
error_text = str(context.raised_error).lower()
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert "non-ascii" in error_text or "unicode" in error_text
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@then('the result must contain "jsonrpc" == "2.0"')
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_result_has_jsonrpc(context: Any) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert isinstance(context.read_result, dict), "Result should be a dict"
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert context.read_result.get("jsonrpc") == "2.0"
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@then('the result must contain "id" == 1')
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_result_has_id(context: Any) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert isinstance(context.read_result, dict), "Result should be a dict"
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert context.read_result.get("id") == 1
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@then('the result must contain "result" == "success"')
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_result_has_result(context: Any) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert isinstance(context.read_result, dict), "Result should be a dict"
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert context.read_result.get("result") == "success"
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@then('the result must contain "Content-Length"')
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_result_has_content_length(context: Any) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert isinstance(context.read_result, dict), "Result should be a dict"
|
||||
|
HAL9001
commented
BLOCKER — Single-quoted string argument fails
Required fix: Change to Automated by CleverAgents Bot **BLOCKER — Single-quoted string argument fails `ruff format --check`**
`hasattr(context, 'read_result')` uses a single-quoted string. The project’s `pyproject.toml` configures `quote-style = "double"` for `ruff format`. The CI `lint` job runs `nox -s format -- --check` after `nox -s lint` — this line fails the format check.
**Required fix:** Change to `hasattr(context, "read_result")` (double quotes). The same fix applies to line 124 in `step_check_message_json_parsing`.
---
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
cl = context.read_result.get("Content-Length")
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert cl is None or isinstance(cl, int)
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@then("the transport should still be alive")
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
def step_transport_alive(context: Any) -> None:
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
assert context.mock_process.poll.return_value is None
|
||||
|
HAL9001
commented
SUGGESTION: The SUGGESTION: The `@then("the result must contain \"Content-Length\"")` step tests for content-length key presence but is not covered by any scenario in the feature file. Consider removing this dead step or adding a scenario that exercises it.
|
||||
@@ -27,6 +27,8 @@ from typing import Any
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
import structlog
|
||||
|
||||
from cleveragents.lsp.errors import LspError
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
# Maximum time (seconds) to wait for a graceful process termination
|
||||
@@ -123,36 +125,15 @@ class StdioTransport:
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
cwd=self._cwd,
|
||||
)
|
||||
except FileNotFoundError as exc:
|
||||
self._process = None
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
from cleveragents.lsp.errors import LspError
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
raise LspError(
|
||||
f"LSP server command not found: {self._command}",
|
||||
details={"command": self._command, "args": self._args},
|
||||
) from exc
|
||||
except OSError as exc:
|
||||
# Popen may have partially started the subprocess before
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
# raising (e.g. execve failure post-fork on some platforms).
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
# Ensure cleanup so the process does not leak into the caller's
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
# address space.
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
if self._process is not None:
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
self.stop()
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
self._process = None
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
from cleveragents.lsp.errors import LspError
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
raise LspError(
|
||||
f"Failed to start LSP server: {exc}",
|
||||
details={"command": self._command, "error": str(exc)},
|
||||
) from exc
|
||||
except Exception:
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
# Catch-all for any other low-level OSError / resource-error
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
# variants that might leave a zombie process behind.
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
if self._process is not None:
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
self.stop()
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
self._process = None
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
raise
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
# All post-Popen initialization logic must be placed within the
|
||||
# guarded block below to prevent orphaned subprocesses if init
|
||||
@@ -275,7 +256,23 @@ class StdioTransport:
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
return self._read_one_message(effective_timeout)
|
||||
|
||||
def _read_one_message(self, timeout: float) -> dict[str, Any] | None:
|
||||
"""Parse a single ``Content-Length`` framed JSON-RPC message."""
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
"""Parse a single ``Content-Length``-framed JSON-RPC message.
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
Header lines are decoded with ``errors="strict"``; any non-ASCII byte
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
raises :class:`~cleveragents.lsp.errors.LspError`. An additional
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
printable-ASCII guard rejects decoded headers containing characters
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
outside the codepoint range 0x20 (space) to 0x7E (tilde).
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
Returns
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
-------
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
dict[str, Any] | None
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
Parsed JSON body, or ``None`` on EOF / timeout.
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
Raises
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
------
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
LspError
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
If a header contains non-ASCII bytes or non-printable characters.
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
"""
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
assert self._process is not None
|
||||
assert self._process.stdout is not None
|
||||
|
||||
@@ -290,7 +287,20 @@ class StdioTransport:
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
line = stdout.readline()
|
||||
if not line:
|
||||
return None # EOF — server exited
|
||||
decoded = line.decode("ascii", errors="replace").strip()
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
try:
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
decoded = line.decode("ascii", errors="strict").strip()
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
except UnicodeDecodeError as exc:
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
raise LspError(
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
f"LSP header contains non-ASCII bytes: {exc}",
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
details={"raw_header": repr(line)},
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
) from exc
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
# Printable-ASCII guard: reject control characters
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
# outside the range 0x20 (space) through 0x7E (tilde).
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
if not all(0x20 <= ord(c) <= 0x7E for c in decoded):
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
raise LspError(
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
f"LSP header contains non-printable ASCII characters: {decoded!r}",
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
details={"raw_header": repr(line)},
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
)
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
if not decoded:
|
||||
break # Empty line = end of headers
|
||||
if decoded.lower().startswith("content-length:"):
|
||||
|
||||
|
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
HAL9001
commented
SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates SUGGESTION: Consider edge case for very long header lines. The printable-ASCII guard iterates `all(0x20 <= ord(c) <= 0x7E for c in decoded)` which is O(n) — fine for reasonable inputs but worth noting that extremely long headers could impact performance marginally.
|
||||
SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up.
SUGGESTION: Line 159 has a pre-existing single-space indentation before 'Updated' that may be flagged by ruff (expected continuation lines use 2-space indent). Not introduced by this PR but worth fixing in a follow-up.