diff --git a/dist/safety.c b/dist/safety.c index 980b3f0..7446fd9 100644 --- a/dist/safety.c +++ b/dist/safety.c @@ -340,6 +340,7 @@ el_val_t handle_safety_contact_get(void) { if (str_eq(raw, EL_STR(""))) { return EL_STR("{\"configured\":false}"); } + el_val_t _reset = fs_read(EL_STR("")); return el_str_concat(el_str_concat(EL_STR("{\"configured\":true,\"contact\":"), raw), EL_STR("}")); return 0; } @@ -359,9 +360,8 @@ el_val_t handle_safety_contact_post(el_val_t body) { el_val_t crisis_str = ({ el_val_t _if_result_51 = 0; if (is_crisis) { _if_result_51 = (EL_STR("true")); } else { _if_result_51 = (EL_STR("false")); } _if_result_51; }); el_val_t now = time_format(time_now(), EL_STR("%Y-%m-%dT%H:%M:%SZ")); el_val_t contact_json = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"name\":\""), json_safe(name)), EL_STR("\"")), EL_STR(",\"contact_method\":\"")), json_safe(method)), EL_STR("\"")), EL_STR(",\"contact_value\":\"")), json_safe(value)), EL_STR("\"")), EL_STR(",\"relationship\":\"")), json_safe(rel)), EL_STR("\"")), EL_STR(",\"confirmed\":true")), EL_STR(",\"is_crisis_line\":")), crisis_str), EL_STR(",\"set_at\":\"")), now), EL_STR("\"}")); - fs_write(safety_contact_path(), contact_json); - el_val_t check = fs_read(safety_contact_path()); - if (str_eq(check, EL_STR(""))) { + el_val_t write_ok = fs_write(safety_contact_path(), contact_json); + if (write_ok == 0) { return EL_STR("{\"ok\":false,\"error\":\"write_failed\"}"); } return el_str_concat(el_str_concat(EL_STR("{\"configured\":true,\"contact\":"), contact_json), EL_STR(",\"ok\":true}")); diff --git a/dist/soul.c b/dist/soul.c index 0265c00..0ab6aa0 100644 --- a/dist/soul.c +++ b/dist/soul.c @@ -25754,6 +25754,7 @@ el_val_t handle_safety_contact_get(void) { if (str_eq(raw, EL_STR(""))) { return EL_STR("{\"configured\":false}"); } + el_val_t _reset = fs_read(EL_STR("")); return el_str_concat(el_str_concat(EL_STR("{\"configured\":true,\"contact\":"), raw), EL_STR("}")); return 0; } @@ -25773,9 +25774,8 @@ el_val_t handle_safety_contact_post(el_val_t body) { el_val_t crisis_str = ({ el_val_t _if_result_51 = 0; if (is_crisis) { _if_result_51 = (EL_STR("true")); } else { _if_result_51 = (EL_STR("false")); } _if_result_51; }); el_val_t now = time_format(time_now(), EL_STR("%Y-%m-%dT%H:%M:%SZ")); el_val_t contact_json = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"name\":\""), json_safe(name)), EL_STR("\"")), EL_STR(",\"contact_method\":\"")), json_safe(method)), EL_STR("\"")), EL_STR(",\"contact_value\":\"")), json_safe(value)), EL_STR("\"")), EL_STR(",\"relationship\":\"")), json_safe(rel)), EL_STR("\"")), EL_STR(",\"confirmed\":true")), EL_STR(",\"is_crisis_line\":")), crisis_str), EL_STR(",\"set_at\":\"")), now), EL_STR("\"}")); - fs_write(safety_contact_path(), contact_json); - el_val_t check = fs_read(safety_contact_path()); - if (str_eq(check, EL_STR(""))) { + el_val_t write_ok = fs_write(safety_contact_path(), contact_json); + if (write_ok == 0) { return EL_STR("{\"ok\":false,\"error\":\"write_failed\"}"); } return el_str_concat(el_str_concat(EL_STR("{\"configured\":true,\"contact\":"), contact_json), EL_STR(",\"ok\":true}")); diff --git a/safety.el b/safety.el index 0590916..e230813 100644 --- a/safety.el +++ b/safety.el @@ -438,6 +438,12 @@ fn safety_contact_path() -> String { fn handle_safety_contact_get() -> String { let raw: String = fs_read(safety_contact_path()) if str_eq(raw, "") { return "{\"configured\":false}" } + // fs_read set the runtime's binary-safe send length to len(raw); the HTTP + // response writer uses that length when non-zero, which would TRUNCATE this + // wrapped (longer) response to len(raw). Reset it with a no-op read of a + // missing path (fs_read zeroes the length before it opens) so the full + // response is sent. + let _reset: String = fs_read("") return "{\"configured\":true,\"contact\":" + raw + "}" } @@ -463,9 +469,12 @@ fn handle_safety_contact_post(body: String) -> String { + ",\"confirmed\":true" + ",\"is_crisis_line\":" + crisis_str + ",\"set_at\":\"" + now + "\"}" - fs_write(safety_contact_path(), contact_json) - // Read-back verify the write actually persisted. - let check: String = fs_read(safety_contact_path()) - if str_eq(check, "") { return "{\"ok\":false,\"error\":\"write_failed\"}" } + // Verify persistence via fs_write's return (1 = all bytes written, 0 = fail). + // The previous fs_read read-back set the runtime's binary-safe send length to + // the file size, which then TRUNCATED this longer JSON response to that size + // (the safety-contact 988 response was cut mid-"set_at"). Checking the write + // return avoids the fs_read entirely, so the full response is sent. + let write_ok: Int = fs_write(safety_contact_path(), contact_json) + if write_ok == 0 { return "{\"ok\":false,\"error\":\"write_failed\"}" } return "{\"configured\":true,\"contact\":" + contact_json + ",\"ok\":true}" }