]> granicus.if.org Git - php/commitdiff
Switch use of strtok() to gd_strtok_r()
authorSara Golemon <pollita@php.net>
Tue, 19 Aug 2014 19:46:53 +0000 (12:46 -0700)
committerSara Golemon <pollita@php.net>
Tue, 19 Aug 2014 20:16:44 +0000 (13:16 -0700)
strtok() is not thread safe, so this will potentially break in
very bad ways if used in ZTS mode.

I'm not sure why gd_strtok_r() exists since it seems to do the
same thing as strtok_r(), but I'll assume it's a portability
decision and do as the Romans do.

NEWS
ext/gd/libgd/gdft.c

diff --git a/NEWS b/NEWS
index f515bbe57c71f624964c487be5f366dc7d1f515f..5df40324da6c7a41eee02a4c99f93c0c73f5ee21 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,9 @@ PHP                                                                        NEWS
 - Date:
   . Fixed bug #66091 (memory leaks in DateTime constructor). (Tjerk).
 
+- GD
+  . Made fontFetch's path parser thread-safe. (Sara).
+
 ?? ??? 2014, PHP 5.4.32
 
 - COM:
index ac2bf344ffecf2ce5eb6e873b71c4639eef9fe1c..884a4148fe8dd5f23b589a910b3229f334ff02c2 100644 (file)
@@ -370,9 +370,10 @@ static void *fontFetch (char **error, void *key)
        fontlist = gdEstrdup(a->fontlist);
 
        /*
-        * Must use gd_strtok_r else pointer corrupted by strtok in nested loop.
+        * Must use gd_strtok_r becasuse strtok() isn't thread safe
         */
        for (name = gd_strtok_r (fontlist, LISTSEPARATOR, &strtok_ptr); name; name = gd_strtok_r (0, LISTSEPARATOR, &strtok_ptr)) {
+               char *strtok_ptr_path;
                /* make a fresh copy each time - strtok corrupts it. */
                path = gdEstrdup (fontsearchpath);
 
@@ -388,7 +389,8 @@ static void *fontFetch (char **error, void *key)
                                break;
                        }
                }
-               for (dir = strtok (path, PATHSEPARATOR); dir; dir = strtok (0, PATHSEPARATOR)) {
+               for (dir = gd_strtok_r (path, PATHSEPARATOR, &strtok_ptr_path); dir;
+                    dir = gd_strtok_r (0, PATHSEPARATOR, &strtok_ptr_path)) {
                        if (!strcmp(dir, ".")) {
                                TSRMLS_FETCH();
 #if HAVE_GETCWD