Quellcode durchsuchen

make check_memory run fine

Julius Pfrommer vor 10 Jahren
Ursprung
Commit
74f69d37a6
5 geänderte Dateien mit 26 neuen und 9 gelöschten Zeilen
  1. 2 0
      include/ua_types.h
  2. 4 1
      src/ua_types.c
  3. 14 3
      src/ua_types_encoding_binary.c
  4. 1 2
      tests/check_builtin.c
  5. 5 3
      tests/check_memory.c

+ 2 - 0
include/ua_types.h

@@ -423,6 +423,8 @@ void UA_EXPORT UA_delete(void *p, const UA_DataType *dataType);
 /* Array operations */
 /********************/
 
+#define MAX_ARRAY_SIZE 104857600 // arrays must be smaller than 100MB
+
 UA_StatusCode UA_EXPORT UA_Array_new(void **p, UA_Int32 noElements, const UA_DataType *dataType);
 UA_StatusCode UA_EXPORT UA_Array_copy(const void *src, UA_Int32 noElements, void **dst, const UA_DataType *dataType);
 void UA_EXPORT UA_Array_delete(void *p, UA_Int32 noElements, const UA_DataType *dataType);

+ 4 - 1
src/ua_types.c

@@ -955,7 +955,7 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
             retval |= UA_String_copy((const UA_String*)ptrs, (UA_String*)ptrd);
             break;
         default:
-            retval |= UA_copy(ptrs, ptrd, &UA_TYPES[member->memberTypeIndex]);
+            retval |= UA_copy(ptrs, ptrd, memberType);
         }
         ptrs += memberType->memSize;
         ptrd += memberType->memSize;
@@ -1049,6 +1049,9 @@ UA_StatusCode UA_Array_new(void **p, UA_Int32 noElements, const UA_DataType *dat
         return UA_STATUSCODE_BADINTERNALERROR;
     }
 
+    if(dataType->memSize * noElements < 0 || dataType->memSize * noElements > MAX_ARRAY_SIZE )
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+
     *p = malloc(dataType->memSize * noElements);
     if(!p)
         return UA_STATUSCODE_BADOUTOFMEMORY;

+ 14 - 3
src/ua_types_encoding_binary.c

@@ -747,6 +747,8 @@ enum UA_VARIANT_ENCODINGMASKTYPE_enum {
 UA_UInt32 UA_Variant_calcSizeBinary(UA_Variant const *p) {
     UA_UInt32 arrayLength, length;
     const UA_VariantData *data;
+    if(!p->type)
+        return 0;
     if(p->storageType == UA_VARIANT_DATA)
         data = &p->storage.data;
     else {
@@ -782,6 +784,8 @@ UA_UInt32 UA_Variant_calcSizeBinary(UA_Variant const *p) {
 
 UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst, UA_UInt32 *offset) {
     const UA_VariantData  *data;
+    if(!src->type)
+        return UA_STATUSCODE_BADINTERNALERROR;
     if(src->storageType == UA_VARIANT_DATA)
         data = &src->storage.data;
     else {
@@ -837,7 +841,7 @@ UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, UA_UInt32 *offse
     UA_Variant_init(dst);
     UA_Byte encodingByte;
     UA_StatusCode retval = UA_Byte_decodeBinary(src, offset, &encodingByte);
-    if(retval)
+    if(retval != UA_STATUSCODE_GOOD)
         return retval;
 
     UA_VariantData *data = &dst->storage.data;
@@ -1153,6 +1157,7 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, UA_UInt32 *offset, void
     UA_Byte *ptr = (UA_Byte*)dst;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_Byte membersSize = dataType->membersSize;
+    UA_init(dst, dataType);
     for(int i=0;i<membersSize && retval == UA_STATUSCODE_GOOD; i++) {
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
@@ -1236,7 +1241,7 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, UA_UInt32 *offset, void
             retval = UA_String_decodeBinary(src, offset, (UA_String*)ptr);
             break;
         default:
-            retval = UA_decodeBinary(src, offset, ptr, dataType);
+            retval = UA_decodeBinary(src, offset, ptr, memberType);
         }
         ptr += memberType->memSize;
     }
@@ -1285,8 +1290,14 @@ UA_StatusCode UA_Array_decodeBinary(const UA_ByteString *src, UA_UInt32 *offset,
         return UA_STATUSCODE_GOOD;
     }
 
+    if(dataType->memSize * noElements < 0 || dataType->memSize * noElements > MAX_ARRAY_SIZE )
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+
+    if(*offset + (dataType->memSize * noElements) > (UA_UInt32)src->length)
+        return UA_STATUSCODE_BADDECODINGERROR;
+
     *dst = UA_malloc(dataType->memSize * noElements);
-    if(!dst)
+    if(!*dst)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
     UA_Byte *ptr = (UA_Byte*)*dst;

+ 1 - 2
tests/check_builtin.c

@@ -1658,7 +1658,6 @@ START_TEST(UA_ExtensionObject_encodeDecodeShallWorkOnExtensionObject) {
     // finally
     UA_ExtensionObject_deleteMembers(&extensionObjectDecoded);
     UA_Variant_deleteMembers(&varAttrDecoded.value);
-
 }
 END_TEST
 
@@ -1769,7 +1768,7 @@ int main(void) {
 
 	s  = testSuite_builtin();
 	sr = srunner_create(s);
-	srunner_set_fork_status(sr, CK_NOFORK);
+	//srunner_set_fork_status(sr, CK_NOFORK);
 	srunner_run_all(sr, CK_NORMAL);
 	number_failed += srunner_ntests_failed(sr);
 	srunner_free(sr);

+ 5 - 3
tests/check_memory.c

@@ -54,7 +54,6 @@ START_TEST(encodeShallYieldDecode) {
 	UA_ByteString_newMembers(&msg1, UA_calcSizeBinary(obj1, &UA_TYPES[_i]));
     UA_StatusCode retval = UA_encodeBinary(obj1, &UA_TYPES[_i], &msg1, &pos);
 	if(retval != UA_STATUSCODE_GOOD) {
-		// this happens, e.g. when we encode a variant (with UA_TYPES[UA_INVALIDTYPE] in the vtable)
 		UA_delete(obj1, &UA_TYPES[_i]);
 		UA_ByteString_deleteMembers(&msg1);
 		return;	
@@ -86,8 +85,11 @@ START_TEST(decodeShallFailWithTruncatedBufferButSurvive) {
 	UA_UInt32 pos;
 	void *obj1 = UA_new(&UA_TYPES[_i]);
 	UA_ByteString_newMembers(&msg1, UA_calcSizeBinary(obj1, &UA_TYPES[_i]));
-    pos = 0; UA_encodeBinary(obj1, &UA_TYPES[_i], &msg1, &pos);
+    pos = 0;
+    UA_StatusCode retval = UA_encodeBinary(obj1, &UA_TYPES[_i], &msg1, &pos);
 	UA_delete(obj1, &UA_TYPES[_i]);
+    if(retval != UA_STATUSCODE_GOOD)
+        return; // e.g. variants cannot be encoded after an init without failing (no datatype set)
 	// when
 	void *obj2 = UA_new(&UA_TYPES[_i]);
 	pos = 0;
@@ -191,7 +193,7 @@ int main(void) {
 	suite_add_tcase(s, tc);
 
 	sr = srunner_create(s);
-	//srunner_set_fork_status(sr, CK_NOFORK);
+	srunner_set_fork_status(sr, CK_NOFORK);
 	srunner_run_all (sr, CK_NORMAL);
 	number_failed += srunner_ntests_failed(sr);
 	srunner_free(sr);