fix: release remaining runtime-owned values
This commit is contained in:
@@ -28,9 +28,9 @@ Verified in this checkout on 2026-09-23:
|
|||||||
- `./claro doctor`: all checks `OK`.
|
- `./claro doctor`: all checks `OK`.
|
||||||
- `./claro validate`: validation passed.
|
- `./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`, and now release loaded program paths, lines, and pointer arrays at the end of each script run. Focused coverage is `tools/validate_memory_cleanup.py`; it reports `PASS: expression token allocations are released` under an ASan/UBSan build with LeakSanitizer checking and rejects any remaining `load_program` leak report while exercising repeated four-argument calls plus string/list/map overwrites. Remaining memory-growth areas include final runtime teardown for variables/functions/classes/modules and other expression temporaries. 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. Focused coverage is `tools/validate_memory_cleanup.py`; it reports `PASS: expression token allocations are released` under an ASan/UBSan build with LeakSanitizer checking and rejects any remaining `load_program` report while exercising repeated four-argument calls plus string/list/map overwrites. Remaining memory-growth areas include other expression temporaries. 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 final runtime teardown for variables/functions/classes/modules and other expression temporaries. Claro remains a trusted-script interpreter, 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.
|
||||||
|
|
||||||
`RUN COMMAND` is documented and validated as a trusted-code capability: it executes shell commands with the user's permissions and is not a sandbox. Claro does not claim untrusted-script safety or use a fragile blacklist sanitizer. Focused documentation coverage is `tools/validate_trusted_command_docs.py`.
|
`RUN COMMAND` is documented and validated as a trusted-code capability: it executes shell commands with the user's permissions and is not a sandbox. Claro does not claim untrusted-script safety or use a fragile blacklist sanitizer. Focused documentation coverage is `tools/validate_trusted_command_docs.py`.
|
||||||
|
|
||||||
|
|||||||
+3
-1
File diff suppressed because one or more lines are too long
@@ -64,6 +64,9 @@ def main() -> int:
|
|||||||
if "static void value_free(Value v)" not in source or "value_free(v->val);" not in source:
|
if "static void value_free(Value v)" not in source or "value_free(v->val);" not in source:
|
||||||
print("FAIL: overwritten runtime values are not released")
|
print("FAIL: overwritten runtime values are not released")
|
||||||
return 1
|
return 1
|
||||||
|
if "static void runtime_free(Runtime *rt)" not in source:
|
||||||
|
print("FAIL: runtime-owned values have no final cleanup boundary")
|
||||||
|
return 1
|
||||||
functional = subprocess.run(
|
functional = subprocess.run(
|
||||||
[str(binary), str(script)], cwd=ROOT, text=True,
|
[str(binary), str(script)], cwd=ROOT, text=True,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
|
|||||||
Reference in New Issue
Block a user