Skip to content

fix(tools): close ROADMAP-02/03/04 — markdown escaping, bounded reads, finite results - #120

Merged
getdownandcode merged 4 commits into
mainfrom
fix/roadmap-02-03-04-tools-hardening
Oct 27, 2026
Merged

getdownandcode merged 4 commits into
mainfrom
fix/roadmap-02-03-04-tools-hardening

Conversation

@getdownandcode

Copy link
Copy Markdown
Owner

Small stacked hardening batch closing three P0 ROADMAP issues from the 2026-10-27 assessment. All changes are confined to agentkit/tools/builtin/ plus their unit tests, so no other in-flight work conflicts with this PR.

Closes #94 (ROADMAP-02 — SQL markdown cell escaping)
Closes #95 (ROADMAP-03 — read_file check-then-read race)
Closes #96 (ROADMAP-04 — calculator non-finite results)

What changed

#94 sql_readonly — escape and bound rendered cells

  • _format_cell / _escape_cell_text rewrite each cell: backslash first, then | → \|, newline/CR/tab → \n/\r/\t escapes, and every other C0/DEL control char → \uXXXX.
  • Rendered cell length capped at MAX_CELL_CHARS (200) with a [Truncated] marker, so one wide column can't eat the executor budget; column names get the same treatment.
  • A cell can no longer forge rows/columns or smuggle prompt structure (stored prompt injection).

#95 read_file — cap enforced on the bytes actually read

  • The cap used to be a stat().st_size check followed by a second open; a file grown between the two was read in full. One bounded read(max_bytes + 1) replaces it; oversize still fails with the same user-visible phrase, and an exact-cap file stays fully readable.

#96 calculator — reject non-finite results

  • 1e308 * 10 ** 3 previously rendered inf into the prompt. The final result is checked with math.isfinite; the propagating inf/nan becomes a structured ValueError.
  • Float literals that overflow double range (1e999 → inf at parse time) are rejected at the operand boundary.
  • The bare 1000/100 literals in the Pow guard become MAX_POW_BASE_MAGNITUDE / MAX_POW_PAIR_EXPONENT with unchanged values (behaviour preserved; existing guard tests pass untouched).

Tests

  • 11 new tests across test_tool_calculator.py, test_tool_read_file.py, test_tool_sql_readonly.py (incl. one lying-st_size regression that fails on the old read code, and adversarial-cell scenarios both unit and end-to-end through the sqlite fixture).
  • pytest: 494 passed, 30 skipped (was 483 passed); real-infra tier unchanged.
  • ruff check ., ruff format --check ., mypy agentkit tests: clean.
  • Note: mypy agentkit tests examples hits the pre-existing demo.py dual-module-name error on main (CI correctly runs mypy agentkit tests).

…a prior stat

The cap was checked via stat().st_size and then enforced by a second open,
so a file grown between the two calls was read in full. One bounded read of
max_bytes + 1 closes the check-then-read window; an exact-cap file stays
fully readable. Regression test simulates the race with a lying st_size.

Closes #95 (ROADMAP-03)
…air guard

Float overflow (1e308 * 10 ** 3) previously rendered 'inf' into the prompt,
and an overflowing float literal (1e999) silently parsed to inf at AST level
and flowed through every operation. The result is now checked with
math.isfinite at the exit, and non-finite literals are rejected at the
operand boundary. The bare 1000/100 literals in the Pow guard become
MAX_POW_BASE_MAGNITUDE / MAX_POW_PAIR_EXPONENT with unchanged values.

Closes #96 (ROADMAP-04)
Cell values were inserted into the markdown table unescaped, so a value
containing a pipe, newline or control character could forge table rows and
smuggle prompt structure — stored prompt injection through database data.
Escapes are applied per cell (backslash first), the rendered cell length is
capped (MAX_CELL_CHARS), and column names get the same treatment.

Closes #94 (ROADMAP-02)
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-27T17:54:10.976013Z 3701aa2 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@getdownandcode
getdownandcode merged commit 78f0ace into main Oct 27, 2026
4 checks passed
@getdownandcode
getdownandcode deleted the fix/roadmap-02-03-04-tools-hardening branch October 27, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant