build: avoid overriding system symbols for fopen functions

By introducing wrappers for them in the curlx namespace:
`curlx_fopen()`, `curlx_fdopen()`, `curlx_fclose()`.

The undefine/redefine/`(function)()` methods broke on systems
implementing these functions as macros. E.g. AIX 32-bit's `fopen()`.

Also:
- rename `lib/fopen.*` to `lib/curl_fopen.*` (for `Curl_fopen()`)
  to make room for the newly added `curlx/fopen.h`.
- curlx: move file-related functions from `multibyte.c` to `fopen.c`.
- tests/server: stop using the curl-specific `fopen()` implementation
  on Windows. Unicode isn't used by runtests, and it isn't critical to
  run tests on longs path. It can be re-enabled if this becomes
  necessary, or if the wrapper receives a feature that's critical for
  test servers.

Reported-by: Andrew Kirillov
Bug: https://github.com/curl/curl/issues/18510#issuecomment-3274393640

Follow-up to bf7375ecc5 #18503
Follow-up to 9863599d69 #18502
Follow-up to 3bb5e58c10 #17827

Closes #18634
This commit is contained in:
Viktor Szakats 2025-09-14 15:34:18 +02:00
parent 10bac43b87
commit 20142f5d06
No known key found for this signature in database
GPG key ID: B5ABD165E2AEF201
65 changed files with 568 additions and 484 deletions

View file

@ -47,7 +47,7 @@ func_return() ;
a = sprintf(buffer, "%s", moo);
FILE *f = fopen("filename", "r");
FILE *f = curlx_fopen("filename", "r");
void startfunc(int a, int b) {
func();
@ -124,7 +124,7 @@ void startfunc(int a, int b) {
a = sprintf(buffer, "%s", moo);
^
./%LOGDIR/code1185.c:32:11: warning: use of non-binary fopen without FOPEN_* macro: r (FOPENMODE)
FILE *f = fopen("filename", "r");
FILE *f = curlx_fopen("filename", "r");
^
./%LOGDIR/code1185.c:34:30: warning: wrongly placed open brace (BRACEPOS)
void startfunc(int a, int b) {

View file

@ -34,6 +34,7 @@ UTILS_C = memptr.c testutil.c testtrace.c
UTILS_H = testutil.h testtrace.h unitcheck.h
CURLX_C = \
../../lib/curlx/fopen.c \
../../lib/curlx/warnless.c \
../../lib/curlx/multibyte.c \
../../lib/curlx/timediff.c \

View file

@ -30,7 +30,7 @@ static FILE *out_download;
static int setup_h2_serverpush(CURL *hnd, const char *url)
{
out_download = fopen("download_0.data", "wb");
out_download = curlx_fopen("download_0.data", "wb");
if(!out_download)
return 1; /* failed */
@ -72,7 +72,7 @@ static int server_push_callback(CURL *parent,
curl_msnprintf(filename, sizeof(filename) - 1, "push%u", count++);
/* here's a new stream, save it in a new file for each new push */
out_push = fopen(filename, "wb");
out_push = curlx_fopen(filename, "wb");
if(!out_push) {
/* if we cannot save it, deny it */
curl_mfprintf(stderr, "Failed to create output file for push\n");
@ -129,7 +129,7 @@ static CURLcode test_cli_h2_serverpush(const char *URL)
easy = curl_easy_init();
if(setup_h2_serverpush(easy, URL)) {
fclose(out_download);
curlx_fclose(out_download);
curl_mfprintf(stderr, "failed\n");
return (CURLcode)1;
}
@ -166,9 +166,9 @@ static CURLcode test_cli_h2_serverpush(const char *URL)
curl_multi_cleanup(multi_handle);
fclose(out_download);
curlx_fclose(out_download);
if(out_push)
fclose(out_push);
curlx_fclose(out_push);
return CURLE_OK;
}

View file

@ -94,7 +94,7 @@ static size_t my_write_d_cb(char *buf, size_t nitems, size_t buflen,
if(!t->out) {
curl_msnprintf(t->filename, sizeof(t->filename)-1, "download_%zu.data",
t->idx);
t->out = fopen(t->filename, "wb");
t->out = curlx_fopen(t->filename, "wb");
if(!t->out)
return 0;
}
@ -530,7 +530,7 @@ static CURLcode test_cli_hx_download(const char *URL)
for(i = 0; i < transfer_count_d; ++i) {
t = &transfer_d[i];
if(t->out) {
fclose(t->out);
curlx_fclose(t->out);
t->out = NULL;
}
if(t->easy) {

View file

@ -74,7 +74,7 @@ static size_t my_write_u_cb(char *buf, size_t nitems, size_t buflen,
if(!t->out) {
curl_msnprintf(t->filename, sizeof(t->filename)-1, "download_%zu.data",
t->idx);
t->out = fopen(t->filename, "wb");
t->out = curlx_fopen(t->filename, "wb");
if(!t->out)
return 0;
}
@ -494,7 +494,7 @@ static CURLcode test_cli_hx_upload(const char *URL)
for(i = 0; i < transfer_count_u; ++i) {
t = &transfer_u[i];
if(t->out) {
fclose(t->out);
curlx_fclose(t->out);
t->out = NULL;
}
if(t->easy) {

View file

@ -90,7 +90,7 @@ static CURLcode test_lib500(const char *URL)
if(!res) {
res = curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP, &ipstr);
if(libtest_arg2) {
FILE *moo = fopen(libtest_arg2, "wb");
FILE *moo = curlx_fopen(libtest_arg2, "wb");
if(moo) {
curl_off_t time_namelookup;
curl_off_t time_connect;
@ -163,7 +163,7 @@ static CURLcode test_lib500(const char *URL)
(long)(time_total % 1000000));
}
fclose(moo);
curlx_fclose(moo);
}
}
}

View file

@ -51,7 +51,7 @@ static CURLcode test_lib505(const char *URL)
return TEST_ERR_USAGE;
}
hd_src = fopen(libtest_arg2, "rb");
hd_src = curlx_fopen(libtest_arg2, "rb");
if(!hd_src) {
curl_mfprintf(stderr, "fopen failed with error (%d) %s\n",
errno, strerror(errno));
@ -70,19 +70,19 @@ static CURLcode test_lib505(const char *URL)
curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n",
errno, strerror(errno));
curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2);
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
if(!file_info.st_size) {
curl_mfprintf(stderr, "File %s has zero size!\n", libtest_arg2);
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
curl_mfprintf(stderr, "curl_global_init() failed\n");
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
@ -91,7 +91,7 @@ static CURLcode test_lib505(const char *URL)
if(!curl) {
curl_mfprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
@ -102,7 +102,7 @@ static CURLcode test_lib505(const char *URL)
curl_mfprintf(stderr, "curl_slist_append() failed\n");
curl_easy_cleanup(curl);
curl_global_cleanup();
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
headerlist = curl_slist_append(hl, buf_2);
@ -111,7 +111,7 @@ static CURLcode test_lib505(const char *URL)
curl_slist_free_all(hl);
curl_easy_cleanup(curl);
curl_global_cleanup();
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
headerlist = hl;
@ -144,7 +144,7 @@ test_cleanup:
curl_slist_free_all(headerlist);
/* close the local file */
fclose(hd_src);
curlx_fclose(hd_src);
curl_easy_cleanup(curl);
curl_global_cleanup();

View file

@ -77,7 +77,7 @@ static int t518_fopen_works(void)
fpa[i] = NULL;
}
for(i = 0; i < 3; i++) {
fpa[i] = fopen(DEV_NULL, FOPEN_READTEXT);
fpa[i] = curlx_fopen(DEV_NULL, FOPEN_READTEXT);
if(!fpa[i]) {
t518_store_errmsg("fopen failed", errno);
curl_mfprintf(stderr, "%s\n", t518_msgbuff);
@ -87,7 +87,7 @@ static int t518_fopen_works(void)
}
for(i = 0; i < 3; i++) {
if(fpa[i])
fclose(fpa[i]);
curlx_fclose(fpa[i]);
}
return ret;
}

View file

@ -42,7 +42,7 @@ static CURLcode test_lib525(const char *URL)
return TEST_ERR_USAGE;
}
hd_src = fopen(libtest_arg2, "rb");
hd_src = curlx_fopen(libtest_arg2, "rb");
if(!hd_src) {
curl_mfprintf(stderr, "fopen failed with error (%d) %s\n",
errno, strerror(errno));
@ -61,13 +61,13 @@ static CURLcode test_lib525(const char *URL)
curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n",
errno, strerror(errno));
curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2);
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_FSTAT;
}
res_global_init(CURL_GLOBAL_ALL);
if(res) {
fclose(hd_src);
curlx_fclose(hd_src);
return res;
}
@ -149,7 +149,7 @@ test_cleanup:
}
/* close the local file */
fclose(hd_src);
curlx_fclose(hd_src);
return res;
}

View file

@ -74,7 +74,7 @@ static int t537_fopen_works(void)
fpa[i] = NULL;
}
for(i = 0; i < 3; i++) {
fpa[i] = fopen(DEV_NULL, FOPEN_READTEXT);
fpa[i] = curlx_fopen(DEV_NULL, FOPEN_READTEXT);
if(!fpa[i]) {
t537_store_errmsg("fopen failed", errno);
curl_mfprintf(stderr, "%s\n", t537_msgbuff);
@ -84,7 +84,7 @@ static int t537_fopen_works(void)
}
for(i = 0; i < 3; i++) {
if(fpa[i])
fclose(fpa[i]);
curlx_fclose(fpa[i]);
}
return ret;
}

View file

@ -42,7 +42,7 @@ static CURLcode test_lib541(const char *URL)
return TEST_ERR_USAGE;
}
hd_src = fopen(libtest_arg2, "rb");
hd_src = curlx_fopen(libtest_arg2, "rb");
if(!hd_src) {
curl_mfprintf(stderr, "fopen failed with error (%d) %s\n",
errno, strerror(errno));
@ -61,19 +61,19 @@ static CURLcode test_lib541(const char *URL)
curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n",
errno, strerror(errno));
curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2);
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
if(!file_info.st_size) {
curl_mfprintf(stderr, "File %s has zero size!\n", libtest_arg2);
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
curl_mfprintf(stderr, "curl_global_init() failed\n");
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
@ -82,7 +82,7 @@ static CURLcode test_lib541(const char *URL)
if(!curl) {
curl_mfprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
@ -110,7 +110,7 @@ static CURLcode test_lib541(const char *URL)
test_cleanup:
/* close the local file */
fclose(hd_src);
curlx_fclose(hd_src);
curl_easy_cleanup(curl);
curl_global_cleanup();

View file

@ -54,10 +54,10 @@ static CURLcode test_lib566(const char *URL)
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD,
&content_length);
moo = fopen(libtest_arg2, "wb");
moo = curlx_fopen(libtest_arg2, "wb");
if(moo) {
curl_mfprintf(moo, "CL %.0f\n", content_length);
fclose(moo);
curlx_fclose(moo);
}
}

View file

@ -75,7 +75,7 @@ static CURLcode test_lib568(const char *URL)
fstat(sdp, &file_info);
close(sdp);
sdpf = fopen(libtest_arg2, "rb");
sdpf = curlx_fopen(libtest_arg2, "rb");
if(!sdpf) {
curl_mfprintf(stderr, "can't fopen %s\n", libtest_arg2);
res = TEST_ERR_MAJOR_BAD;
@ -94,7 +94,7 @@ static CURLcode test_lib568(const char *URL)
goto test_cleanup;
test_setopt(curl, CURLOPT_UPLOAD, 0L);
fclose(sdpf);
curlx_fclose(sdpf);
sdpf = NULL;
/* Make sure we can do a normal request now */
@ -159,7 +159,7 @@ static CURLcode test_lib568(const char *URL)
test_cleanup:
if(sdpf)
fclose(sdpf);
curlx_fclose(sdpf);
curl_free(stream_uri);

View file

@ -38,7 +38,7 @@ static CURLcode test_lib569(const char *URL)
int request = 1;
int i;
FILE *idfile = fopen(libtest_arg2, "wb");
FILE *idfile = curlx_fopen(libtest_arg2, "wb");
if(!idfile) {
curl_mfprintf(stderr, "couldn't open the Session ID File\n");
return TEST_ERR_MAJOR_BAD;
@ -46,7 +46,7 @@ static CURLcode test_lib569(const char *URL)
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
curl_mfprintf(stderr, "curl_global_init() failed\n");
fclose(idfile);
curlx_fclose(idfile);
return TEST_ERR_MAJOR_BAD;
}
@ -54,7 +54,7 @@ static CURLcode test_lib569(const char *URL)
if(!curl) {
curl_mfprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
fclose(idfile);
curlx_fclose(idfile);
return TEST_ERR_MAJOR_BAD;
}
@ -116,7 +116,7 @@ static CURLcode test_lib569(const char *URL)
test_cleanup:
if(idfile)
fclose(idfile);
curlx_fclose(idfile);
curl_free(stream_uri);
curl_easy_cleanup(curl);

View file

@ -95,7 +95,7 @@ static CURLcode test_lib571(const char *URL)
char *stream_uri = NULL;
int request = 1;
FILE *protofile = fopen(libtest_arg2, "wb");
FILE *protofile = curlx_fopen(libtest_arg2, "wb");
if(!protofile) {
curl_mfprintf(stderr, "Couldn't open the protocol dump file\n");
return TEST_ERR_MAJOR_BAD;
@ -103,14 +103,14 @@ static CURLcode test_lib571(const char *URL)
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
curl_mfprintf(stderr, "curl_global_init() failed\n");
fclose(protofile);
curlx_fclose(protofile);
return TEST_ERR_MAJOR_BAD;
}
curl = curl_easy_init();
if(!curl) {
curl_mfprintf(stderr, "curl_easy_init() failed\n");
fclose(protofile);
curlx_fclose(protofile);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
@ -194,7 +194,7 @@ test_cleanup:
curl_free(stream_uri);
if(protofile)
fclose(protofile);
curlx_fclose(protofile);
curl_easy_cleanup(curl);
curl_global_cleanup();

View file

@ -93,7 +93,7 @@ static CURLcode test_lib572(const char *URL)
fstat(params, &file_info);
close(params);
paramsf = fopen(libtest_arg2, "rb");
paramsf = curlx_fopen(libtest_arg2, "rb");
if(!paramsf) {
curl_mfprintf(stderr, "can't fopen %s\n", libtest_arg2);
res = TEST_ERR_MAJOR_BAD;
@ -110,7 +110,7 @@ static CURLcode test_lib572(const char *URL)
goto test_cleanup;
test_setopt(curl, CURLOPT_UPLOAD, 0L);
fclose(paramsf);
curlx_fclose(paramsf);
paramsf = NULL;
/* Heartbeat GET_PARAMETERS */
@ -163,7 +163,7 @@ static CURLcode test_lib572(const char *URL)
test_cleanup:
if(paramsf)
fclose(paramsf);
curlx_fclose(paramsf);
curl_free(stream_uri);

View file

@ -33,7 +33,7 @@ static size_t data_size = CURL_ARRAYSIZE(t578_testdata);
static int t578_progress_callback(void *clientp, double dltotal, double dlnow,
double ultotal, double ulnow)
{
FILE *moo = fopen(libtest_arg2, "wb");
FILE *moo = curlx_fopen(libtest_arg2, "wb");
(void)clientp;
(void)dltotal;
@ -45,7 +45,7 @@ static int t578_progress_callback(void *clientp, double dltotal, double dlnow,
else
curl_mfprintf(moo, "Progress callback called with UL %f out of %f\n",
ulnow, ultotal);
fclose(moo);
curlx_fclose(moo);
}
return 0;
}

View file

@ -35,11 +35,11 @@ static size_t last_ul_total = 0;
static void progress_final_report(void)
{
FILE *moo = fopen(libtest_arg2, "ab");
FILE *moo = curlx_fopen(libtest_arg2, "ab");
curl_mfprintf(moo ? moo : stderr, "Progress: end UL %zu/%zu\n",
last_ul, last_ul_total);
if(moo)
fclose(moo);
curlx_fclose(moo);
else
curl_mfprintf(stderr, "Progress: end UL, can't open %s\n", libtest_arg2);
started = FALSE;
@ -59,11 +59,11 @@ static int t579_progress_callback(void *clientp, double dltotal, double dlnow,
last_ul = (size_t)ulnow;
last_ul_total = (size_t)ultotal;
if(!started) {
FILE *moo = fopen(libtest_arg2, "ab");
FILE *moo = curlx_fopen(libtest_arg2, "ab");
curl_mfprintf(moo ? moo : stderr, "Progress: start UL %zu/%zu\n",
last_ul, last_ul_total);
if(moo)
fclose(moo);
curlx_fclose(moo);
else
curl_mfprintf(stderr, "Progress: start UL, can't open %s\n",
libtest_arg2);

View file

@ -243,7 +243,7 @@ static CURLcode test_lib582(const char *URL)
return TEST_ERR_USAGE;
}
hd_src = fopen(libtest_arg2, "rb");
hd_src = curlx_fopen(libtest_arg2, "rb");
if(!hd_src) {
curl_mfprintf(stderr, "fopen() failed with error (%d) %s\n",
errno, strerror(errno));
@ -262,7 +262,7 @@ static CURLcode test_lib582(const char *URL)
curl_mfprintf(stderr, "fstat() failed with error (%d) %s\n",
errno, strerror(errno));
curl_mfprintf(stderr, "Error opening file '%s'\n", libtest_arg2);
fclose(hd_src);
curlx_fclose(hd_src);
return TEST_ERR_FSTAT;
}
curl_mfprintf(stderr, "Set to upload %" CURL_FORMAT_CURL_OFF_T " bytes\n",
@ -270,7 +270,7 @@ static CURLcode test_lib582(const char *URL)
res_global_init(CURL_GLOBAL_ALL);
if(res != CURLE_OK) {
fclose(hd_src);
curlx_fclose(hd_src);
return res;
}
@ -356,7 +356,7 @@ test_cleanup:
curl_global_cleanup();
/* close the local file */
fclose(hd_src);
curlx_fclose(hd_src);
/* free local memory */
free(sockets.read.sockets);

View file

@ -39,7 +39,7 @@ static CURLcode test_lib591(const char *URL)
start_test_timing();
upload = fopen(libtest_arg3, "rb");
upload = curlx_fopen(libtest_arg3, "rb");
if(!upload) {
curl_mfprintf(stderr, "fopen() failed with error (%d) %s\n",
errno, strerror(errno));
@ -49,7 +49,7 @@ static CURLcode test_lib591(const char *URL)
res_global_init(CURL_GLOBAL_ALL);
if(res) {
fclose(upload);
curlx_fclose(upload);
return res;
}
@ -138,7 +138,7 @@ test_cleanup:
curl_global_cleanup();
/* close the local file */
fclose(upload);
curlx_fclose(upload);
return res;
}

View file

@ -82,10 +82,10 @@ static CURLcode test_lib599(const char *URL)
FILE *moo;
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD,
&content_length);
moo = fopen(libtest_arg2, "wb");
moo = curlx_fopen(libtest_arg2, "wb");
if(moo) {
curl_mfprintf(moo, "CL %.0f\n", content_length);
fclose(moo);
curlx_fclose(moo);
}
}

View file

@ -30,7 +30,7 @@ static int loadfile(const char *filename, void **filedata, size_t *filesize)
size_t datasize = 0;
void *data = NULL;
if(filename) {
FILE *fInCert = fopen(filename, "rb");
FILE *fInCert = curlx_fopen(filename, "rb");
if(fInCert) {
long cert_tell = 0;
@ -48,7 +48,7 @@ static int loadfile(const char *filename, void **filedata, size_t *filesize)
if((!data) ||
((int)fread(data, datasize, 1, fInCert) != 1))
continue_reading = FALSE;
fclose(fInCert);
curlx_fclose(fInCert);
if(!continue_reading) {
free(data);
datasize = 0;

View file

@ -1,4 +1,6 @@
allowfunc accept
allowfunc fclose
allowfunc fopen
allowfunc freeaddrinfo
allowfunc getaddrinfo
allowfunc recv

View file

@ -35,6 +35,7 @@ UTILS_H =
CURLX_C = \
../../lib/curlx/base64.c \
../../lib/curlx/fopen.c \
../../lib/curlx/inet_pton.c \
../../lib/curlx/inet_ntop.c \
../../lib/curlx/multibyte.c \

View file

@ -84,12 +84,12 @@ static CURLcode test_unit3200(const char *arg)
char *line;
curlx_dyn_init(&buf, len);
fp = fopen(arg, "wb");
fp = curlx_fopen(arg, "wb");
abort_unless(fp != NULL, "Cannot open testfile");
fwrite(filecontents[i], 1, strlen(filecontents[i]), fp);
fclose(fp);
curlx_fclose(fp);
fp = fopen(arg, "rb");
fp = curlx_fopen(arg, "rb");
abort_unless(fp != NULL, "Cannot open testfile");
curl_mfprintf(stderr, "Test %zd...", i);
@ -158,7 +158,7 @@ static CURLcode test_unit3200(const char *arg)
break;
}
curlx_dyn_free(&buf);
fclose(fp);
curlx_fclose(fp);
curl_mfprintf(stderr, "OK\n");
}
return (CURLcode)rc;