Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#FFCCCC
char *path = getenv("PATH"); 
/* PATH is something like "/usr/bin:/bin:/usr/sbin:/sbin" */
char *token; 
 
token = strtok(path, ":"); 
puts(token); 
 
while (token = strtok(0, ":")) { 
  puts(token); 
} 
 
printf("PATH: %s\n", path); 
/* PATH is now just "/usr/bin" */

Wiki MarkupIn this example, the {{strtok()}} function is used to parse the first argument into colon-delimited tokens; it will output each word from the string on a new line. However, after the while loop ends, path\[\] will have been modified to look like this: {{"/usr/bin\0/bin\0/usr/sbin\0/sbin\0"}}. This is an issue on several levels. If we check our local {{path}} variable, we will only see {{/usr/bin}} now. Even worse, we have changed the environment variable PATH, which could cause more confusion (see
ENV30-C. Do not modify the string returned by getenv()).

Compliant Solutions

One possible solution is to copy the string being tokenized into a temporary buffer which isn't referenced after the calls to strtok():

Code Block
bgColor#ccccff
char string[]*path = "Hello secure coding wiki!";
char buff[256]getenv("PATH"); 
/* PATH is something like "/usr/bin:/bin:/usr/sbin:/sbin" */

char *copy = malloc(strlen(path) + 1);
strcpy(copy, path);
char *token;
 
strncpy(buff, string);
token = strtok(buffcopy, ' '":"); 
puts(token); 
 
while (token = strtok(NULL0, ' '":")) { 
  puts(token); 
} 
 
printf("PATH: %s\n", path); 
/* furtherPATH stringis manipulation on string[] succeedsstill "/usr/bin:/bin:/usr/sbin:/sbin" */

Another possibility is to provide your own implementation of strtok() which does not modify the initial arguments.

...