Check for null-termination of strings
[platform/core/base/bundle.git] / src / keyval.c
index 4ca41bd..d49be0e 100755 (executable)
@@ -19,6 +19,7 @@
  * Implementation of keyval object
  */
 
+#define _GNU_SOURCE
 #include <stdlib.h>
 
 #include "keyval_type.h"
@@ -38,6 +39,7 @@ keyval_t *keyval_new(keyval_t *kv, const char *key,
                const int type, const void *val, const size_t size)
 {
        int must_free_obj = kv ? 0 : 1;
+       char *str;
 
        if (!kv) {
                kv = calloc(1, sizeof(keyval_t));
@@ -66,11 +68,17 @@ keyval_t *keyval_new(keyval_t *kv, const char *key,
                kv->val = calloc(1, size);
                if (!kv->val) {
                        set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
-                       keyval_free(kv, 1);
+                       keyval_free(kv, must_free_obj);
                        return NULL;
                }
-               if (val)
+               if (val) {
                        memcpy(kv->val, val, size);
+                       if (type == BUNDLE_TYPE_STR) {
+                               str = (char *)kv->val;
+                               if (str[size - 1] != '\0')
+                                       str[size - 1] = '\0';
+                       }
+               }
        }
 
        kv->method = &method;
@@ -117,6 +125,7 @@ int keyval_get_data(keyval_t *kv, int *type, void **val, size_t *size)
        return 0;
 }
 
+/* LCOV_EXCL_START */
 int keyval_compare(keyval_t *kv1, keyval_t *kv2)
 {
        if (!kv1 || !kv2)
@@ -138,6 +147,7 @@ int keyval_compare(keyval_t *kv1, keyval_t *kv2)
 
        return 0;
 }
+/* LCOV_EXCL_STOP */
 
 size_t keyval_get_encoded_size(keyval_t *kv)
 {
@@ -208,7 +218,7 @@ size_t keyval_encode(keyval_t *kv, unsigned char **byte, size_t *byte_len)
  *                  If kv is not NULL, given kv is used. (No new kv is created.)
  * @return        Number of bytes read from byte.
  */
-size_t keyval_decode(unsigned char *byte, keyval_t **kv)
+size_t keyval_decode(unsigned char *byte, keyval_t **kv, size_t byte_size)
 {
        static const size_t sz_byte_len = sizeof(size_t);
        static const size_t sz_type = sizeof(int);
@@ -221,18 +231,53 @@ size_t keyval_decode(unsigned char *byte, keyval_t **kv)
        size_t size;
        void *val;
        unsigned char *p = byte;
+       size_t encoded_size;
 
        byte_len = *((size_t *)p);
+
+       if (byte_size < sz_byte_len)
+               return 0;
+
+       byte_size -= sz_byte_len;
        p += sz_byte_len;
        type = *((int *)p);
+
+       if (byte_size < sz_type)
+               return 0;
+
+       byte_size -= sz_type;
        p += sz_type;
        keysize = *((size_t *)p);
+
+       if (byte_size < sz_keysize)
+               return 0;
+
+       byte_size -= sz_keysize;
        p += sz_keysize;
        key = (char *)p;
+
+       if (byte_size < keysize)
+               return 0;
+
+       if (!key || (strnlen(key, keysize) + 1) != keysize)
+               return 0;
+
+       byte_size -= keysize;
        p += keysize;
        size = *((size_t *)p);
+
+       if (byte_size < sz_size)
+               return 0;
+
+       byte_size -= sz_size;
        p += sz_size;
        val = (void *)p;
+
+       encoded_size = sz_byte_len + sz_type + sz_keysize + keysize +
+               sz_size + size;
+       if (encoded_size != byte_len)
+               return 0;
+
        p += size;
 
        if (kv)
@@ -247,7 +292,7 @@ int keyval_get_type_from_encoded_byte(unsigned char *byte)
        unsigned char *p = byte;
        int type;
 
-        p += sz_byte_len;
+       p += sz_byte_len;
        type = *((int *)p);
 
        return type;