lib: use Curl_str_* instead of strtok_r()

Helps avoid extra mallocs. Gets rid of the private strtok_r
implementation.

Closes #16360
This commit is contained in:
Daniel Stenberg 2025-02-17 09:43:45 +01:00
parent 076444ec46
commit 676de7f580
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
26 changed files with 102 additions and 397 deletions

View File

@ -250,7 +250,6 @@ if(_CURL_OLD_LINUX)
else() else()
set(HAVE_STROPTS_H 0) # glibc 2.30 or newer. https://sourceware.org/legacy-ml/libc-alpha/2019-08/msg00029.html set(HAVE_STROPTS_H 0) # glibc 2.30 or newer. https://sourceware.org/legacy-ml/libc-alpha/2019-08/msg00029.html
endif() endif()
set(HAVE_STRTOK_R 1)
set(HAVE_STRUCT_SOCKADDR_STORAGE 1) set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
set(HAVE_STRUCT_TIMEVAL 1) set(HAVE_STRUCT_TIMEVAL 1)
if(ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "iOS") if(ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "iOS")

View File

@ -44,13 +44,6 @@ if(MINGW)
set(HAVE_UTIME_H 1) # wrapper to sys/utime.h set(HAVE_UTIME_H 1) # wrapper to sys/utime.h
set(HAVE_DIRENT_H 1) set(HAVE_DIRENT_H 1)
set(HAVE_OPENDIR 1) set(HAVE_OPENDIR 1)
if(MINGW64_VERSION)
if(NOT MINGW64_VERSION VERSION_LESS 4.0)
set(HAVE_STRTOK_R 1)
else()
set(HAVE_STRTOK_R 0)
endif()
endif()
else() else()
set(HAVE_LIBGEN_H 0) set(HAVE_LIBGEN_H 0)
set(HAVE_FTRUNCATE 0) set(HAVE_FTRUNCATE 0)
@ -81,7 +74,6 @@ else()
set(HAVE_SNPRINTF 0) set(HAVE_SNPRINTF 0)
endif() endif()
set(HAVE_BASENAME 0) set(HAVE_BASENAME 0)
set(HAVE_STRTOK_R 0)
set(HAVE_FILE_OFFSET_BITS 0) set(HAVE_FILE_OFFSET_BITS 0)
endif() endif()
endif() endif()

View File

@ -1707,7 +1707,6 @@ check_function_exists("sendmsg" HAVE_SENDMSG)
check_function_exists("sendmmsg" HAVE_SENDMMSG) check_function_exists("sendmmsg" HAVE_SENDMMSG)
check_symbol_exists("select" "${CURL_INCLUDES}" HAVE_SELECT) # proto/bsdsocket.h sys/select.h sys/socket.h check_symbol_exists("select" "${CURL_INCLUDES}" HAVE_SELECT) # proto/bsdsocket.h sys/select.h sys/socket.h
check_symbol_exists("strdup" "string.h" HAVE_STRDUP) check_symbol_exists("strdup" "string.h" HAVE_STRDUP)
check_symbol_exists("strtok_r" "string.h" HAVE_STRTOK_R)
check_symbol_exists("memrchr" "string.h" HAVE_MEMRCHR) check_symbol_exists("memrchr" "string.h" HAVE_MEMRCHR)
check_symbol_exists("alarm" "unistd.h" HAVE_ALARM) check_symbol_exists("alarm" "unistd.h" HAVE_ALARM)
check_symbol_exists("fcntl" "fcntl.h" HAVE_FCNTL) check_symbol_exists("fcntl" "fcntl.h" HAVE_FCNTL)

View File

@ -4043,7 +4043,6 @@ CURL_CHECK_FUNC_SOCKET
CURL_CHECK_FUNC_SOCKETPAIR CURL_CHECK_FUNC_SOCKETPAIR
CURL_CHECK_FUNC_STRDUP CURL_CHECK_FUNC_STRDUP
CURL_CHECK_FUNC_STRERROR_R CURL_CHECK_FUNC_STRERROR_R
CURL_CHECK_FUNC_STRTOK_R
case $host in case $host in
*msdosdjgpp) *msdosdjgpp)

View File

@ -5,3 +5,4 @@ banfunc snprintf
banfunc vsnprint banfunc vsnprint
banfunc strtoul banfunc strtoul
banfunc strtol banfunc strtol
banfunc strtok_r

View File

@ -229,7 +229,6 @@ LIB_CFILES = \
strequal.c \ strequal.c \
strerror.c \ strerror.c \
strparse.c \ strparse.c \
strtok.c \
strtoofft.c \ strtoofft.c \
system_win32.c \ system_win32.c \
telnet.c \ telnet.c \
@ -367,7 +366,6 @@ LIB_HFILES = \
strdup.h \ strdup.h \
strerror.h \ strerror.h \
strparse.h \ strparse.h \
strtok.h \
strtoofft.h \ strtoofft.h \
system_win32.h \ system_win32.h \
telnet.h \ telnet.h \

View File

@ -152,9 +152,6 @@
/* Define if you have the <stropts.h> header file. */ /* Define if you have the <stropts.h> header file. */
#undef HAVE_STROPTS_H #undef HAVE_STROPTS_H
/* Define if you have the `strtok_r' function. */
#define HAVE_STRTOK_R
/* Define if you have the <sys/param.h> header file. */ /* Define if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H #define HAVE_SYS_PARAM_H

View File

@ -109,7 +109,6 @@
#define HAVE_STDBOOL_H 1 #define HAVE_STDBOOL_H 1
#define HAVE_STRCASECMP 1 #define HAVE_STRCASECMP 1
#define HAVE_STRDUP 1 #define HAVE_STRDUP 1
#define HAVE_STRTOK_R 1
#define HAVE_STRUCT_TIMEVAL 1 #define HAVE_STRUCT_TIMEVAL 1
#define HAVE_SYS_IOCTL_H 1 #define HAVE_SYS_IOCTL_H 1
#define HAVE_SYS_PARAM_H 1 #define HAVE_SYS_PARAM_H 1

View File

@ -138,9 +138,6 @@
/* Define if you have the <strings.h> header file. */ /* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H #undef HAVE_STRINGS_H
/* Define if you have the `strtok_r' function. */
#undef HAVE_STRTOK_R
/* Define if you have the <sys/param.h> header file. */ /* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H #undef HAVE_SYS_PARAM_H

View File

@ -225,11 +225,6 @@
#define HAVE_BASENAME 1 #define HAVE_BASENAME 1
#endif #endif
/* Define to 1 if you have the strtok_r function. */
#if defined(__MINGW32__) && !defined(__MINGW32CE__)
#define HAVE_STRTOK_R 1
#endif
/* Define to 1 if you have the signal function. */ /* Define to 1 if you have the signal function. */
#ifndef UNDER_CE #ifndef UNDER_CE
#define HAVE_SIGNAL 1 #define HAVE_SIGNAL 1

View File

@ -76,7 +76,6 @@ Example set of cookies:
#include "urldata.h" #include "urldata.h"
#include "cookie.h" #include "cookie.h"
#include "psl.h" #include "psl.h"
#include "strtok.h"
#include "sendf.h" #include "sendf.h"
#include "slist.h" #include "slist.h"
#include "share.h" #include "share.h"

View File

@ -547,9 +547,6 @@
/* Define to 1 if you have the <stropts.h> header file. */ /* Define to 1 if you have the <stropts.h> header file. */
#cmakedefine HAVE_STROPTS_H 1 #cmakedefine HAVE_STROPTS_H 1
/* Define to 1 if you have the strtok_r function. */
#cmakedefine HAVE_STRTOK_R 1
/* Define to 1 if you have the memrchr function. */ /* Define to 1 if you have the memrchr function. */
#cmakedefine HAVE_MEMRCHR 1 #cmakedefine HAVE_MEMRCHR 1

View File

@ -50,7 +50,6 @@
#include "curl_hmac.h" #include "curl_hmac.h"
#include "curl_sasl.h" #include "curl_sasl.h"
#include "warnless.h" #include "warnless.h"
#include "strtok.h"
#include "sendf.h" #include "sendf.h"
/* The last 3 #include files should be in this order */ /* The last 3 #include files should be in this order */
#include "curl_printf.h" #include "curl_printf.h"

View File

@ -668,7 +668,6 @@
# ifdef __minix # ifdef __minix
/* Minix 3 versions up to at least 3.1.3 are missing these prototypes */ /* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
extern char *strtok_r(char *s, const char *delim, char **last);
extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp); extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp);
# endif # endif

View File

@ -44,7 +44,7 @@
#include "cf-haproxy.h" #include "cf-haproxy.h"
#include "cf-https-connect.h" #include "cf-https-connect.h"
#include "socks.h" #include "socks.h"
#include "strtok.h" #include "strparse.h"
#include "vtls/vtls.h" #include "vtls/vtls.h"
#include "vquic/vquic.h" #include "vquic/vquic.h"
@ -341,18 +341,18 @@ static struct trc_cft_def trc_cfts[] = {
#endif #endif
}; };
static void trc_apply_level_by_name(const char * const token, int lvl) static void trc_apply_level_by_name(struct Curl_str *token, int lvl)
{ {
size_t i; size_t i;
for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) { for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) {
if(strcasecompare(token, trc_cfts[i].cft->name)) { if(Curl_str_casecompare(token, trc_cfts[i].cft->name)) {
trc_cfts[i].cft->log_level = lvl; trc_cfts[i].cft->log_level = lvl;
break; break;
} }
} }
for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) { for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) {
if(strcasecompare(token, trc_feats[i].feat->name)) { if(Curl_str_casecompare(token, trc_feats[i].feat->name)) {
trc_feats[i].feat->log_level = lvl; trc_feats[i].feat->log_level = lvl;
break; break;
} }
@ -375,42 +375,32 @@ static void trc_apply_level_by_category(int category, int lvl)
static CURLcode trc_opt(const char *config) static CURLcode trc_opt(const char *config)
{ {
char *token, *tok_buf, *tmp; struct Curl_str out;
int lvl; while(!Curl_str_until(&config, &out, 32, ',')) {
int lvl = CURL_LOG_LVL_INFO;
const char *token = out.str;
tmp = strdup(config); if(*token == '-') {
if(!tmp) lvl = CURL_LOG_LVL_NONE;
return CURLE_OUT_OF_MEMORY; Curl_str_nudge(&out, 1);
token = Curl_strtok_r(tmp, ", ", &tok_buf);
while(token) {
switch(*token) {
case '-':
lvl = CURL_LOG_LVL_NONE;
++token;
break;
case '+':
lvl = CURL_LOG_LVL_INFO;
++token;
break;
default:
lvl = CURL_LOG_LVL_INFO;
break;
} }
if(strcasecompare(token, "all")) else if(*token == '+')
Curl_str_nudge(&out, 1);
if(Curl_str_casecompare(&out, "all"))
trc_apply_level_by_category(TRC_CT_NONE, lvl); trc_apply_level_by_category(TRC_CT_NONE, lvl);
else if(strcasecompare(token, "protocol")) else if(Curl_str_casecompare(&out, "protocol"))
trc_apply_level_by_category(TRC_CT_PROTOCOL, lvl); trc_apply_level_by_category(TRC_CT_PROTOCOL, lvl);
else if(strcasecompare(token, "network")) else if(Curl_str_casecompare(&out, "network"))
trc_apply_level_by_category(TRC_CT_NETWORK, lvl); trc_apply_level_by_category(TRC_CT_NETWORK, lvl);
else if(strcasecompare(token, "proxy")) else if(Curl_str_casecompare(&out, "proxy"))
trc_apply_level_by_category(TRC_CT_PROXY, lvl); trc_apply_level_by_category(TRC_CT_PROXY, lvl);
else else
trc_apply_level_by_name(token, lvl); trc_apply_level_by_name(&out, lvl);
token = Curl_strtok_r(NULL, ", ", &tok_buf); if(Curl_str_single(&config, ','))
break;
} }
free(tmp);
return CURLE_OK; return CURLE_OK;
} }

View File

@ -89,7 +89,7 @@
#include "progress.h" #include "progress.h"
#include "transfer.h" #include "transfer.h"
#include "strcase.h" #include "strcase.h"
#include "strtok.h" #include "strparse.h"
#include "curl_ldap.h" #include "curl_ldap.h"
#include "curl_multibyte.h" #include "curl_multibyte.h"
#include "curl_base64.h" #include "curl_base64.h"
@ -761,36 +761,17 @@ static int str2scope(const char *p)
return -1; return -1;
} }
/* /* number of entries in the attributes list */
* Split 'str' into strings separated by commas. static size_t num_entries(const char *s)
* Note: out[] points into 'str'.
*/
static bool split_str(char *str, char ***out, size_t *count)
{ {
char **res;
char *lasts;
char *s;
size_t i;
size_t items = 1; size_t items = 1;
s = strchr(str, ','); s = strchr(s, ',');
while(s) { while(s) {
items++; items++;
s = strchr(++s, ','); s = strchr(s + 1, ',');
} }
return items;
res = calloc(items, sizeof(char *));
if(!res)
return FALSE;
for(i = 0, s = Curl_strtok_r(str, ",", &lasts); s && i < items;
s = Curl_strtok_r(NULL, ",", &lasts), i++)
res[i] = s;
*out = res;
*count = items;
return TRUE;
} }
/* /*
@ -884,15 +865,8 @@ static int _ldap_url_parse2(struct Curl_easy *data,
*q++ = '\0'; *q++ = '\0';
if(*p) { if(*p) {
char **attributes; size_t count = num_entries(p); /* at least one */
size_t count = 0; const char *atp = p;
/* Split the string into an array of attributes */
if(!split_str(p, &attributes, &count)) {
rc = LDAP_NO_MEMORY;
goto quit;
}
/* Allocate our array (+1 for the NULL entry) */ /* Allocate our array (+1 for the NULL entry) */
#if defined(USE_WIN32_LDAP) #if defined(USE_WIN32_LDAP)
@ -901,27 +875,25 @@ static int _ldap_url_parse2(struct Curl_easy *data,
ludp->lud_attrs = calloc(count + 1, sizeof(char *)); ludp->lud_attrs = calloc(count + 1, sizeof(char *));
#endif #endif
if(!ludp->lud_attrs) { if(!ludp->lud_attrs) {
free(attributes);
rc = LDAP_NO_MEMORY; rc = LDAP_NO_MEMORY;
goto quit; goto quit;
} }
for(i = 0; i < count; i++) { for(i = 0; i < count; i++) {
char *unescaped; char *unescaped;
CURLcode result; CURLcode result;
struct Curl_str out;
LDAP_TRACE(("attr[%zu] '%s'\n", i, attributes[i])); if(Curl_str_until(&atp, &out, 1024, ','))
break;
LDAP_TRACE(("attr[%zu] '%.*s'\n", i, (int)out.len, out.str));
/* Unescape the attribute */ /* Unescape the attribute */
result = Curl_urldecode(attributes[i], 0, &unescaped, NULL, result = Curl_urldecode(out.str, out.len, &unescaped, NULL,
REJECT_ZERO); REJECT_ZERO);
if(result) { if(result) {
free(attributes);
rc = LDAP_NO_MEMORY; rc = LDAP_NO_MEMORY;
goto quit; goto quit;
} }
@ -933,10 +905,7 @@ static int _ldap_url_parse2(struct Curl_easy *data,
free(unescaped); free(unescaped);
if(!ludp->lud_attrs[i]) { if(!ludp->lud_attrs[i]) {
free(attributes);
rc = LDAP_NO_MEMORY; rc = LDAP_NO_MEMORY;
goto quit; goto quit;
} }
#else #else
@ -944,9 +913,9 @@ static int _ldap_url_parse2(struct Curl_easy *data,
#endif #endif
ludp->lud_attrs_dups++; ludp->lud_attrs_dups++;
if(Curl_str_single(&atp, ','))
break;
} }
free(attributes);
} }
p = q; p = q;

View File

@ -173,3 +173,23 @@ int Curl_str_newline(const char **linep)
} }
return STRE_NEWLINE; return STRE_NEWLINE;
} }
/* case insensitive compare that the parsed string matches the
given string. Returns non-zero on match. */
int Curl_str_casecompare(struct Curl_str *str, const char *check)
{
size_t clen = check ? strlen(check) : 0;
return ((str->len == clen) && strncasecompare(str->str, check, clen));
}
/* Trim off 'num' number of bytes from the beginning (left side) of the
string. If 'num' is larger than the string, return error. */
int Curl_str_nudge(struct Curl_str *str, size_t num)
{
if(num <= str->len) {
str->str += num;
str->len -= num;
return STRE_OK;
}
return STRE_OVERFLOW;
}

View File

@ -75,4 +75,10 @@ int Curl_str_octal(const char **linep, curl_off_t *nump, curl_off_t max);
return non-zero on error */ return non-zero on error */
int Curl_str_newline(const char **linep); int Curl_str_newline(const char **linep);
/* case insensitive compare that the parsed string matches the
given string. */
int Curl_str_casecompare(struct Curl_str *str, const char *check);
int Curl_str_nudge(struct Curl_str *str, size_t num);
#endif /* HEADER_CURL_STRPARSE_H */ #endif /* HEADER_CURL_STRPARSE_H */

View File

@ -1,68 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "curl_setup.h"
#ifndef HAVE_STRTOK_R
#include <stddef.h>
#include "strtok.h"
char *
Curl_strtok_r(char *ptr, const char *sep, char **end)
{
if(!ptr)
/* we got NULL input so then we get our last position instead */
ptr = *end;
/* pass all letters that are including in the separator string */
while(*ptr && strchr(sep, *ptr))
++ptr;
if(*ptr) {
/* so this is where the next piece of string starts */
char *start = ptr;
/* set the end pointer to the first byte after the start */
*end = start + 1;
/* scan through the string to find where it ends, it ends on a
null byte or a character that exists in the separator string */
while(**end && !strchr(sep, **end))
++*end;
if(**end) {
/* the end is not a null byte */
**end = '\0'; /* null-terminate it! */
++*end; /* advance the last pointer to beyond the null byte */
}
return start; /* return the position where the string starts */
}
/* we ended up on a null byte, there are no more strings to find! */
return NULL;
}
#endif /* this was only compiled if strtok_r was not present */

View File

@ -1,36 +0,0 @@
#ifndef HEADER_CURL_STRTOK_H
#define HEADER_CURL_STRTOK_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "curl_setup.h"
#include <stddef.h>
#ifdef HAVE_STRTOK_R
#include <string.h>
#define Curl_strtok_r strtok_r
#else
char *Curl_strtok_r(char *s, const char *delim, char **last);
#endif
#endif /* HEADER_CURL_STRTOK_H */

View File

@ -75,7 +75,6 @@
#include "strcase.h" #include "strcase.h"
#include "strerror.h" #include "strerror.h"
#include "escape.h" #include "escape.h"
#include "strtok.h"
#include "share.h" #include "share.h"
#include "content_encoding.h" #include "content_encoding.h"
#include "http_digest.h" #include "http_digest.h"

View File

@ -36,7 +36,6 @@
#include "vauth/vauth.h" #include "vauth/vauth.h"
#include "warnless.h" #include "warnless.h"
#include "strtok.h"
#include "sendf.h" #include "sendf.h"
#include "curl_printf.h" #include "curl_printf.h"

View File

@ -41,7 +41,7 @@
#include "curl_sha512_256.h" #include "curl_sha512_256.h"
#include "vtls/vtls.h" #include "vtls/vtls.h"
#include "warnless.h" #include "warnless.h"
#include "strtok.h" #include "strparse.h"
#include "strcase.h" #include "strcase.h"
#include "curl_printf.h" #include "curl_printf.h"
#include "rand.h" #include "rand.h"
@ -219,33 +219,21 @@ static bool auth_digest_get_key_value(const char *chlg,
static CURLcode auth_digest_get_qop_values(const char *options, int *value) static CURLcode auth_digest_get_qop_values(const char *options, int *value)
{ {
char *tmp; struct Curl_str out;
char *token;
char *tok_buf = NULL;
/* Initialise the output */ /* Initialise the output */
*value = 0; *value = 0;
/* Tokenise the list of qop values. Use a temporary clone of the buffer since while(!Curl_str_until(&options, &out, 32, ',')) {
Curl_strtok_r() ruins it. */ if(Curl_str_casecompare(&out, DIGEST_QOP_VALUE_STRING_AUTH))
tmp = strdup(options);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
token = Curl_strtok_r(tmp, ",", &tok_buf);
while(token) {
if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH))
*value |= DIGEST_QOP_VALUE_AUTH; *value |= DIGEST_QOP_VALUE_AUTH;
else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) else if(Curl_str_casecompare(&out, DIGEST_QOP_VALUE_STRING_AUTH_INT))
*value |= DIGEST_QOP_VALUE_AUTH_INT; *value |= DIGEST_QOP_VALUE_AUTH_INT;
else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF)) else if(Curl_str_casecompare(&out, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
*value |= DIGEST_QOP_VALUE_AUTH_CONF; *value |= DIGEST_QOP_VALUE_AUTH_CONF;
if(Curl_str_single(&options, ','))
token = Curl_strtok_r(NULL, ",", &tok_buf); break;
} }
free(tmp);
return CURLE_OK; return CURLE_OK;
} }
@ -504,10 +492,6 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
struct digestdata *digest) struct digestdata *digest)
{ {
bool before = FALSE; /* got a nonce before */ bool before = FALSE; /* got a nonce before */
bool foundAuth = FALSE;
bool foundAuthInt = FALSE;
char *token = NULL;
char *tmp = NULL;
/* If we already have received a nonce, keep that in mind */ /* If we already have received a nonce, keep that in mind */
if(digest->nonce) if(digest->nonce)
@ -551,29 +535,25 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
else if(strcasecompare(value, "qop")) { else if(strcasecompare(value, "qop")) {
char *tok_buf = NULL; const char *token = content;
/* Tokenize the list and choose auth if possible, use a temporary struct Curl_str out;
clone of the buffer since Curl_strtok_r() ruins it */ bool foundAuth = FALSE;
tmp = strdup(content); bool foundAuthInt = FALSE;
if(!tmp) /* Pass leading spaces */
return CURLE_OUT_OF_MEMORY; while(*token && ISBLANK(*token))
token++;
token = Curl_strtok_r(tmp, ",", &tok_buf); while(!Curl_str_until(&token, &out, 32, ',')) {
while(token) { if(Curl_str_casecompare(&out, DIGEST_QOP_VALUE_STRING_AUTH))
/* Pass additional spaces here */ foundAuth = TRUE;
else if(Curl_str_casecompare(&out,
DIGEST_QOP_VALUE_STRING_AUTH_INT))
foundAuthInt = TRUE;
if(Curl_str_single(&token, ','))
break;
while(*token && ISBLANK(*token)) while(*token && ISBLANK(*token))
token++; token++;
if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
foundAuth = TRUE;
}
else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
foundAuthInt = TRUE;
}
token = Curl_strtok_r(NULL, ",", &tok_buf);
} }
free(tmp);
/* Select only auth or auth-int. Otherwise, ignore */ /* Select only auth or auth-int. Otherwise, ignore */
if(foundAuth) { if(foundAuth) {
free(digest->qop); free(digest->qop);

View File

@ -34,7 +34,7 @@
#include "urldata.h" /* for the Curl_easy definition */ #include "urldata.h" /* for the Curl_easy definition */
#include "curl_base64.h" #include "curl_base64.h"
#include "strtok.h" #include "strparse.h"
#include "multiif.h" #include "multiif.h"
#include "strcase.h" #include "strcase.h"
#include "x509asn1.h" #include "x509asn1.h"
@ -341,30 +341,28 @@ static OSStatus sectransp_bio_cf_out_write(SSLConnectionRef connection,
CF_INLINE void GetDarwinVersionNumber(int *major, int *minor) CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
{ {
int mib[2]; int mib[2];
char *os_version;
size_t os_version_len; size_t os_version_len;
char *os_version_major, *os_version_minor; char buf[256];
char *tok_buf;
/* Get the Darwin kernel version from the kernel using sysctl(): */ /* Get the Darwin kernel version from the kernel using sysctl(): */
mib[0] = CTL_KERN; mib[0] = CTL_KERN;
mib[1] = KERN_OSRELEASE; mib[1] = KERN_OSRELEASE;
if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1) if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
return; return;
os_version = malloc(os_version_len*sizeof(char)); if(os_version_len < sizeof(buf)) {
if(!os_version) if(sysctl(mib, 2, buf, &os_version_len, NULL, 0) != -1) {
return; const char *os = buf;
if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) { curl_off_t fnum;
free(os_version); curl_off_t snum;
return; /* Parse the version: */
if(!Curl_str_number(&os, &fnum, INT_MAX) &&
!Curl_str_single(&os, '.') &&
!Curl_str_number(&os, &snum, INT_MAX)) {
*major = (int)fnum;
*minor = (int)snum;
}
}
} }
/* Parse the version: */
os_version_major = Curl_strtok_r(os_version, ".", &tok_buf);
os_version_minor = Curl_strtok_r(NULL, ".", &tok_buf);
*major = atoi(os_version_major);
*minor = atoi(os_version_minor);
free(os_version);
} }
#endif /* CURL_BUILD_MAC */ #endif /* CURL_BUILD_MAC */

View File

@ -4229,91 +4229,6 @@ AC_DEFUN([CURL_CHECK_FUNC_STRICMP], [
fi fi
]) ])
dnl CURL_CHECK_FUNC_STRTOK_R
dnl -------------------------------------------------
dnl Verify if strtok_r is available, prototyped, and
dnl can be compiled. If all of these are true, and
dnl usage has not been previously disallowed with
dnl shell variable curl_disallow_strtok_r, then
dnl HAVE_STRTOK_R will be defined.
AC_DEFUN([CURL_CHECK_FUNC_STRTOK_R], [
AC_REQUIRE([CURL_INCLUDES_STRING])dnl
#
tst_links_strtok_r="unknown"
tst_proto_strtok_r="unknown"
tst_compi_strtok_r="unknown"
tst_allow_strtok_r="unknown"
#
AC_MSG_CHECKING([if strtok_r can be linked])
AC_LINK_IFELSE([
AC_LANG_FUNC_LINK_TRY([strtok_r])
],[
AC_MSG_RESULT([yes])
tst_links_strtok_r="yes"
],[
AC_MSG_RESULT([no])
tst_links_strtok_r="no"
])
#
if test "$tst_links_strtok_r" = "yes"; then
AC_MSG_CHECKING([if strtok_r is prototyped])
AC_EGREP_CPP([strtok_r],[
$curl_includes_string
],[
AC_MSG_RESULT([yes])
tst_proto_strtok_r="yes"
],[
AC_MSG_RESULT([no])
tst_proto_strtok_r="no"
])
fi
#
if test "$tst_proto_strtok_r" = "yes"; then
AC_MSG_CHECKING([if strtok_r is compilable])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_string
]],[[
if(0 != strtok_r(0, "", 0))
return 1;
]])
],[
AC_MSG_RESULT([yes])
tst_compi_strtok_r="yes"
],[
AC_MSG_RESULT([no])
tst_compi_strtok_r="no"
])
fi
#
if test "$tst_compi_strtok_r" = "yes"; then
AC_MSG_CHECKING([if strtok_r usage allowed])
if test "x$curl_disallow_strtok_r" != "xyes"; then
AC_MSG_RESULT([yes])
tst_allow_strtok_r="yes"
else
AC_MSG_RESULT([no])
tst_allow_strtok_r="no"
fi
fi
#
AC_MSG_CHECKING([if strtok_r might be used])
if test "$tst_links_strtok_r" = "yes" &&
test "$tst_proto_strtok_r" = "yes" &&
test "$tst_compi_strtok_r" = "yes" &&
test "$tst_allow_strtok_r" = "yes"; then
AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED(HAVE_STRTOK_R, 1,
[Define to 1 if you have the strtok_r function.])
curl_cv_func_strtok_r="yes"
else
AC_MSG_RESULT([no])
curl_cv_func_strtok_r="no"
fi
])
dnl CURL_RUN_IFELSE dnl CURL_RUN_IFELSE
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl Wrapper macro to use instead of AC_RUN_IFELSE. It dnl Wrapper macro to use instead of AC_RUN_IFELSE. It

View File

@ -184,40 +184,6 @@ AC_DEFUN([CURL_CHECK_NEED_REENTRANT_STRERROR_R], [
fi fi
]) ])
dnl CURL_CHECK_NEED_REENTRANT_STRTOK_R
dnl -------------------------------------------------
dnl Checks if the preprocessor _REENTRANT definition
dnl makes function strtok_r compiler visible.
AC_DEFUN([CURL_CHECK_NEED_REENTRANT_STRTOK_R], [
AC_LINK_IFELSE([
AC_LANG_FUNC_LINK_TRY([strtok_r])
],[
tmp_strtok_r="yes"
],[
tmp_strtok_r="no"
])
if test "$tmp_strtok_r" = "yes"; then
AC_EGREP_CPP([strtok_r],[
#include <sys/types.h>
#include <string.h>
],[
tmp_strtok_r="proto_declared"
],[
AC_EGREP_CPP([strtok_r],[
#define _REENTRANT
#include <sys/types.h>
#include <string.h>
],[
tmp_strtok_r="proto_needs_reentrant"
tmp_need_reentrant="yes"
])
])
fi
])
dnl CURL_CHECK_NEED_REENTRANT_GETHOSTBYNAME_R dnl CURL_CHECK_NEED_REENTRANT_GETHOSTBYNAME_R
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl Checks if the preprocessor _REENTRANT definition dnl Checks if the preprocessor _REENTRANT definition
@ -300,9 +266,6 @@ AC_DEFUN([CURL_CHECK_NEED_REENTRANT_FUNCTIONS_R], [
if test "$tmp_need_reentrant" = "no"; then if test "$tmp_need_reentrant" = "no"; then
CURL_CHECK_NEED_REENTRANT_STRERROR_R CURL_CHECK_NEED_REENTRANT_STRERROR_R
fi fi
if test "$tmp_need_reentrant" = "no"; then
CURL_CHECK_NEED_REENTRANT_STRTOK_R
fi
if test "$tmp_need_reentrant" = "no"; then if test "$tmp_need_reentrant" = "no"; then
CURL_CHECK_NEED_REENTRANT_GETHOSTBYNAME_R CURL_CHECK_NEED_REENTRANT_GETHOSTBYNAME_R
fi fi