tool_cb_hdr: only truncate etags output when regular file

When sending the output to stdout it cannot truncate.

Add test1619 to verify --etag-save to stdout

Spotted by Codex Security

Closes #21103
This commit is contained in:
Daniel Stenberg 2026-03-26 14:45:37 +01:00
parent e1fdbdd16f
commit d63432d1f8
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 61 additions and 11 deletions

View file

@ -263,18 +263,23 @@ static size_t save_etag(const char *etag_h, const char *endp,
if(eot >= etag_h) {
size_t etag_length = eot - etag_h + 1;
/*
* Truncate the etag save stream, it can have an existing etag value.
*/
curlx_struct_stat file;
int fd = fileno(etag_save->stream);
if((fd != -1) &&
!curlx_fstat(fd, &file) &&
(S_ISREG(file.st_mode))) {
/*
* Truncate regular files to avoid stale etag content.
*/
#ifdef HAVE_FTRUNCATE
if(ftruncate(fileno(etag_save->stream), 0)) {
return CURL_WRITEFUNC_ERROR;
}
if(ftruncate(fileno(etag_save->stream), 0))
return CURL_WRITEFUNC_ERROR;
#else
if(fseek(etag_save->stream, 0, SEEK_SET)) {
return CURL_WRITEFUNC_ERROR;
}
if(fseek(etag_save->stream, 0, SEEK_SET))
return CURL_WRITEFUNC_ERROR;
#endif
}
fwrite(etag_h, 1, etag_length, etag_save->stream);
/* terminate with newline */