Fixed pointer-type arrays with NULL values
authorErich Keane <erich.keane@intel.com>
Thu, 10 Sep 2015 17:24:53 +0000 (10:24 -0700)
committerJon A. Cruz <jonc@osg.samsung.com>
Thu, 10 Sep 2015 21:39:10 +0000 (21:39 +0000)
NULL values for OCRepresentation and string types in an array would
cause a variety of seg-faults.  This patch corrects the behavior to
allow for NULLs in these arrays.

This is necessary because the CSDK enforces rectangular arrays, but
the C++ stack does NOT, so it compiles with those dimensions.

Change-Id: Ie0ddc5faea980ccb37f0ac8f6b73027b965b7257
Signed-off-by: Erich Keane <erich.keane@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/2452
Reviewed-by: Sachin Agrawal <sachin.agrawal@intel.com>
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jonc@osg.samsung.com>
resource/csdk/stack/src/ocpayloadconvert.c
resource/csdk/stack/src/ocpayloadparse.c
resource/src/OCRepresentation.cpp

index 0dfd056..9a51f67 100644 (file)
@@ -495,11 +495,25 @@ static int64_t OCConvertArray(CborEncoder* parent, const OCRepPayloadValueArray*
                 err = err | cbor_encode_boolean(&array, valArray->bArray[i]);
                 break;
             case OCREP_PROP_STRING:
-                err = err | cbor_encode_text_string(&array, valArray->strArray[i],
-                        strlen(valArray->strArray[i]));
+                if (!valArray->strArray[i])
+                {
+                    err = err | cbor_encode_null(&array);
+                }
+                else
+                {
+                    err = err | cbor_encode_text_string(&array, valArray->strArray[i],
+                            strlen(valArray->strArray[i]));
+                }
                 break;
             case OCREP_PROP_OBJECT:
-                err = OCConvertSingleRepPayload(&array, valArray->objArray[i]);
+                if (!valArray->objArray[i])
+                {
+                    err = err | cbor_encode_null(&array);
+                }
+                else
+                {
+                    err = OCConvertSingleRepPayload(&array, valArray->objArray[i]);
+                }
                 break;
             case OCREP_PROP_ARRAY:
                 OC_LOG(ERROR, TAG, "ConvertArray Invalid child array");
index 1d4e57f..e3d4ea2 100644 (file)
@@ -647,15 +647,18 @@ static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* contain
             }
             break;
         case OCREP_PROP_STRING:
-            arr = (char**)OICMalloc(dimTotal * sizeof(char*));
+            arr = (char**)OICCalloc(dimTotal, sizeof(char*));
             if(arr)
             {
                 for(size_t i = 0; i < dimTotal && !err; ++i)
                 {
-                    err = err || cbor_value_dup_text_string(&insideArray, &tempStr,
-                            &len, NULL);
+                    if (!cbor_type_is_null(&insideArray))
+                    {
+                        err = err || cbor_value_dup_text_string(&insideArray, &tempStr,
+                                &len, NULL);
+                        ((char**)arr)[i] = tempStr;
+                    }
                     err = err || cbor_value_advance(&insideArray);
-                    ((char**)arr)[i] = tempStr;
                 }
                 if(err || !OCRepPayloadSetStringArrayAsOwner(out, name, (char**)arr, dimensions))
                 {
@@ -669,15 +672,18 @@ static bool OCParseArray(OCRepPayload* out, const char* name, CborValue* contain
             }
             break;
         case OCREP_PROP_OBJECT:
-            arr = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+            arr = (OCRepPayload**)OICCalloc(dimTotal, sizeof(OCRepPayload*));
             if(arr)
             {
                 for(size_t i = 0; i < dimTotal && !err; ++i)
                 {
-                    pl = NULL;
-                    err = err || OCParseSingleRepPayload(&pl, &insideArray);
+                    if (!cbor_type_is_null(&insideArray))
+                    {
+                        pl = NULL;
+                        err = err || OCParseSingleRepPayload(&pl, &insideArray);
+                        ((OCRepPayload**)arr)[i] = pl;
+                    }
                     err = err || cbor_value_advance(&insideArray);
-                    ((OCRepPayload**)arr)[i] = pl;
                 }
                 if(err || !OCRepPayloadSetPropObjectArrayAsOwner(out, name,
                         (OCRepPayload**)arr, dimensions))
@@ -760,6 +766,7 @@ static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repPar
             err = err || cbor_value_leave_container(&insidePropArray, &ifArray);
         }
     }
+
     err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal);
     if(cbor_value_is_map(&curVal))
     {
index 5649f90..315f83b 100644 (file)
@@ -299,6 +299,18 @@ namespace OC
     }
 
     template<>
+    void get_payload_array::copy_to_array(std::string item, void* array, size_t pos)
+    {
+        ((char**)array)[pos] = OICStrdup(item.c_str());
+    }
+
+    template<>
+    void get_payload_array::copy_to_array(std::string& item, void* array, size_t pos)
+    {
+        ((char**)array)[pos] = OICStrdup(item.c_str());
+    }
+
+    template<>
     void get_payload_array::copy_to_array(const std::string& item, void* array, size_t pos)
     {
         ((char**)array)[pos] = OICStrdup(item.c_str());
@@ -451,14 +463,24 @@ namespace OC
     std::string OCRepresentation::payload_array_helper_copy<std::string>(
             size_t index, const OCRepPayloadValue* pl)
     {
-        return std::string(pl->arr.strArray[index]);
+        if (pl->arr.strArray[index])
+        {
+            return std::string(pl->arr.strArray[index]);
+        }
+        else
+        {
+            return std::string{};
+        }
     }
     template<>
     OCRepresentation OCRepresentation::payload_array_helper_copy<OCRepresentation>(
             size_t index, const OCRepPayloadValue* pl)
     {
         OCRepresentation r;
-        r.setPayload(pl->arr.objArray[index]);
+        if (pl->arr.objArray[index])
+        {
+            r.setPayload(pl->arr.objArray[index]);
+        }
         return r;
     }