Skip to content

Replace strtok(3) by strsep(3)#1555

Open
alejandro-colomar wants to merge 6 commits into
shadow-maint:masterfrom
alejandro-colomar:strtok
Open

Replace strtok(3) by strsep(3)#1555
alejandro-colomar wants to merge 6 commits into
shadow-maint:masterfrom
alejandro-colomar:strtok

Conversation

@alejandro-colomar
Copy link
Copy Markdown
Collaborator

@alejandro-colomar alejandro-colomar commented Feb 28, 2026

This PR removes all remaining uses and references to strtok(3), and adds it to the sanctions list.

Cc: @kees, @spth


Revisions:

v1b
  • Rebase
$ git rd 
1:  6e1ab018 = 1:  0e5b7f66 src/useradd.c: create_home(): Move the first copy to 'path' closer to its use
2:  a4182b11 = 2:  ddb4cf74 src/useradd.c: create_home(): Handle first slash separately
3:  c925eb4d = 3:  5d168c28 src/useradd.c: Use strsep(3) instead of strtok(3)
4:  617fcf02 = 4:  afdf8ce9 lib/, src/: Move lib/string/{strtok => strsep}/
5:  a3c4055b = 5:  99246f3a lib/string/README: Add strtok(3) to the sanctions list
v2
  • Also disallow strtok_r(3).
$ git rd 
1:  0e5b7f66 = 1:  0e5b7f66 src/useradd.c: create_home(): Move the first copy to 'path' closer to its use
2:  ddb4cf74 = 2:  ddb4cf74 src/useradd.c: create_home(): Handle first slash separately
3:  5d168c28 = 3:  5d168c28 src/useradd.c: Use strsep(3) instead of strtok(3)
4:  afdf8ce9 = 4:  afdf8ce9 lib/, src/: Move lib/string/{strtok => strsep}/
5:  99246f3a = 5:  99246f3a lib/string/README: Add strtok(3) to the sanctions list
-:  -------- > 6:  199883d7 lib/string/README: Add strtok_r(3) to the sanctions list
v2b
  • Rebase
$ git rd 
1:  0e5b7f66 = 1:  86e5fdbd src/useradd.c: create_home(): Move the first copy to 'path' closer to its use
2:  ddb4cf74 ! 2:  1d7b23bc src/useradd.c: create_home(): Handle first slash separately
    @@ src/useradd.c
      #include "string/strerrno.h"
     +#include "string/strspn/stpspn.h"
      #include "string/strtok/stpsep.h"
    - 
    + #include "sysconf.h"
      
     @@ src/useradd.c: static void create_home(const struct option_flags *flags)
           owner root:root.
3:  5d168c28 = 3:  e8c7b568 src/useradd.c: Use strsep(3) instead of strtok(3)
4:  afdf8ce9 ! 4:  878d44d9 lib/, src/: Move lib/string/{strtok => strsep}/
    @@ lib/commonio.c
     -#include "string/strtok/stpsep.h"
     +#include "string/strsep/stpsep.h"
      
    - 
    - /* local function prototypes */
    + #undef NDEBUG
    + #include <assert.h>
     
      ## lib/console.c ##
     @@
    @@ lib/list.c
     -#include "string/strtok/strsep2ls.h"
     +#include "string/strsep/strsep2ls.h"
      
    - 
    - /*
    + #undef NDEBUG
    + #include <assert.h>
     
      ## lib/loginprompt.c ##
     @@
    @@ lib/ttytype.c
     
      ## lib/tz.c ##
     @@
    - #include "defines.h"
      #include "getdef.h"
    + #include "io/fgets/fgets.h"
      #include "prototypes.h"
     -#include "string/strtok/stpsep.h"
     +#include "string/strsep/stpsep.h"
    @@ src/useradd.c
      #include "string/strspn/stpspn.h"
     -#include "string/strtok/stpsep.h"
     +#include "string/strsep/stpsep.h"
    + #include "sysconf.h"
      
    - 
    - #ifndef SKEL_DIR
    + #undef NDEBUG
5:  99246f3a = 5:  3da58157 lib/string/README: Add strtok(3) to the sanctions list
6:  199883d7 = 6:  89b85c93 lib/string/README: Add strtok_r(3) to the sanctions list
v2c
  • Rebase
$ git rd 
1:  86e5fdbd = 1:  74b9d4a9 src/useradd.c: create_home(): Move the first copy to 'path' closer to its use
2:  1d7b23bc = 2:  fbdd1bbc src/useradd.c: create_home(): Handle first slash separately
3:  e8c7b568 = 3:  1d1f90ab src/useradd.c: Use strsep(3) instead of strtok(3)
4:  878d44d9 = 4:  9cafb845 lib/, src/: Move lib/string/{strtok => strsep}/
5:  3da58157 = 5:  fbf9c518 lib/string/README: Add strtok(3) to the sanctions list
6:  89b85c93 = 6:  f9f33a4c lib/string/README: Add strtok_r(3) to the sanctions list
v3
  • Rebase
$ git rd 
1:  74b9d4a9 ! 1:  428e4d38 src/useradd.c: create_home(): Move the first copy to 'path' closer to its use
    @@ src/useradd.c: static void create_home(const struct option_flags *flags)
         */
     +  strcpy(path, "");
        for (cp = strtok(bhome, "/"); cp != NULL; cp = strtok(NULL, "/")) {
    -           /* Avoid turning a relative path into an absolute path. */
    -           if (strprefix(bhome, "/") || !streq(path, ""))
    +           bool  dir_created;
    + 
2:  fbdd1bbc ! 2:  781dcce6 src/useradd.c: create_home(): Handle first slash separately
    @@ src/useradd.c: static void create_home(const struct option_flags *flags)
     +  if (strspn(bhome, "/"))
     +          strcat(path, "/");
        for (cp = strtok(bhome, "/"); cp != NULL; cp = strtok(NULL, "/")) {
    +           bool  dir_created;
    + 
     -          /* Avoid turning a relative path into an absolute path. */
     -          if (strprefix(bhome, "/") || !streq(path, ""))
     +          if (!streq(stpspn(path, "/"), ""))
3:  1d1f90ab ! 3:  ca2a8c12 src/useradd.c: Use strsep(3) instead of strtok(3)
    @@ src/useradd.c: static void create_home(const struct option_flags *flags)
     -  for (cp = strtok(bhome, "/"); cp != NULL; cp = strtok(NULL, "/")) {
     +  p = bhome;
     +  while (NULL != (cp = strsep(&p, "/"))) {
    +           bool  dir_created;
    + 
     +          if (streq(cp, ""))
     +                  continue;
     +
4:  9cafb845 ! 4:  8bf35048 lib/, src/: Move lib/string/{strtok => strsep}/
    @@ lib/getdef.c
      ## lib/hushed.c ##
     @@
      #include "prototypes.h"
    - #include "string/sprintf/snprintf.h"
    + #include "string/sprintf/stprintf.h"
      #include "string/strcmp/streq.h"
     -#include "string/strtok/stpsep.h"
     +#include "string/strsep/stpsep.h"
    @@ lib/string/strtok/strsep2ls.h => lib/string/strsep/strsep2ls.h
      ## lib/subordinateio.c ##
     @@
      #include "string/ctype/strisascii/strisdigit.h"
    - #include "string/sprintf/snprintf.h"
    + #include "string/sprintf/stprintf.h"
      #include "string/strcmp/streq.h"
     -#include "string/strtok/strsep2arr.h"
     +#include "string/strsep/strsep2arr.h"
5:  fbf9c518 = 5:  2897e9da lib/string/README: Add strtok(3) to the sanctions list
6:  f9f33a4c = 6:  1e95370b lib/string/README: Add strtok_r(3) to the sanctions list

This removes the only use of 'bhome' within the loop other than in the
strtok(3) calls.  That was problematic, because it didn't allow changing
this code to use strsep(3) --as strsep(3) wouldn't respect the first
slash in the 'bhome' string as strtok(3) does--.

Signed-off-by: Alejandro Colomar <[email protected]>
This removes the remaining uses of strtok(3).

strsep(3) differs from strtok(3) in that it doesn't collapse adjacent
delimiters, and thus it produces empty strings for adjacent delimiters
(slashes).  We must skip these to keep the strtok(3) behavior.  It makes
sense, as we don't want to have unnecessarily repeated slashes in a
path.  That's why we do

	if (streq(cp, ""))
		continue;

Also, while strtok(3) holds internal state, strsep(3) doesn't, which
means we hold the state externally.  Thus, we need to add the new
pointer 'p'.

Signed-off-by: Alejandro Colomar <[email protected]>
We got rid of the last strtok(3) call, and don't want any references to
it.  It's dead.

Signed-off-by: Alejandro Colomar <[email protected]>
It's not as bad as strtok(3), but strsep(3)/stpsep() are still better.

Signed-off-by: Alejandro Colomar <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant