fix: release GET AT expression values

This commit is contained in:
Hermes Agent
2026-09-24 21:39:29 +00:00
parent eca642d8d8
commit 8183d0a9fa
3 changed files with 53 additions and 2 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ Verified in this checkout on 2026-09-23:
- `./claro doctor`: all checks `OK`.
- `./claro validate`: validation passed.
The memory cleanup slices release the previous deep value when a runtime variable or map entry is overwritten, release temporary split argument arrays and strings from `DO`, `CALL`, `TEXT ... CONTAINS`, and `RANDOM`, release loaded program paths, lines, and pointer arrays at the end of each script run, and now release the remaining runtime-owned variables, functions, modules, classes, import paths, captured output, return value, and error strings before the interpreter exits. The expression evaluator now releases discarded intermediate `Value` operands and command boundaries release evaluated `SET`/`SAY` values after copying or printing them. `FOR EACH` now releases its copied collection after iteration, preventing discarded list/map copies from accumulating in long scripts. `IF` and `DO ... TIMES` now release their temporary control-expression values after branch/loop selection. `ASK` now releases evaluated prompt values and temporary input values after converting/copying them into runtime storage. Focused coverage is `tools/validate_memory_cleanup.py`, `tools/validate_expression_cleanup.py`, `tools/validate_control_flow_cleanup.py`, `tools/validate_control_expression_cleanup.py`, and `tools/validate_ask_prompt_cleanup.py`; each focused cleanup validator runs an ASan/UBSan build with LeakSanitizer checking. Verified on 2026-09-24: `python3 tools/validate_ask_prompt_cleanup.py` passes (2,000 prompt/input operations under ASan/UBSan/LSan); `make -s all`, `./claro test`, `./claro doctor`, and `./claro validate` all pass. A malformed-input ASan/UBSan/LSan smoke run did not pass: it reports two leaked `rt_error` message strings (140 bytes total) at `src/claro.c:142`. This unrelated existing diagnostic-path leak remains unaddressed and blocks claiming sanitizer-clean malformed-input handling. The `COUNT ... AS` command now releases its evaluated list/map value after extracting the item count. `python3 tools/validate_count_expression_cleanup.py` first reproduced a 28,000-byte leak across 2,000 list expressions, then passed with LeakSanitizer enabled after the fix. Remaining memory-growth areas include other expression temporaries and command boundaries. The `RUN COMMAND` path remains trusted shell execution, not a sandbox.
The memory cleanup slices release the previous deep value when a runtime variable or map entry is overwritten, release temporary split argument arrays and strings from `DO`, `CALL`, `TEXT ... CONTAINS`, and `RANDOM`, release loaded program paths, lines, and pointer arrays at the end of each script run, and now release the remaining runtime-owned variables, functions, modules, classes, import paths, captured output, return value, and error strings before the interpreter exits. The expression evaluator now releases discarded intermediate `Value` operands and command boundaries release evaluated `SET`/`SAY` values after copying or printing them. `FOR EACH` now releases its copied collection after iteration, preventing discarded list/map copies from accumulating in long scripts. `IF` and `DO ... TIMES` now release their temporary control-expression values after branch/loop selection. `ASK` now releases evaluated prompt values and temporary input values after converting/copying them into runtime storage. Focused coverage is `tools/validate_memory_cleanup.py`, `tools/validate_expression_cleanup.py`, `tools/validate_control_flow_cleanup.py`, `tools/validate_control_expression_cleanup.py`, and `tools/validate_ask_prompt_cleanup.py`; each focused cleanup validator runs an ASan/UBSan build with LeakSanitizer checking. Verified on 2026-09-24: `python3 tools/validate_ask_prompt_cleanup.py` passes (2,000 prompt/input operations under ASan/UBSan/LSan); `make -s all`, `./claro test`, `./claro doctor`, and `./claro validate` all pass. A malformed-input ASan/UBSan/LSan smoke run did not pass: it reports two leaked `rt_error` message strings (140 bytes total) at `src/claro.c:142`. This unrelated existing diagnostic-path leak remains unaddressed and blocks claiming sanitizer-clean malformed-input handling. The `COUNT ... AS` command now releases its evaluated list/map value after extracting the item count. `python3 tools/validate_count_expression_cleanup.py` first reproduced a 28,000-byte leak across 2,000 list expressions, then passed with LeakSanitizer enabled after the fix. `GET ... AT ... AS ...` now releases its copied collection and empty-result temporary after storing the selected item; `python3 tools/validate_get_expression_cleanup.py` first reproduced 34,000 bytes of leaks across 2,000 empty-list lookups, then passed with LeakSanitizer enabled after the fix. Remaining memory-growth areas include other expression temporaries and command boundaries. The `RUN COMMAND` path remains trusted shell execution, not a sandbox.
The `RUN COMMAND` path now decodes POSIX `pclose()` wait status before storing `LASTEXIT`, so a child that exits with code 3 exposes `3` rather than the encoded status `768`. Focused coverage is `tests/42_last_exit_code.claro`. HTTP responses now have a 1,048,576-byte cap and marker-like response bodies are preserved while extracting the final HTTP status marker. Focused coverage is `tools/validate_http_hardening.py`. Remaining memory-growth areas include other expression temporaries. Claro remains a trusted-script interpreter, not a sandbox.