From d585714f20c1abcef197feb81be13b6ee23e44d5 Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Thu, 10 Sep 2015 10:24:53 -0700 Subject: [PATCH] Fixed pointer-type arrays with NULL values 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 Reviewed-on: https://gerrit.iotivity.org/gerrit/2452 Reviewed-by: Sachin Agrawal Tested-by: jenkins-iotivity Reviewed-by: Jon A. Cruz --- resource/csdk/stack/src/ocpayloadconvert.c | 20 +++++++++++++++++--- resource/csdk/stack/src/ocpayloadparse.c | 23 +++++++++++++++-------- resource/src/OCRepresentation.cpp | 26 ++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 13 deletions(-) diff --git a/resource/csdk/stack/src/ocpayloadconvert.c b/resource/csdk/stack/src/ocpayloadconvert.c index 0dfd056..9a51f67 100644 --- a/resource/csdk/stack/src/ocpayloadconvert.c +++ b/resource/csdk/stack/src/ocpayloadconvert.c @@ -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"); diff --git a/resource/csdk/stack/src/ocpayloadparse.c b/resource/csdk/stack/src/ocpayloadparse.c index 1d4e57f..e3d4ea2 100644 --- a/resource/csdk/stack/src/ocpayloadparse.c +++ b/resource/csdk/stack/src/ocpayloadparse.c @@ -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)) { diff --git a/resource/src/OCRepresentation.cpp b/resource/src/OCRepresentation.cpp index 5649f90..315f83b 100644 --- a/resource/src/OCRepresentation.cpp +++ b/resource/src/OCRepresentation.cpp @@ -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( 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( 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; } -- 2.7.4