Fix the portability implementation of strndup
authorChristopher Dykes <cdykes@fb.com>
Thu, 31 Mar 2016 17:14:42 +0000 (10:14 -0700)
committerFacebook Github Bot 8 <facebook-github-bot-8-bot@fb.com>
Thu, 31 Mar 2016 17:20:36 +0000 (10:20 -0700)
Summary:It was mistakenly assuming the length passed in included the null terminator.
This also makes the portability implementation of `strndup` available to OSX and FreeBSD, where they weren't present, and where HHVM had a wrapper for them.
This also removes the extra pair of conditions around `memrchr`, as the main define should always be getting set.

Reviewed By: yfeldblum

Differential Revision: D3116467

fb-gh-sync-id: 243dd4dace219efab2c2bf2f383202e70fbec4de
fbshipit-source-id: 243dd4dace219efab2c2bf2f383202e70fbec4de

folly/portability/String.cpp
folly/portability/String.h

index eae93f5edbef86bf39c18d8891d8199622c7a477..e48076b1415b845d561571ad4836f8ebecaa188a 100755 (executable)
@@ -16,7 +16,7 @@
 
 #include <folly/portability/String.h>
 
-#if !FOLLY_HAVE_MEMRCHR || defined(_WIN32) || defined(__APPLE__)
+#if !FOLLY_HAVE_MEMRCHR
 extern "C" void* memrchr(const void* s, int c, size_t n) {
   for (auto p = ((const char*)s) + n - 1; p >= (const char*)s; p--) {
     if (*p == (char)c) {
@@ -27,23 +27,24 @@ extern "C" void* memrchr(const void* s, int c, size_t n) {
 }
 #endif
 
-#ifdef _WIN32
-#include <stdlib.h>
-
-extern "C" {
-char* strndup(const char* a, size_t len) {
+#if defined(_WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
+extern "C" char* strndup(const char* a, size_t len) {
   auto neededLen = strlen(a);
   if (neededLen > len) {
-    neededLen = len - 1;
+    neededLen = len;
   }
   char* buf = (char*)malloc((neededLen + 1) * sizeof(char));
+  if (!buf) {
+    return nullptr;
+  }
   memcpy(buf, a, neededLen);
   buf[neededLen] = '\0';
   return buf;
 }
+#endif
 
-char* strtok_r(char* str, char const* delim, char** ctx) {
+#ifdef _WIN32
+extern "C" char* strtok_r(char* str, char const* delim, char** ctx) {
   return strtok_s(str, delim, ctx);
 }
-}
 #endif
index 5dd8a654c953070183d6e2fe9bf295048a459bd3..0d235559c10aa2dd45d66834943f1425dfee6f2c 100755 (executable)
 #pragma once
 
 #include <string.h>
+#include <stdlib.h>
 
 #include <folly/portability/Config.h>
 
-#if !FOLLY_HAVE_MEMRCHR || defined(_WIN32) || defined(__APPLE__)
-#include <stdint.h>
+#if !FOLLY_HAVE_MEMRCHR
 extern "C" void* memrchr(const void* s, int c, size_t n);
 #endif
 
+#if defined(_WIN32) || defined(__APPLE__) || defined(__FreeBSD__)
+extern "C" char* strndup(const char* a, size_t len);
+#endif
+
 #ifdef _WIN32
-extern "C" {
-char* strndup(const char* a, size_t len);
-char* strtok_r(char* str, char const* delim, char** ctx);
-}
+extern "C" char* strtok_r(char* str, char const* delim, char** ctx);
 #endif