curlx: dedupe basename copies into curlx_basename()

Also stop redefining system `basename()` symbol. Call `curlx_basename()`
instead, and map that to `basename()` if available.

Closes #20424
This commit is contained in:
Viktor Szakats 2026-01-25 05:35:00 +01:00
parent 0e2507a3c6
commit 6974bd7cc8
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
7 changed files with 54 additions and 79 deletions

View File

@ -25,6 +25,7 @@
LIB_CURLX_CFILES = \ LIB_CURLX_CFILES = \
curlx/base64.c \ curlx/base64.c \
curlx/basename.c \
curlx/dynbuf.c \ curlx/dynbuf.c \
curlx/fopen.c \ curlx/fopen.c \
curlx/inet_ntop.c \ curlx/inet_ntop.c \
@ -42,8 +43,9 @@ LIB_CURLX_CFILES = \
curlx/winapi.c curlx/winapi.c
LIB_CURLX_HFILES = \ LIB_CURLX_HFILES = \
curlx/binmode.h \
curlx/base64.h \ curlx/base64.h \
curlx/binmode.h \
curlx/basename.h \
curlx/curlx.h \ curlx/curlx.h \
curlx/dynbuf.h \ curlx/dynbuf.h \
curlx/fopen.h \ curlx/fopen.h \

View File

@ -21,23 +21,48 @@
* SPDX-License-Identifier: curl * SPDX-License-Identifier: curl
* *
***************************************************************************/ ***************************************************************************/
#include "tool_setup.h" #include "../curl_setup.h"
#ifndef HAVE_BASENAME #ifndef HAVE_BASENAME
#include "tool_bname.h" #include "basename.h"
char *tool_basename(char *path) /*
(Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
Edition)
The basename() function shall take the pathname pointed to by path and
return a pointer to the final component of the pathname, deleting any
trailing '/' characters.
If the string pointed to by path consists entirely of the '/' character,
basename() shall return a pointer to the string "/". If the string pointed
to by path is exactly "//", it is implementation-defined whether '/' or "//"
is returned.
If path is a null pointer or points to an empty string, basename() shall
return a pointer to the string ".".
The basename() function may modify the string pointed to by path, and may
return a pointer to static storage that may then be overwritten by a
subsequent call to basename().
The basename() function need not be reentrant. A function that is not
required to be reentrant is not required to be thread-safe.
*/
char *curlx_basename(char *path)
{ {
/* Ignore all the details above for now and make a quick and simple
implementation here */
char *s1; char *s1;
char *s2; char *s2;
s1 = strrchr(path, '/'); s1 = strrchr(path, '/');
s2 = strrchr(path, '\\'); s2 = strrchr(path, '\\');
if(s1 && s2) { if(s1 && s2)
path = (s1 > s2) ? s1 + 1 : s2 + 1; path = ((s1 > s2) ? s1 : s2) + 1;
}
else if(s1) else if(s1)
path = s1 + 1; path = s1 + 1;
else if(s2) else if(s2)
@ -46,4 +71,4 @@ char *tool_basename(char *path)
return path; return path;
} }
#endif /* HAVE_BASENAME */ #endif /* !HAVE_BASENAME */

View File

@ -1,5 +1,5 @@
#ifndef HEADER_CURL_TOOL_BNAME_H #ifndef HEADER_CURLX_BASENAME_H
#define HEADER_CURL_TOOL_BNAME_H #define HEADER_CURLX_BASENAME_H
/*************************************************************************** /***************************************************************************
* _ _ ____ _ * _ _ ____ _
* Project ___| | | | _ \| | * Project ___| | | | _ \| |
@ -23,14 +23,17 @@
* SPDX-License-Identifier: curl * SPDX-License-Identifier: curl
* *
***************************************************************************/ ***************************************************************************/
#include "tool_setup.h" #include "../curl_setup.h"
#ifndef HAVE_BASENAME #ifndef HAVE_BASENAME
char *curlx_basename(char *path);
#else
char *tool_basename(char *path); #ifdef HAVE_LIBGEN_H
#include <libgen.h>
#endif
#define basename(x) tool_basename(x) #define curlx_basename(x) basename(x)
#endif /* !HAVE_BASENAME */
#endif /* HAVE_BASENAME */ #endif /* HEADER_CURLX_BASENAME_H */
#endif /* HEADER_CURL_TOOL_BNAME_H */

View File

@ -31,6 +31,9 @@
* be. * be.
*/ */
#include "basename.h"
/* for curlx_basename() function */
#include "binmode.h" #include "binmode.h"
/* "binmode.h" provides macro CURLX_SET_BINMODE() */ /* "binmode.h" provides macro CURLX_SET_BINMODE() */

View File

@ -31,6 +31,7 @@ struct Curl_easy;
#include "curl_trc.h" #include "curl_trc.h"
#include "transfer.h" #include "transfer.h"
#include "strdup.h" #include "strdup.h"
#include "curlx/basename.h"
#include "curlx/strcopy.h" #include "curlx/strcopy.h"
#include "curlx/fopen.h" #include "curlx/fopen.h"
#include "curlx/base64.h" #include "curlx/base64.h"
@ -39,10 +40,6 @@ struct Curl_easy;
!defined(CURL_DISABLE_SMTP) || \ !defined(CURL_DISABLE_SMTP) || \
!defined(CURL_DISABLE_IMAP)) !defined(CURL_DISABLE_IMAP))
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
#include <libgen.h>
#endif
#include "rand.h" #include "rand.h"
#include "slist.h" #include "slist.h"
#include "curlx/dynbuf.h" #include "curlx/dynbuf.h"
@ -182,55 +179,6 @@ static FILE *vmsfopenread(const char *file, const char *mode)
#define fopen_read vmsfopenread #define fopen_read vmsfopenread
#endif /* !__VMS */ #endif /* !__VMS */
#ifndef HAVE_BASENAME
/*
(Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
Edition)
The basename() function shall take the pathname pointed to by path and
return a pointer to the final component of the pathname, deleting any
trailing '/' characters.
If the string pointed to by path consists entirely of the '/' character,
basename() shall return a pointer to the string "/". If the string pointed
to by path is exactly "//", it is implementation-defined whether '/' or "//"
is returned.
If path is a null pointer or points to an empty string, basename() shall
return a pointer to the string ".".
The basename() function may modify the string pointed to by path, and may
return a pointer to static storage that may then be overwritten by a
subsequent call to basename().
The basename() function need not be reentrant. A function that is not
required to be reentrant is not required to be thread-safe.
*/
static char *Curl_basename(char *path)
{
/* Ignore all the details above for now and make a quick and simple
implementation here */
char *s1;
char *s2;
s1 = strrchr(path, '/');
s2 = strrchr(path, '\\');
if(s1 && s2) {
path = (s1 > s2 ? s1 : s2) + 1;
}
else if(s1)
path = s1 + 1;
else if(s2)
path = s2 + 1;
return path;
}
#define basename(x) Curl_basename(x)
#endif /* !HAVE_BASENAME */
/* Set readback state. */ /* Set readback state. */
static void mimesetstate(struct mime_state *state, static void mimesetstate(struct mime_state *state,
enum mimestate tok, void *ptr) enum mimestate tok, void *ptr)
@ -319,7 +267,7 @@ static char *strippath(const char *fullfile)
the buffer it works on */ the buffer it works on */
if(!filename) if(!filename)
return NULL; return NULL;
base = curlx_strdup(basename(filename)); base = curlx_strdup(curlx_basename(filename));
curlx_free(filename); /* free temporary buffer */ curlx_free(filename); /* free temporary buffer */

View File

@ -34,6 +34,7 @@
# the official API, but we reuse the code here to avoid duplication. # the official API, but we reuse the code here to avoid duplication.
CURLX_CFILES = \ CURLX_CFILES = \
../lib/curlx/base64.c \ ../lib/curlx/base64.c \
../lib/curlx/basename.c \
../lib/curlx/dynbuf.c \ ../lib/curlx/dynbuf.c \
../lib/curlx/fopen.c \ ../lib/curlx/fopen.c \
../lib/curlx/multibyte.c \ ../lib/curlx/multibyte.c \
@ -76,7 +77,6 @@ CURL_CFILES = \
config2setopts.c \ config2setopts.c \
slist_wc.c \ slist_wc.c \
terminal.c \ terminal.c \
tool_bname.c \
tool_cb_dbg.c \ tool_cb_dbg.c \
tool_cb_hdr.c \ tool_cb_hdr.c \
tool_cb_prg.c \ tool_cb_prg.c \
@ -122,7 +122,6 @@ CURL_HFILES = \
config2setopts.h \ config2setopts.h \
slist_wc.h \ slist_wc.h \
terminal.h \ terminal.h \
tool_bname.h \
tool_cb_dbg.h \ tool_cb_dbg.h \
tool_cb_hdr.h \ tool_cb_hdr.h \
tool_cb_prg.h \ tool_cb_prg.h \

View File

@ -25,10 +25,6 @@
#if defined(_WIN32) || defined(MSDOS) #if defined(_WIN32) || defined(MSDOS)
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
# include <libgen.h>
#endif
#ifdef _WIN32 #ifdef _WIN32
# include <tlhelp32.h> # include <tlhelp32.h>
# undef PATH_MAX # undef PATH_MAX
@ -41,7 +37,6 @@
#endif #endif
#include "tool_cfgable.h" #include "tool_cfgable.h"
#include "tool_bname.h"
#include "tool_doswin.h" #include "tool_doswin.h"
#include "tool_msgs.h" #include "tool_msgs.h"
@ -327,7 +322,7 @@ static SANITIZEcode rename_if_reserved_dos(char ** const sanitized,
memcpy(buffer, file_name, len + 1); memcpy(buffer, file_name, len + 1);
base = basename(buffer); base = curlx_basename(buffer);
/* Rename reserved device names that are known to be accessible without \\.\ /* Rename reserved device names that are known to be accessible without \\.\
Examples: CON => _CON, CON.EXT => CON_EXT, CON:ADS => CON_ADS Examples: CON => _CON, CON.EXT => CON_EXT, CON:ADS => CON_ADS
@ -378,7 +373,7 @@ static SANITIZEcode rename_if_reserved_dos(char ** const sanitized,
/* the basename pointer must be updated since the path has expanded */ /* the basename pointer must be updated since the path has expanded */
if(p == buffer) if(p == buffer)
base = basename(buffer); base = curlx_basename(buffer);
} }
/* This is the legacy portion from rename_if_dos_device_name that checks for /* This is the legacy portion from rename_if_dos_device_name that checks for