Fixes for strcat/strcpy implementation
authorErich Keane <erich.keane@intel.com>
Fri, 29 May 2015 20:39:40 +0000 (13:39 -0700)
committerErich Keane <erich.keane@intel.com>
Mon, 1 Jun 2015 20:26:15 +0000 (20:26 +0000)
Jon Cruz suggested a number of ways of simplifying the Strcpy/StrCat
implementation, sot his contains them.  Additionally, the error
conditions are now run-time so as to be entirely run-time safe, rather
than asserts, which resulted in some nasty undefined behavio.

Change-Id: I175b0df37d822d2c95b22b6521dbfbedbe15797b
Signed-off-by: Erich Keane <erich.keane@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1147
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
resource/csdk/connectivity/common/inc/oic_string.h
resource/csdk/connectivity/common/src/oic_string.c

index 9f3ca2e..4aea907 100644 (file)
@@ -29,7 +29,7 @@ extern "C"
 /**
  * Duplicates the source string and returns it.
  *
- * @note Caller needs to release this memory by calling @ref OICFree.
+ * @note Caller needs to release this memory by calling OICFree().
  *
  * @param str Original valid string which needs to be duplicated.
  *
index ec787d4..34ee859 100644 (file)
 #define TAG "OIC_STRING"
 char *OICStrdup(const char *str)
 {
-    assert(str);
+    if(!str)
+    {
+        return NULL;
+    }
 
     // Allocate memory for original string length and 1 extra byte for '\0'
     size_t length = strlen(str);
@@ -36,50 +39,49 @@ char *OICStrdup(const char *str)
     {
         memcpy(dup, str, length + 1);
     }
-    else
-    {
-        assert(NULL != dup);
-    }
 
     return dup;
 }
 
 char* OICStrcpy(char* dest, size_t destSize, const char* source)
 {
-    return OICStrcpyPartial(dest, destSize, source, destSize);
+    return OICStrcpyPartial(dest, destSize, source, destSize == 0 ? 0 : destSize - 1);
 }
 
 char* OICStrcat(char* dest, size_t destSize, const char* source)
 {
-    return OICStrcatPartial(dest, destSize, source, destSize);
+    return OICStrcatPartial(dest, destSize, source, destSize == 0 ? 0 : destSize - 1);
 }
 
-static size_t min3(size_t a, size_t b, size_t c)
+#ifndef min
+static size_t min(size_t a, size_t b)
 {
-    return a < b ? (a < c ? a : c) : (b < c ? b: c);
+    return a < b ? a : b;
 }
+#endif
 
 char* OICStrcpyPartial(char* dest, size_t destSize, const char* source, size_t sourceLen)
 {
-    assert(dest);
-    assert(source);
+    if(!dest || !source)
+    {
+        return NULL;
+    }
 
     if(destSize == 0 || sourceLen == 0)
     {
         return dest;
     }
 
-    size_t limit = min3(destSize - 1, sourceLen, strlen(source));
-    memcpy(dest, source, limit);
-    dest[limit] = '\0';
-
-    return dest;
+    dest[0] = '\0';
+    return strncat(dest, source, min(destSize - 1, sourceLen));
 }
 
 char* OICStrcatPartial(char* dest, size_t destSize, const char* source, size_t sourceLen)
 {
-    assert(dest);
-    assert(source);
+    if (!dest || !source)
+    {
+        return NULL;
+    }
 
     if(destSize == 0 || sourceLen == 0)
     {
@@ -88,13 +90,10 @@ char* OICStrcatPartial(char* dest, size_t destSize, const char* source, size_t s
 
     size_t destLen = strlen(dest);
 
-    if (destLen >= destSize)
+    if(destLen >= destSize)
     {
         return dest;
     }
 
-    size_t limit = min3(destSize - destLen - 1, sourceLen, strlen(source));
-    memcpy(dest + destLen, source, limit);
-    dest[destLen + limit] = '\0';
-    return dest;
+    return strncat(dest, source, min(destSize - destLen - 1, sourceLen));
 }