Static analyzer bug fixes
[silc.git] / lib / silccore / silcattrs.c
index 27f25f7373ebea728ba10e1c984ce7d5e9bca532..414ecf6e791c49eda5d2c727386aafc78c33cab0 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2002 - 2005 Pekka Riikonen
+  Copyright (C) 2002 - 2014 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -48,15 +48,19 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
   unsigned char tmp[4], *str = NULL, *ret;
   SilcUInt32 len;
 
+  if (ret_len)
+    *ret_len = 0;
+
   /* Encode according to attribute type */
   if (flags & SILC_ATTRIBUTE_FLAG_VALID) {
-    if (!object && !object_size)
+    if (!object || !object_size)
       return NULL;
 
     switch (attribute) {
 
     case SILC_ATTRIBUTE_USER_INFO:
       {
+#ifdef SILC_DIST_VCARD
        SilcVCard vcard = object;
        if (object_size != sizeof(*vcard))
          return NULL;
@@ -64,6 +68,7 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
        if (!str)
          return NULL;
        object = str;
+#endif /* SILC_DIST_VCARD */
       }
       break;
 
@@ -76,6 +81,8 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
        len = strlen(service->address);
        len2 = strlen(service->signon);
        tmpbuf = silc_buffer_alloc_size(13 + len + len2);
+       if (!tmpbuf)
+         return NULL;
        silc_buffer_format(tmpbuf,
                           SILC_STR_UI_INT(service->port),
                           SILC_STR_UI_SHORT(len),
@@ -127,6 +134,7 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
        str = silc_mime_encode(mime, &object_size);
        if (!str)
          return NULL;
+       object = str;
       }
       break;
 
@@ -193,6 +201,27 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
       }
       break;
 
+    case SILC_ATTRIBUTE_PHONE_NUMBER:
+      {
+       SilcAttributeObjPN *pn = object;
+       if (object_size != sizeof(*pn))
+         return NULL;
+       if (!pn->number || strlen(pn->number) < 5)
+         return NULL;
+       tmpbuf = silc_buffer_alloc(0);
+       if (!tmpbuf)
+         return NULL;
+       if (silc_buffer_format(tmpbuf,
+                              SILC_STR_UI_INT(pn->format),
+                              SILC_STR_UI_SHORT(strlen(pn->number)),
+                              SILC_STR_UI16_STRING(pn->number),
+                              SILC_STR_END) < 0)
+         return NULL;
+       object = tmpbuf->data;
+       object_size = silc_buffer_len(tmpbuf);
+      }
+      break;
+
     case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
     case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
       {
@@ -263,11 +292,11 @@ SilcAttributePayload silc_attribute_payload_alloc(SilcAttribute attribute,
   attr->data =
     silc_attribute_payload_encode_int(attribute, flags, object,
                                      object_size, &tmp_len);
-  attr->data_len = (SilcUInt16)tmp_len;
   if (!attr->data) {
     silc_free(attr);
     return NULL;
   }
+  attr->data_len = (SilcUInt16)tmp_len;
 
   return attr;
 }
@@ -351,7 +380,8 @@ SilcBuffer silc_attribute_payload_encode_data(SilcBuffer attrs,
 
   len = 4 + (SilcUInt16)data_len;
   buffer = silc_buffer_realloc(buffer,
-                              (buffer ? silc_buffer_truelen(buffer) + len : len));
+                              (buffer ? silc_buffer_truelen(buffer) +
+                               len : len));
   if (!buffer)
     return NULL;
   silc_buffer_pull(buffer, silc_buffer_len(buffer));
@@ -466,7 +496,7 @@ unsigned char *silc_attribute_get_verify_data(SilcDList attrs,
 /* Return parsed attribute object */
 
 SilcBool silc_attribute_get_object(SilcAttributePayload payload,
-                              void *object, SilcUInt32 object_size)
+                                  void *object, SilcUInt32 object_size)
 {
   SilcUInt16 len;
   SilcBool ret = FALSE;
@@ -477,12 +507,14 @@ SilcBool silc_attribute_get_object(SilcAttributePayload payload,
   switch (payload->attribute) {
   case SILC_ATTRIBUTE_USER_INFO:
     {
+#ifdef SILC_DIST_VCARD
       SilcVCard vcard = object;
       if (object_size != sizeof(*vcard))
        break;
       if (!silc_vcard_decode(payload->data, payload->data_len, vcard))
        break;
       ret = TRUE;
+#endif /* SILC_DIST_VCARD */
     }
     break;
 
@@ -608,6 +640,28 @@ SilcBool silc_attribute_get_object(SilcAttributePayload payload,
     }
     break;
 
+  case SILC_ATTRIBUTE_PHONE_NUMBER:
+    {
+      SilcAttributeObjPN *pn = object;
+      SilcBufferStruct buffer;
+      SilcUInt32 pn_format;
+      int res;
+      if (object_size != sizeof(*pn))
+       break;
+      silc_buffer_set(&buffer, (unsigned char *)payload->data,
+                     payload->data_len);
+      res =
+       silc_buffer_unformat(&buffer,
+                            SILC_STR_UI_INT(&pn_format),
+                            SILC_STR_UI16_STRING_ALLOC(&pn->number),
+                            SILC_STR_END);
+      if (res == -1)
+       break;
+      pn->format = pn_format;
+      ret = TRUE;
+    }
+    break;
+
   case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
   case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
     {