ECC-1458: Thread safety: Use 'strtok_r' instead of 'strtok'

This commit is contained in:
Shahram Najm 2022-10-26 13:02:19 +01:00
parent eb3a5c2bae
commit 6490acab81
7 changed files with 57 additions and 69 deletions

View File

@ -23,36 +23,36 @@ extern "C" {
/* cmake config header */ /* cmake config header */
#ifdef HAVE_ECCODES_CONFIG_H #ifdef HAVE_ECCODES_CONFIG_H
#include "eccodes_config.h" #include "eccodes_config.h"
#endif #endif
/* autoconf config header */ /* autoconf config header */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#ifdef _LARGE_FILES #ifdef _LARGE_FILES
#undef _LARGE_FILE_API #undef _LARGE_FILE_API
#endif #endif
#endif #endif
#ifndef GRIB_INLINE #ifndef GRIB_INLINE
#define GRIB_INLINE #define GRIB_INLINE
#endif #endif
/* See ECC-670 */ /* See ECC-670 */
#if IS_BIG_ENDIAN #if IS_BIG_ENDIAN
#if GRIB_MEM_ALIGN #if GRIB_MEM_ALIGN
#define FAST_BIG_ENDIAN 1 #define FAST_BIG_ENDIAN 1
#else #else
#define FAST_BIG_ENDIAN 0 #define FAST_BIG_ENDIAN 0
#endif #endif
#endif #endif
#if IEEE_BE #if IEEE_BE
#define IEEE #define IEEE
#else #else
#if IEEE_LE #if IEEE_LE
#define IEEE #define IEEE
#endif #endif
#endif #endif
#include <stdio.h> #include <stdio.h>
@ -62,48 +62,49 @@ extern "C" {
#include "eccodes_windef.h" #include "eccodes_windef.h"
#ifndef ECCODES_ON_WINDOWS #ifndef ECCODES_ON_WINDOWS
#include <dirent.h> #include <dirent.h>
#include <unistd.h> #include <unistd.h>
#include <inttypes.h> #include <inttypes.h>
#define ecc_snprintf snprintf #define ecc_snprintf snprintf
#else #else
#include <direct.h> #define strtok_r strtok_s
#include <io.h> #include <direct.h>
#include <io.h>
/* Replace C99/Unix rint() for Windows Visual C++ (only before VC++ 2013 versions) */ /* Replace C99/Unix rint() for Windows Visual C++ (only before VC++ 2013 versions) */
#if defined _MSC_VER && _MSC_VER < 1800 #if defined _MSC_VER && _MSC_VER < 1800
double rint(double x); double rint(double x);
#endif #endif
#ifndef S_ISREG #ifndef S_ISREG
#define S_ISREG(mode) (mode & S_IFREG) #define S_ISREG(mode) (mode & S_IFREG)
#endif #endif
#ifndef S_ISDIR #ifndef S_ISDIR
#define S_ISDIR(mode) (mode & S_IFDIR) #define S_ISDIR(mode) (mode & S_IFDIR)
#endif #endif
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
#endif #endif
#define R_OK 04 /* Needed for Windows */ #define R_OK 04 /* Needed for Windows */
#ifndef F_OK #ifndef F_OK
#define F_OK 0 #define F_OK 0
#endif #endif
#define mkdir(dirname, mode) _mkdir(dirname) #define mkdir(dirname, mode) _mkdir(dirname)
#ifdef _MSC_VER #ifdef _MSC_VER
#define access(path, mode) _access(path, mode) #define access(path, mode) _access(path, mode)
#define chmod(path, mode) _chmod(path, mode) #define chmod(path, mode) _chmod(path, mode)
#define strdup(str) _strdup(str) #define strdup(str) _strdup(str)
#endif #endif
#define ecc_snprintf _snprintf #define ecc_snprintf _snprintf
#endif #endif /* ifndef ECCODES_ON_WINDOWS */
#include <limits.h> #include <limits.h>
@ -113,9 +114,9 @@ double rint(double x);
#ifdef HAVE_STRING_H #ifdef HAVE_STRING_H
#include <string.h> #include <string.h>
#else #else
#include <strings.h> #include <strings.h>
#endif #endif
/* /*

View File

@ -16,7 +16,6 @@
#include <unistd.h> #include <unistd.h>
#else #else
#include <fcntl.h> /* Windows: for _O_BINARY */ #include <fcntl.h> /* Windows: for _O_BINARY */
#define strtok_r strtok_s
#endif #endif
#ifdef ENABLE_FLOATING_POINT_EXCEPTIONS #ifdef ENABLE_FLOATING_POINT_EXCEPTIONS

View File

@ -607,6 +607,7 @@ static grib_order_by* grib_db_new_order_by(grib_context* c, char* obstr)
char *t1 = 0, *t2 = 0, *p = 0; char *t1 = 0, *t2 = 0, *p = 0;
int id = 0; int id = 0;
char *z = 0, *zs = 0; char *z = 0, *zs = 0;
char* lasts = NULL;
int mode, mode_default = GRIB_ORDER_BY_ASC; int mode, mode_default = GRIB_ORDER_BY_ASC;
grib_order_by *ob, *sob; grib_order_by *ob, *sob;
@ -628,7 +629,7 @@ static grib_order_by* grib_db_new_order_by(grib_context* c, char* obstr)
ob->mode = 0; ob->mode = 0;
ob->next = 0; ob->next = 0;
t1 = strtok(z, ","); t1 = strtok_r(z, ",", &lasts);
while (t1) { while (t1) {
grib_trim(&t1); grib_trim(&t1);
@ -651,7 +652,7 @@ static grib_order_by* grib_db_new_order_by(grib_context* c, char* obstr)
} }
grib_trim(&t2); grib_trim(&t2);
id = -1; id = -1;
t1 = strtok(NULL, ","); t1 = strtok_r(NULL, ",", &lasts);
if (ob->key) { if (ob->key) {
ob->next = (grib_order_by*)grib_context_malloc(c, sizeof(grib_order_by)); ob->next = (grib_order_by*)grib_context_malloc(c, sizeof(grib_order_by));

View File

@ -11,10 +11,6 @@
#include "grib_api_internal.h" #include "grib_api_internal.h"
#include <ctype.h> #include <ctype.h>
#if defined(ECCODES_ON_WINDOWS)
#define strtok_r strtok_s
#endif
/* /*
This is used by make_class.pl This is used by make_class.pl

View File

@ -25,10 +25,6 @@
#define GRIB_ORDER_BY_ASC 1 #define GRIB_ORDER_BY_ASC 1
#define GRIB_ORDER_BY_DESC -1 #define GRIB_ORDER_BY_DESC -1
#if defined(ECCODES_ON_WINDOWS)
#define strtok_r strtok_s
#endif
/* Note: A fast cut-down version of strcmp which does NOT return -1 */ /* Note: A fast cut-down version of strcmp which does NOT return -1 */
/* 0 means input strings are equal and 1 means not equal */ /* 0 means input strings are equal and 1 means not equal */
GRIB_INLINE static int grib_inline_strcmp(const char* a, const char* b) GRIB_INLINE static int grib_inline_strcmp(const char* a, const char* b)

View File

@ -13,10 +13,6 @@
#define STR_EQUAL(s1, s2) (strcmp((s1), (s2)) == 0) #define STR_EQUAL(s1, s2) (strcmp((s1), (s2)) == 0)
#if defined(ECCODES_ON_WINDOWS)
#define strtok_r strtok_s
#endif
typedef enum typedef enum
{ {
eROUND_ANGLE_UP, eROUND_ANGLE_UP,
@ -1944,11 +1940,11 @@ static void set_value(grib_values* value, char* str, int equal)
/* /*
'grib_tool' Optional tool name which is printed on error. Can be NULL 'grib_tool' Optional tool name which is printed on error. Can be NULL
'arg' The string to be parsed e.g. key1=value1,key2!=value2 etc 'arg' The string to be parsed e.g. key1=value1,key2!=value2 etc (cannot be const)
'values_required' If true then each key must have a value after it 'values_required' If true then each key must have a value after it
'default_type' The default type e.g. GRIB_TYPE_UNDEFINED or GRIB_TYPE_DOUBLE 'default_type' The default type e.g. GRIB_TYPE_UNDEFINED or GRIB_TYPE_DOUBLE
'values' The array we populate and return (output) 'values' The array we populate and return (output)
'count' The number of elements (output) 'count' Number of elements (output). Must be initialised to the size of the values array
*/ */
int parse_keyval_string(const char* grib_tool, int parse_keyval_string(const char* grib_tool,
char* arg, int values_required, int default_type, char* arg, int values_required, int default_type,
@ -1961,6 +1957,9 @@ int parse_keyval_string(const char* grib_tool,
*count = 0; *count = 0;
return GRIB_SUCCESS; return GRIB_SUCCESS;
} }
/* Note: strtok modifies its input argument 'arg'
* so it cannot be 'const'
*/
p = strtok_r(arg, ",", &lasts); p = strtok_r(arg, ",", &lasts);
while (p != NULL) { while (p != NULL) {
values[i].name = (char*)calloc(1, strlen(p) + 1); values[i].name = (char*)calloc(1, strlen(p) + 1);

View File

@ -10,10 +10,6 @@
#include "grib_api_internal.h" #include "grib_api_internal.h"
#if defined(ECCODES_ON_WINDOWS)
#define strtok_r strtok_s
#endif
/* Compare two strings ignoring case. /* Compare two strings ignoring case.
* strcasecmp is not in the C standard. However, it's defined by * strcasecmp is not in the C standard. However, it's defined by
* 4.4BSD, POSIX.1-2001. So we use our own * 4.4BSD, POSIX.1-2001. So we use our own