Bladeren bron

initialize types after deleteMembers; clean up type handling

Julius Pfrommer 8 jaren geleden
bovenliggende
commit
1cc01277d0
6 gewijzigde bestanden met toevoegingen van 111 en 109 verwijderingen
  1. 2 2
      include/ua_types.h
  2. 1 1
      src/server/ua_server.c
  3. 99 84
      src/ua_types.c
  4. 8 17
      src/ua_types_encoding_binary.c
  5. 0 4
      tests/check_memory.c
  6. 1 1
      tests/check_services_nodemanagement.c

+ 2 - 2
include/ua_types.h

@@ -45,8 +45,8 @@ extern "C" {
  *   Copy the content of the data type. Returns ``UA_STATUSCODE_GOOD`` or
  *   ``UA_STATUSCODE_BADOUTOFMEMORY``.
  * ``void T_deleteMembers(T *ptr)``
- *   Delete the dynamically allocated content of the data type, but not the data
- *   type itself.
+ *   Delete the dynamically allocated content of the data type and perform a
+ *   ``T_init`` to reset the type.
  * ``void T_delete(T *ptr)``
  *   Delete the content of the data type and the memory for the data type itself.
  *

+ 1 - 1
src/server/ua_server.c

@@ -246,7 +246,7 @@ __UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass,
     if(outNewNodeId && result.statusCode == UA_STATUSCODE_GOOD)
         *outNewNodeId = result.addedNodeId;
     else
-        UA_AddNodesResult_deleteMembers(&result);
+        UA_NodeId_deleteMembers(&result.addedNodeId);
     return result.statusCode;
 }
 

+ 99 - 84
src/ua_types.c

@@ -15,6 +15,8 @@ UA_EXPORT const UA_ExpandedNodeId UA_EXPANDEDNODEID_NULL = {
     .nodeId = { .namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0 },
     .namespaceUri = {.length = 0, .data = NULL}, .serverIndex = 0 };
 
+static void UA_deleteMembers_noInit(void *p, const UA_DataType *type);
+
 /***************************/
 /* Random Number Generator */
 /***************************/
@@ -52,6 +54,10 @@ UA_Boolean UA_String_equal(const UA_String *string1, const UA_String *string2) {
     return (is == 0) ? true : false;
 }
 
+static void String_deleteMembers(UA_String *s, const UA_DataType *_) {
+    UA_free((void*)((uintptr_t)s->data & ~(uintptr_t)UA_EMPTY_ARRAY_SENTINEL));
+}
+
 /* DateTime */
 UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime t) {
     /* Calculating the the milli-, micro- and nanoseconds */
@@ -151,8 +157,7 @@ static void NodeId_deleteMembers(UA_NodeId *p, const UA_DataType *_) {
     switch(p->identifierType) {
     case UA_NODEIDTYPE_STRING:
     case UA_NODEIDTYPE_BYTESTRING:
-        UA_free((void*)((uintptr_t)p->identifier.byteString.data & ~(uintptr_t)UA_EMPTY_ARRAY_SENTINEL));
-        p->identifier.byteString = UA_BYTESTRING_NULL;
+        String_deleteMembers(&p->identifier.string, NULL);
         break;
     default: break;
     }
@@ -178,8 +183,6 @@ static UA_StatusCode NodeId_copy(UA_NodeId const *src, UA_NodeId *dst, const UA_
     }
     dst->namespaceIndex = src->namespaceIndex;
     dst->identifierType = src->identifierType;
-    if(retval != UA_STATUSCODE_GOOD)
-        NodeId_deleteMembers(dst, NULL);
     return retval;
 }
 
@@ -229,7 +232,7 @@ UA_Boolean UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
 /* ExpandedNodeId */
 static void ExpandedNodeId_deleteMembers(UA_ExpandedNodeId *p, const UA_DataType *_) {
     NodeId_deleteMembers(&p->nodeId, _);
-    UA_String_deleteMembers(&p->namespaceUri);
+    String_deleteMembers(&p->namespaceUri, NULL);
 }
 
 static UA_StatusCode
@@ -237,8 +240,6 @@ ExpandedNodeId_copy(UA_ExpandedNodeId const *src, UA_ExpandedNodeId *dst, const
     UA_StatusCode retval = NodeId_copy(&src->nodeId, &dst->nodeId, NULL);
     retval |= UA_String_copy(&src->namespaceUri, &dst->namespaceUri);
     dst->serverIndex = src->serverIndex;
-    if(retval != UA_STATUSCODE_GOOD)
-        ExpandedNodeId_deleteMembers(dst, NULL);
     return retval;
 }
 
@@ -249,18 +250,12 @@ static void ExtensionObject_deleteMembers(UA_ExtensionObject *p, const UA_DataTy
     case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
     case UA_EXTENSIONOBJECT_ENCODED_XML:
         NodeId_deleteMembers(&p->content.encoded.typeId, NULL);
-        UA_free((void*)((uintptr_t)p->content.encoded.body.data & ~(uintptr_t)UA_EMPTY_ARRAY_SENTINEL));
-        p->content.encoded.body = UA_BYTESTRING_NULL;
+        String_deleteMembers(&p->content.encoded.body, NULL);
         break;
     case UA_EXTENSIONOBJECT_DECODED:
-        if(!p->content.decoded.data)
-            break;
-        UA_delete(p->content.decoded.data, p->content.decoded.type);
-        p->content.decoded.data = NULL;
-        p->content.decoded.type = NULL;
+        if(p->content.decoded.data)
+            UA_delete(p->content.decoded.data, p->content.decoded.type);
         break;
-    case UA_EXTENSIONOBJECT_DECODED_NODELETE:
-        p->content.decoded.type = NULL;
     default:
         break;
     }
@@ -300,14 +295,9 @@ static void Variant_deletemembers(UA_Variant *p, const UA_DataType *_) {
         if(p->arrayLength == 0)
             p->arrayLength = 1;
         UA_Array_delete(p->data, p->arrayLength, p->type);
-        p->data = NULL;
-        p->arrayLength = 0;
-    }
-    if(p->arrayDimensions) {
-        UA_Array_delete(p->arrayDimensions, p->arrayDimensionsSize, &UA_TYPES[UA_TYPES_INT32]);
-        p->arrayDimensions = NULL;
-        p->arrayDimensionsSize = 0;
     }
+    if((void*)p->arrayDimensions > UA_EMPTY_ARRAY_SENTINEL)
+        UA_free(p->arrayDimensions);
 }
 
 static UA_StatusCode
@@ -323,12 +313,11 @@ Variant_copy(UA_Variant const *src, UA_Variant *dst, const UA_DataType *_) {
     if(src->arrayDimensions) {
         retval = UA_Array_copy(src->arrayDimensions, src->arrayDimensionsSize,
             (void**)&dst->arrayDimensions, &UA_TYPES[UA_TYPES_INT32]);
-        if(retval == UA_STATUSCODE_GOOD)
-            dst->arrayDimensionsSize = src->arrayDimensionsSize;
-        else
-            Variant_deletemembers(dst, NULL);
+        if(retval != UA_STATUSCODE_GOOD)
+            return retval;
+        dst->arrayDimensionsSize = src->arrayDimensionsSize;
     }
-    return retval;
+    return UA_STATUSCODE_GOOD;
 }
 
 /**
@@ -398,9 +387,11 @@ processRangeDefinition(const UA_Variant *v, const UA_NumericRange range, size_t
 }
 
 UA_StatusCode
-UA_Variant_copyRange(const UA_Variant *src, UA_Variant *dst, const UA_NumericRange range) {
+UA_Variant_copyRange(const UA_Variant *src, UA_Variant *dst,
+                     const UA_NumericRange range) {
     size_t count, block, stride, first;
-    UA_StatusCode retval = processRangeDefinition(src, range, &count, &block, &stride, &first);
+    UA_StatusCode retval = processRangeDefinition(src, range, &count, &block,
+                                                  &stride, &first);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
     UA_Variant_init(dst);
@@ -440,22 +431,27 @@ UA_Variant_copyRange(const UA_Variant *src, UA_Variant *dst, const UA_NumericRan
 
     /* Copy the range dimensions */
     if(src->arrayDimensionsSize > 0) {
-        dst->arrayDimensions = UA_Array_new(src->arrayDimensionsSize, &UA_TYPES[UA_TYPES_UINT32]);
+        dst->arrayDimensions = UA_Array_new(src->arrayDimensionsSize,
+                                            &UA_TYPES[UA_TYPES_UINT32]);
         if(!dst->arrayDimensions) {
             Variant_deletemembers(dst, NULL);
+            memset(dst, 0, sizeof(UA_Variant)); /* init */
             return UA_STATUSCODE_BADOUTOFMEMORY;
         }
         dst->arrayDimensionsSize = src->arrayDimensionsSize;
         for(size_t k = 0; k < src->arrayDimensionsSize; k++)
-            dst->arrayDimensions[k] = (UA_Int32)(range.dimensions[k].max - range.dimensions[k].min + 1);
+            dst->arrayDimensions[k] =
+                (UA_Int32)(range.dimensions[k].max - range.dimensions[k].min + 1);
     }
     return UA_STATUSCODE_GOOD;
 }
 
 UA_StatusCode
-UA_Variant_setRange(UA_Variant *v, void * UA_RESTRICT array, size_t arraySize, const UA_NumericRange range) {
+UA_Variant_setRange(UA_Variant *v, void * UA_RESTRICT array, size_t arraySize,
+                    const UA_NumericRange range) {
     size_t count, block, stride, first;
-    UA_StatusCode retval = processRangeDefinition(v, range, &count, &block, &stride, &first);
+    UA_StatusCode retval = processRangeDefinition(v, range, &count, &block,
+                                                  &stride, &first);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
     if(count != arraySize)
@@ -468,7 +464,7 @@ UA_Variant_setRange(UA_Variant *v, void * UA_RESTRICT array, size_t arraySize, c
     for(size_t i = 0; i < block_count; i++) {
         if(!v->type->fixedSize) {
             for(size_t j = 0; j < block; j++) {
-                UA_deleteMembers((void*)nextdst, v->type);
+                UA_deleteMembers_noInit((void*)nextdst, v->type);
                 nextdst += elem_size;
             }
             nextdst -= block * elem_size;
@@ -481,9 +477,11 @@ UA_Variant_setRange(UA_Variant *v, void * UA_RESTRICT array, size_t arraySize, c
 }
 
 UA_StatusCode
-UA_Variant_setRangeCopy(UA_Variant *v, const void *array, size_t arraySize, const UA_NumericRange range) {
+UA_Variant_setRangeCopy(UA_Variant *v, const void *array, size_t arraySize,
+                        const UA_NumericRange range) {
     size_t count, block, stride, first;
-    UA_StatusCode retval = processRangeDefinition(v, range, &count, &block, &stride, &first);
+    UA_StatusCode retval = processRangeDefinition(v, range, &count, &block,
+                                                  &stride, &first);
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
     if(count != arraySize)
@@ -502,7 +500,7 @@ UA_Variant_setRangeCopy(UA_Variant *v, const void *array, size_t arraySize, cons
     } else {
         for(size_t i = 0; i < block_count; i++) {
             for(size_t j = 0; j < block; j++) {
-                UA_deleteMembers((void*)nextdst, v->type);
+                UA_deleteMembers_noInit((void*)nextdst, v->type);
                 retval |= UA_copy((void*)nextsrc, (void*)nextdst, v->type);
                 nextdst += elem_size;
                 nextsrc += elem_size;
@@ -513,14 +511,16 @@ UA_Variant_setRangeCopy(UA_Variant *v, const void *array, size_t arraySize, cons
     return retval;
 }
 
-void UA_Variant_setScalar(UA_Variant *v, void * UA_RESTRICT p, const UA_DataType *type) {
+void UA_Variant_setScalar(UA_Variant *v, void * UA_RESTRICT p,
+                          const UA_DataType *type) {
     UA_Variant_init(v);
     v->type = type;
     v->arrayLength = 0;
     v->data = p;
 }
 
-UA_StatusCode UA_Variant_setScalarCopy(UA_Variant *v, const void *p, const UA_DataType *type) {
+UA_StatusCode UA_Variant_setScalarCopy(UA_Variant *v, const void *p,
+                                       const UA_DataType *type) {
     void *new = UA_malloc(type->memSize);
     if(!new)
         return UA_STATUSCODE_BADOUTOFMEMORY;
@@ -535,9 +535,8 @@ UA_StatusCode UA_Variant_setScalarCopy(UA_Variant *v, const void *p, const UA_Da
     return UA_STATUSCODE_GOOD;
 }
 
-void
-UA_Variant_setArray(UA_Variant *v, void * UA_RESTRICT array,
-                    size_t arraySize, const UA_DataType *type) {
+void UA_Variant_setArray(UA_Variant *v, void * UA_RESTRICT array,
+                         size_t arraySize, const UA_DataType *type) {
     UA_Variant_init(v);
     v->data = array;
     v->arrayLength = arraySize;
@@ -557,13 +556,15 @@ UA_Variant_setArrayCopy(UA_Variant *v, const void *array,
 }
 
 /* LocalizedText */
-static void LocalizedText_deleteMembers(UA_LocalizedText *p, const UA_DataType *_) {
-    UA_String_deleteMembers(&p->locale);
-    UA_String_deleteMembers(&p->text);
+static void
+LocalizedText_deleteMembers(UA_LocalizedText *p, const UA_DataType *_) {
+    String_deleteMembers(&p->locale, NULL);
+    String_deleteMembers(&p->text, NULL);
 }
 
 static UA_StatusCode
-LocalizedText_copy(UA_LocalizedText const *src, UA_LocalizedText *dst, const UA_DataType *_) {
+LocalizedText_copy(UA_LocalizedText const *src, UA_LocalizedText *dst,
+                   const UA_DataType *_) {
     UA_StatusCode retval = UA_String_copy(&src->locale, &dst->locale);
     retval |= UA_String_copy(&src->text, &dst->text);
     return retval;
@@ -575,7 +576,8 @@ static void DataValue_deleteMembers(UA_DataValue *p, const UA_DataType *_) {
 }
 
 static UA_StatusCode
-DataValue_copy(UA_DataValue const *src, UA_DataValue *dst, const UA_DataType *_) {
+DataValue_copy(UA_DataValue const *src, UA_DataValue *dst,
+               const UA_DataType *_) {
     memcpy(dst, src, sizeof(UA_DataValue));
     UA_Variant_init(&dst->value);
     UA_StatusCode retval = Variant_copy(&src->value, &dst->value, NULL);
@@ -585,8 +587,9 @@ DataValue_copy(UA_DataValue const *src, UA_DataValue *dst, const UA_DataType *_)
 }
 
 /* DiagnosticInfo */
-static void DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p, const UA_DataType *_) {
-    UA_String_deleteMembers(&p->additionalInfo);
+static void
+DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p, const UA_DataType *_) {
+    String_deleteMembers(&p->additionalInfo, NULL);
     if(p->hasInnerDiagnosticInfo && p->innerDiagnosticInfo) {
         DiagnosticInfo_deleteMembers(p->innerDiagnosticInfo, NULL);
         UA_free(p->innerDiagnosticInfo);
@@ -596,7 +599,8 @@ static void DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p, const UA_DataType
 }
 
 static UA_StatusCode
-DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_DiagnosticInfo *dst, const UA_DataType *_) {
+DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_DiagnosticInfo *dst,
+                    const UA_DataType *_) {
     memcpy(dst, src, sizeof(UA_DiagnosticInfo));
     UA_String_init(&dst->additionalInfo);
     dst->innerDiagnosticInfo = NULL;
@@ -605,55 +609,61 @@ DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_DiagnosticInfo *dst, const
        retval = UA_String_copy(&src->additionalInfo, &dst->additionalInfo);
     if(src->hasInnerDiagnosticInfo && src->innerDiagnosticInfo) {
         if((dst->innerDiagnosticInfo = UA_malloc(sizeof(UA_DiagnosticInfo)))) {
-            retval |= DiagnosticInfo_copy(src->innerDiagnosticInfo, dst->innerDiagnosticInfo, NULL);
+            retval |= DiagnosticInfo_copy(src->innerDiagnosticInfo,
+                                          dst->innerDiagnosticInfo, NULL);
             dst->hasInnerDiagnosticInfo = true;
         } else {
             dst->hasInnerDiagnosticInfo = false;
             retval |= UA_STATUSCODE_BADOUTOFMEMORY;
         }
     }
-    if(retval != UA_STATUSCODE_GOOD)
-        DiagnosticInfo_deleteMembers(dst, NULL);
     return retval;
 }
 
-/*******************/
-/* Structure Types */
-/*******************/
+/********************/
+/* Structured Types */
+/********************/
 
 void * UA_new(const UA_DataType *type) {
     void *p = UA_calloc(1, type->memSize);
     return p;
 }
 
-static UA_StatusCode copyByte(const void *src, void *dst, const UA_DataType *_) {
-    memcpy(dst, src, sizeof(UA_Byte));
+static UA_StatusCode
+copyByte(const UA_Byte *src, UA_Byte *dst, const UA_DataType *_) {
+    *dst = *src;
     return UA_STATUSCODE_GOOD;
 }
 
-static UA_StatusCode copy2Byte(const void *src, void *dst, const UA_DataType *_) {
-    memcpy(dst, src, sizeof(UA_UInt16));
+static UA_StatusCode
+copy2Byte(const UA_UInt16 *src, UA_UInt16 *dst, const UA_DataType *_) {
+    *dst = *src;
     return UA_STATUSCODE_GOOD;
 }
 
-static UA_StatusCode copy4Byte(const void *src, void *dst, const UA_DataType *_) {
-    memcpy(dst, src, sizeof(UA_UInt32));
+static UA_StatusCode
+copy4Byte(const UA_UInt32 *src, UA_UInt32 *dst, const UA_DataType *_) {
+    *dst = *src;
     return UA_STATUSCODE_GOOD;
 }
 
-static UA_StatusCode copy8Byte(const void *src, void *dst, const UA_DataType *_) {
-    memcpy(dst, src, sizeof(UA_UInt64));
+static UA_StatusCode
+copy8Byte(const UA_UInt64 *src, UA_UInt64 *dst, const UA_DataType *_) {
+    *dst = *src;
     return UA_STATUSCODE_GOOD;
 }
 
-static UA_StatusCode copyFixedSize(const void *src, void *dst, const UA_DataType *type) {
-    memcpy(dst, src, type->memSize);
+static UA_StatusCode
+copyGuid(const UA_Guid *src, UA_Guid *dst, const UA_DataType *_) {
+    *dst = *src;
     return UA_STATUSCODE_GOOD;
 }
 
 static UA_StatusCode copyNoInit(const void *src, void *dst, const UA_DataType *type);
 
-typedef UA_StatusCode (*UA_copySignature)(const void *src, void *dst, const UA_DataType *type);
+typedef UA_StatusCode
+(*UA_copySignature)(const void *src, void *dst, const UA_DataType *type);
+
 static const UA_copySignature copyJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
     (UA_copySignature)copyByte, // Boolean
     (UA_copySignature)copyByte, // SByte
@@ -668,7 +678,7 @@ static const UA_copySignature copyJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
     (UA_copySignature)copy8Byte, // Double
     (UA_copySignature)copyNoInit, // String
     (UA_copySignature)copy8Byte, // DateTime
-    (UA_copySignature)copyFixedSize, // Guid
+    (UA_copySignature)copyGuid, // Guid
     (UA_copySignature)copyNoInit, // ByteString
     (UA_copySignature)copyNoInit, // XmlElement
     (UA_copySignature)NodeId_copy,
@@ -707,21 +717,23 @@ static UA_StatusCode copyNoInit(const void *src, void *dst, const UA_DataType *t
             ptrs += sizeof(size_t);
             ptrd += sizeof(size_t);
             retval |= UA_Array_copy(*(void* const*)ptrs, size, (void**)ptrd, memberType);
-            *dst_size = size;
-            if(retval != UA_STATUSCODE_GOOD)
+            if(retval == UA_STATUSCODE_GOOD)
+                *dst_size = size;
+            else
                 *dst_size = 0;
             ptrs += sizeof(void*);
             ptrd += sizeof(void*);
         }
     }
-    if(retval != UA_STATUSCODE_GOOD)
-        UA_deleteMembers(dst, type);
     return retval;
 }
 
 UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *type) {
-    memset(dst, 0, type->memSize);
-    return copyNoInit(src, dst, type);
+    memset(dst, 0, type->memSize); /* init */
+    UA_StatusCode retval = copyNoInit(src, dst, type);
+    if(retval != UA_STATUSCODE_GOOD)
+        UA_deleteMembers(dst, type);
+    return retval;
 }
 
 typedef void (*UA_deleteMembersSignature)(void *p, const UA_DataType *type);
@@ -739,24 +751,24 @@ static const UA_deleteMembersSignature deleteMembersJumpTable[UA_BUILTIN_TYPES_C
     (UA_deleteMembersSignature)nopDeleteMembers, // UInt64
     (UA_deleteMembersSignature)nopDeleteMembers, // Float
     (UA_deleteMembersSignature)nopDeleteMembers, // Double
-    (UA_deleteMembersSignature)UA_deleteMembers, // String
+    (UA_deleteMembersSignature)String_deleteMembers, // String
     (UA_deleteMembersSignature)nopDeleteMembers, // DateTime
     (UA_deleteMembersSignature)nopDeleteMembers, // Guid
-    (UA_deleteMembersSignature)UA_deleteMembers, // ByteString
-    (UA_deleteMembersSignature)UA_deleteMembers, // XmlElement
+    (UA_deleteMembersSignature)String_deleteMembers, // ByteString
+    (UA_deleteMembersSignature)String_deleteMembers, // XmlElement
     (UA_deleteMembersSignature)NodeId_deleteMembers,
     (UA_deleteMembersSignature)ExpandedNodeId_deleteMembers, // ExpandedNodeId
     (UA_deleteMembersSignature)nopDeleteMembers, // StatusCode
-    (UA_deleteMembersSignature)UA_deleteMembers, // QualifiedName
+    (UA_deleteMembersSignature)UA_deleteMembers_noInit, // QualifiedName
     (UA_deleteMembersSignature)LocalizedText_deleteMembers, // LocalizedText
     (UA_deleteMembersSignature)ExtensionObject_deleteMembers,
     (UA_deleteMembersSignature)DataValue_deleteMembers,
     (UA_deleteMembersSignature)Variant_deletemembers,
     (UA_deleteMembersSignature)DiagnosticInfo_deleteMembers,
-    (UA_deleteMembersSignature)UA_deleteMembers,
+    (UA_deleteMembersSignature)UA_deleteMembers_noInit,
 };
 
-void UA_deleteMembers(void *p, const UA_DataType *type) {
+static void UA_deleteMembers_noInit(void *p, const UA_DataType *type) {
     uintptr_t ptr = (uintptr_t)p;
     UA_Byte membersSize = type->membersSize;
     for(size_t i = 0; i < membersSize; i++) {
@@ -771,17 +783,20 @@ void UA_deleteMembers(void *p, const UA_DataType *type) {
         } else {
             ptr += member->padding;
             size_t length = *(size_t*)ptr;
-            *(size_t*)ptr = 0;
             ptr += sizeof(size_t);
             UA_Array_delete(*(void**)ptr, length, memberType);
-            *(void**)ptr = NULL;
             ptr += sizeof(void*);
         }
     }
 }
 
+void UA_deleteMembers(void *p, const UA_DataType *type) {
+    UA_deleteMembers_noInit(p, type);
+    memset(p, 0, type->memSize); /* init */
+}
+
 void UA_delete(void *p, const UA_DataType *type) {
-    UA_deleteMembers(p, type);
+    UA_deleteMembers_noInit(p, type);
     UA_free(p);
 }
 

+ 8 - 17
src/ua_types_encoding_binary.c

@@ -602,8 +602,6 @@ NodeId_decodeBinary(UA_NodeId *dst, const UA_DataType *_) {
         retval |= UA_STATUSCODE_BADINTERNALERROR; // the client sends an encodingByte we do not recognize
         break;
     }
-    if(retval != UA_STATUSCODE_GOOD)
-        UA_NodeId_deleteMembers(dst);
     return retval;
 }
 
@@ -641,8 +639,6 @@ ExpandedNodeId_decodeBinary(UA_ExpandedNodeId *dst, const UA_DataType *_) {
     }
     if(encodingByte & UA_EXPANDEDNODEID_SERVERINDEX_FLAG)
         retval |= UInt32_decodeBinary(&dst->serverIndex, NULL);
-    if(retval != UA_STATUSCODE_GOOD)
-        UA_ExpandedNodeId_deleteMembers(dst);
     return retval;
 }
 
@@ -673,8 +669,6 @@ LocalizedText_decodeBinary(UA_LocalizedText *dst, const UA_DataType *_) {
         retval |= String_decodeBinary(&dst->locale, NULL);
     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT)
         retval |= String_decodeBinary(&dst->text, NULL);
-    if(retval != UA_STATUSCODE_GOOD)
-        UA_LocalizedText_deleteMembers(dst);
     return retval;
 }
 
@@ -777,8 +771,6 @@ ExtensionObject_decodeBinary(UA_ExtensionObject *dst, const UA_DataType *_) {
             dst->content.encoded.typeId = typeId;
         }
     }
-    if(retval != UA_STATUSCODE_GOOD)
-        UA_ExtensionObject_deleteMembers(dst);
     return retval;
 }
 
@@ -939,8 +931,6 @@ Variant_decodeBinary(UA_Variant *dst, const UA_DataType *_) {
                                         &dst->arrayDimensionsSize, &UA_TYPES[UA_TYPES_INT32]);
     }
 
-    if(retval != UA_STATUSCODE_GOOD)
-        UA_Variant_deleteMembers(dst);
     return retval;
 }
 
@@ -1002,8 +992,6 @@ DataValue_decodeBinary(UA_DataValue *dst, const UA_DataType *_) {
         if(dst->serverPicoseconds > MAX_PICO_SECONDS)
             dst->serverPicoseconds = MAX_PICO_SECONDS;
     }
-    if(retval != UA_STATUSCODE_GOOD)
-        UA_DataValue_deleteMembers(dst);
     return retval;
 }
 
@@ -1072,8 +1060,6 @@ DiagnosticInfo_decodeBinary(UA_DiagnosticInfo *dst, const UA_DataType *_) {
             retval |= UA_STATUSCODE_BADOUTOFMEMORY;
         }
     }
-    if(retval != UA_STATUSCODE_GOOD)
-        UA_DiagnosticInfo_deleteMembers(dst);
     return retval;
 }
 
@@ -1183,8 +1169,10 @@ UA_decodeBinaryInternal(void *dst, const UA_DataType *type) {
             ptr += sizeof(void*);
         }
     }
-    if(retval != UA_STATUSCODE_GOOD)
-        UA_deleteMembers(dst, type);
+    /* deleteMembers is executed only at the highest level in UA_decodeBinary to
+       avoid duplicate work */
+    /* if(retval != UA_STATUSCODE_GOOD) */
+    /*     UA_deleteMembers(dst, type); */
     return retval;
 }
 
@@ -1223,7 +1211,10 @@ UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, const UA_Da
     pos = &src->data[*offset];
     end = &src->data[src->length];
     UA_StatusCode retval = UA_decodeBinaryInternal(dst, type);
-    *offset = (size_t)(pos - src->data) / sizeof(UA_Byte);
+    if(retval == UA_STATUSCODE_GOOD)
+        *offset = (size_t)(pos - src->data) / sizeof(UA_Byte);
+    else
+        UA_deleteMembers(dst, type);
     return retval;
 }
 

+ 0 - 4
tests/check_memory.c

@@ -110,12 +110,8 @@ START_TEST(decodeShallFailWithTruncatedBufferButSurvive) {
     void *obj2 = UA_new(&UA_TYPES[_i]);
     msg1.length = pos / 2;
     pos = 0;
-    //fprintf(stderr,"testing %s with half buffer\n",UA_TYPES[_i].name);
     retval = UA_decodeBinary(&msg1, &pos, obj2, &UA_TYPES[_i]);
     ck_assert_int_ne(retval, UA_STATUSCODE_GOOD);
-    //then
-    // finally
-    //fprintf(stderr,"delete %s with half buffer\n",UA_TYPES[_i].name);
     UA_delete(obj2, &UA_TYPES[_i]);
     UA_ByteString_deleteMembers(&msg1);
 }

+ 1 - 1
tests/check_services_nodemanagement.c

@@ -54,7 +54,7 @@ START_TEST(AddComplexTypeWithInheritance) {
   UA_QualifiedName myObjectName = UA_QUALIFIEDNAME(1, "the.fake.Server.Struct");
   UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
   UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
-  UA_Int32 handleCalled;
+  UA_Int32 handleCalled = 0;
   UA_InstantiationCallback iCallback = {.method=instantiationMethod, .handle = (void *) &handleCalled};
     
   UA_StatusCode res = UA_Server_addObjectNode(server, myObjectNodeId, parentNodeId, parentReferenceNodeId,