From 32ffd3a4cda481c2ef9695584dd3c8b1cde07e99 Mon Sep 17 00:00:00 2001 From: ac-stef Date: Sun, 28 Feb 2016 23:14:47 +0100 Subject: [PATCH] replace non-thread-safe functions replace all uses of strtok, localtime, gmtime and readdir on platforms without safe versions, use homebrew or unsafe... --- source/src/client.cpp | 8 ++++---- source/src/clientgame.cpp | 4 ++-- source/src/clients2c.cpp | 6 +++--- source/src/console.cpp | 6 +++--- source/src/entities.cpp | 6 +++--- source/src/platform.h | 1 + source/src/serverbrowser.cpp | 12 ++++++------ source/src/serverfiles.h | 30 +++++++++++++++--------------- source/src/stream.cpp | 4 ++-- source/src/tools.cpp | 18 ++++++++++++++++++ source/src/tools.h | 3 +++ 11 files changed, 60 insertions(+), 38 deletions(-) diff --git a/source/src/client.cpp b/source/src/client.cpp index a9ac3d93..a9e97a0a 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -256,11 +256,11 @@ void toserverme(char *text) void echo(char *text) { - const char *s = strtok(text, "\n"); + char *b, *s = strtok_r(text, "\n", &b); do { conoutf("%s", s ? s : ""); - s = strtok(NULL, "\n"); + s = strtok_r(NULL, "\n", &b); } while(s); } @@ -268,12 +268,12 @@ void echo(char *text) VARP(allowhudechos, 0, 1, 1); void hudecho(char *text) { - const char *s = strtok(text, "\n"); + char *b, *s = strtok_r(text, "\n", &b); void (*outf)(const char *s, ...) = allowhudechos ? hudoutf : conoutf; do { outf("%s", s ? s : ""); - s = strtok(NULL, "\n"); + s = strtok_r(NULL, "\n", &b); } while(s); } diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index c27690b9..766ff77a 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -87,7 +87,7 @@ const char *highlight(const char *text) if(!marker || !strstr(text, player1->name)) return text; defformatstring(subst)("\fs%s%s\fr", marker, player1->name); char *temp = newstring(text); - char *s = strtok(temp, sep), *l = temp, *c, *r = result; + char *b, *s = strtok_r(temp, sep, &b), *l = temp, *c, *r = result; result[0] = '\0'; while(s) { @@ -101,7 +101,7 @@ const char *highlight(const char *text) } l = s + strlen(s); } - s = strtok(NULL, sep); + s = strtok_r(NULL, sep, &b); } if(MAXTRANS - strlen(result) > strlen(text) - (l - temp)) strcat(result, text + (l - temp)); delete[] temp; diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 91de286a..ff0c9162 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -1423,8 +1423,8 @@ const char *parseDemoFilename(char *srvfinfo) { int fip = 0; char sep[] = ":"; - char *pch; - pch = strtok (srvfinfo,sep); + char *pch, *b; + pch = strtok_r(srvfinfo, sep, &b); while (pch != NULL && fip < 4) { fip++; @@ -1436,7 +1436,7 @@ const char *parseDemoFilename(char *srvfinfo) case 4: stamp = atoi(pch); break; default: break; } - pch = strtok (NULL, sep); + pch = strtok_r(NULL, sep, &b); } copystring(srvmap, pch); } diff --git a/source/src/console.cpp b/source/src/console.cpp index e073f0ec..4886165e 100644 --- a/source/src/console.cpp +++ b/source/src/console.cpp @@ -454,12 +454,12 @@ void loadhistory() { char *histbuf = loadfile(path("config/history", true), NULL); if(!histbuf) return; - char *line = NULL; - line = strtok(histbuf, "\n"); + char *line = NULL, *b; + line = strtok_r(histbuf, "\n", &b); while(line) { history.add(new hline)->buf = newstring(line); - line = strtok(NULL, "\n"); + line = strtok_r(NULL, "\n", &b); } DELETEA(histbuf); histpos = history.length(); diff --git a/source/src/entities.cpp b/source/src/entities.cpp index 8901a88c..d310f488 100644 --- a/source/src/entities.cpp +++ b/source/src/entities.cpp @@ -98,7 +98,7 @@ void setedithide(char *text) // FIXME: human indexing inside eh_ents.setsize(0); if(text && text[0] != '\0') { - const char *s = strtok(text, " "); + char *b, *s = strtok_r(text, " ", &b); do { bool k = false; @@ -108,7 +108,7 @@ void setedithide(char *text) // FIXME: human indexing inside if(sn!=-1) { loopv(eh_ents) { if(eh_ents[i]==sn) { k = true; } } } else sn = tn; if(!k) { if(sn>0 && sn #endif #define ZLIB_DLL + #define NO_POSIX_R #endif #ifndef STANDALONE diff --git a/source/src/serverbrowser.cpp b/source/src/serverbrowser.cpp index 29e19dce..86def1da 100644 --- a/source/src/serverbrowser.cpp +++ b/source/src/serverbrowser.cpp @@ -854,7 +854,7 @@ const char *favcatcheck(serverinfo &si, const char *ckeys, char *autokeys = NULL if(!ckeys) return NULL; static char *nkeys = NULL; const char *sep = " \t\n\r"; - char *keys = newstring(ckeys), *k = strtok(keys, sep); + char *keys = newstring(ckeys), *b, *k = strtok_r(keys, sep, &b); bool res = false; DELETEA(nkeys); nkeys = newstring(strlen(ckeys)); @@ -871,7 +871,7 @@ const char *favcatcheck(serverinfo &si, const char *ckeys, char *autokeys = NULL if(*nkeys) strcat(nkeys, " "); strcat(nkeys, k); } - k = strtok(NULL, sep); + k = strtok_r(NULL, sep, &b); } delete[] keys; return res ? nkeys : NULL; @@ -883,13 +883,13 @@ void serverbrowseralternativeviews(int shiftdirection) const char *ckeys = getalias("serverbrowseraltviews"); if(!ckeys) return; const char *sep = " \t\n\r"; - char *keys = newstring(ckeys), *k = strtok(keys, sep); + char *keys = newstring(ckeys), *b, *k = strtok_r(keys, sep, &b); vector cats; cats.add(0); while(k) { loopv(favcats) if(!strcmp(favcats[i], k)) cats.add(i + 1); - k = strtok(NULL, sep); + k = strtok_r(NULL, sep, &b); } delete[] keys; if(cats.length()) @@ -916,7 +916,7 @@ bool assignserverfavourites() loopi(FC_NUM) { alx[i] = getalias(favcatargname(favcats[j], i)); alxn[i] = alx[i] ? atoi(alx[i]) : 0; } favcattags.add(alx[FC_TAG]); bool showonlythiscat = j == showonlyfavourites - 1; - char *keys = newstring(alx[FC_KEYS]), *k = strtok(keys, sep); + char *keys = newstring(alx[FC_KEYS]), *b, *k = strtok_r(keys, sep, &b); while(k) { loopv(servers) @@ -939,7 +939,7 @@ bool assignserverfavourites() } } } - k = strtok(NULL, sep); + k = strtok_r(NULL, sep, &b); } delete[] keys; } diff --git a/source/src/serverfiles.h b/source/src/serverfiles.h index 87f66b91..b7e07dc8 100644 --- a/source/src/serverfiles.h +++ b/source/src/serverfiles.h @@ -318,19 +318,19 @@ struct servermaprot : serverconfigfile const char *sep = ": "; configset c; int i, line = 0; - char *l, *p = buf; + char *b, *l, *p = buf; logline(ACLOG_VERBOSE,"reading map rotation '%s'", filename); while(p < buf + filelen) { l = p; p += strlen(p) + 1; line++; - l = strtok(l, sep); + l = strtok_r(l, sep, &b); if(l) { copystring(c.mapname, behindpath(l)); for(i = 3; i < CONFIG_MAXPAR; i++) c.par[i] = 0; // default values for(i = 0; i < CONFIG_MAXPAR; i++) { - if((l = strtok(NULL, sep)) != NULL) c.par[i] = atoi(l); + if((l = strtok_r(NULL, sep, &b)) != NULL) c.par[i] = atoi(l); else break; } if(i > 2) @@ -498,15 +498,15 @@ struct servernickblacklist : serverconfigfile int line = 1, errors = 0; iprchain iprc; blackline bl; - char *l, *s, *r, *p = buf; + char *b, *l, *s, *r, *p = buf; logline(ACLOG_VERBOSE,"reading nickname blacklist '%s'", filename); while(p < buf + filelen) { l = p; p += strlen(p) + 1; - l = strtok(l, sep); + l = strtok_r(l, sep, &b); if(l) { - s = strtok(NULL, sep); + s = strtok_r(NULL, sep, &b); int ic = 0; if(s && (!strcmp(l, "accept") || !strcmp(l, "a"))) { // accept nickname IP-range @@ -544,7 +544,7 @@ struct servernickblacklist : serverconfigfile bl.frag[i] = blfraglist.length(); blfraglist.add(newstring(s)); } - s = strtok(NULL, sep); + s = strtok_r(NULL, sep, &b); if(!s) break; } bl.ignorecase = ic > 0; @@ -733,19 +733,19 @@ struct serverpasswords : serverconfigfile pwddetail c; const char *sep = " "; int i, line = 1, par[ADMINPWD_MAXPAR]; - char *l, *p = buf; + char *b, *l, *p = buf; logline(ACLOG_VERBOSE,"reading admin passwords '%s'", filename); while(p < buf + filelen) { l = p; p += strlen(p) + 1; - l = strtok(l, sep); + l = strtok_r(l, sep, &b); if(l) { copystring(c.pwd, l); par[0] = 0; // default values for(i = 0; i < ADMINPWD_MAXPAR; i++) { - if((l = strtok(NULL, sep)) != NULL) par[i] = atoi(l); + if((l = strtok_r(NULL, sep, &b)) != NULL) par[i] = atoi(l); else break; } //if(i > 0) @@ -815,10 +815,10 @@ struct serverinfofile defformatstring(fname)("%s_%s.txt", fnbase, lang); path(fname); int len, n; - char *c, *s, *t, *buf = loadfile(fname, &len); + char *c, *b, *s, *t, *buf = loadfile(fname, &len); if(!buf) return NULL; char *nbuf = new char[len + 2]; - for(t = nbuf, s = strtok(buf, "\n\r"); s; s = strtok(NULL, "\n\r")) + for(t = nbuf, s = strtok_r(buf, "\n\r", &b); s; s = strtok_r(NULL, "\n\r", &b)) { c = strstr(s, "//"); if(c) *c = '\0'; // strip comments @@ -885,19 +885,19 @@ struct killmessagesfile : serverconfigfile if(getfilesize(filename) == filelen) return; if(!load()) return; - char *l, *s, *p = buf; + char *b, *l, *s, *p = buf; const char *sep = " \""; int line = 0; logline(ACLOG_VERBOSE,"reading kill messages file '%s'", filename); while(p < buf + filelen) { l = p; p += strlen(p) + 1; - l = strtok(l, sep); + l = strtok_r(l, sep, &b); char *message; if(l) { - s = strtok(NULL, sep); + s = strtok_r(NULL, sep, &b); bool fragmsg = !strcmp(l, "fragmessage"); bool gibmsg = !strcmp(l, "gibmessage"); if(s && (fragmsg || gibmsg)) diff --git a/source/src/stream.cpp b/source/src/stream.cpp index 5e066ef9..44d7cbb2 100644 --- a/source/src/stream.cpp +++ b/source/src/stream.cpp @@ -277,8 +277,8 @@ bool listdir(const char *dir, const char *ext, vector &files) DIR *d = opendir(path(pathname)); if(d) { - struct dirent *de; - while((de = readdir(d)) != NULL) + struct dirent *de, b; + while(!readdir_r(d, &b, &de) && de != NULL) { if(!ext) files.add(newstring(de->d_name)); else diff --git a/source/src/tools.cpp b/source/src/tools.cpp index 34ccf7e8..3fbab428 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -2,12 +2,30 @@ #include "cube.h" +#ifdef NO_POSIX_R +char *strtok_r(char *s, const char *delim, char **b) +{ + if(s) *b = s; + *b += strspn(*b, delim); + if(!**b) return NULL; + s = *b; + *b += strcspn(s, delim); + if(**b) *(*b)++ = '\0'; + return s; +} +#endif + const char *timestring(bool local, const char *fmt) { static string asciitime; time_t t = time(NULL); +#ifdef NO_POSIX_R struct tm * timeinfo; timeinfo = local ? localtime(&t) : gmtime (&t); +#else + struct tm *timeinfo, b; + timeinfo = local ? localtime_r(&t, &b) : gmtime_r(&t, &b); +#endif strftime(asciitime, sizeof(string) - 1, fmt ? fmt : "%Y%m%d_%H.%M.%S", timeinfo); // sortable time for filenames return asciitime; } diff --git a/source/src/tools.h b/source/src/tools.h index b2ee7fe7..f5159f47 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -28,6 +28,9 @@ typedef unsigned int uint; #define ASSERT(c) if(c) {} #endif +#ifdef NO_POSIX_R +extern char *strtok_r(char *s, const char *delim, char **b); // homebrew +#endif #ifdef swap #undef swap #endif