From 5241ab5673f48ee5f4b892b489bf5475ad4ffcf7 Mon Sep 17 00:00:00 2001 From: Rui He Date: Sat, 18 Jul 2026 21:20:41 -0400 Subject: [PATCH] tool_cb_hdr: check the etag file write results in save_etag save_etag() returns CURL_WRITEFUNC_ERROR when the ftruncate/fseek of the etag file fails, but the subsequent fwrite() and fputc() results were ignored and the fflush() return was (void)-cast. A write failure after a successful truncate (a full disk, a quota, or an I/O error) left the --etag-save file empty or partially written while curl still exited successfully. A later --etag-compare run then reads the empty validator and silently loses the conditional request. Check fwrite/fputc/fflush and return CURL_WRITEFUNC_ERROR on failure, the same way the truncate failure in the same function is already handled. Co-Authored-By: Claude Fable 5 --- src/tool_cb_hdr.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c index 918fe1907e..8b481d7cb9 100644 --- a/src/tool_cb_hdr.c +++ b/src/tool_cb_hdr.c @@ -273,10 +273,13 @@ static size_t save_etag(const char *etag_h, const char *endp, toolx_ftruncate(fd, 0))) return CURL_WRITEFUNC_ERROR; - fwrite(etag_h, 1, etag_length, etag_save->stream); - /* terminate with newline */ - fputc('\n', etag_save->stream); - (void)fflush(etag_save->stream); + /* a failed etag write must surface, not be silently discarded */ + if(fwrite(etag_h, 1, etag_length, etag_save->stream) != etag_length || + /* terminate with newline */ + fputc('\n', etag_save->stream) == EOF || + fflush(etag_save->stream)) { + return CURL_WRITEFUNC_ERROR; /* etag write failed */ + } } } return 0; /* ok */