[libc-commits] [PATCH] D106885: [libc] Fix strtok_r crash when src and *saveptr are both nullptr

Alf via Phabricator via libc-commits libc-commits at lists.llvm.org
Tue Jul 27 08:51:08 PDT 2021


gAlfonso-bit created this revision.
gAlfonso-bit added reviewers: LLVM, libc-project.
gAlfonso-bit added projects: LLVM, libc-project.
Herald added subscribers: libc-commits, ecnelises, tschuett.
gAlfonso-bit requested review of this revision.

While working and testing my refactoring of multiple string functions in libc, I came across a bug that needs to be addressed in a patch on its own: src is checked for nullptr and assigned to *saveptr if it is nullptr. However, saveptr is initially nullptr when it comes to reentry. This could cause a problem if both saveptr and src are null; we need to do the check first and return nullptr if both are nullptr.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D106885

Files:
  libc/src/string/string_utils.h


Index: libc/src/string/string_utils.h
===================================================================
--- libc/src/string/string_utils.h
+++ libc/src/string/string_utils.h
@@ -58,23 +58,26 @@
 static inline char *string_token(char *__restrict src,
                                  const char *__restrict delimiter_string,
                                  char **__restrict saveptr) {
+  // Check for nullptr in src AND *saveptr first
+  if (src == nullptr && ((src = *saveptr) == nullptr))
+    return nullptr;
+
   cpp::Bitset<256> delimiter_set;
-  for (; *delimiter_string; ++delimiter_string)
+  for (; *delimiter_string != '\0'; ++delimiter_string)
     delimiter_set.set(*delimiter_string);
 
-  src = src ? src : *saveptr;
-  for (; *src && delimiter_set.test(*src); ++src)
+  for (; *src != '\0' && delimiter_set.test(*src); ++src)
     ;
-  if (!*src) {
+  if (*src == '\0') {
     *saveptr = src;
     return nullptr;
   }
   char *token = src;
-  for (; *src && !delimiter_set.test(*src); ++src)
-    ;
-  if (*src) {
-    *src = '\0';
-    ++src;
+  for (; *src != '\0'; ++src) {
+    if (delimiter_set.test(*src)) {
+      *src++ = '\0';
+      break;
+    }
   }
   *saveptr = src;
   return token;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D106885.362044.patch
Type: text/x-patch
Size: 1219 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20210727/df6d7787/attachment.bin>


More information about the libc-commits mailing list