changeset 387:743195485eec

Additional fixes for empty octet string AVPs
author Sebastien Decugis <sdecugis@nict.go.jp>
date Tue, 06 Jul 2010 14:49:33 +0900
parents ce8d20725308
children 554fe1d67acc
files libfreeDiameter/messages.c
diffstat 1 files changed, 23 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/libfreeDiameter/messages.c	Tue Jul 06 13:27:11 2010 +0900
+++ b/libfreeDiameter/messages.c	Tue Jul 06 14:49:33 2010 +0900
@@ -1138,10 +1138,14 @@
 	memcpy(&avp->avp_storage, value, sizeof(union avp_value));
 	
 	/* Copy an octetstring if needed. */
-	if ((type == AVP_TYPE_OCTETSTRING) && (value->os.len)) {
-		CHECK_MALLOC(  avp->avp_storage.os.data = malloc(value->os.len)  );
-		avp->avp_mustfreeos = 1;
-		memcpy(avp->avp_storage.os.data, value->os.data, value->os.len);
+	if (type == AVP_TYPE_OCTETSTRING) {
+		if (value->os.len) {
+			CHECK_MALLOC(  avp->avp_storage.os.data = malloc(value->os.len)  );
+			avp->avp_mustfreeos = 1;
+			memcpy(avp->avp_storage.os.data, value->os.data, value->os.len);
+		} else {
+			avp->avp_storage.os.data = NULL;
+		}
 	}
 	
 	/* Set the data pointer of the public part */
@@ -1333,7 +1337,8 @@
 				return bufferize_chain(buffer, buflen, offset, &avp->avp_chain.children);
 
 			case AVP_TYPE_OCTETSTRING:
-				memcpy(&buffer[*offset], avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len);
+				if (avp->avp_public.avp_value->os.len)
+					memcpy(&buffer[*offset], avp->avp_public.avp_value->os.data, avp->avp_public.avp_value->os.len);
 				*offset += PAD4(avp->avp_public.avp_value->os.len);
 				break;
 
@@ -1620,9 +1625,12 @@
 			
 			avp->avp_rawlen = avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags );
 			
-			CHECK_MALLOC(  avp->avp_rawdata = malloc(avp->avp_rawlen)  );
+			if (avp->avp_rawlen) {
+				CHECK_MALLOC(  avp->avp_rawdata = malloc(avp->avp_rawlen)  );
 			
-			memcpy(avp->avp_rawdata, avp->avp_source, avp->avp_rawlen);
+				memcpy(avp->avp_rawdata, avp->avp_source, avp->avp_rawlen);
+			}
+			
 			avp->avp_source = NULL;
 			
 			TRACE_DEBUG(FULL, "Unsupported optional AVP found, raw source data saved in avp_rawdata.");
@@ -1674,7 +1682,7 @@
 			
 		case AVP_TYPE_OCTETSTRING:
 			/* We just have to copy the string into the storage area */
-			CHECK_PARAMS_DO( avp->avp_public.avp_len > GETAVPHDRSZ( avp->avp_public.avp_flags ),
+			CHECK_PARAMS_DO( avp->avp_public.avp_len >= GETAVPHDRSZ( avp->avp_public.avp_flags ),
 				{
 					if (error_info) {
 						error_info->pei_errcode = "DIAMETER_INVALID_AVP_LENGTH";
@@ -1683,9 +1691,13 @@
 					return EBADMSG;
 				} );
 			avp->avp_storage.os.len = avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags );
-			CHECK_MALLOC(  avp->avp_storage.os.data = malloc(avp->avp_storage.os.len)  );
-			avp->avp_mustfreeos = 1;
-			memcpy(avp->avp_storage.os.data, avp->avp_source, avp->avp_storage.os.len);
+			if (avp->avp_storage.os.len) {
+				CHECK_MALLOC(  avp->avp_storage.os.data = malloc(avp->avp_storage.os.len)  );
+				avp->avp_mustfreeos = 1;
+				memcpy(avp->avp_storage.os.data, avp->avp_source, avp->avp_storage.os.len);
+			} else {
+				avp->avp_storage.os.data = NULL;
+			}
 			break;
 		
 		case AVP_TYPE_INTEGER32:
"Welcome to our mercurial repository"